Index: /tags/rel1_1/psLib/.cvsignore
===================================================================
--- /tags/rel1_1/psLib/.cvsignore	(revision 1056)
+++ /tags/rel1_1/psLib/.cvsignore	(revision 1056)
@@ -0,0 +1,5 @@
+bin
+lib
+docs
+testbin
+psLib.kdevelop.*
Index: /tags/rel1_1/psLib/src/.cvsignore
===================================================================
--- /tags/rel1_1/psLib/src/.cvsignore	(revision 1056)
+++ /tags/rel1_1/psLib/src/.cvsignore	(revision 1056)
@@ -0,0 +1,1 @@
+DoxygenLog
Index: /tags/rel1_1/psLib/src/Doxyfile
===================================================================
--- /tags/rel1_1/psLib/src/Doxyfile	(revision 1056)
+++ /tags/rel1_1/psLib/src/Doxyfile	(revision 1056)
@@ -0,0 +1,1083 @@
+# Doxyfile 1.3.4
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+#       TAG = value [value, ...]
+# For lists items can also be appended using:
+#       TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
+# by quotes) that should identify the project.
+
+PROJECT_NAME           = "Pan-STARRS Foundation Library"
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number.
+# This could be handy for archiving the generated documentation or
+# if some version control system is used.
+
+PROJECT_NUMBER         = 
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
+# base path where the generated documentation will be put.
+# If a relative path is entered, it will be relative to the location
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       = ../docs
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# The default language is English, other supported languages are:
+# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch,
+# Finnish, French, German, Greek, Hungarian, Italian, Japanese, Japanese-en
+# (Japanese with English messages), Korean, Norwegian, Polish, Portuguese,
+# Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian.
+
+OUTPUT_LANGUAGE        = English
+
+# This tag can be used to specify the encoding used in the generated output.
+# The encoding is not always determined by the language that is chosen,
+# but also whether or not the output is meant for Windows or non-Windows users.
+# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES
+# forces the Windows encoding (this is the default for the Windows binary),
+# whereas setting the tag to NO uses a Unix-style encoding (the default for
+# all platforms other than Windows).
+
+USE_WINDOWS_ENCODING   = NO
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
+# include brief member descriptions after the members that are listed in
+# the file and class documentation (similar to JavaDoc).
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
+# the brief description of a member or function before the detailed description.
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF           = YES
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# Doxygen will generate a detailed section even if there is only a brief
+# description.
+
+ALWAYS_DETAILED_SEC    = YES
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all inherited
+# members of a class in the documentation of that class as if those members were
+# ordinary class members. Constructors, destructors and assignment operators of
+# the base classes will not be shown.
+
+INLINE_INHERITED_MEMB  = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
+# path before files name in the file list and in the header files. If set
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES        = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
+# can be used to strip a user-defined part of the path. Stripping is
+# only done if one of the specified strings matches the left-hand part of
+# the path. It is allowed to use relative paths in the argument list.
+
+STRIP_FROM_PATH        =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
+# (but less readable) file names. This can be useful is your file systems
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES            = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
+# will interpret the first line (until the first dot) of a JavaDoc-style
+# comment as the brief description. If set to NO, the JavaDoc
+# comments will behave just like the Qt-style comments (thus requiring an
+# explict @brief command for a brief description.
+
+JAVADOC_AUTOBRIEF      = YES
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
+# treat a multi-line C++ special comment block (i.e. a block of //! or ///
+# comments) as a brief description. This used to be the default behaviour.
+# The new default is to treat a multi-line C++ comment block as a detailed
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the DETAILS_AT_TOP tag is set to YES then Doxygen
+# will output the detailed description near the top, like JavaDoc.
+# If set to NO, the detailed description appears after the member
+# documentation.
+
+DETAILS_AT_TOP         = YES
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
+# member inherits the documentation from any documented member that it
+# reimplements.
+
+INHERIT_DOCS           = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab.
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE               = 4
+
+# This tag can be used to specify a number of aliases that acts
+# as commands in the documentation. An alias has the form "name=value".
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to
+# put the command \sideeffect (or @sideeffect) in the documentation, which
+# will result in a user-defined paragraph with heading "Side Effects:".
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES                =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
+# only. Doxygen will then generate output that is more tailored for C.
+# For instance, some of the names that are used will be different. The list
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C  = YES
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources
+# only. Doxygen will then generate output that is more tailored for Java.
+# For instance, namespaces will be presented as packages, qualified scopes
+# will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA   = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
+# the same type (for instance a group of public functions) to be put as a
+# subgroup of that type (e.g. under the Public Functions section). Set it to
+# NO to prevent subgrouping. Alternatively, this can be done per class using
+# the \nosubgrouping command.
+
+SUBGROUPING            = NO
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available.
+# Private class members and static file members will be hidden unless
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL            = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
+# will be included in the documentation.
+
+EXTRACT_PRIVATE        = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file
+# will be included in the documentation.
+
+EXTRACT_STATIC         = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
+# defined locally in source files will be included in the documentation.
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES  = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
+# undocumented members of documented classes, files or namespaces.
+# If set to NO (the default) these members will be included in the
+# various overviews, but no documentation section is generated.
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS     = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy.
+# If set to NO (the default) these classes will be included in the various
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES     = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
+# friend (class|struct|union) declarations.
+# If set to NO (the default) these declarations will be included in the
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS  = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any 
+# documentation blocks found inside the body of a function. 
+# If set to NO (the default) these blocks will be appended to the 
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS      = NO
+
+# The INTERNAL_DOCS tag determines if documentation 
+# that is typed after a \internal command is included. If the tag is set 
+# to NO (the default) then the documentation will be excluded.
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS          = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate 
+# file names in lower-case letters. If set to YES upper-case letters are also 
+# allowed. This is useful if you have classes or files whose names only differ 
+# in case and if your file system supports case sensitive file names. Windows 
+# users are advised to set this option to NO.
+
+CASE_SENSE_NAMES       = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen 
+# will show members with their full class and namespace scopes in the 
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES       = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen 
+# will put a list of the files that are included by a file in the documentation 
+# of that file.
+
+SHOW_INCLUDE_FILES     = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] 
+# is inserted in the documentation for inline members.
+
+INLINE_INFO            = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen 
+# will sort the (detailed) documentation of file and class members 
+# alphabetically by member name. If set to NO the members will appear in 
+# declaration order.
+
+SORT_MEMBER_DOCS       = YES
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or 
+# disable (NO) the todo list. This list is created by putting \todo 
+# commands in the documentation.
+
+GENERATE_TODOLIST      = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or 
+# disable (NO) the test list. This list is created by putting \test 
+# commands in the documentation.
+
+GENERATE_TESTLIST      = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or 
+# disable (NO) the bug list. This list is created by putting \bug 
+# commands in the documentation.
+
+GENERATE_BUGLIST       = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or 
+# disable (NO) the deprecated list. This list is created by putting 
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional 
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS       =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines 
+# the initial value of a variable or define consists of for it to appear in 
+# the documentation. If the initializer consists of more lines than specified
+# here it will be hidden. Use a value of 0 to hide initializers completely. 
+# The appearance of the initializer of individual variables and defines in the 
+# documentation can be controlled using \showinitializer or \hideinitializer 
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES  = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated 
+# at the bottom of the documentation of classes and structs. If set to YES the 
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES        = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated 
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET                  = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are 
+# generated by doxygen. Possible values are YES and NO. If left blank
+# NO is used.
+
+WARNINGS               = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings 
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will 
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED   = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for 
+# potential errors in the documentation, such as not documenting some 
+# parameters in a documented function, or documenting parameters that 
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR      = YES
+
+# The WARN_FORMAT tag determines the format of the warning messages that 
+# doxygen can produce. The string should contain the $file, $line, and $text 
+# tags, which will be replaced by the file and line number from which the 
+# warning originated and the warning text.
+
+WARN_FORMAT            = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning 
+# and error messages should be written. If left blank the output is written 
+# to stderr.
+
+WARN_LOGFILE           = DoxygenLog
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain 
+# documented source files. You may enter file names like "myfile.cpp" or 
+# directories like "/usr/src/myproject". Separate the files or directories 
+# with spaces.
+
+INPUT                  = pslib.h \
+                         mainpage.dox \
+                         sysUtils \
+                         dataManip \
+                         collections
+
+# If the value of the INPUT tag contains directories, you can use the 
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank the following patterns are tested:
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp
+# *.h++ *.idl *.odl *.cs *.php *.php3 *.inc
+
+FILE_PATTERNS          = *.h *.dox
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories
+# should be searched for input files as well. Possible values are YES and NO.
+# If left blank NO is used.
+
+RECURSIVE              = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should
+# excluded from the INPUT source files. This way you can easily exclude a 
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE                =
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories 
+# that are symbolic links (a Unix filesystem feature) are excluded from the input.
+
+EXCLUDE_SYMLINKS       = NO
+
+# If the value of the INPUT tag contains directories, you can use the 
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude 
+# certain files from those directories.
+
+EXCLUDE_PATTERNS       = *_wrap.c
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or
+# directories that contain example code fragments that are included (see 
+# the \include command).
+
+EXAMPLE_PATH           =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the 
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank all files are included.
+
+EXAMPLE_PATTERNS       = 
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be 
+# searched for input files to be used with the \include or \dontinclude 
+# commands irrespective of the value of the RECURSIVE tag. 
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE      = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or 
+# directories that contain image that are included in the documentation (see 
+# the \image command).
+
+IMAGE_PATH             = 
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should 
+# invoke to filter for each input file. Doxygen will invoke the filter program 
+# by executing (via popen()) the command <filter> <input-file>, where <filter> 
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an 
+# input file. Doxygen will then use the output that the filter program writes 
+# to standard output.
+
+INPUT_FILTER           = 
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using 
+# INPUT_FILTER) will be used to filter the input files when producing source 
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES    = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will 
+# be generated. Documented entities will be cross-referenced with these sources.
+
+SOURCE_BROWSER         = YES
+
+# Setting the INLINE_SOURCES tag to YES will include the body 
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES         = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct 
+# doxygen to hide any special comment blocks from generated source code 
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS    = NO
+
+# If the REFERENCED_BY_RELATION tag is set to YES (the default) 
+# then for each documented function all documented 
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = YES
+
+# If the REFERENCES_RELATION tag is set to YES (the default) 
+# then for each documented function all documented entities 
+# called/used by that function will be listed.
+
+REFERENCES_RELATION    = YES
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen 
+# will generate a verbatim copy of the header file for each class for 
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS       = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index 
+# of all compounds will be generated. Enable this if the project 
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX     = YES
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then 
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns 
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX    = 5
+
+# In case all classes in a project start with a common prefix, all 
+# classes will be put under the same header in the alphabetical index. 
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that 
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX          = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will 
+# generate HTML output.
+
+GENERATE_HTML          = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT            = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for 
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank 
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION    = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard header.
+
+HTML_HEADER            = 
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard footer.
+
+HTML_FOOTER            =
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading 
+# style sheet that is used by each HTML page. It can be used to 
+# fine-tune the look of the HTML output. If the tag is left blank doxygen 
+# will generate a default style sheet
+
+HTML_STYLESHEET        = 
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, 
+# files or namespaces will be aligned in HTML using tables. If set to 
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS     = YES
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files 
+# will be generated that can be used as input for tools like the 
+# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) 
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP      = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can 
+# be used to specify the file name of the resulting .chm file. You 
+# can add a path in front of the file if the result should not be 
+# written to the html output dir.
+
+CHM_FILE               = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can 
+# be used to specify the location (absolute path including file name) of 
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run 
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION           = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag 
+# controls if a separate .chi index file is generated (YES) or that 
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI           = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag 
+# controls whether a binary table of contents is generated (YES) or a 
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members 
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND             = YES
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at 
+# top of each HTML page. The value NO (the default) enables the index and 
+# the value YES disables it.
+
+DISABLE_INDEX          = NO
+
+# This tag can be used to set the number of enum values (range [1..20]) 
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE   = 10
+
+# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
+# generated containing a tree-like index structure (just like the one that 
+# is generated for HTML Help). For this to work a browser that supports 
+# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, 
+# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are 
+# probably better off using the HTML help feature.
+
+GENERATE_TREEVIEW      = NO
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be 
+# used to set the initial width (in pixels) of the frame in which the tree 
+# is shown.
+
+TREEVIEW_WIDTH         = 250
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will 
+# generate Latex output.
+
+GENERATE_LATEX         = YES
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT           = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be 
+# invoked. If left blank `latex' will be used as the default command name.
+
+LATEX_CMD_NAME         = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to 
+# generate index for LaTeX. If left blank `makeindex' will be used as the 
+# default command name.
+
+MAKEINDEX_CMD_NAME     = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact 
+# LaTeX documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_LATEX          = YES
+
+# The PAPER_TYPE tag can be used to set the paper type that is used 
+# by the printer. Possible values are: a4, a4wide, letter, legal and 
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE             = letter
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX 
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES         = times
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for 
+# the generated latex document. The header should contain everything until 
+# the first chapter. If it is left blank doxygen will generate a 
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER           = 
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated 
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will 
+# contain links (just like the HTML output) instead of page references 
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS         = YES
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of 
+# plain latex in the generated Makefile. Set this option to YES to get a 
+# higher quality PDF documentation.
+
+USE_PDFLATEX           = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. 
+# command to the generated LaTeX files. This will instruct LaTeX to keep 
+# running if errors occur, instead of asking the user for help. 
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE        = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not 
+# include the index chapters (such as File Index, Compound Index, etc.) 
+# in the output.
+
+LATEX_HIDE_INDICES     = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output 
+# The RTF output is optimised for Word 97 and may not look very pretty with 
+# other RTF readers or editors.
+
+GENERATE_RTF           = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT             = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact 
+# RTF documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_RTF            = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated 
+# will contain hyperlink fields. The RTF file will 
+# contain links (just like the HTML output) instead of page references. 
+# This makes the output suitable for online browsing using WORD or other 
+# programs which support those fields. 
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS         = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's 
+# config file, i.e. a series of assigments. You only have to provide 
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE    = 
+
+# Set optional variables used in the generation of an rtf document. 
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE    = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will 
+# generate man pages
+
+GENERATE_MAN           = YES
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT             = man
+
+# The MAN_EXTENSION tag determines the extension that is added to
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION          = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output, 
+# then it will generate one additional man file for each entity 
+# documented in the real man page(s). These additional files 
+# only source the real man page, but without them the man command 
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS              = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will 
+# generate an XML file that captures the structure of 
+# the code including all documentation. Note that this 
+# feature is still experimental and incomplete at the 
+# moment.
+
+GENERATE_XML           = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT             = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_SCHEMA             = 
+
+# The XML_DTD tag can be used to specify an XML DTD, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_DTD                = 
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will 
+# generate an AutoGen Definitions (see autogen.sf.net) file 
+# that captures the structure of the code including all 
+# documentation. Note that this feature is still experimental 
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will 
+# generate a Perl module file that captures the structure of 
+# the code including all documentation. Note that this 
+# feature is still experimental and incomplete at the 
+# moment.
+
+GENERATE_PERLMOD       = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate 
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able 
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX          = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be 
+# nicely formatted so it can be parsed by a human reader.  This is useful 
+# if you want to understand what is going on.  On the other hand, if this 
+# tag is set to NO the size of the Perl module output will be much smaller 
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY         = YES
+
+# The names of the make variables in the generated doxyrules.make file 
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. 
+# This is useful so different doxyrules.make files included by the same 
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
+# evaluate all C-preprocessor directives found in the sources and include
+# files.
+
+ENABLE_PREPROCESSING   = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro 
+# names in the source code. If set to NO (the default) only conditional 
+# compilation will be performed. Macro expansion can be done in a controlled 
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION        = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES 
+# then the macro expansion is limited to the macros specified with the 
+# PREDEFINED and EXPAND_AS_PREDEFINED tags.
+
+EXPAND_ONLY_PREDEF     = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files 
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that 
+# contain include files that are not input files but should be processed by 
+# the preprocessor.
+
+INCLUDE_PATH           =
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard 
+# patterns (like *.h and *.hpp) to filter out the header-files in the 
+# directories. If left blank, the patterns specified with FILE_PATTERNS will 
+# be used.
+
+INCLUDE_FILE_PATTERNS  = 
+
+# The PREDEFINED tag can be used to specify one or more macro names that 
+# are defined before the preprocessor is started (similar to the -D option of
+# gcc). The argument of the tag is a list of macros of the form: name
+# or name=definition (no spaces). If the definition and the = are
+# omitted =1 is assumed.
+
+PREDEFINED             = DOXYGEN
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
+# this tag can be used to specify a list of macro names that should be expanded.
+# The macro definition that is found in the sources will be used. 
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED      = 
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then 
+# doxygen's preprocessor will remove all function-like macros that are alone 
+# on a line, have an all uppercase name, and do not end with a semicolon. Such 
+# function macros are typically used for boiler-plate code, and will confuse the 
+# parser if not removed.
+
+SKIP_FUNCTION_MACROS   = YES
+
+#---------------------------------------------------------------------------
+# Configuration::addtions related to external references   
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles. 
+# Optionally an initial location of the external documentation 
+# can be added for each tagfile. The format of a tag file without 
+# this location is as follows: 
+#   TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows: 
+#   TAGFILES = file1=loc1 "file2 = loc2" ... 
+# where "loc1" and "loc2" can be relative or absolute paths or 
+# URLs. If a location is present for each tag, the installdox tool 
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen 
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES               =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create 
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE       =
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed 
+# in the class index. If set to NO only the inherited external classes 
+# will be listed.
+
+ALLEXTERNALS           = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed 
+# in the modules index. If set to NO, only the current project's groups will 
+# be listed.
+
+EXTERNAL_GROUPS        = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script 
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH              = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool   
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will 
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base or
+# super classes. Setting the tag to NO turns the diagrams off. Note that this 
+# option is superceded by the HAVE_DOT option below. This is only a fallback. It is 
+# recommended to install and use dot, since it yields more powerful graphs.
+
+CLASS_DIAGRAMS         = YES
+
+# If set to YES, the inheritance and collaboration graphs will hide 
+# inheritance and usage relations if the target is undocumented 
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS   = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is 
+# available from the path. This tool is part of Graphviz, a graph visualization 
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section 
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT               = NO
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect inheritance relations. Setting this tag to YES will force the 
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH            = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect implementation dependencies (inheritance, containment, and 
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH    = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and 
+# collaboration diagrams in a style similiar to the OMG's Unified Modeling 
+# Language.
+
+UML_LOOK               = YES
+
+# If set to YES, the inheritance and collaboration graphs will show the
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS     = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT 
+# tags are set to YES then doxygen will generate a graph for each documented 
+# file showing the direct and indirect include dependencies of the file with 
+# other documented files.
+
+INCLUDE_GRAPH          = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and 
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each 
+# documented header file showing the documented files that directly or 
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH      = YES
+
+# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will 
+# generate a call dependency graph for every global function or class method. 
+# Note that enabling this option will significantly increase the time of a run. 
+# So in most cases it will be better to enable call graphs for selected 
+# functions only using the \callgraph command.
+
+CALL_GRAPH             = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen 
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY    = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images 
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT       = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be 
+# found. If left blank, it is assumed the dot tool can be found on the path.
+
+DOT_PATH               = 
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that 
+# contain dot files that are included in the documentation (see the 
+# \dotfile command).
+
+DOTFILE_DIRS           = 
+
+# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width 
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than 
+# this value, doxygen will try to truncate the graph, so that it fits within 
+# the specified constraint. Beware that most browsers cannot cope with very 
+# large images.
+
+MAX_DOT_GRAPH_WIDTH    = 1024
+
+# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height 
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than 
+# this value, doxygen will try to truncate the graph, so that it fits within 
+# the specified constraint. Beware that most browsers cannot cope with very 
+# large images.
+
+MAX_DOT_GRAPH_HEIGHT   = 1024
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the 
+# graphs generated by dot. A depth value of 3 means that only nodes reachable 
+# from the root by following a path via at most 3 edges will be shown. Nodes that 
+# lay further from the root node will be omitted. Note that setting this option to 
+# 1 or 2 may greatly reduce the computation time needed for large code bases. Also 
+# note that a graph may be further truncated if the graph's image dimensions are 
+# not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH and MAX_DOT_GRAPH_HEIGHT). 
+# If 0 is used for the depth value (the default), the graph is not depth-constrained.
+
+MAX_DOT_GRAPH_DEPTH    = 0
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will 
+# generate a legend page explaining the meaning of the various boxes and 
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND        = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will 
+# remove the intermediate dot files that are used to generate 
+# the various graphs.
+
+DOT_CLEANUP            = YES
+
+#---------------------------------------------------------------------------
+# Configuration::addtions related to the search engine   
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be 
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE           = NO
+
Index: /tags/rel1_1/psLib/src/Makefile
===================================================================
--- /tags/rel1_1/psLib/src/Makefile	(revision 1056)
+++ /tags/rel1_1/psLib/src/Makefile	(revision 1056)
@@ -0,0 +1,164 @@
+###############################################################################
+##
+##  Makefile:  psLib
+##
+##  $Revision: 1.12.2.2 $  $Name: not supported by cvs2svn $
+##  $Date: 2004-06-15 21:48:46 $
+##
+##  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+##
+###############################################################################
+
+# Define variable prefix to the top level project - psLib
+# This is necessary for definition in Makefile.Globals
+
+ifndef prefix
+    export prefix=$(shell cd ..;pwd)
+endif
+
+# Include the make global definitions for the project
+
+include Makefile.Globals
+
+# Detect and save the CVS for this makefile
+
+NAME:= "$Name: not supported by cvs2svn $ "
+ifeq ($(NAME), "ame:  $ ")
+   VERSION:= ": Project Version: Unknown "
+else
+   VERSION:= ": Project Version: $(NAME) "
+endif
+
+# Define the target to build
+
+ALLTARGETS = sysUtils collections dataManip
+
+TARGET_DYNAMIC = libpslib.$(DLL)
+TARGET_STATIC = libpslib.a
+
+# Define the installation targets
+
+INSTALLTARGETS = installSysUtils installCollections installDataManip
+
+# Define the clean up targets
+
+CLEANTARGETS = cleanSysUtils cleanCollections cleanDataManip
+
+# Define the distribution clean up targets
+
+DISTCLEANTARGETS = distcleanSysUtils distcleanCollections distcleanDataManip
+
+# Define PHONY target "all" which will make all necessary items
+
+all:	$(ALLTARGETS)
+	$(BUILD_DYNAMIC1) $(TARGET_STATIC) $(BUILD_DYNAMIC2) $(TARGET_DYNAMIC)
+	@echo ""
+	@echo "    ---- All targets built successfully $(VERSION) ----"
+	@echo ""
+
+# Define PHONY target "sysUtils" which will make the system utilites
+# portion of the psLib
+
+sysUtils:
+	$(MAKE) --directory=sysUtils all
+
+collections:
+	$(MAKE) --directory=collections all
+
+dataManip:
+	$(MAKE) --directory=dataManip all
+
+
+## ADD ADDITIONAL PORTIONS OF PSLIB HERE
+
+# Define PHONY target "installSysUtils" which will install all the necessary
+# files for system utilities portion of psLib
+
+installSysUtils:
+	$(MAKE) --directory=sysUtils install
+
+installCollections:
+	$(MAKE) --directory=collections install
+
+installDataManip:
+	$(MAKE) --directory=dataManip install
+
+
+# Define PHONY target "cleanSysUtils" which will clean up the development
+# area for system utilites
+
+cleanSysUtils:
+	$(MAKE) --directory=sysUtils clean
+
+cleanCollections:
+	$(MAKE) --directory=collections clean
+
+cleanDataManip:
+	$(MAKE) --directory=dataManip clean
+
+# Define PHONY target "distcleanSysUtils which will clean up the distribution
+# files related to system utilities
+
+distcleanSysUtils:
+	$(MAKE) --directory=sysUtils distclean
+        
+distcleanCollections:
+	$(MAKE) --directory=collections distclean
+
+distcleanDataManip:
+	$(MAKE) --directory=dataManip distclean
+
+
+# Rule to make include directory if needed
+
+$(includedir):
+	mkdir -p $(includedir)
+
+# Rule to make bin directory if needed
+
+$(bindir):
+	mkdir -p $(bindir)
+
+# Rule to make lib directory if needed
+
+$(libexecdir):
+	mkdir -p $(libexecdir)
+        
+# Rule to make the installation directories if needed
+
+installdirs: $(includedir) $(bindir) $(libexecdir)
+
+# Define PHONY target "install" to make the necessary directories for
+# the installation
+
+install: all installdirs $(INSTALLTARGETS)
+	install *.h $(includedir)
+	install $(TARGET_STATIC) $(libexecdir)
+	install $(TARGET_DYNAMIC) $(libexecdir)
+
+# Define PHONY target "clean" to clean up the development areas for
+# psLib
+
+clean: $(CLEANTARGETS)
+	$(RM) -f $(TARGET_STATIC)
+	$(RM) -f $(TARGET_DYNAMIC)
+
+# Define PHONY target "distclean" to clean up the distribution area for
+# psLib
+
+distclean: $(DISTCLEANTARGETS)
+	$(RM) -f $(libexecdir)/$(TARGET_STATIC)
+	$(RM) -f $(libexecdir)/$(TARGET_DYNAMIC)
+	$(RM) -f $(TARGET_DYNAMIC)
+	$(RM) -f $(TARGET_STATIC)
+
+# Define PHONY target "docs" to generate the Doxygen files for psLib
+        
+docs:
+	$(DOCS)
+
+tags:	
+	cd $(IPPROOT) ; etags `find . \( -name \*.[chy] -o -name \*.cpp \) -print`
+
+# List of PHONY targets with make file
+.PHONY:  sysUtils collections dataManip
Index: /tags/rel1_1/psLib/src/Makefile.Globals
===================================================================
--- /tags/rel1_1/psLib/src/Makefile.Globals	(revision 1056)
+++ /tags/rel1_1/psLib/src/Makefile.Globals	(revision 1056)
@@ -0,0 +1,91 @@
+################################################################################
+##
+##  Makefile:  Globals
+##
+##  Assumptions:    Variable "prefix" already defined
+##
+##  $Revision: 1.10.2.3 $  $Name: not supported by cvs2svn $
+##  $Date: 2004-06-15 22:06:36 $
+##
+##  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+##
+###############################################################################
+
+# Determine the operating system and set variable for later conditional use
+
+ifndef OSTYPE
+    OSTYPE = $(shell uname -s)
+endif
+
+# Set environment variables for the project's directory structure
+
+ifndef mandir
+    export mandir = $(prefix)/man
+endif
+
+ifndef includedir
+    export includedir = $(prefix)/include
+endif
+
+ifndef testbindir
+    export testbindir = $(prefix)/testbin
+endif
+
+ifndef bindir
+    export bindir = $(prefix)/bin
+endif
+
+ifndef libexecdir
+    export libexecdir = $(prefix)/lib
+endif
+
+# Set initial value for CFLAGS which will include all OS common flags for GCC
+
+CFLAGS := -O0 -g2 -Wall -Werror -std=c99 -D_GNU_SOURCE -pipe
+
+# Set initial value for LDFLAGS which will include all OS common flags for GCC and required libraries.
+
+EXTLIBS := -lcfitsio -lgsl -lgslcblas -lfftw3f
+LDFLAGS := -g2 -pipe $(EXTLIBS) 
+
+# Define or refine variables for the Linux OS
+
+ifneq "$(findstring inux,$(OSTYPE))" ""
+    CFLAGS_RELOC := $(CFLAGS) -fpic
+    LDFLAGS_SO := $(LDFLAGS) -fpic -shared -ldl
+    LDFLAGS_DLL := $(LDFLAGS) -fpic -shared
+    DLL = so
+    SO  = so
+    DOCS = doxygen Doxyfile; make --directory=$(prefix)/docs/latex
+    BUILD_DYNAMIC1 = $(CC) $(LDFLAGS_DLL) -Wl,--whole-archive
+    BUILD_DYNAMIC2 = -Wl,--no-whole-archive -lm -o
+endif
+
+ifneq "$(findstring arwin,$(OSTYPE))" ""
+    CFLAGS += -Wno-long-double -DDARWIN
+    CFLAGS_RELOC := $(CFLAGS)
+    LDFLAGS := $(LDFLAGS) -lmx
+    LDFLAGS_SO := $(LDFLAGS) -bundle -flat_namespace -undefined suppress
+    LDFLAGS_DLL := $(LDFLAGS) -dynamiclib
+    DLL = dylib
+    SO = bundle
+    DOCS =
+    BUILD_DYNAMIC1 = libtool -dynamic
+    BUILD_DYNAMIC2 = -lm -lmx -lgcc $(EXTLIBS) -o
+endif
+
+# Set default for variable CC
+
+ifndef CC
+    export CC=cc
+endif
+
+# Set default for variable LD
+
+ifndef LD
+    export LD=ld
+endif
+
+# Set list of PHONY targets
+.PHONY: all install distclean clean docs tags print_header
+
Index: /tags/rel1_1/psLib/src/collections/.cvsignore
===================================================================
--- /tags/rel1_1/psLib/src/collections/.cvsignore	(revision 1056)
+++ /tags/rel1_1/psLib/src/collections/.cvsignore	(revision 1056)
@@ -0,0 +1,1 @@
+*.i
Index: /tags/rel1_1/psLib/src/collections/Makefile
===================================================================
--- /tags/rel1_1/psLib/src/collections/Makefile	(revision 1056)
+++ /tags/rel1_1/psLib/src/collections/Makefile	(revision 1056)
@@ -0,0 +1,82 @@
+###############################################################################
+##
+##  Makefile:   collections
+##
+##  $Revision: 1.20 $  $Name: not supported by cvs2svn $
+##  $Date: 2004-06-10 20:40:26 $
+##
+##  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+###############################################################################
+
+# Define variable prefix to the top level project - psLib
+# This is necessary for definition is Makefile.Globals uses prefix
+
+ifndef prefix
+    export prefix=$(shell cd ../..;pwd)
+endif
+
+# Define the two targets to be built
+
+TARGET_STATIC  = libpslib.a
+
+# Include the make global definitions for the project
+
+include ../Makefile.Globals
+
+# Set CFLAGS used by the implicit rule to compile .c
+
+CFLAGS := $(CFLAGS_RELOC) -I../sysUtils 
+
+# Define the source objects
+ 
+SRC_OBJS = psBitSet.o \
+           psVector.o \
+           psSort.o \
+           psImage.o \
+           psList.o
+
+# Define PHONY target "all" which will make all the necessary items
+
+all: $(TARGET_STATIC)
+
+# force the creation of a psImage.i for psImage.o (to expand macros).
+psImage.o: psImage.i
+
+# Rule to make static library
+
+libpslib.a: $(SRC_OBJS)
+# The ar option -r is to add/replace object and -s is to create
+# a symbol table in the archive
+	$(AR) rcs ../$@ $(SRC_OBJS)
+
+# Define PHONY target "install" which will install necessary files
+
+install: $(TARGET_STATIC)
+	install *.h $(includedir)
+
+# Define PHONY target "distclean" which will cleanup the distribution
+
+distclean:	clean
+	$(RM) ../$(TARGET_STATIC)
+
+# Define PHONY target "clean" which will cleanup the development area
+
+clean:
+	@echo "    Deleting intermediate files for 'collections'"
+	$(RM) $(SRC_OBJS) *.lint $(SRC_OBJS:.o=.i)
+
+%.lint: %.c
+	splint +posixlib -exportlocal -realcompare $(INCLUDE_GLOBAL) $? > $@; cat $@
+
+%.i: %.c
+	$(CC) -E $(CFLAGS) -o $@ $<
+
+%.o: %.i
+	$(CC) -c $(CFLAGS) -o $@ $<
+
+%.d: %.c
+	$(CC) -MM $(CFLAGS) $< > $@.tmp
+	sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' $@.tmp > $@
+	$(RM) -f $@.tmp
+
+include $(SRC_OBJS:.o=.d)
Index: /tags/rel1_1/psLib/src/collections/psBitSet.c
===================================================================
--- /tags/rel1_1/psLib/src/collections/psBitSet.c	(revision 1056)
+++ /tags/rel1_1/psLib/src/collections/psBitSet.c	(revision 1056)
@@ -0,0 +1,232 @@
+/** @file  psBitSet.c
+ *
+ *  @brief Creates an array of bytes of arbitrary length for storing individual bits.
+ *
+ *  Bit masks are useful tools for toggling various flags and options. This set of functions module provides
+ *  a mechanism to create an array of bits of arbitrary length and manipulate them with basic binary
+ *  operations. A print function is also provided to display the entire set of bits in binary format as a
+ *  string.
+ *
+ *  @author Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.6.2.1 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-15 03:09:18 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+/******************************************************************************/
+/*  INCLUDE FILES                                                             */
+/******************************************************************************/
+#include <string.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <math.h>
+
+#include "psBitSet.h"
+#include "psMemory.h"
+#include "psError.h"
+
+/******************************************************************************/
+/*  DEFINE STATEMENTS                                                         */
+/******************************************************************************/
+
+// None
+
+/******************************************************************************/
+/*  TYPE DEFINITIONS                                                          */
+/******************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  GLOBAL VARIABLES                                                         */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  FILE STATIC VARIABLES                                                    */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  FUNCTION IMPLEMENTATION - LOCAL                                          */
+/*****************************************************************************/
+
+/** Private function to create a mask.
+ *
+ *  Creates an eight bit mask with the given bit set. All other bits in the byte are zero. The input bit uses
+ *  zero-based indexing, and is the cumulitive index within the array, not the localized byte's bit position.
+ *
+ *  @return  char*: Pointer to byte in which bit is contained.
+ */
+static char mask(int bit)
+{
+    char mask = (char)0x01;
+    // Ignore splint warning about negative bit shifts
+    /*@i@*/
+    mask = mask << (bit%8);
+
+    return mask;
+}
+
+/*****************************************************************************/
+/* FUNCTION IMPLEMENTATION - PUBLIC                                          */
+/*****************************************************************************/
+psBitSet* psBitSetAlloc(int n)
+{
+    int numBytes = 0;
+    psBitSet *newObj = NULL;
+
+    if(n <= 0) {
+        psError(__func__, " : Line %d - Allocation size must be > 0: size = %d\n", __LINE__, n);
+        return 0;
+    }
+
+    numBytes = ceil(n/8.0);
+    newObj = psAlloc(sizeof(psBitSet));
+    newObj->n = numBytes;
+
+    // Ignore splint warning about releasing pointer members, since they've not been allocated yet
+    /*@i@*/
+    newObj->bits = psAlloc(sizeof(char)*numBytes);
+    memset(newObj->bits, numBytes, 0);
+
+    return newObj;
+}
+
+void psBitSetFree(psBitSet *restrict inBitSet)
+{
+    if(inBitSet == NULL) {
+        psError(__func__, " : Line %d - Null psBitSet for inBitSet argument\n", __LINE__);
+        return;
+    }
+    psFree(inBitSet->bits);
+    psFree(inBitSet);
+}
+
+psBitSet* psBitSetSet(psBitSet *inBitSet, int bit)
+{
+    char* byte = NULL;
+
+    if(inBitSet == NULL) {
+        psError(__func__, " : Line %d - Null psBitSet for inBitSet argument\n", __LINE__);
+        return inBitSet;
+    } else if(bit < 0) {
+        psError(__func__, " : Line %d - Bit position too small: %d\n", __LINE__, bit);
+        return inBitSet;
+    } else if(bit > inBitSet->n*8-1) {
+        psError(__func__, " : Line %d - Bit position too large: %d\n", __LINE__, bit);
+        return inBitSet;
+    }
+
+    // Variable byte is the byte in the array that contains the bit to be set
+    byte = inBitSet->bits+bit/8;
+    *byte |= mask(bit);
+
+    return inBitSet;
+}
+
+int psBitSetTest(const psBitSet *inBitSet, int bit)
+{
+    char* byte = NULL;
+
+    if(inBitSet == NULL) {
+        psError(__func__, " : Line %d - Null psBitSet for inBitSet argument\n", __LINE__);
+        return 0;
+    } else if(bit < 0) {
+        psError(__func__, " : Line %d - Bit position too small: %d\n", __LINE__, bit);
+        return 0;
+    } else if(bit > inBitSet->n*8-1) {
+        psError(__func__, " : Line %d - Bit position too large: %d\n", __LINE__, bit);
+        return 0;
+    }
+
+    // Variable byte is the byte in the array that contains the bit to be tested
+    byte = inBitSet->bits+bit/8;
+    if((int)(*byte&mask(bit)) == 0) {
+        return 0;
+    }
+
+    return 1;
+}
+
+psBitSet* psBitSetOp(psBitSet *outBitSet, const psBitSet *restrict inBitSet1, char *operator,
+                     const psBitSet *restrict inBitSet2)
+{
+    int i = 0;
+    int n = 0;
+    char tempChar = '0';
+    char *outBits = NULL;
+    char *inBits1 = NULL;
+    char *inBits2 = NULL;
+
+    if(outBitSet == NULL) {
+        psError(__func__, " : Line %d - Null psBitSet for outBitSet argument\n", __LINE__);
+        return outBitSet;
+    }
+
+    if(inBitSet1 == NULL) {
+        psError(__func__, " : Line %d - Null psBitSet for inBitSet1 argument\n", __LINE__);
+        return outBitSet;
+    }
+
+    if(operator == NULL) {
+        psError(__func__, " : Line %d - Null input operator\n", __LINE__);
+        return outBitSet;
+    }
+
+    if(inBitSet2 == NULL) {
+        psError(__func__, " : Line %d - Null psBitSet for inBitSet2 argument\n", __LINE__);
+        return outBitSet;
+    }
+
+    if(inBitSet1->n != inBitSet2->n || outBitSet->n != inBitSet1->n) {
+        psError(__func__, " : Line %d - psBitSet sizes not the same\n", __LINE__);
+        return outBitSet;
+    }
+
+    n = outBitSet->n;
+    outBits = outBitSet->bits;
+    inBits1 = inBitSet1->bits;
+    inBits2 = inBitSet2->bits;
+
+    tempChar = toupper(operator[0]);
+    switch(tempChar) {
+    case 'A':
+        for(i=0; i<n; i++) {
+            outBits[i] = inBits1[i] & inBits2[i];
+        }
+        break;
+    case 'O':
+        for(i=0; i<n; i++) {
+            outBits[i] = inBits1[i] | inBits2[i];
+        }
+        break;
+    case 'X':
+        for(i=0; i<n; i++) {
+            outBits[i] = inBits1[i] ^ inBits2[i];
+        }
+        break;
+    default:
+        psError(__func__, " : Line %d - Invalid psBitMask binary operation: %s\n", __LINE__, operator);
+    }
+
+    return outBitSet;
+}
+
+char *psBitSetToString(const psBitSet *restrict inBitSet)
+{
+    int i = 0;
+    int numBits = inBitSet->n*8;
+    char* outString = psAlloc((size_t)numBits+1);
+    for(i=0; i<numBits; i++) {
+        outString[numBits-i-1] = (psBitSetTest(inBitSet, i) == 1)?'1':'0';
+    }
+
+    outString[numBits] = 0;
+
+    return outString;
+}
Index: /tags/rel1_1/psLib/src/collections/psBitSet.d
===================================================================
--- /tags/rel1_1/psLib/src/collections/psBitSet.d	(revision 1056)
+++ /tags/rel1_1/psLib/src/collections/psBitSet.d	(revision 1056)
@@ -0,0 +1,2 @@
+psBitSet.o psBitSet.d : psBitSet.c psBitSet.h ../sysUtils/psMemory.h \
+  ../sysUtils/psError.h
Index: /tags/rel1_1/psLib/src/collections/psBitSet.h
===================================================================
--- /tags/rel1_1/psLib/src/collections/psBitSet.h	(revision 1056)
+++ /tags/rel1_1/psLib/src/collections/psBitSet.h	(revision 1056)
@@ -0,0 +1,120 @@
+/** @file  psBitSet.h
+ *
+ *  @brief Creates an array of bytes of arbitrary length for storing individual bits.
+ *
+ *  Bit masks are useful tools for toggling various flags and options. This set of functions module provides
+ *  a mechanism to create an array of bits of arbitrary length and manipulate them with basic binary
+ *  operations. A print function is also provided to display the entire set of bits in binary format as a
+ *  string.
+ *
+ *  @ingroup BitSet
+ *
+ *  @author Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.6 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-10 01:58:06 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PSBITSET_H
+#define PSBITSET_H
+
+/// @addtogroup BitSet
+/// @{
+
+/******************************************************************************/
+/*  TYPE DEFINITIONS                                                          */
+/******************************************************************************/
+
+/** Struct containing array of bytes to hold bit data and corresponding array length.
+ *
+ *  The bits in the struct are assembled in as an array of bytes with eight bits per byte. The bits are
+ *  arranged with the LSB in first (right most) position of the first array element.
+ */
+typedef struct
+{
+    int n;      /**< Number of bytes in the array */
+    char *bits; /**< Aray of bytes holding bits */
+}
+psBitSet;
+
+/*****************************************************************************/
+/* FUNCTION PROTOTYPES                                                       */
+/*****************************************************************************/
+
+/** Allocate a psBitSet.
+ *
+ *  Create a psBitSet with the number of bits specified by the user. All bits are set to zero upon
+ *  allocation.
+ *
+ *  @return  psBitSet*: Pointer to struct containing array of bits and size of array.
+ */
+/*@null@*/
+psBitSet* psBitSetAlloc(
+    int n   /**< Number of bits in psBitSet array */
+);
+
+/** Free a psBitSet
+ *
+ *  Deletes a psBitSet array.
+ */
+void psBitSetFree(
+    psBitSet *restrict inMask  /**< Pointer to psBitSet to be deleted. */
+);
+
+/** Set a bit.
+ *
+ *  Sets a bit at a given bit location, either one or zero. The bit is set based on a zero index with the
+ *  first bit set in the zero bit slot of the zero element of the byte array. As an example, setting bit 3 in
+ *  an array with two elements would result in an psBitSet that looks like 00000000 00001000.
+ *
+ *  @return  psBitSet*: Pointer to struct containing psBitSet.
+ */
+psBitSet* psBitSetSet(
+    /*@returned@*/psBitSet *restrict inMask,  /**< Pointer to psBitSet to be set. */
+    int bit                     /**< Bit to be set. */
+);
+
+/** Test the value of a bit.
+ *
+ *  Prints the value of a bit at a given bit location, either one or zero. The resulting bit is based on a
+ *  zero index format with the first bit set in the zero bit slot of the zero element of the byte array
+ *  As an example, testing bit 3 in a psBitSet with two bytes that looks like 00000000 00001000 would return a
+ *  value of one, since that is the value that was set.
+ *
+ *  @return  int: Value of bit, either one or zero.
+ */
+int psBitSetTest(
+    const psBitSet *restrict inMask,    /**< Pointer psBitSet to be tested. */
+    int bit                             /**< Bit to be tested. */
+);
+
+/** Perform a binary operation on two psBitSets
+ *
+ *  Perform an AND, OR, or XOR on two psBitSets. If the BitMasks are not the same size, the operation will not
+ *  be performed and an error message will be logged.
+ *
+ *  @return  psBitSet*: Pointer to struct containing result of binary operation.
+ */
+psBitSet* psBitSetOp(
+    /*@returned@*/psBitSet *restrict outMask,   /**< Resulting psBitSet from binary operation */
+    const psBitSet *restrict inMask1,           /**< First psBitSet on which to operate */
+    char *operator,                             /**< Bit operation */
+    const psBitSet *restrict inMask2            /**< First psBitSet on which to operate */
+);
+
+/** Convert the psBitSet to a string of ones and zeros.
+ *
+ *  Converts the contents of a psBitSet to a string representation of its binary form of ones and zeros. The
+ *  LSB is the right-most chracter. Each set of eight characters represents one byte.
+ *
+ *  @return  char*: Pointer to character array containing string data.
+ */
+char *psBitSetToString(
+    const psBitSet *restrict inMask /**< psBitSet to convert */
+);
+
+/// @}
+
+#endif
Index: /tags/rel1_1/psLib/src/collections/psList.c
===================================================================
--- /tags/rel1_1/psLib/src/collections/psList.c	(revision 1056)
+++ /tags/rel1_1/psLib/src/collections/psList.c	(revision 1056)
@@ -0,0 +1,458 @@
+/** @file psList.c
+ *  @brief Support for doubly linked lists
+ *  @ingroup DataContainers
+ *
+ *  @author Robert Lupton, Princeton University
+ *  @author Robert Daniel DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.6 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-14 19:45:46 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include <stdlib.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <pthread.h>                   // we need a mutex to make this stuff thread safe.
+
+#include "psError.h"
+#include "psAbort.h"
+#include "psMemory.h"
+#include "psList.h"
+#include "psTrace.h"
+#include "psLogMsg.h"
+
+#define ITER_INIT_HEAD ((void *)1) // next iteration should return head
+#define ITER_INIT_TAIL ((void *)2) // next iteration should return tail
+
+// private functions.
+psListElem* listGetIterator(psList* list);
+int listGetIteratorIndex(psList* list);
+void listSetIterator(psList *list, int where, bool lockList);
+
+
+psList *psListAlloc(void *data)
+{
+    psList *list = psAlloc(sizeof(psList));
+
+    list->size = 0;
+    list->head = list->tail = NULL;
+    list->iter = ITER_INIT_HEAD;
+    list->iterIndex = PS_LIST_HEAD;
+    pthread_mutex_init(&(list->lock),NULL)
+    ;
+
+    if (data != NULL) {
+        psListAdd(list, data, PS_LIST_TAIL);
+    }
+
+    return list;
+}
+
+void psListFree(psList *list, psFreeFcn elemFree)
+{
+    if (list == NULL) {
+        return;
+    }
+
+    pthread_mutex_lock(&list->lock)
+    ;
+
+    for(psListElem *ptr = list->head; ptr != NULL; ) {
+        psListElem *next = ptr->next;
+
+        p_psCustomFree(elemFree, psMemDecrRefCounter(ptr->data));
+        psFree(ptr);
+
+        ptr = next;
+    }
+
+    pthread_mutex_unlock(&list->lock)
+    ;
+
+    pthread_mutex_destroy(&list->lock)
+    ;
+
+    psFree(list);
+}
+
+psList* psListAdd(psList *list, void *data, int where)
+{
+    psListElem* position;
+    psListElem* elem;
+    int cursorIndex = 0;
+
+    if (list == NULL) {
+        return NULL;
+    }
+
+    if (data == NULL) {
+        return list;
+    }
+    elem = psAlloc(sizeof(psListElem));
+
+    pthread_mutex_lock(&list->lock)
+    ;
+
+    if (where <= PS_LIST_UNKNOWN) {
+        /// XXX What is the better way to communicate this failure to the caller?
+        psLogMsg(__func__,PS_LOG_WARN,
+                 "The given insert location (%i) for psListAdd is invalid. Adding to head instead.",
+                 where);
+        where = PS_LIST_HEAD; // given I can't tell caller about this, should just add it somewhere???
+    }
+
+    if (where > 0 && where > list->size) {
+        psLogMsg(__func__,PS_LOG_WARN,
+                 "Invalid index %d (only %d elements in psList); assuming tail.",
+                 where, list->size);
+        where = PS_LIST_TAIL;
+    }
+
+    if (where == PS_LIST_TAIL || list->size == 0) {
+        // insert the element at the end of the list
+        elem->prev = list->tail;
+        elem->next = NULL;
+
+        if (list->tail != NULL) {
+            list->tail->next = elem;
+        }
+
+        if (list->head == NULL) {
+            list->head = elem;
+        }
+        list->tail = elem;
+
+        list->size++;
+        list->iter = elem;
+        list->iterIndex = list->size - 1;
+    } else {
+        // move ourselves to the given position
+        listSetIterator(list, where, false);
+        position = listGetIterator(list);
+        cursorIndex = listGetIteratorIndex(list);
+
+        if (position == NULL) {
+            psError(__func__,"%s failed to move cursor to specified location (%d)",__func__,where);
+            position = list->head; // since we no list->size != 0, this must be non-NULL
+        }
+
+        // insert our new element in front of the given position
+        elem->prev = position->prev;
+        elem->next = position;
+        position->prev = elem;
+
+        if (elem->prev == NULL) { // must be front of list
+            list->head = elem;
+        } else {
+            elem->prev->next = elem;
+        }
+
+        list->size++;
+        list->iter = elem;
+        list->iterIndex = cursorIndex;
+    }
+
+    elem->data = psMemIncrRefCounter(data);
+
+    pthread_mutex_unlock(&list->lock)
+    ;
+
+    return list;
+}
+
+/*****************************************************************************/
+
+psList *psListAppend(psList *list, void *data)
+{
+    return psListAdd(list, data, PS_LIST_TAIL);
+}
+
+/*****************************************************************************/
+/*
+ * Remove an element from a list
+ */
+void *psListRemove(psList *list, void *data,  int which)
+{
+    psListElem *elem = NULL;  // element to remove
+    int cursorIndex = 0;
+
+    if (list == NULL) {
+        psError(__func__,"list parameter found to be NULL in %s",__func__);
+        return NULL;
+    }
+
+    // get exclusive access to list so that other threads will not get in the way.
+    pthread_mutex_lock(&list->lock)
+    ;
+
+    if (which == PS_LIST_UNKNOWN) {
+        // search list for the data item.
+
+        int i = 0;   // index
+        for (psListElem *ptr = list->head; ptr != NULL; ptr = ptr->next) {
+            if (ptr->data == data) {
+                which = i;
+                break;
+            }
+            i++;
+        }
+
+        if (which == PS_LIST_UNKNOWN) {
+            psError(__func__, "Failed to find item in given psList.");
+            return NULL;
+        }
+    }
+
+    // position the list's cursor to the desired location
+    listSetIterator(list,which,false);
+    elem = listGetIterator(list);
+    cursorIndex = listGetIteratorIndex(list);
+
+    if (elem == NULL) {
+        psError(__func__, "Couldn't position to given index (%d) to remove element from list.",which);
+        return NULL;
+    }
+
+    list->size--;
+
+    if (elem->prev == NULL) { // head of list?
+        list->head = elem->next;
+    } else {
+        elem->prev->next = elem->next;
+    }
+
+    if (elem->next == NULL) { // tail of list?
+        list->tail = elem->prev;
+
+        // removed tail, so iter should be the last element of list to keep it valid
+        if (list->size > 0) {
+            list->iter = list->tail;
+            list->iterIndex = list->size - 1;
+        } else {
+            list->iter = ITER_INIT_TAIL;
+        }
+    } else {
+        elem->next->prev = elem->prev;
+        list->iter = elem->next;
+        list->iterIndex = cursorIndex;
+    }
+
+    pthread_mutex_unlock(&list->lock)
+    ;
+
+    /*
+     * OK, delete list element and return the data
+     */
+    data = elem->data;
+    psFree(elem);
+    return data;
+}
+
+void psListSetIterator(psList *list, int where)
+{
+    listSetIterator(list,where,true);
+}
+
+void listSetIterator(psList* list, int where, bool lockList)
+{
+    psListElem* cursor;
+    int position;
+
+    if (list == NULL) {
+        psError(__func__,"Unexpected null pointer for psList parameter (%s:%d).",__FILE__,__LINE__);
+        return;
+    }
+
+    if (where == PS_LIST_CURRENT) {
+        return;
+    }
+
+    if (lockList) {
+        pthread_mutex_lock(&list->lock)
+        ;
+        // don't want the list changing on us while we move about
+    }
+
+    if (where >= (int)list->size) {
+        list->iter = NULL;
+        return;
+    }
+
+    switch (where) {
+    case PS_LIST_HEAD:
+        list->iter = ITER_INIT_HEAD;
+        break;
+
+    case PS_LIST_TAIL:
+        list->iter = ITER_INIT_TAIL;
+        break;
+
+    case PS_LIST_PREVIOUS:
+        cursor = listGetIterator(list);
+        position = listGetIteratorIndex(list);
+
+        if (cursor != NULL) {
+            list->iter = cursor->prev;
+            list->iterIndex = position-1;
+        }
+        break;
+
+    case PS_LIST_NEXT:
+        cursor = listGetIterator(list);
+        position = listGetIteratorIndex(list);
+
+        if (cursor != NULL) {
+            list->iter = cursor->next;
+            list->iterIndex = position+1;
+        }
+        break;
+
+    case PS_LIST_CURRENT:
+        break;
+
+    default:
+        if (where <= PS_LIST_HEAD) { // bascially same as PS_LIST_UNKNOWN above
+            psError(__func__,"Can't move to an unknown position.  Not moving the iterator position.");
+        } else {
+            cursor = listGetIterator(list);
+            if (cursor == NULL) { // reset the iterator if it is invalid
+                list->iter = ITER_INIT_HEAD;
+                list->iterIndex = 0;
+            }
+
+            int position = listGetIteratorIndex(list);
+
+            if (where < position) {
+                int diff = position-where;
+                for (int count=0;count < diff; count++) {
+                    listSetIterator(list,PS_LIST_PREVIOUS,false);
+                }
+            } else {
+                int diff = where-position;
+                for (int count=0;count < diff; count++) {
+                    listSetIterator(list,PS_LIST_NEXT,false);
+                }
+            }
+        }
+        break;
+    }
+
+    if (lockList) {
+        pthread_mutex_unlock(&list->lock)
+        ;
+    }
+}
+
+psListElem* listGetIterator(psList* list)
+{
+    if (list == NULL) {
+        return NULL;
+    }
+
+    if (list->iter == ITER_INIT_HEAD) {
+        return list->head;
+    } else if (list->iter == ITER_INIT_TAIL) {
+        return list->tail;
+    } else {
+        return list->iter;
+    }
+}
+
+int listGetIteratorIndex(psList* list)
+{
+    if (list->iter == ITER_INIT_HEAD) {
+        return 0;
+    } else if (list->iter == ITER_INIT_TAIL) {
+        return list->size-1;
+    } else {
+        return list->iterIndex;
+    }
+}
+
+void* psListGet(psList* list,int which)
+{
+    psListElem* element;
+
+    psListSetIterator(list,which);
+    element = listGetIterator(list);
+
+    if (element == NULL) {
+        return NULL;
+    } else {
+        return element->data;
+    }
+}
+/*
+ * and now return the previous/next element of the list
+ */
+void *psListGetNext(psList *list)
+{
+    return psListGet(list, PS_LIST_NEXT);
+}
+
+void *psListGetPrevious(psList *list)
+{
+    return psListGet(list, PS_LIST_PREVIOUS);
+}
+
+void *psListGetCurrent(psList *list)
+{
+    return psListGet(list, PS_LIST_CURRENT);
+}
+
+/*
+ * Convert a psList to/from a psVoidPtrArray
+ */
+psVector* psListToVector(psList* restrict list)
+{
+    psListElem* ptr;
+    unsigned int n;
+    psVector* restrict arr;
+
+    if (list == NULL) {
+        return NULL;
+    }
+
+    if (list->size > 0) {
+        arr = psVectorAlloc(list->size, PS_TYPE_PTR);
+    } else {
+        arr = psVectorAlloc(1, PS_TYPE_PTR);
+    }
+
+    arr->n = list->size;
+
+
+    ptr = list->head;
+    n = list->size;
+    for (int i = 0; i < n; i++) {
+        arr->data.PTR[i] = psMemIncrRefCounter(ptr->data);
+        ptr = ptr->next;
+    }
+
+    return arr;
+}
+
+psList* psVectorToList(psVector* arr)
+{
+    unsigned int n;
+    psList* list; // list of elements
+
+    if (arr == NULL) {
+        return NULL;
+    }
+
+    if (arr->type.type != PS_TYPE_PTR) {
+        psError(__func__,"Can not convert a non pointer-vector to a linked list.");
+        return NULL;
+    }
+
+    list = psListAlloc(NULL);
+    n = arr->n;
+    for (int i = 0; i < n; i++) {
+        psListAppend(list,arr->data.PTR[i]);
+    }
+
+    return list;
+}
Index: /tags/rel1_1/psLib/src/collections/psList.d
===================================================================
--- /tags/rel1_1/psLib/src/collections/psList.d	(revision 1056)
+++ /tags/rel1_1/psLib/src/collections/psList.d	(revision 1056)
@@ -0,0 +1,3 @@
+psList.o psList.d : psList.c ../sysUtils/psError.h ../sysUtils/psAbort.h \
+  ../sysUtils/psMemory.h psList.h psVector.h psType.h \
+  ../sysUtils/psTrace.h ../sysUtils/psLogMsg.h
Index: /tags/rel1_1/psLib/src/collections/psList.h
===================================================================
--- /tags/rel1_1/psLib/src/collections/psList.h	(revision 1056)
+++ /tags/rel1_1/psLib/src/collections/psList.h	(revision 1056)
@@ -0,0 +1,196 @@
+#if !defined(PS_LIST_H)
+#define PS_LIST_H
+
+/** @file psList.h
+ *  @brief Support for doubly linked lists
+ *
+ *  @author Robert Lupton, Princeton University
+ *  @author Robert Daniel DeSonia, MHPCC
+ *
+ *  @ingroup LinkedList
+ *
+ *  @version $Revision: 1.4 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-12 22:15:39 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include <pthread.h>                   // we need a mutex to make this stuff thread safe.
+
+#include "psVector.h"
+
+/** @addtogroup LinkedList
+ *  @{
+ */
+
+/** Special values of index into list
+ *
+ *  This list of possible list position values should be contiguous non-positive values ending with
+ *  PS_LIST_UNKNOWN.  Any value less-than-or-equal-to PS_LIST_UNKNOWN is considered a undefined position.
+ *
+ */
+enum {
+    PS_LIST_HEAD = 0,                  ///< at head
+    PS_LIST_TAIL = -1,                 ///< at tail
+    PS_LIST_PREVIOUS = -2,             ///< previous element
+    PS_LIST_CURRENT = -3,              ///< current element
+    PS_LIST_NEXT = -4,                 ///< next element
+    PS_LIST_UNKNOWN = -5               ///< unknown position (should be last in enum list)
+};
+
+/** Doubly-linked list element */
+typedef struct psListElem
+{
+    struct psListElem *prev;            ///< previous link in list
+    struct psListElem *next;            ///< next link in list
+    void *data;                         ///< real data item
+}
+psListElem;
+
+/** The psList Linked list structure.  User should not allocate this struct
+ *  directly; rather the psListAlloc should be used.
+ *
+ *  @see psListAlloc, psListFree
+ */
+typedef struct
+{
+    unsigned int size;                  ///< number of elements on list
+    psListElem* head;                   ///< first element on list (may be NULL)
+    psListElem* tail;                   ///< last element on list (may be NULL)
+    psListElem* iter;                   ///< iteration cursor
+    unsigned int iterIndex;             ///< the numeric position of the iteration cursor in the list
+    pthread_mutex_t lock;               ///< mutex to lock a node during changes
+}
+psList;
+
+/** Creates a psList linked list object.
+ *
+ *  @return psList*     A new psList object.
+ */
+psList* psListAlloc(
+    void *data
+    ///< initial data item; may be NULL if no an empty psList is desired
+)
+;
+
+#include "psMemory.h"
+/** Destroys a psList linked list object.  This also frees the elements of the
+ *  list using the psFreeFcn given, if any.  If no psFreeFcn is specified,
+ *  the elements are just dereferenced via psMemDecrRefCounter(...).
+ *
+ */
+void psListFree(
+    psList* restrict list,              ///< list to destroy
+    psFreeFcn elemFree                  ///< destructor for data on list
+);
+
+/** Adds an element to a psList at position given.
+ *
+ *  @return psList*     The psList with added data item.  If list parameter is
+ *                      NULL, the return value will also be NULL.
+ */
+psList* psListAdd(
+    psList* restrict list,              ///< list to add to (if NULL, nothing is done)
+    void* data,                         ///< data item to add.  If NULL, list is not modified.
+    int where                           ///< index, PS_LIST_HEAD, PS_LIST_TAIL, or numbered location.
+);
+
+/** Appends an item to a psList.
+ *
+ *  @return psList*     The psList with added data item.  If list parameter is
+ *                      NULL, the return value will also be NULL.
+ */
+psList* psListAppend(
+    psList* restrict list,              ///< list to append to (if NULL, nothing is done)
+    void *data                          ///< data item to add. If NULL, list is not modified.
+);
+
+/** Remove an item from a list.  If which parameter is PS_LIST_UNKNOWN,
+ *
+ *  @return void*       The data item that was removed.  If NULL, no item was
+ *                      removed.
+ */
+void* psListRemove(
+    psList* restrict list,
+    ///< list to remove element from
+    void *data,
+    ///< if which is PS_LIST_UNKNOWN, data item to find and remove, otherwise this is ignored.
+    int which
+    ///< index of item, or PS_LIST_UNKNOWN, PS_LIST_NEXT, PS_LIST_PREV, or numbered location.
+);
+
+/** Retrieve an item from a list.
+ *
+ *  @return void*       the item corresponding to the which parameter.  If
+ *                      which is invalid (e.g., a numbered index greater
+ *                      than the list size or if the list is empty), a
+ *                      NULL is returned.
+ */
+void* psListGet(
+    psList* restrict list,             ///< list to retrieve element from
+    int which                          ///< index number, or PS_LIST_NEXT, PS_LIST_PREV, PS_LIST_UNKNOWN
+);
+
+/** Set the iterator of the list to a given position.  If where is invalid the
+ *  iterator position is not changed.
+ *
+ */
+void psListSetIterator(
+    psList* restrict list,             ///< list to retrieve element from
+    int where                           ///< index number, PS_LIST_HEAD, or PS_LIST_TAIL
+);
+
+/** Get next element relative to the iterator.  This also moves the iterator to
+ *  the next list position.
+ *
+ *  @return void*       the data item next on the list or NULL if the iterator
+ *                      is already pointing to the last element or the list
+ *                      parameter was NULL.
+ */
+void* psListGetNext(
+    psList* restrict list              ///< list to retrieve element from
+);
+
+/** Get current element according to the psList's iterator cursor.  This does
+ *  not move the iterator location.
+ *
+ *  @return void*       the data item cooresponding to current iterator
+ *                      cursor position of the list, or NULL if either the
+ *                      iterator is not valid or list parameter was NULL.
+ */
+void* psListGetCurrent(
+    psList* restrict list              ///< list to retrieve element from
+);
+
+/** Get previous element relative to list's iterator. This also moves the
+ *  iterator to the previous list position.
+ *
+ *  @return void*       the data item previous on the list or NULL if the iterator
+ *                      is already pointing to the first element or the list
+ *                      parameter was NULL.
+ */
+void* psListGetPrevious(
+    psList* restrict list              ///< list to retrieve element from
+);
+
+/** Convert a linked list to an array
+ *
+ *  @return psVector*   A new psVector populated with elements from the list,
+ *                      or NULL if the given dlist parameter is NULL.
+ */
+psVector* psListToVector(
+    psList *dlist                      ///< List to convert
+);
+
+/** Convert array to a doubly-linked list
+ *
+ *  @return psList*     A new psList populated with elements formt the psVector,
+ *                      or NULL is the given arr parameter is NULL.
+ */
+psList* psVectorToList(
+    psVector* arr                      ///< vector to convert
+);
+
+/// @} End of DataGroup Functions
+
+#endif
Index: /tags/rel1_1/psLib/src/collections/psSort.c
===================================================================
--- /tags/rel1_1/psLib/src/collections/psSort.c	(revision 1056)
+++ /tags/rel1_1/psLib/src/collections/psSort.c	(revision 1056)
@@ -0,0 +1,247 @@
+/** @file  psSort.c
+ *
+ *  @brief Sorts vectors
+ *
+ *  The psSort functions use the qsort() stdlib function with a user-defined callback to sort an vector of
+ *  floats. The qsort function requires the starting point of the vector, number of elements in the vector, size
+ *  of each element, and a pointer to a callback comparison function. Once called, qsort() will sort the vector
+ *  contents in ascending order according to the comparison function. The comparison function is called with
+ *  two arguments that point to the objects being compared - in this case two floats. The comparison function
+ *  must return an integer less than, equal to, or greater than zero if the first argument is considered to be
+ *  respectively less than, equal to, or greater than the second. If two members compare as equal, their order
+ *  in the sorted vector is undefined.
+ *
+ *  @author Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.11 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-10 23:15:08 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+/******************************************************************************/
+/*  INCLUDE FILES                                                             */
+/******************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <float.h>
+
+#include "psVector.h"
+#include "psSort.h"
+#include "psError.h"
+
+/******************************************************************************/
+/*  DEFINE STATEMENTS                                                         */
+/******************************************************************************/
+
+// None
+
+/******************************************************************************/
+/*  TYPE DEFINITIONS                                                          */
+/******************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  GLOBAL VARIABLES                                                         */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  FILE STATIC VARIABLES                                                    */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  FUNCTION IMPLEMENTATION - LOCAL                                          */
+/*****************************************************************************/
+
+/** Private callback comparison function to compare two floats.
+ *
+ *  The comparison function is called by qsort() with two arguments that point to the objects being
+ *  compared. The comparison function must return an integer less than, equal to, or greater than zero if
+ *  the first argument is considered to be respectively less than, equal to, or greater than the second.
+ *
+ *  @return  int: Result of comparsion (-1, 0, or 1).
+ */
+#define PS_COMPARE(TYPE)                                                                                     \
+static int psCompare##TYPE(const void *x, const void *y)                                                     \
+{                                                                                                            \
+    ps##TYPE *item1 = NULL;                                                                                  \
+    ps##TYPE *item2 = NULL;                                                                                  \
+    \
+    if(x == NULL || y == NULL) {                                                                             \
+        psError(__func__, " : Line %d - Null input argument: x=%d y=%d\n", __LINE__, x, y);                  \
+    }                                                                                                        \
+    \
+    item1 = (ps##TYPE *)x;                                                                                   \
+    item2 = (ps##TYPE *)y;                                                                                   \
+    \
+    if(item1 == NULL || item2 == NULL) {                                                                     \
+        psError(__func__, " : Line %d - Improper cast to float: item1=%d item2=%d\n", __LINE__, item1,       \
+                item2);                                                                                      \
+    }                                                                                                        \
+    \
+    if(*item1 < *item2) {                                                                                    \
+        return -1;                                                                                           \
+    } else if(*item1 > *item2) {                                                                             \
+        return 1;                                                                                            \
+    } else {                                                                                                 \
+        return 0;                                                                                            \
+    }                                                                                                        \
+}
+
+PS_COMPARE(U8)
+PS_COMPARE(U16)
+PS_COMPARE(F32)
+PS_COMPARE(F64)
+
+/*****************************************************************************/
+/* FUNCTION IMPLEMENTATION - PUBLIC                                          */
+/*****************************************************************************/
+
+psVector *psSort(psVector *restrict outVector, const psVector *restrict inVector)
+{
+    int inN = 0;
+    int outN = 0;
+    int elSize = 0;
+    void *inVec = NULL;
+    void *outVec = NULL;
+    psElemType inType = 0;
+
+    if(inVector == NULL) {
+        psError(__func__, " : Line %d - Null input vector\n", __LINE__);
+        return outVector;
+    }
+
+    inType = inVector->type.type;
+    inN = inVector->n;
+    inVec = inVector->data.V;
+    elSize = PSELEMTYPE_SIZEOF(inType);
+
+    if(outVector == NULL) {
+        outVector = psVectorAlloc(inN, inType);
+        outVector->n = inVector->n;
+    }
+
+    outN = outVector->n;
+    outVec = outVector->data.V;
+
+    if(inN != outN) {
+        psError(__func__, " : Line %d - Input and output vector sizes are not equal: in=%d out=%d\n", __LINE__,
+                inN, outN);
+        return outVector;
+    }
+
+    if(inN == 0) {
+        psError(__func__, " : Line %d - No elements in use for input vector\n", __LINE__);
+        return outVector;
+    }
+
+    if(outN == 0) {
+        psError(__func__, " : Line %d - No elements in use for output vector\n", __LINE__);
+        return outVector;
+    }
+
+    // Copy input vector values into output vector
+    memcpy(outVec, inVec, elSize*outN);
+
+    // Sort output vector
+    switch(inType) {
+    case PS_TYPE_U8:
+        qsort(outVec, inN, elSize, psCompareU8);
+        break;
+    case PS_TYPE_U16:
+        qsort(outVec, inN, elSize, psCompareU16);
+        break;
+    case PS_TYPE_F32:
+        qsort(outVec, inN, elSize, psCompareF32);
+        break;
+    case PS_TYPE_F64:
+        qsort(outVec, inN, elSize, psCompareF64);
+        break;
+    default:
+        psError(__func__, " : Line %d - Invalid psType\n", __LINE__);
+    }
+
+    return outVector;
+}
+
+#define SORT_INDICES(TYPE)                                                                                   \
+for(i=0; i<inN; i++) {                                                                                       \
+    for(j=0; j<inN; j++) {                                                                                   \
+        diff = fabs((double)tmpVector->data.TYPE[i] - inVec[j]);                                             \
+        if(diff < FLT_EPSILON) {                                                                             \
+            outVec[i] = j;                                                                                   \
+            break;                                                                                           \
+        }                                                                                                    \
+    }                                                                                                        \
+}
+
+psVector *psSortIndex(psVector *restrict outVector, const psVector *restrict inVector)
+{
+    int inN = 0;
+    int outN = 0;
+    int i = 0;
+    int j = 0;
+    float *inVec = NULL;
+    int *outVec = NULL;
+    double diff = 0.0f;
+    psVector *tmpVector = NULL;
+    psElemType inType = 0;
+
+    if(inVector == NULL) {
+        psError(__func__, " : Line %d - Null input vector\n", __LINE__);
+        return outVector;
+    }
+
+    inN = inVector->n;
+    inVec = inVector->data.V;
+    inType = inVector->type.type;
+
+    if(outVector == NULL) {
+        outVector = psVectorAlloc(inN, PS_TYPE_U32);
+        outVector->n = inN;
+    }
+
+    outN = outVector->n;
+    outVec = outVector->data.V;
+
+    if(inN != outN) {
+        psError(__func__, " : Line %d - Input and output vector sizes are not equal: in=%d out=%d\n",
+                __LINE__, inN, outN);
+        return outVector;
+    }
+
+    tmpVector = psVectorAlloc(inN, inType);
+    tmpVector->n = inN;
+    tmpVector = psSort(tmpVector, inVector);
+
+    // Sort output vector
+    switch(inType) {
+    case PS_TYPE_U8:
+        SORT_INDICES(U8);
+        break;
+    case PS_TYPE_U16:
+        SORT_INDICES(U16);
+        break;
+    case PS_TYPE_F32:
+        SORT_INDICES(F32);
+        break;
+    case PS_TYPE_F64:
+        SORT_INDICES(F64);
+        break;
+    default:
+        psError(__func__, " : Line %d - Invalid psType\n", __LINE__);
+    }
+
+    // Free temp memory
+    psVectorFree(tmpVector);
+
+    return outVector;
+}
Index: /tags/rel1_1/psLib/src/collections/psSort.d
===================================================================
--- /tags/rel1_1/psLib/src/collections/psSort.d	(revision 1056)
+++ /tags/rel1_1/psLib/src/collections/psSort.d	(revision 1056)
@@ -0,0 +1,1 @@
+psSort.o psSort.d : psSort.c psVector.h psType.h psSort.h ../sysUtils/psError.h
Index: /tags/rel1_1/psLib/src/collections/psSort.h
===================================================================
--- /tags/rel1_1/psLib/src/collections/psSort.h	(revision 1056)
+++ /tags/rel1_1/psLib/src/collections/psSort.h	(revision 1056)
@@ -0,0 +1,67 @@
+/** @file  psSort.h
+ *
+ *  @brief Sorts vectors
+ *
+ *  The psSort functions use the qsort() stdlib function with a user-defined callback to sort an array of
+ *  floats. The qsort function requires the starting point of the array, number of elements in the array, size
+ *  of each element, and a pointer to a callback comparison function. Once called, qsort() will sort the array
+ *  contents in ascending order according to the comparison function. The comparison function is called with
+ *  two arguments that point to the objects being compared - in this case two floats. The comparison function
+ *  must return an integer less than, equal to, or greater than zero if the first argument is considered to be
+ *  respectively less than, equal to, or greater than the second. If two members compare as equal, their order
+ *  in the sorted array is undefined.
+ *
+ *  @ingroup Sort
+ *
+ *  @author Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.6 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-10 01:58:06 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PSSORT_H
+#define PSSORT_H
+
+/// @addtogroup Sort
+/// @{
+
+/******************************************************************************/
+/*  DEFINE STATEMENTS                                                         */
+/******************************************************************************/
+
+// None
+
+/******************************************************************************/
+/*  TYPE DEFINITIONS                                                          */
+/******************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/* FUNCTION PROTOTYPES                                                       */
+/*****************************************************************************/
+
+/** Sort an array of floats.
+ *
+ *  Sorts an array of floats in ascendin order with the qsort() stdlib function.
+ *
+ *  @return  psFloatArray*: Pointer to sorted psFloatArray.
+ */
+
+psVector *psSort(psVector *restrict outVector, const psVector *restrict inVector);
+
+/** Creates an array of indices based on sort odred of float array.
+ *
+ *  Sorts an array of floats and creates an integer array holding indices of sorted float values based on
+ *  pre-sort index positions.
+ *
+ *  @return  psIntArray*: Pointer to psIntArray of sorted indices.
+ */
+
+psVector *psSortIndex(psVector *restrict outVector, const psVector *restrict inVector);
+
+/// @}
+
+#endif
Index: /tags/rel1_1/psLib/src/collections/psVector.c
===================================================================
--- /tags/rel1_1/psLib/src/collections/psVector.c	(revision 1056)
+++ /tags/rel1_1/psLib/src/collections/psVector.c	(revision 1056)
@@ -0,0 +1,187 @@
+/** @file  psVector.c
+ *
+ *  @brief Contains support for basic vector types
+ *
+ *  This file defines the basic type for a vector struct and functions useful
+ *  in manupulating vectors.
+ *
+ *  @author Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.10 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-12 01:33:16 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+/******************************************************************************/
+/*  INCLUDE FILES                                                             */
+/******************************************************************************/
+#include "psMemory.h"
+#include "psError.h"
+#include "psVector.h"
+#include "psLogMsg.h"
+
+/******************************************************************************/
+/*  DEFINE STATEMENTS                                                         */
+/******************************************************************************/
+
+// None
+
+/******************************************************************************/
+/*  TYPE DEFINITIONS                                                          */
+/******************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  GLOBAL VARIABLES                                                         */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  FILE STATIC VARIABLES                                                    */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  FUNCTION IMPLEMENTATION - LOCAL                                          */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* FUNCTION IMPLEMENTATION - PUBLIC                                          */
+/*****************************************************************************/
+psVector* psVectorAlloc(unsigned int nalloc, psElemType elemType)
+{
+    psVector *psVec = NULL;
+    int elementSize = 0;
+
+    // Invalid nalloc
+    if(nalloc < 1) {
+        psError(__func__, "Invalid value for nalloc. nalloc: %d\n", nalloc);
+        return NULL;
+    }
+
+    elementSize = PSELEMTYPE_SIZEOF(elemType);
+
+    // Create vector struct
+    psVec = (psVector *)psAlloc(sizeof(psVector));
+
+    psVec->type.dimen = PS_DIMEN_VECTOR;
+    psVec->type.type = elemType;
+    psVec->nalloc = nalloc;
+    psVec->n = 0;
+
+    // Create vector data array
+    psVec->data.V = psAlloc(nalloc*elementSize);
+
+    return psVec;
+}
+
+psVector *psVectorRealloc(unsigned int nalloc, psVector *restrict in)
+{
+    int elementSize = 0;
+    psElemType elemType;
+
+    // Invalid nalloc
+    if(nalloc < 1) {
+        psError(__func__, "Invalid value for realloc (%d)\n", nalloc);
+        return NULL;
+    }
+
+    if(in == NULL) {
+        psError(__func__, "Null input vector\n");
+        return NULL;
+    } else if(in->nalloc != nalloc) {                    // No need to realloc to same size
+        elemType = in->type.type;
+        elementSize = PSELEMTYPE_SIZEOF(elemType);
+        if(nalloc < in->n) {
+            if (elemType == PS_TYPE_PTR) {
+                for (int i = nalloc; i < in->n; i++) {   // For reduction in vector size
+                    psMemDecrRefCounter(in->data.PTR[i]);
+                }
+            }
+            in->n = nalloc;
+        }
+
+        // Realloc after decrementation to avoid accessing freed array elements
+        in->data.V = psRealloc(in->data.V,nalloc*elementSize);
+        in->nalloc = nalloc;
+    }
+
+    return in;
+}
+
+psVector *psVectorRecycle(psVector *restrict in, psElemType type, unsigned int nalloc)
+{
+    psElemType elemType;
+
+    if (in == NULL) {
+        return psVectorAlloc(nalloc, type);
+    }
+
+    elemType = in->type.type;
+
+    if (in->nalloc == nalloc && elemType == type) {
+        // it is proper size/type already
+        return in;
+    }
+
+    // Invalid nalloc
+    if(nalloc < 1) {
+        psError(__func__, "Invalid value for nalloc (%d)\n", nalloc);
+        psVectorFree(in);
+        return NULL;
+    }
+
+
+    // if vector of pointers, dereference old values.
+    if (elemType == PS_TYPE_PTR) {
+        for (int i = 0; i < in->n; i++) {   // For reduction in vector size
+            psMemDecrRefCounter(in->data.PTR[i]);
+            in->data.PTR[i] = NULL;
+        }
+    }
+
+    in->data.V = psRealloc(in->data.V,nalloc*PSELEMTYPE_SIZEOF(type));
+
+    in->n = 0;
+    in->type.type = type;
+    in->nalloc = nalloc;
+
+    return in;
+}
+
+void psVectorFree(psVector *restrict psVec)
+{
+    if (psVec == NULL) {
+        return;
+    }
+
+    psFree(psVec->data.V);
+    psFree(psVec);
+}
+
+void psVectorElementFree(psVector *restrict psVec, void (*elemFree)(void *))
+{
+
+    if(psVec == NULL) {
+        return;
+    }
+
+    if (psVec->type.type != PS_TYPE_PTR) {
+        psLogMsg(__func__,PS_LOG_WARN,"psVectorElementFree only operates on void* vectors");
+        return;
+    }
+
+    for(int i = 0; i < psVec->nalloc; i++) {
+        if(elemFree == NULL) {
+            psMemDecrRefCounter(psVec->data.PTR[i]);
+        } else {
+            elemFree(psMemDecrRefCounter(psVec->data.PTR[i]));
+        }
+        psVec->data.PTR[i] = NULL;
+    }
+}
+
Index: /tags/rel1_1/psLib/src/collections/psVector.d
===================================================================
--- /tags/rel1_1/psLib/src/collections/psVector.d	(revision 1056)
+++ /tags/rel1_1/psLib/src/collections/psVector.d	(revision 1056)
@@ -0,0 +1,2 @@
+psVector.o psVector.d : psVector.c ../sysUtils/psMemory.h ../sysUtils/psError.h \
+  psVector.h psType.h ../sysUtils/psLogMsg.h
Index: /tags/rel1_1/psLib/src/collections/psVector.h
===================================================================
--- /tags/rel1_1/psLib/src/collections/psVector.h	(revision 1056)
+++ /tags/rel1_1/psLib/src/collections/psVector.h	(revision 1056)
@@ -0,0 +1,130 @@
+/** @file  psVector.h
+ *
+ *  @brief Contains basic vector definitions and operations
+ *
+ *  This file defines the basic type for a vector struct and functions useful
+ *  in manupulating vectors.
+ *
+ *  @ingroup Vector
+ *
+ *  @author Robert DeSonia, MHPCC
+ *  @author Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.10 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-10 01:58:06 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PS_VECTOR_H
+#define PS_VECTOR_H
+
+#include "psType.h"
+
+/// @addtogroup Vector
+/// @{
+
+/** An vector to support primitive types.
+ *
+ * Struct for maintaining an vector of frequently used primitive types.
+ *
+ */
+typedef struct
+{
+    psType type;                        ///< Type of data.
+    unsigned int nalloc;                ///< Total number of elements available.
+    unsigned int n;                     ///< Number of elements in use.
+
+    union {
+        psU8    *U8;                    ///< Unsigned 8-bit integer data.
+        psU16   *U16;                   ///< Unsigned 16-bit integer data.
+        psU32   *U32;                   ///< Unsigned 32-bit integer data.
+        psU64   *U64;                   ///< Unsigned 64-bit integer data.
+        psS8    *S8;                    ///< Signed 8-bit integer data.
+        psS16   *S16;                   ///< Signed 16-bit integer data.
+        psS32   *S32;                   ///< Signed 32-bit integer data.
+        psS64   *S64;                   ///< Signed 64-bit integer data.
+        psF32   *F32;                   ///< Single-precision float data.
+        psF64   *F64;                   ///< Double-precision float data.
+        psC32   *C32;                   ///< Single-precision complex data.
+        psC64   *C64;                   ///< Double-precision complex data.
+        psPTR   *PTR;                   ///< Void pointers.
+        psPTR    V;                     ///< Pointer to data.
+    } data;                             ///< Union for data types.
+}
+psVector;
+
+/*****************************************************************************/
+/* FUNCTION PROTOTYPES                                                       */
+/*****************************************************************************/
+
+/** Allocate a vector.
+ *
+ * Uses psLib memory allocation functions to create a vector collection of data as defined by the psType type.
+ *
+ * @return psVector*: Pointer to psVector.
+ *
+ */
+psVector *psVectorAlloc(
+    unsigned int nalloc,                ///< Total number of elements to make available.
+    psElemType dataType                 ///< Type of data to be held by vector.
+);
+
+/** Reallocate a vector.
+ *
+ * Uses psLib memory allocation functions to reallocate a vector collection of data. The vector is reallocated
+ * according to the psType type member contained within the vector.
+ *
+ * @return psVector*: Pointer to psVector.
+ *
+ */
+psVector *psVectorRealloc(
+    unsigned int nalloc,                ///< Total number of elements to make available.
+    psVector *restrict psVec            ///< Vector to reallocate.
+);
+
+/** Recycle a vector.
+ *
+ * Uses psLib memory allocation functions to reallocate a vector collection of data. The vector is reallocated
+ * according to the psElemType type parameter.
+ *
+ * @return psVector*: Pointer to psVector.
+ *
+ */
+psVector *psVectorRecycle(
+    psVector *restrict psVec,
+    ///< Vector to recycle.  If NULL, a new vector is created.  No effort taken to preserve the values.
+
+    unsigned int nalloc,                ///< Total number of elements to make available.
+    psElemType type                     ///< the datatype of the returned vector
+);
+
+/** Deallocate a vector.
+ *
+ * Uses psLib memory allocation functions to deallocate a vector collection of data. The vector is deallocated
+ * according to the psType type member contained within the vector.
+ *
+ * @return psVector*: Pointer to psVector.
+ *
+ */
+void psVectorFree(
+    psVector *restrict psVec  ///< Vector to free.
+);
+
+
+/** Deallocate/Dereference elements of a void pointer vector.
+ *
+ * Uses psLib memory allocation functions to deallocate/dereference elements of a vector of void pointers.
+ * This function does not free the vector elements unless the user provides a elemFree function
+ * pointer. If the elemFree function pointer is NULL, the reference cound of the elements are decremented
+ * without being freed.  The vector psVec is not freed, and its elements will all be set to NULL.
+ *
+ */
+void psVectorElementFree(
+    psVector *restrict psVec,   ///< Void pointer vector to destroy.
+    void (*elemFree)(void *)    ///< Optional callback function to remove vector elements.
+);
+
+/// @}
+
+#endif
Index: /tags/rel1_1/psLib/src/dataManip/.cvsignore
===================================================================
--- /tags/rel1_1/psLib/src/dataManip/.cvsignore	(revision 1056)
+++ /tags/rel1_1/psLib/src/dataManip/.cvsignore	(revision 1056)
@@ -0,0 +1,1 @@
+*.i
Index: /tags/rel1_1/psLib/src/dataManip/Makefile
===================================================================
--- /tags/rel1_1/psLib/src/dataManip/Makefile	(revision 1056)
+++ /tags/rel1_1/psLib/src/dataManip/Makefile	(revision 1056)
@@ -0,0 +1,48 @@
+ifndef prefix
+    export prefix=$(shell cd ../..;pwd)
+endif
+
+TARGET_STATIC  = libpslib.a
+include ../Makefile.Globals
+CFLAGS := $(CFLAGS_RELOC) -I. -I../sysUtils -I../collections -I..
+
+SRC_OBJS = psStats.o  \
+           psFunctions.o \
+           psImageStats.o \
+           psMatrix.o \
+           psFFT.o \
+           psImageIO.o
+
+all: $(TARGET_STATIC)
+
+%.o:	%.c
+	@echo "    Compiling $<. "
+	$(CC) $(CFLAGS)  -c $< -o $@
+
+libpslib.a:	$(SRC_OBJS)
+# The ar option -r is to add/replace object and -s is to create
+# a symbol table in the archive
+	$(AR) rcs ../$@ $(SRC_OBJS)
+
+# Define PHONY target "install" which will install necessary files
+install: $(TARGET_STATIC) 
+	install *.h $(includedir)
+
+# Define PHONY target "distclean" which will cleanup the distribution
+distclean:	clean
+	$(RM) ../$(TARGET_STATIC)
+
+# Define PHONY target "clean" which will cleanup the development area
+clean:
+	@echo "    Deleting intermediate files for 'sysUtils'"
+	$(RM) $(SRC_OBJS) *.lint
+
+%.lint: %.c
+	splint +posixlib -exportlocal -realcompare $(INCLUDE_GLOBAL) $? > $@; cat $@
+
+%.d: %.c
+	$(CC) -MM $(CFLAGS) $< > $@.tmp
+	sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' $@.tmp > $@
+	$(RM) -f $@.tmp
+
+include $(SRC_OBJS:.o=.d)
Index: /tags/rel1_1/psLib/src/dataManip/psFFT.c
===================================================================
--- /tags/rel1_1/psLib/src/dataManip/psFFT.c	(revision 1056)
+++ /tags/rel1_1/psLib/src/dataManip/psFFT.c	(revision 1056)
@@ -0,0 +1,755 @@
+/** @file  psFFT.c
+ *
+ *  @brief Contains FFT transforms functions
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.10 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-12 02:17:25 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include <unistd.h>
+#include <stdbool.h>
+#include <string.h>
+#include <complex.h>
+#include <fftw3.h>
+
+#include "psFFT.h"
+#include "psError.h"
+#include "psMemory.h"
+#include "psLogMsg.h"
+
+#define P_FFTW_PLAN_RIGOR FFTW_ESTIMATE
+
+static bool p_fftwWisdomImported = false;
+
+psImage* psImageFFT(psImage* out, const psImage* in, psFftDirection direction)
+{
+    unsigned int numCols;
+    unsigned int numRows;
+    psElemType type;
+    fftwf_plan plan;
+
+    /* got good image data? */
+    if (in==NULL) {
+        psImageFree(out);
+        return NULL;
+    }
+
+    type = in->type.type;
+
+    if ( (type != PS_TYPE_F32) && (type != PS_TYPE_C32) ) {
+        psError(__func__,"Input image must be a 32-bit float or complex image (type=%d)",
+                type);
+        psImageFree(out);
+        return NULL;
+    }
+
+    if ( type != PS_TYPE_C32 && direction == PS_FFT_REVERSE ) {
+        psError(__func__,"Input image must be complex image for reverse FFT (type=%d).",
+                type);
+        psImageFree(out);
+        return NULL;
+
+    }
+
+    /* make sure the system-level wisdom information is imported. */
+    if (! p_fftwWisdomImported) {
+        fftwf_import_system_wisdom();
+        p_fftwWisdomImported = true;
+    }
+
+    numRows = in->numRows;
+    numCols = in->numCols;
+
+    out = psImageCopy(out,in, PS_TYPE_C32);
+
+    plan = fftwf_plan_dft_2d(numCols, numRows,
+                             (fftwf_complex*)out->data.C32[0],
+                             (fftwf_complex*)out->data.C32[0],
+                             direction,
+                             P_FFTW_PLAN_RIGOR);
+
+    /* check if a plan exists now*/
+    if (plan == NULL) {
+        psError(__func__,"Failed to create FFTW plan.");
+        psImageFree(out);
+        return NULL;
+    }
+
+    /* finally, call FFTW with the plan made above */
+    fftwf_execute(plan);
+
+    fftwf_destroy_plan(plan);
+
+    return out;
+
+}
+
+
+psImage *psImageReal(psImage *out, const psImage* in)
+{
+    psElemType type;
+    unsigned int numCols;
+    unsigned int numRows;
+
+
+    if (in == NULL) {
+        psImageFree(out);
+        return NULL;
+    }
+
+    type = in->type.type;
+    numCols = in->numCols;
+    numRows = in->numRows;
+
+    /* if not a complex number, this is logically just a copy */
+    if (! PS_IS_PSELEMTYPE_COMPLEX(type)) {
+        // Warn user, as this is probably not expected
+        psLogMsg(__func__,PS_LOG_WARN,"Real portion of a non-Complex type called called for. "
+                 "Just an image copy was performed.");
+        return psImageCopy(out,in,type);
+    }
+
+    if (type == PS_TYPE_C32) {
+        psF32* outRow;
+        psC32* inRow;
+
+        out = psImageRecycle(out,numCols,numRows,PS_TYPE_F32);
+        for (unsigned int row=0;row<numRows;row++) {
+            outRow = out->data.F32[row];
+            inRow = in->data.C32[row];
+
+            for (unsigned int col=0;col<numCols;col++) {
+                outRow[col] = crealf(inRow[col]);
+            }
+        }
+    } else if (type == PS_TYPE_C64) {
+        psF64* outRow;
+        psC64* inRow;
+
+        out = psImageRecycle(out,numCols,numRows,PS_TYPE_F64);
+        for (unsigned int row=0;row<numRows;row++) {
+            outRow = out->data.F64[row];
+            inRow = in->data.C64[row];
+
+            for (unsigned int col=0;col<numCols;col++) {
+                outRow[col] = creal(inRow[col]);
+            }
+        }
+    } else {
+        psError(__func__,"Can not extract real component from given image type (%d).",
+                type);
+        psImageFree(out);
+        return NULL;
+    }
+
+    return out;
+}
+
+psImage *psImageImaginary(psImage *out, const psImage* in)
+{
+    psElemType type;
+    unsigned int numCols;
+    unsigned int numRows;
+
+
+    if (in == NULL) {
+        psImageFree(out);
+        return NULL;
+    }
+
+    type = in->type.type;
+    numCols = in->numCols;
+    numRows = in->numRows;
+
+    /* if not a complex number, this is logically just zeroed image of same size */
+    if (! PS_IS_PSELEMTYPE_COMPLEX(type)) {
+        // Warn user, as this is probably not expected
+        psLogMsg(__func__,PS_LOG_WARN,"Imaginary portion of a non-Complex type called for. "
+                 "A zero image was returned.");
+        out = psImageRecycle(out,numCols,numRows,type);
+        memset(out->data.V[0],0,PSELEMTYPE_SIZEOF(type)*numCols*numRows);
+        return out;
+    }
+
+    if (type == PS_TYPE_C32) {
+        psF32* outRow;
+        psC32* inRow;
+
+        out = psImageRecycle(out,numCols,numRows,PS_TYPE_F32);
+        for (unsigned int row=0;row<numRows;row++) {
+            outRow = out->data.F32[row];
+            inRow = in->data.C32[row];
+
+            for (unsigned int col=0;col<numCols;col++) {
+                outRow[col] = cimagf(inRow[col]);
+            }
+        }
+    } else if (type == PS_TYPE_C64) {
+        psF64* outRow;
+        psC64* inRow;
+
+        out = psImageRecycle(out,numCols,numRows,PS_TYPE_F64);
+        for (unsigned int row=0;row<numRows;row++) {
+            outRow = out->data.F64[row];
+            inRow = in->data.C64[row];
+
+            for (unsigned int col=0;col<numCols;col++) {
+                outRow[col] = cimag(inRow[col]);
+            }
+        }
+    } else {
+        psError(__func__,"Can not extract imaginary component from given image type (%d).",
+                type);
+        psImageFree(out);
+        return NULL;
+    }
+
+    return out;
+}
+
+psImage *psImageComplex(psImage* out, psImage *real, const psImage *imag)
+{
+    psElemType type;
+    unsigned int numCols;
+    unsigned int numRows;
+
+
+    if (real == NULL || imag == NULL) {
+        psImageFree(out);
+        return NULL;
+    }
+
+    type = real->type.type;
+    numCols = real->numCols;
+    numRows = real->numRows;
+
+    if (imag->type.type != type) {
+        psError(__func__,"The inputs to psImageComplex must be the same type.");
+        psImageFree(out);
+        return NULL;
+    }
+
+    if (imag->numCols != numCols ||
+            imag->numRows != numRows) {
+        psError(__func__,"The inputs to psImageComplex must be the same dimensions.");
+        psImageFree(out);
+        return NULL;
+    }
+
+    if (PS_IS_PSELEMTYPE_COMPLEX(type)) {
+        psError(__func__,"The inputs to psImageComplex can not be complex.");
+        psImageFree(out);
+        return NULL;
+    }
+
+    if (type != PS_TYPE_F32 && type != PS_TYPE_F64) {
+        psError(__func__,"The input type to psImageComplex must be a floating point.");
+        psImageFree(out);
+        return NULL;
+    }
+
+    if (type == PS_TYPE_F32) {
+        psC32* outRow;
+        psF32* realRow;
+        psF32* imagRow;
+
+        out = psImageRecycle(out,numCols,numRows,PS_TYPE_C32);
+
+        for (unsigned int row=0;row<numRows;row++) {
+            outRow = out->data.C32[row];
+            realRow = real->data.F32[row];
+            imagRow = imag->data.F32[row];
+
+            for (unsigned int col=0;col<numCols;col++) {
+                outRow[col] = realRow[col] + I*imagRow[col];
+            }
+        }
+    } else if (type == PS_TYPE_F64) {
+        psC64* outRow;
+        psF64* realRow;
+        psF64* imagRow;
+
+        out = psImageRecycle(out, numCols,numRows,PS_TYPE_C64);
+        for (unsigned int row=0;row<numRows;row++) {
+            outRow = out->data.C64[row];
+            realRow = real->data.F64[row];
+            imagRow = imag->data.F64[row];
+
+            for (unsigned int col=0;col<numCols;col++) {
+                outRow[col] = realRow[col] + I*imagRow[col];
+            }
+        }
+    } else {
+        psError(__func__,"Can not merge real and imaginary portions for given image type (%d).",
+                type);
+        psImageFree(out);
+        return NULL;
+    }
+
+    return out;
+}
+
+psImage *psImageConjugate(psImage *out, const psImage *in)
+{
+    psElemType type;
+    unsigned int numCols;
+    unsigned int numRows;
+
+
+    if (in == NULL) {
+        psImageFree(out);
+        return NULL;
+    }
+
+    type = in->type.type;
+    numCols = in->numCols;
+    numRows = in->numRows;
+
+    /* if not a complex number, this is logically just a image copy */
+    if (! PS_IS_PSELEMTYPE_COMPLEX(type)) {
+        // Warn user, as this is probably not expected
+        psLogMsg(__func__,PS_LOG_WARN,"Complex Conjugate of a non-Complex type called for. "
+                 "Image copy was performed instead.");
+        return psImageCopy(out,in,type);
+    }
+
+    if (type == PS_TYPE_C32) {
+        psC32* outRow;
+        psC32* inRow;
+
+        out = psImageRecycle(out,numCols,numRows,PS_TYPE_C32);
+        for (unsigned int row=0;row<numRows;row++) {
+            outRow = out->data.C32[row];
+            inRow = in->data.C32[row];
+
+            for (unsigned int col=0;col<numCols;col++) {
+                outRow[col] = crealf(inRow[col]) - I*cimagf(inRow[col]);
+            }
+        }
+    } else if (type == PS_TYPE_C64) {
+        psC64* outRow;
+        psC64* inRow;
+
+        out = psImageRecycle(out,numCols,numRows,PS_TYPE_C64);
+        for (unsigned int row=0;row<numRows;row++) {
+            outRow = out->data.C64[row];
+            inRow = in->data.C64[row];
+
+            for (unsigned int col=0;col<numCols;col++) {
+                outRow[col] = creal(inRow[col]) - I*cimag(inRow[col]);
+            }
+        }
+    } else {
+        psError(__func__,"Can not compute complex conjugate for given image type (%d).",
+                type);
+        psImageFree(out);
+        return NULL;
+    }
+
+    return out;
+}
+
+psImage *psImagePowerSpectrum(psImage* out, const psImage* in)
+{
+    psElemType type;
+    unsigned int numCols;
+    unsigned int numRows;
+    int numElementsSquared;
+
+    if (in == NULL) {
+        psImageFree(out);
+        return NULL;
+    }
+
+    type = in->type.type;
+    numCols = in->numCols;
+    numRows = in->numRows;
+    numElementsSquared = numCols*numCols*numRows*numRows;
+
+    /* if not a complex number, this is not implemented */
+    if (! PS_IS_PSELEMTYPE_COMPLEX(type)) {
+        psError(__func__,"Power Spectrum for non-complex inputs is not implemented.");
+        psImageFree(out);
+        return NULL;
+    }
+
+    if (type == PS_TYPE_C32) {
+        psF32* outRow;
+        psC32* inRow;
+        psF32 real;
+        psF32 imag;
+
+
+        out = psImageRecycle(out,numCols,numRows,PS_TYPE_F32);
+        for (unsigned int row=0;row<numRows;row++) {
+            outRow = out->data.F32[row];
+            inRow = in->data.C32[row];
+
+            for (unsigned int col=0;col<numCols;col++) {
+                real = crealf(inRow[col]);
+                imag = cimagf(inRow[col]);
+                outRow[col] = (real*real+imag*imag)/numElementsSquared;
+            }
+        }
+    } else if (type == PS_TYPE_C64) {
+        psF64* outRow;
+        psC64* inRow;
+        psF64 real;
+        psF64 imag;
+
+
+        out = psImageRecycle(out,numCols,numRows,PS_TYPE_F64);
+        for (unsigned int row=0;row<numRows;row++) {
+            outRow = out->data.F64[row];
+            inRow = in->data.C64[row];
+
+            for (unsigned int col=0;col<numCols;col++) {
+                real = crealf(inRow[col]);
+                imag = cimagf(inRow[col]);
+                outRow[col] = real*real+imag*imag/numElementsSquared;
+            }
+        }
+    } else {
+        psError(__func__,"Can not power spectrum for given image type (%d).",
+                type);
+        psImageFree(out);
+        return NULL;
+    }
+
+    return out;
+
+}
+
+/************************************** Vector Functions ***************************************/
+
+psVector* psVectorFFT(psVector* out, const psVector* in, psFftDirection direction)
+{
+    unsigned int numElements;
+    psElemType type;
+    fftwf_plan plan;
+
+    /* got good image data? */
+    if (in==NULL) {
+        psVectorFree(out);
+        return NULL;
+    }
+
+    type = in->type.type;
+
+    if ( (type != PS_TYPE_F32) && (type != PS_TYPE_C32) ) {
+        psError(__func__,"Input image must be a 32-bit float or complex image (type=%d)",
+                type);
+        psVectorFree(out);
+        return NULL;
+    }
+
+    if ( (type != PS_TYPE_C32) && (direction == PS_FFT_REVERSE) ) {
+        psError(__func__,"Input image must be complex image for reverse FFT (type=%d).",
+                type);
+        psVectorFree(out);
+        return NULL;
+
+    }
+
+    /* make sure the system-level wisdom information is imported. */
+    if (! p_fftwWisdomImported) {
+        fftwf_import_system_wisdom();
+        p_fftwWisdomImported = true;
+    }
+
+    numElements = in->n;
+
+    out = psVectorRecycle(out, PS_TYPE_C32, numElements);
+    out->n = numElements;
+
+    if (type == PS_TYPE_F32) {
+        // need to convert to complex
+        psC32* outVec = out->data.C32;
+        psF32* inVec = in->data.F32;
+        for (unsigned int i=0;i<numElements;i++) {
+            outVec[i] = inVec[i];
+        }
+    } else {
+        psC32* outVec = out->data.C32;
+        psC32* inVec = in->data.C32;
+        for (unsigned int i=0;i<numElements;i++) {
+            outVec[i] = inVec[i];
+        }
+    }
+
+    plan = fftwf_plan_dft_1d(numElements,
+                             (fftwf_complex*)out->data.C32,
+                             (fftwf_complex*)out->data.C32,
+                             direction,
+                             P_FFTW_PLAN_RIGOR);
+
+    /* check if a plan exists now*/
+    if (plan == NULL) {
+        psError(__func__,"Failed to create FFTW plan.");
+        psVectorFree(out);
+        return NULL;
+    }
+
+    /* finally, call FFTW with the plan made above */
+    fftwf_execute(plan);
+
+    fftwf_destroy_plan(plan);
+
+    return out;
+}
+
+
+psVector *psVectorReal(psVector *out, const psVector* in)
+{
+    psElemType type;
+    unsigned int numElements;
+
+    if (in == NULL) {
+        psVectorFree(out);
+        return NULL;
+    }
+
+    type = in->type.type;
+    numElements = in->n;
+
+    /* if not a complex number, this is logically just a copy */
+    if (! PS_IS_PSELEMTYPE_COMPLEX(type)) {
+        // Warn user, as this is probably not expected
+        psLogMsg(__func__,PS_LOG_WARN,"Real portion of a non-Complex type called called for. "
+                 "Just a vector copy was performed.");
+        out = psVectorRecycle(out,type,numElements);
+        out->n = numElements;
+        memcpy(out->data.V,in->data.V,numElements*PSELEMTYPE_SIZEOF(type));
+        return out;
+    }
+
+    if (type == PS_TYPE_C32) {
+        psF32* outVec;
+        psC32* inVec = in->data.C32;
+
+        out = psVectorRecycle(out,PS_TYPE_F32,numElements);
+        out->n = numElements;
+        outVec = out->data.F32;
+
+        for (unsigned int i=0;i<numElements;i++) {
+            outVec[i] = crealf(inVec[i]);
+        }
+    } else {
+        psError(__func__,"Can not extract real component from given vector type (%d).",
+                type);
+        psVectorFree(out);
+        return NULL;
+    }
+
+    return out;
+}
+
+psVector *psVectorImaginary(psVector *out, const psVector* in)
+{
+    psElemType type;
+    unsigned int numElements;
+
+
+    if (in == NULL) {
+        psVectorFree(out);
+        return NULL;
+    }
+
+    type = in->type.type;
+    numElements = in->n;
+
+    /* if not a complex number, this is logically just zeroed image of same size */
+    if (! PS_IS_PSELEMTYPE_COMPLEX(type)) {
+        // Warn user, as this is probably not expected
+        psLogMsg(__func__,PS_LOG_WARN,"Imaginary portion of a non-Complex type called for. "
+                 "A zeroed vector was returned.");
+        out = psVectorRecycle(out,type,numElements);
+        out->n = numElements;
+        memset(out->data.V,0,PSELEMTYPE_SIZEOF(type)*numElements);
+        return out;
+    }
+
+    if (type == PS_TYPE_C32) {
+        psF32* outVec;
+        psC32* inVec = in->data.C32;
+
+        out = psVectorRecycle(out,PS_TYPE_F32,numElements);
+        out->n = numElements;
+        outVec = out->data.F32;
+
+        for (unsigned int i=0;i<numElements;i++) {
+            outVec[i] = cimagf(inVec[i]);
+        }
+    } else {
+        psError(__func__,"Can not extract imaginary component from given vector type (%d).",
+                type);
+        psVectorFree(out);
+        return NULL;
+    }
+
+    return out;
+}
+
+psVector *psVectorComplex(psVector* out, psVector *real, const psVector *imag)
+{
+    psElemType type;
+    unsigned int numElements;
+
+
+    if (real == NULL || imag == NULL) {
+        psVectorFree(out);
+        return NULL;
+    }
+
+    type = real->type.type;
+    if (real->n >= imag->n) {
+        numElements = real->n;
+    } else {
+        numElements = imag->n;
+    }
+
+    if (imag->type.type != type) {
+        psError(__func__,"The inputs to psVectorComplex must be the same type.");
+        psVectorFree(out);
+        return NULL;
+    }
+
+    if (PS_IS_PSELEMTYPE_COMPLEX(type)) {
+        psError(__func__,"The inputs to psVectorComplex can not be complex.");
+        psVectorFree(out);
+        return NULL;
+    }
+
+    if (type == PS_TYPE_F32) {
+        psC32* outVec;
+        psF32* realVec = real->data.F32;
+        psF32* imagVec = imag->data.F32;
+
+        out = psVectorRecycle(out,PS_TYPE_C32,numElements);
+        out->n = numElements;
+        outVec = out->data.C32;
+
+        for (unsigned int i=0;i<numElements;i++) {
+            outVec[i] = realVec[i] + I*imagVec[i];
+        }
+    } else {
+        psError(__func__,"Can not merge real and imaginary portions for given vector type (%d).",
+                type);
+        psVectorFree(out);
+        return NULL;
+    }
+
+    return out;
+}
+
+psVector *psVectorConjugate(psVector *out, const psVector *in)
+{
+    psElemType type;
+    unsigned int numElements;
+
+
+    if (in == NULL) {
+        psVectorFree(out);
+        return NULL;
+    }
+
+    type = in->type.type;
+    numElements = in->n;
+
+    /* if not a complex number, this is logically just a image copy */
+    if (! PS_IS_PSELEMTYPE_COMPLEX(type)) {
+        // Warn user, as this is probably not expected
+        psLogMsg(__func__,PS_LOG_WARN,"Complex Conjugate of a non-Complex type called for. "
+                 "Vector copy was performed instead.");
+
+        out = psVectorRecycle(out,type,numElements);
+        out->n = numElements;
+        memcpy(out->data.V,in->data.V,PSELEMTYPE_SIZEOF(type)*numElements);
+        return out;
+    }
+
+    if (type == PS_TYPE_C32) {
+        psC32* outVec;
+        psC32* inVec = in->data.C32;
+
+        out = psVectorRecycle(out,PS_TYPE_C32, numElements);
+        out->n = numElements;
+        outVec = out->data.C32;
+
+        for (unsigned int i=0;i<numElements;i++) {
+            outVec[i] = crealf(inVec[i]) - I*cimagf(inVec[i]);
+        }
+    } else {
+        psError(__func__,"Can not compute complex conjugate for given vector type (%d).",
+                type);
+        psVectorFree(out);
+        return NULL;
+    }
+
+    return out;
+}
+
+psVector *psVectorPowerSpectrum(psVector* out, const psVector* in)
+{
+    psElemType type;
+    unsigned int outNumElements;
+    unsigned int inNumElements;
+    unsigned int inHalfNumElements;
+    unsigned int inNumElementsSquared;
+
+    if (in == NULL) {
+        psVectorFree(out);
+        return NULL;
+    }
+
+    type = in->type.type;
+    inNumElements = in->n;
+    inNumElementsSquared = inNumElements*inNumElements;
+    inHalfNumElements = inNumElements/2;
+    outNumElements = inHalfNumElements+1;
+
+    /* if not a complex number, this is not implemented */
+    if (! PS_IS_PSELEMTYPE_COMPLEX(type)) {
+        psError(__func__,"Power Spectrum for non-complex inputs is not implemented.");
+        psVectorFree(out);
+        return NULL;
+    }
+
+    if (type == PS_TYPE_C32) {
+        psF32* outVec;
+        psC32* inVec = in->data.C32;
+        psF32 inAbs1;
+        psF32 inAbs2;
+
+        out = psVectorRecycle(out,PS_TYPE_F32,outNumElements);
+        out->n = outNumElements;
+        outVec = out->data.F32;
+
+        // from ADD: P_0 = |C_0|^2/N^2
+        inAbs1 = cabsf(inVec[0]);
+        outVec[0] = inAbs1*inAbs1/inNumElementsSquared;
+
+        // from ADD: P_j = (|C_j|^2+|C_N-j|^2)/N^2, where j = 1,2,...,(N/2-1)
+        for (unsigned int i=1;i<inHalfNumElements;i++) {
+            inAbs1 = cabsf(inVec[i]);
+            inAbs2 = cabsf(inVec[inNumElements-i]);
+            outVec[i] = (inAbs1*inAbs1+inAbs2*inAbs2)/inNumElementsSquared;
+        }
+
+        // from ADD: P_N/2 = |C_N/2|^2/N^2
+        inAbs1 = cabsf(inVec[inHalfNumElements]);
+        outVec[inHalfNumElements] = inAbs1*inAbs1/inNumElementsSquared;
+    } else {
+        psError(__func__,"Can not power spectrum for given vector type (%d).",
+                type);
+        psVectorFree(out);
+        return NULL;
+    }
+
+    return out;
+
+}
Index: /tags/rel1_1/psLib/src/dataManip/psFFT.d
===================================================================
--- /tags/rel1_1/psLib/src/dataManip/psFFT.d	(revision 1056)
+++ /tags/rel1_1/psLib/src/dataManip/psFFT.d	(revision 1056)
@@ -0,0 +1,3 @@
+psFFT.o psFFT.d : psFFT.c psFFT.h ../collections/psImage.h ../collections/psType.h \
+  ../collections/psVector.h ../sysUtils/psError.h ../sysUtils/psMemory.h \
+  ../sysUtils/psLogMsg.h
Index: /tags/rel1_1/psLib/src/dataManip/psFFT.h
===================================================================
--- /tags/rel1_1/psLib/src/dataManip/psFFT.h	(revision 1056)
+++ /tags/rel1_1/psLib/src/dataManip/psFFT.h	(revision 1056)
@@ -0,0 +1,52 @@
+/** @file  psFFT.h
+ *
+ *  @brief Contains FFT transforms functions
+ *
+ *  @ingroup Transform
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.6 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-10 01:58:06 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PS_FFT_H
+#define PS_FFT_H
+
+#include "psImage.h"
+#include "psVector.h"
+
+/// @addtogroup Transform
+/// @{
+
+/** Details on FFT implementation (private). */
+
+
+typedef enum {
+    /// psImageFFT/psVectorFFT should perform a forward FFT.
+    PS_FFT_FORWARD = (-1),
+
+    ///< psImageFFT/psVectorFFT should perform a reverse FFT.
+    PS_FFT_REVERSE = (+1)
+} psFftDirection;
+
+psImage* psImageFFT(psImage* out, const psImage* in, psFftDirection direction);
+psImage* psImageReal(psImage *out, const psImage* in);
+psImage* psImageImaginary(psImage *out, const psImage* in);
+psImage* psImageComplex(psImage* out, psImage *real, const psImage *imag);
+psImage* psImageConjugate(psImage *out, const psImage *in);
+psImage* psImagePowerSpectrum(psImage* out, const psImage* in);
+
+psVector* psVectorFFT(psVector* out, const psVector* in, psFftDirection direction);
+psVector* psVectorReal(psVector* out, const psVector* in);
+psVector* psVectorImaginary(psVector* out, const psVector* in);
+psVector* psVectorComplex(psVector* out, psVector* real, const psVector* imag);
+psVector* psVectorConjugate(psVector* out, const psVector* in);
+psVector* psVectorPowerSpectrum(psVector* out, const psVector* in);
+
+/// @}
+
+#endif
+
Index: /tags/rel1_1/psLib/src/dataManip/psFunctions.c
===================================================================
--- /tags/rel1_1/psLib/src/dataManip/psFunctions.c	(revision 1056)
+++ /tags/rel1_1/psLib/src/dataManip/psFunctions.c	(revision 1056)
@@ -0,0 +1,751 @@
+/** @file  psFunctions.c
+ *
+ *  @brief Contains basic function allocation, deallocation, and evaluation
+ *         routines.
+ *
+ *  This file will hold the functions for allocated, freeing, and evaluating
+ *  polynomials.  It also contains a Gaussian functions.
+ *
+ *  @version $Revision: 1.13 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-14 19:40:14 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+/*****************************************************************************/
+/*  INCLUDE FILES                                                            */
+/*****************************************************************************/
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <float.h>
+#include <math.h>
+
+#include "psMemory.h"
+#include "psVector.h"
+#include "psTrace.h"
+#include "psError.h"
+#include "psAbort.h"
+#include "psFunctions.h"
+#include "psSort.h"
+
+#include "float.h"
+#include <math.h>
+#include <gsl/gsl_rng.h>
+#include <gsl/gsl_randist.h>
+/*****************************************************************************/
+/*  FUNCTION IMPLEMENTATION - PUBLIC                                         */
+/*****************************************************************************/
+
+/*****************************************************************************
+    Evaluate a non-normalized Gaussian with the given mean and sigma at the
+    given coordianate.  Note that this is not a Gaussian deviate.  The
+    evaluated Gaussian is: \f[ exp(-\frac{(x-mean)^2}{2\sigma^2}) \f]
+ *****************************************************************************/
+float
+psGaussian(float x,
+           float mean,
+           float stddev,
+           int normal)
+{
+    float tmp = 0.0;
+
+    if (normal == 1) {
+        #ifdef DARWIN
+        tmp = 1.0 / (float)sqrt(2.0 * M_PI * (stddev * stddev));
+        #else
+
+        tmp = 1.0 / sqrtf(2.0 * M_PI * (stddev * stddev));
+        #endif
+
+        return(tmp * exp(-((x-mean) * (x-mean)) / (2.0 * stddev * stddev)));
+    } else {
+        return(exp(-((x-mean) * (x-mean)) / (2.0 * stddev * stddev)));
+    }
+}
+
+/*****************************************************************************
+    psGaussianDev()
+ This routine creates a psVector of the specified size and type F32
+ and fills it with a random Gaussian distribution of numbers with
+ the specified mean and sigma.  This routine makes use of the GSL
+ routines for generating both uniformly distributed numbers and the
+ Gaussian distribution as well.
+ 
+ NOTE: There is no way to seed the random generator.
+ *****************************************************************************/
+psVector *psGaussianDev(float mean,
+                        float sigma,
+                        int Npts)
+{
+    psVector *gauss = NULL;
+    const gsl_rng_type *T = NULL;
+    gsl_rng *r = NULL;
+    int i = 0;
+
+    gauss = psVectorAlloc(Npts, PS_TYPE_F32);
+    gauss->n = Npts;
+    gsl_rng_env_setup();
+    T = gsl_rng_default;
+    r = gsl_rng_alloc(T);
+
+    for (i = 0; i < Npts; i++) {
+        gauss->data.F32[i] = mean + gsl_ran_gaussian(r, sigma);
+    }
+
+    // NOTE: Should I free r as well?
+    return(gauss);
+}
+
+
+/*****************************************************************************
+    This routine must allocate memory for the polynomial structures.
+ *****************************************************************************/
+psPolynomial1D *psPolynomial1DAlloc(int n)
+{
+    int i = 0;
+    psPolynomial1D *newPoly = NULL;
+
+    newPoly = (psPolynomial1D *) psAlloc(sizeof(psPolynomial1D));
+    newPoly->n = n;
+    newPoly->coeff    = (float *) psAlloc(n * sizeof(float));
+    newPoly->coeffErr = (float *) psAlloc(n * sizeof(float));
+    newPoly->mask     = (char *)  psAlloc(n * sizeof(char));
+    for (i=0;i<n;i++) {
+        newPoly->coeff[i] = 0.0;
+        newPoly->coeffErr[i] = 0.0;
+        newPoly->mask[i] = 0.0;
+    }
+
+    return(newPoly);
+}
+
+psPolynomial2D *psPolynomial2DAlloc(int nX, int nY)
+{
+    int x = 0;
+    int y = 0;
+    psPolynomial2D *newPoly = NULL;
+
+    newPoly = (psPolynomial2D *) psAlloc(sizeof(psPolynomial2D));
+    newPoly->nX = nX;
+    newPoly->nY = nY;
+
+    newPoly->coeff    = (float **) psAlloc(nX * sizeof(float *));
+    newPoly->coeffErr = (float **) psAlloc(nX * sizeof(float *));
+    newPoly->mask     = (char **)  psAlloc(nX * sizeof(char *));
+    for (x=0;x<nX;x++) {
+        newPoly->coeff[x]    = (float *) psAlloc(nY * sizeof(float));
+        newPoly->coeffErr[x] = (float *) psAlloc(nY * sizeof(float));
+        newPoly->mask[x]     = (char *)  psAlloc(nY * sizeof(char));
+    }
+    for (x=0;x<nX;x++) {
+        for (y=0;y<nY;y++) {
+            newPoly->coeff[x][y] = 0.0;
+            newPoly->coeffErr[x][y] = 0.0;
+            newPoly->mask[x][y] = 0;
+        }
+    }
+
+    return(newPoly);
+}
+
+psPolynomial3D *psPolynomial3DAlloc(int nX, int nY, int nZ)
+{
+    int x = 0;
+    int y = 0;
+    int z = 0;
+    psPolynomial3D *newPoly = NULL;
+
+    newPoly = (psPolynomial3D *) psAlloc(sizeof(psPolynomial3D));
+    newPoly->nX = nX;
+    newPoly->nY = nY;
+    newPoly->nZ = nZ;
+
+    newPoly->coeff    = (float ***) psAlloc(nX * sizeof(float **));
+    newPoly->coeffErr = (float ***) psAlloc(nX * sizeof(float **));
+    newPoly->mask     = (char ***)  psAlloc(nX * sizeof(char **));
+    for (x=0;x<nX;x++) {
+        newPoly->coeff[x]    = (float **) psAlloc(nY * sizeof(float *));
+        newPoly->coeffErr[x] = (float **) psAlloc(nY * sizeof(float *));
+        newPoly->mask[x]     = (char **)  psAlloc(nY * sizeof(char *));
+        for (y=0;y<nY;y++) {
+            newPoly->coeff[x][y]    = (float *) psAlloc(nZ * sizeof(float));
+            newPoly->coeffErr[x][y] = (float *) psAlloc(nZ * sizeof(float));
+            newPoly->mask[x][y]     = (char *)  psAlloc(nZ * sizeof(char));
+        }
+    }
+    for (x=0;x<nX;x++) {
+        for (y=0;y<nY;y++) {
+            for (z=0;z<nZ;z++) {
+                newPoly->coeff[x][y][z] = 0.0;
+                newPoly->coeffErr[x][y][z] = 0.0;
+                newPoly->mask[x][y][z] = 0;
+            }
+        }
+    }
+
+    return(newPoly);
+}
+
+psPolynomial4D *psPolynomial4DAlloc(int nW, int nX, int nY, int nZ)
+{
+    int w = 0;
+    int x = 0;
+    int y = 0;
+    int z = 0;
+    psPolynomial4D *newPoly = NULL;
+
+    newPoly = (psPolynomial4D *) psAlloc(sizeof(psPolynomial4D));
+    newPoly->nW = nW;
+    newPoly->nX = nX;
+    newPoly->nY = nY;
+    newPoly->nZ = nZ;
+
+    newPoly->coeff    = (float ****) psAlloc(nW * sizeof(float ***));
+    newPoly->coeffErr = (float ****) psAlloc(nW * sizeof(float ***));
+    newPoly->mask     = (char ****)  psAlloc(nW * sizeof(char ***));
+    for (w=0;w<nW;w++) {
+        newPoly->coeff[w]    = (float ***) psAlloc(nX * sizeof(float **));
+        newPoly->coeffErr[w] = (float ***) psAlloc(nX * sizeof(float **));
+        newPoly->mask[w]     = (char ***)  psAlloc(nX * sizeof(char **));
+        for (x=0;x<nX;x++) {
+            newPoly->coeff[w][x]    = (float **) psAlloc(nY * sizeof(float *));
+            newPoly->coeffErr[w][x] = (float **) psAlloc(nY * sizeof(float *));
+            newPoly->mask[w][x]     = (char **) psAlloc(nY * sizeof(char *));
+            for (y=0;y<nY;y++) {
+                newPoly->coeff[w][x][y]    = (float *) psAlloc(nZ * sizeof(float));
+                newPoly->coeffErr[w][x][y] = (float *) psAlloc(nZ * sizeof(float));
+                newPoly->mask[w][x][y]     = (char *) psAlloc(nZ * sizeof(char));
+            }
+        }
+    }
+    for (w=0;w<nW;w++) {
+        for (x=0;x<nX;x++) {
+            for (y=0;y<nY;y++) {
+                for (z=0;z<nZ;z++) {
+                    newPoly->coeff[w][x][y][z] = 0.0;
+                    newPoly->coeffErr[w][x][y][z] = 0.0;
+                    newPoly->mask[w][x][y][z] = 0;
+                }
+            }
+        }
+    }
+
+    return(newPoly);
+}
+
+void psPolynomial1DFree(psPolynomial1D *myPoly)
+{
+    psFree(myPoly->coeff);
+    psFree(myPoly->coeffErr);
+    psFree(myPoly->mask);
+    psFree(myPoly);
+}
+
+void psPolynomial2DFree(psPolynomial2D *myPoly)
+{
+    int x = 0;
+
+    for (x=0;x<myPoly->nX;x++) {
+        psFree(myPoly->coeff[x]);
+        psFree(myPoly->coeffErr[x]);
+        psFree(myPoly->mask[x]);
+    }
+    psFree(myPoly->coeff);
+    psFree(myPoly->coeffErr);
+    psFree(myPoly->mask);
+
+    psFree(myPoly);
+}
+
+void psPolynomial3DFree(psPolynomial3D *myPoly)
+{
+    int x = 0;
+    int y = 0;
+
+    for (x=0;x<myPoly->nX;x++) {
+        for (y=0;y<myPoly->nY;y++) {
+            psFree(myPoly->coeff[x][y]);
+            psFree(myPoly->coeffErr[x][y]);
+            psFree(myPoly->mask[x][y]);
+        }
+        psFree(myPoly->coeff[x]);
+        psFree(myPoly->coeffErr[x]);
+        psFree(myPoly->mask[x]);
+    }
+
+    psFree(myPoly->coeff);
+    psFree(myPoly->coeffErr);
+    psFree(myPoly->mask);
+    psFree(myPoly);
+}
+
+void psPolynomial4DFree(psPolynomial4D *myPoly)
+{
+    int w = 0;
+    int x = 0;
+    int y = 0;
+
+    for (w=0;w<myPoly->nW;w++) {
+        for (x=0;x<myPoly->nX;x++) {
+            for (y=0;y<myPoly->nY;y++) {
+                psFree(myPoly->coeff[w][x][y]);
+                psFree(myPoly->coeffErr[w][x][y]);
+                psFree(myPoly->mask[w][x][y]);
+            }
+            psFree(myPoly->coeff[w][x]);
+            psFree(myPoly->coeffErr[w][x]);
+            psFree(myPoly->mask[w][x]);
+        }
+        psFree(myPoly->coeff[w]);
+        psFree(myPoly->coeffErr[w]);
+        psFree(myPoly->mask[w]);
+    }
+
+    psFree(myPoly->coeff);
+    psFree(myPoly->coeffErr);
+    psFree(myPoly->mask);
+    psFree(myPoly);
+}
+
+/*****************************************************************************
+    Polynomial coefficients will be accessed in [w][x][y][z] fashion.
+ *****************************************************************************/
+float
+psEvalPolynomial1D(float x,
+                   const psPolynomial1D *myPoly)
+{
+    int loop_x = 0;
+    float polySum = 0.0;
+    float xSum = 1.0;
+
+    // NOTE: Do we want to flag this case?
+    if (myPoly->n == 0) {
+        return(1.0);
+    }
+
+    for (loop_x=0;loop_x<myPoly->n;loop_x++) {
+        polySum+= xSum * myPoly->coeff[loop_x];
+        xSum*=x;
+    }
+
+    return(polySum);
+}
+
+
+float
+psEvalPolynomial2D(float x,
+                   float y,
+                   const psPolynomial2D *myPoly)
+{
+    int loop_x = 0;
+    int loop_y = 0;
+    float polySum = 0.0;
+    float xSum = 1.0;
+    float ySum = 1.0;
+
+    for (loop_x=0;loop_x<myPoly->nX;loop_x++) {
+        ySum = xSum;
+        for (loop_y=0;loop_y<myPoly->nY;loop_y++) {
+            polySum+= ySum * myPoly->coeff[loop_x][loop_y];
+            ySum*=y;
+        }
+        xSum*=x;
+    }
+
+    return(polySum);
+}
+
+float
+psEvalPolynomial3D(float x,
+                   float y,
+                   float z,
+                   const psPolynomial3D *myPoly)
+{
+    int loop_x = 0;
+    int loop_y = 0;
+    int loop_z = 0;
+    float polySum = 0.0;
+    float xSum = 1.0;
+    float ySum = 1.0;
+    float zSum = 1.0;
+
+    for (loop_x=0;loop_x<myPoly->nX;loop_x++) {
+        ySum = xSum;
+        for (loop_y=0;loop_y<myPoly->nY;loop_y++) {
+            zSum = ySum;
+            for (loop_z=0;loop_z<myPoly->nZ;loop_z++) {
+                polySum+= zSum * myPoly->coeff[loop_x][loop_y][loop_z];
+                zSum*=z;
+            }
+            ySum*=y;
+        }
+        xSum*=x;
+    }
+
+    return(polySum);
+}
+
+float
+psEvalPolynomial4D(float w,
+                   float x,
+                   float y,
+                   float z,
+                   const psPolynomial4D *myPoly)
+{
+    int loop_w = 0;
+    int loop_x = 0;
+    int loop_y = 0;
+    int loop_z = 0;
+    float polySum = 0.0;
+    float wSum = 1.0;
+    float xSum = 1.0;
+    float ySum = 1.0;
+    float zSum = 1.0;
+
+    for (loop_w=0;loop_w<myPoly->nW;loop_w++) {
+        xSum = wSum;
+        for (loop_x=0;loop_x<myPoly->nX;loop_x++) {
+            ySum = xSum;
+            for (loop_y=0;loop_y<myPoly->nY;loop_y++) {
+                zSum = ySum;
+                for (loop_z=0;loop_z<myPoly->nZ;loop_z++) {
+                    polySum+= zSum *
+                              myPoly->coeff[loop_w][loop_x][loop_y][loop_z];
+                    zSum*=z;
+                }
+                ySum*=y;
+            }
+            xSum*=x;
+        }
+        wSum*=w;
+    }
+
+    return(polySum);
+}
+
+
+
+
+psDPolynomial1D *psDPolynomial1DAlloc(int n)
+{
+    int i = 0;
+    psDPolynomial1D *newPoly = NULL;
+
+    newPoly = (psDPolynomial1D *) psAlloc(sizeof(psDPolynomial1D));
+    newPoly->n = n;
+    newPoly->coeff    = (double *) psAlloc(n * sizeof(double));
+    newPoly->coeffErr = (double *) psAlloc(n * sizeof(double));
+    newPoly->mask     = (char *)  psAlloc(n * sizeof(char));
+    for (i=0;i<n;i++) {
+        newPoly->coeff[i] = 0.0;
+        newPoly->coeffErr[i] = 0.0;
+        newPoly->mask[i] = 0.0;
+    }
+
+    return(newPoly);
+}
+
+psDPolynomial2D *psDPolynomial2DAlloc(int nX, int nY)
+{
+    int x = 0;
+    int y = 0;
+    psDPolynomial2D *newPoly = NULL;
+
+    newPoly = (psDPolynomial2D *) psAlloc(sizeof(psDPolynomial2D));
+    newPoly->nX = nX;
+    newPoly->nY = nY;
+
+    newPoly->coeff    = (double **) psAlloc(nX * sizeof(double *));
+    newPoly->coeffErr = (double **) psAlloc(nX * sizeof(double *));
+    newPoly->mask     = (char **)  psAlloc(nX * sizeof(char *));
+    for (x=0;x<nX;x++) {
+        newPoly->coeff[x]    = (double *) psAlloc(nY * sizeof(double));
+        newPoly->coeffErr[x] = (double *) psAlloc(nY * sizeof(double));
+        newPoly->mask[x]     = (char *)  psAlloc(nY * sizeof(char));
+    }
+    for (x=0;x<nX;x++) {
+        for (y=0;y<nY;y++) {
+            newPoly->coeff[x][y] = 0.0;
+            newPoly->coeffErr[x][y] = 0.0;
+            newPoly->mask[x][y] = 0;
+        }
+    }
+
+    return(newPoly);
+}
+
+psDPolynomial3D *psDPolynomial3DAlloc(int nX, int nY, int nZ)
+{
+    int x = 0;
+    int y = 0;
+    int z = 0;
+    psDPolynomial3D *newPoly = NULL;
+
+    newPoly = (psDPolynomial3D *) psAlloc(sizeof(psDPolynomial3D));
+    newPoly->nX = nX;
+    newPoly->nY = nY;
+    newPoly->nZ = nZ;
+
+    newPoly->coeff    = (double ***) psAlloc(nX * sizeof(double **));
+    newPoly->coeffErr = (double ***) psAlloc(nX * sizeof(double **));
+    newPoly->mask     = (char ***)  psAlloc(nX * sizeof(char **));
+    for (x=0;x<nX;x++) {
+        newPoly->coeff[x]    = (double **) psAlloc(nY * sizeof(double *));
+        newPoly->coeffErr[x] = (double **) psAlloc(nY * sizeof(double *));
+        newPoly->mask[x]     = (char **)  psAlloc(nY * sizeof(char *));
+        for (y=0;y<nY;y++) {
+            newPoly->coeff[x][y]    = (double *) psAlloc(nZ * sizeof(double));
+            newPoly->coeffErr[x][y] = (double *) psAlloc(nZ * sizeof(double));
+            newPoly->mask[x][y]     = (char *)  psAlloc(nZ * sizeof(char));
+        }
+    }
+    for (x=0;x<nX;x++) {
+        for (y=0;y<nY;y++) {
+            for (z=0;z<nZ;z++) {
+                newPoly->coeff[x][y][z] = 0.0;
+                newPoly->coeffErr[x][y][z] = 0.0;
+                newPoly->mask[x][y][z] = 0;
+            }
+        }
+    }
+
+    return(newPoly);
+}
+
+psDPolynomial4D *psDPolynomial4DAlloc(int nW, int nX, int nY, int nZ)
+{
+    int w = 0;
+    int x = 0;
+    int y = 0;
+    int z = 0;
+    psDPolynomial4D *newPoly = NULL;
+
+    newPoly = (psDPolynomial4D *) psAlloc(sizeof(psDPolynomial4D));
+    newPoly->nW = nW;
+    newPoly->nX = nX;
+    newPoly->nY = nY;
+    newPoly->nZ = nZ;
+
+    newPoly->coeff    = (double ****) psAlloc(nW * sizeof(double ***));
+    newPoly->coeffErr = (double ****) psAlloc(nW * sizeof(double ***));
+    newPoly->mask     = (char ****)  psAlloc(nW * sizeof(char ***));
+    for (w=0;w<nW;w++) {
+        newPoly->coeff[w]    = (double ***) psAlloc(nX * sizeof(double **));
+        newPoly->coeffErr[w] = (double ***) psAlloc(nX * sizeof(double **));
+        newPoly->mask[w]     = (char ***)  psAlloc(nX * sizeof(char **));
+        for (x=0;x<nX;x++) {
+            newPoly->coeff[w][x]    = (double **) psAlloc(nY * sizeof(double *));
+            newPoly->coeffErr[w][x] = (double **) psAlloc(nY * sizeof(double *));
+            newPoly->mask[w][x]     = (char **) psAlloc(nY * sizeof(char *));
+            for (y=0;y<nY;y++) {
+                newPoly->coeff[w][x][y]    = (double *) psAlloc(nZ * sizeof(double));
+                newPoly->coeffErr[w][x][y] = (double *) psAlloc(nZ * sizeof(double));
+                newPoly->mask[w][x][y]     = (char *) psAlloc(nZ * sizeof(char));
+            }
+        }
+    }
+    for (w=0;w<nW;w++) {
+        for (x=0;x<nX;x++) {
+            for (y=0;y<nY;y++) {
+                for (z=0;z<nZ;z++) {
+                    newPoly->coeff[w][x][y][z] = 0.0;
+                    newPoly->coeffErr[w][x][y][z] = 0.0;
+                    newPoly->mask[w][x][y][z] = 0;
+                }
+            }
+        }
+    }
+
+    return(newPoly);
+}
+
+void psDPolynomial1DFree(psDPolynomial1D *myPoly)
+{
+    psFree(myPoly->coeff);
+    psFree(myPoly->coeffErr);
+    psFree(myPoly->mask);
+    psFree(myPoly);
+}
+
+void psDPolynomial2DFree(psDPolynomial2D *myPoly)
+{
+    int x = 0;
+
+    for (x=0;x<myPoly->nX;x++) {
+        psFree(myPoly->coeff[x]);
+        psFree(myPoly->coeffErr[x]);
+        psFree(myPoly->mask[x]);
+    }
+    psFree(myPoly->coeff);
+    psFree(myPoly->coeffErr);
+    psFree(myPoly->mask);
+
+    psFree(myPoly);
+}
+
+void psDPolynomial3DFree(psDPolynomial3D *myPoly)
+{
+    int x = 0;
+    int y = 0;
+
+    for (x=0;x<myPoly->nX;x++) {
+        for (y=0;y<myPoly->nY;y++) {
+            psFree(myPoly->coeff[x][y]);
+            psFree(myPoly->coeffErr[x][y]);
+            psFree(myPoly->mask[x][y]);
+        }
+        psFree(myPoly->coeff[x]);
+        psFree(myPoly->coeffErr[x]);
+        psFree(myPoly->mask[x]);
+    }
+
+    psFree(myPoly->coeff);
+    psFree(myPoly->coeffErr);
+    psFree(myPoly->mask);
+    psFree(myPoly);
+}
+
+void psDPolynomial4DFree(psDPolynomial4D *myPoly)
+{
+    int w = 0;
+    int x = 0;
+    int y = 0;
+
+    for (w=0;w<myPoly->nW;w++) {
+        for (x=0;x<myPoly->nX;x++) {
+            for (y=0;y<myPoly->nY;y++) {
+                psFree(myPoly->coeff[w][x][y]);
+                psFree(myPoly->coeffErr[w][x][y]);
+                psFree(myPoly->mask[w][x][y]);
+            }
+            psFree(myPoly->coeff[w][x]);
+            psFree(myPoly->coeffErr[w][x]);
+            psFree(myPoly->mask[w][x]);
+        }
+        psFree(myPoly->coeff[w]);
+        psFree(myPoly->coeffErr[w]);
+        psFree(myPoly->mask[w]);
+    }
+
+    psFree(myPoly->coeff);
+    psFree(myPoly->coeffErr);
+    psFree(myPoly->mask);
+    psFree(myPoly);
+}
+
+/*****************************************************************************
+    Polynomial coefficients will be accessed in [w][x][y][z] fashion.
+ *****************************************************************************/
+double
+psDEvalPolynomial1D(double x,
+                    const psDPolynomial1D *myPoly)
+{
+    int loop_x = 0;
+    double polySum = 0.0;
+    double xSum = 1.0;
+
+    // NOTE: Do we want to flag this case?
+    if (myPoly->n == 0) {
+        return(1.0);
+    }
+
+    for (loop_x=0;loop_x<myPoly->n;loop_x++) {
+        polySum+= xSum * myPoly->coeff[loop_x];
+        xSum*=x;
+    }
+
+    return(polySum);
+}
+
+
+double
+psDEvalPolynomial2D(double x,
+                    double y,
+                    const psDPolynomial2D *myPoly)
+{
+    int loop_x = 0;
+    int loop_y = 0;
+    double polySum = 0.0;
+    double xSum = 1.0;
+    double ySum = 1.0;
+
+    for (loop_x=0;loop_x<myPoly->nX;loop_x++) {
+        ySum = xSum;
+        for (loop_y=0;loop_y<myPoly->nY;loop_y++) {
+            polySum+= ySum * myPoly->coeff[loop_x][loop_y];
+            ySum*=y;
+        }
+        xSum*=x;
+    }
+
+    return(polySum);
+}
+
+double
+psDEvalPolynomial3D(double x,
+                    double y,
+                    double z,
+                    const psDPolynomial3D *myPoly)
+{
+    int loop_x = 0;
+    int loop_y = 0;
+    int loop_z = 0;
+    double polySum = 0.0;
+    double xSum = 1.0;
+    double ySum = 1.0;
+    double zSum = 1.0;
+
+    for (loop_x=0;loop_x<myPoly->nX;loop_x++) {
+        ySum = xSum;
+        for (loop_y=0;loop_y<myPoly->nY;loop_y++) {
+            zSum = ySum;
+            for (loop_z=0;loop_z<myPoly->nZ;loop_z++) {
+                polySum+= zSum * myPoly->coeff[loop_x][loop_y][loop_z];
+                zSum*=z;
+            }
+            ySum*=y;
+        }
+        xSum*=x;
+    }
+
+    return(polySum);
+}
+
+double
+psDEvalPolynomial4D(double w,
+                    double x,
+                    double y,
+                    double z,
+                    const psDPolynomial4D *myPoly)
+{
+    int loop_w = 0;
+    int loop_x = 0;
+    int loop_y = 0;
+    int loop_z = 0;
+    double polySum = 0.0;
+    double wSum = 1.0;
+    double xSum = 1.0;
+    double ySum = 1.0;
+    double zSum = 1.0;
+
+    for (loop_w=0;loop_w<myPoly->nW;loop_w++) {
+        xSum = wSum;
+        for (loop_x=0;loop_x<myPoly->nX;loop_x++) {
+            ySum = xSum;
+            for (loop_y=0;loop_y<myPoly->nY;loop_y++) {
+                zSum = ySum;
+                for (loop_z=0;loop_z<myPoly->nZ;loop_z++) {
+                    polySum+= zSum *
+                              myPoly->coeff[loop_w][loop_x][loop_y][loop_z];
+                    zSum*=z;
+                }
+                ySum*=y;
+            }
+            xSum*=x;
+        }
+        wSum*=w;
+    }
+
+    return(polySum);
+}
Index: /tags/rel1_1/psLib/src/dataManip/psFunctions.d
===================================================================
--- /tags/rel1_1/psLib/src/dataManip/psFunctions.d	(revision 1056)
+++ /tags/rel1_1/psLib/src/dataManip/psFunctions.d	(revision 1056)
@@ -0,0 +1,4 @@
+psFunctions.o psFunctions.d : psFunctions.c ../sysUtils/psMemory.h \
+  ../collections/psVector.h ../collections/psType.h ../sysUtils/psTrace.h \
+  ../sysUtils/psError.h ../sysUtils/psAbort.h psFunctions.h \
+  ../collections/psSort.h
Index: /tags/rel1_1/psLib/src/dataManip/psFunctions.h
===================================================================
--- /tags/rel1_1/psLib/src/dataManip/psFunctions.h	(revision 1056)
+++ /tags/rel1_1/psLib/src/dataManip/psFunctions.h	(revision 1056)
@@ -0,0 +1,255 @@
+/** @file psFunctions.h
+ *  \brief Standard Mathematical Functions.
+ *  \ingroup Stats
+ *
+ *  This file will hold the prototypes for procedures which allocate, free,
+ *  and evaluate various polynomials.  Those polynomial structures are also
+ *  defined here.
+ *
+ *  @ingroup Stats
+ *
+ *  @author Someone at IfA
+ *  @author George Gusciora, MHPCC
+ *
+ *  @version $Revision: 1.6 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-14 19:32:42 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#if !defined(PS_FUNCTIONS_H)
+#define PS_FUNCTIONS_H
+
+
+/** \addtogroup Stats
+ *  \{
+ */
+
+/** Evaluate a non-normalized Gaussian with the given mean and sigma at the
+    given coordianate.  Note that this is not a Gaussian deviate.  The
+    evaluated Gaussian is: \f[ exp(-\frac{(x-mean)^2}{2\sigma^2}) \f] */
+
+float
+psGaussian(float x,        ///< Value at which to evaluate
+           float mean,     ///< Mean for the Gaussian
+           float stddev,   ///< Standard deviation for the Gaussian
+           int normal      ///< Indicates whether result should be normalized
+          );
+
+
+/** Produce a vector of random numbers from a Gaussian distribution with
+    the specified mean and sigma */
+psVector *psGaussianDev(float mean,    ///< The mean of the Gaussian
+                        float sigma,   ///< The sigma of the Gaussian
+                        int Npts);     ///< The size of the vector
+
+
+
+
+
+/** One-dimensional polynomial */
+typedef struct
+{
+    int n;           ///< Number of terms
+    float *coeff;    ///< Coefficients
+    float *coeffErr; ///< Error in coefficients
+    char *mask;      ///< Coefficient mask
+}
+psPolynomial1D;
+
+/** Two-dimensional polynomial */
+typedef struct
+{
+    int nX, nY;    ///< Number of terms in x and y
+    float **coeff;   ///< Coefficients
+    float **coeffErr;   ///< Error in coefficients
+    char **mask;   ///< Coefficients mask
+}
+psPolynomial2D;
+
+/** Three-dimensional polynomial */
+typedef struct
+{
+    int nX, nY, nZ;   ///< Number of terms in x, y and z
+    float ***coeff;    ///< Coefficients
+    float ***coeffErr;    ///< Error in coefficients
+    char ***mask;    ///< Coefficients mask
+}
+psPolynomial3D;
+
+/** Four-dimensional polynomial */
+typedef struct
+{
+    int nW, nX, nY, nZ;   ///< Number of terms in w, x, y and z
+    float ****coeff;    ///< Coefficients
+    float ****coeffErr;   ///< Error in coefficients
+    char ****mask;    ///< Coefficients mask
+}
+psPolynomial4D;
+
+
+/** Functions **************************************************************/
+
+/** Constructor */
+psPolynomial1D *psPolynomial1DAlloc(int n ///< Number of terms
+                                   );
+/** Constructor */
+psPolynomial2D *psPolynomial2DAlloc(int nX, int nY ///< Number of terms in x and y
+                                   );
+/** Constructor */
+psPolynomial3D *psPolynomial3DAlloc(int nX, int nY, int nZ ///< Number of terms in x, y and z
+                                   );
+/** Constructor */
+psPolynomial4D *psPolynomial4DAlloc(int nW, int nX, int nY, int nZ ///< Number of terms in w, x, y and z
+                                   );
+
+/** Destructor */
+void psPolynomial1DFree(psPolynomial1D *myPoly ///< Polynomial to destroy
+                       );
+
+/** Destructor */
+void psPolynomial2DFree(psPolynomial2D *myPoly ///< Polynomial to destroy
+                       );
+/** Destructor */
+void psPolynomial3DFree(psPolynomial3D *myPoly ///< Polynomial to destroy
+                       );
+/** Destructor */
+void psPolynomial4DFree(psPolynomial4D *myPoly ///< Polynomial to destroy
+                       );
+
+
+/** Evaluate 1D polynomial */
+float
+psEvalPolynomial1D(float x,  ///< Value at which to evaluate
+                   const psPolynomial1D *myPoly ///< Coefficients for the polynomial
+                  );
+
+/** Evaluate 2D polynomial */
+float
+psEvalPolynomial2D(float x,  ///< Value x at which to evaluate
+                   float y,  ///< Value y at which to evaluate
+                   const psPolynomial2D *myPoly ///< Coefficients for the polynomial
+                  );
+
+/** Evaluate 3D polynomial */
+float
+psEvalPolynomial3D(float x,  ///< Value x at which to evaluate
+                   float y,  ///< Value y at which to evaluate
+                   float z,  ///< Value z at which to evaluate
+                   const psPolynomial3D *myPoly ///< Coefficients for the polynomial
+                  );
+
+/** Evaluate 4D polynomial */
+float
+psEvalPolynomial4D(float w,  ///< Value w at which to evaluate
+                   float x,  ///< Value x at which to evaluate
+                   float y,  ///< Value y at which to evaluate
+                   float z,  ///< Value z at which to evaluate
+                   const psPolynomial4D *myPoly ///< Coefficients for the polynomial
+                  );
+
+/*****************************************************************************/
+
+/* Double-precision polynomials, mainly for use in astrometry */
+
+/** Double-precision one-dimensional polynomial */
+typedef struct
+{
+    int n;    ///< Number of terms
+    double *coeff;   ///< Coefficients
+    double *coeffErr;   ///< Error in coefficients
+    char *mask;    ///< Coefficient mask
+}
+psDPolynomial1D;
+
+/** Double-precision two-dimensional polynomial */
+typedef struct
+{
+    int nX, nY;    ///< Number of terms in x and y
+    double **coeff;   ///< Coefficients
+    double **coeffErr;    ///< Error in coefficients
+    char **mask;   ///< Coefficients mask
+}
+psDPolynomial2D;
+
+/** Double-precision three-dimensional polynomial */
+typedef struct
+{
+    int nX, nY, nZ;   ///< Number of terms in x, y and z
+    double ***coeff;   ///< Coefficients
+    double ***coeffErr;   ///< Error in coefficients
+    char ***mask;    ///< Coefficient mask
+}
+psDPolynomial3D;
+
+/** Double-precision four-dimensional polynomial */
+typedef struct
+{
+    int nW, nX, nY, nZ;   ///< Number of terms in w, x, y and z
+    double ****coeff;    ///< Coefficients
+    double ****coeffErr;   ///< Error in coefficients
+    char ****mask;    ///< Coefficients mask
+}
+psDPolynomial4D;
+
+/** Constructor */
+psDPolynomial1D *psDPolynomial1DAlloc(int n ///< Number of terms
+                                     );
+/** Constructor */
+psDPolynomial2D *psDPolynomial2DAlloc(int nX, int nY ///< Number of terms in x and y
+                                     );
+/** Constructor */
+psDPolynomial3D *psDPolynomial3DAlloc(int nX, int nY, int nZ ///< Number of terms in x, y and z
+                                     );
+/** Constructor */
+psDPolynomial4D *psDPolynomial4DAlloc(int nW, int nX, int nY, int nZ ///< Number of terms in w, x, y and z
+                                     );
+
+
+/** Destructor */
+void psDPolynomial1DFree(psDPolynomial1D *myPoly ///< Polynomial to destroy
+                        );
+/** Destructor */
+void psDPolynomial2DFree(psDPolynomial2D *myPoly ///< Polynomial to destroy
+                        );
+/** Destructor */
+void psDPolynomial3DFree(psDPolynomial3D *myPoly ///< Polynomial to destroy
+                        );
+/** Destructor */
+void psDPolynomial4DFree(psDPolynomial4D *myPoly ///< Polynomial to destroy
+                        );
+
+
+/** Evaluate 1D polynomial (double precision) */
+double
+psDEvalPolynomial1D(double x,  ///< Value at which to evaluate
+                    const psDPolynomial1D *myPoly ///< Coefficients for the polynomial
+                   );
+
+/** Evaluate 2D polynomial (double precision) */
+double
+psDEvalPolynomial2D(double x,  ///< Value x at which to evaluate
+                    double y,  ///< Value y at which to evaluate
+                    const psDPolynomial2D *myPoly ///< Coefficients for the polynomial
+                   );
+
+/** Evaluate 3D polynomial (double precision) */
+double
+psDEvalPolynomial3D(double x,  ///< Value x at which to evaluate
+                    double y,  ///< Value y at which to evaluate
+                    double z,  ///< Value z at which to evaluate
+                    const psDPolynomial3D *myPoly ///< Coefficients for the polynomial
+                   );
+
+/** Evaluate 4D polynomial (double precision) */
+double
+psDEvalPolynomial4D(double w,  ///< Value w at which to evaluate
+                    double x,  ///< Value x at which to evaluate
+                    double y,  ///< Value y at which to evaluate
+                    double z,  ///< Value z at which to evaluate
+                    const psDPolynomial4D *myPoly ///< Coefficients for the polynomial
+                   );
+
+/* \} */ // End of MathGroup Functions
+
+#endif
Index: /tags/rel1_1/psLib/src/dataManip/psMatrix.c
===================================================================
--- /tags/rel1_1/psLib/src/dataManip/psMatrix.c	(revision 1056)
+++ /tags/rel1_1/psLib/src/dataManip/psMatrix.c	(revision 1056)
@@ -0,0 +1,571 @@
+/** @file  psMatrix.c
+ *
+ *  @brief Provides functions for linear algebra operations on psImages and psVectors. 
+ *
+ *  Functions are provided to:
+ *      Transpose a psImage
+ *      Compute LUD
+ *      Solve LUD
+ *      Matrix inversion
+ *      Calculate determinant
+ *      Matrix addition
+ *      Matrix subtraction
+ *      Matrix multiplication
+ *      Calculate Eigenvectors
+ *      Convert matrix to vector
+ *      Convert vector to matrix
+ *
+ *  These functions treat psImages as if they were matrices, therefore there is no psMatrix.
+ *
+ *  @author Ross Harman, MHPCC
+ *   
+ *  @version $Revision: 1.8 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-08 01:57:52 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+/******************************************************************************/
+/*  INCLUDE FILES                                                             */
+/******************************************************************************/
+#include <string.h>
+#include <gsl/gsl_matrix.h>
+#include <gsl/gsl_linalg.h>
+#include <gsl/gsl_permutation.h>
+#include <gsl/gsl_eigen.h>
+
+#include "psMemory.h"
+#include "psError.h"
+#include "psImage.h"
+#include "psVector.h"
+#include "psMatrix.h"
+
+/******************************************************************************/
+/*  DEFINE STATEMENTS                                                         */
+/******************************************************************************/
+
+// None
+
+/******************************************************************************/
+/*  TYPE DEFINITIONS                                                          */
+/******************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  GLOBAL VARIABLES                                                         */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  FILE STATIC VARIABLES                                                    */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  FUNCTION IMPLEMENTATION - LOCAL                                          */
+/*****************************************************************************/
+
+/** Preprocessor macro to generate error a NULL image */
+#define PS_CHECK_NULL_VECTOR(NAME, RETURN)                                                          \
+if (NAME == NULL || NAME->data.V == NULL) {                                                         \
+    psError(__func__,"Invalid operation: %s or its data is NULL.", #NAME);                          \
+    return RETURN;                                                                                  \
+}
+
+/** Preprocessor macro to create vector based on another */
+#define PS_CHECK_ALLOC_VECTOR(NAME, SIZE, PS_TYPE)                                                  \
+if(NAME == NULL) {                                                                                  \
+    NAME = psVectorAlloc(SIZE, PS_TYPE);                                                            \
+}
+
+/** Preprocessor macro to generate error for zero length vector */
+#define PS_CHECK_SIZE_VECTOR(NAME, RETURN)                                                          \
+if (NAME->n < 1) {                                                                                  \
+    psError(__func__,"Invalid operation: %s has zero n value.", #NAME);                             \
+    return RETURN;                                                                                  \
+}
+
+/** Preprocessor macro to generate error a NULL image */
+#define PS_CHECK_NULL_IMAGE(NAME, RETURN)                                                           \
+if (NAME == NULL || NAME->data.V == NULL) {                                                         \
+    psError(__func__,"Invalid operation: %s or its data is NULL.", #NAME);                          \
+    return RETURN;                                                                                  \
+}
+
+/** Preprocessor macro to create image based on another */
+#define PS_CHECK_ALLOC_IMAGE(NAME, NCOLS, NROWS, PS_TYPE)                                           \
+if(NAME == NULL) {                                                                                  \
+    NAME = psImageAlloc(NCOLS, NROWS, PS_TYPE);                                                     \
+}
+
+/** Preprocessor macro to generate error for zero length rows or columns */
+#define PS_CHECK_SIZE_IMAGE(NAME, RETURN)                                                           \
+if (NAME->numCols < 1 || NAME->numRows < 1) {                                                       \
+    psError(__func__,"Invalid operation: %s has zero rows or columns (%dx%d).", #NAME,              \
+            NAME->numCols, NAME->numRows);                                                          \
+    return RETURN;                                                                                  \
+}
+
+/** Preprocessor macro to generate error for image dimensionality not set to PS_DIMEN_IMAGE */
+#define PS_CHECK_DIMEN_AND_TYPE(NAME, PS_DIMEN, RETURN)                                             \
+if (NAME->type.dimen != PS_DIMEN) {                                                                 \
+    psError(__func__,"Invalid operation: %s incorrect dimensionality %d.", #NAME, PS_DIMEN);        \
+    return RETURN;                                                                                  \
+} else if(NAME->type.type != PS_TYPE_F64) {                                                         \
+    psError(__func__, "Invalid operation: %s not PS_TYPE_F64.", #NAME);                             \
+    return RETURN;                                                                                  \
+}
+
+/** Preprocessor macro to check that input is not equal to output */
+#define PS_CHECK_POINTERS(NAME1, NAME2, RETURN)                                                     \
+if (NAME1 == NAME2) {                                                                               \
+    psError(__func__,"Invalid operation: Pointer to %s is same as %s.", #NAME1, #NAME2);            \
+    return RETURN;                                                                                  \
+}
+
+/** Preprocessor macro to check that an image is square */
+#define PS_CHECK_SQUARE(NAME, RETURN)                                                               \
+if (NAME->numCols != NAME->numRows) {                                                               \
+    psError(__func__,"Invalid operation: %s not square array.", #NAME);                             \
+    return RETURN;                                                                                  \
+}
+
+/** Preprocessor macro to initalize a GSL matrix. */
+#define PS_GSL_MATRIX_INITIALIZE(LHS_NAME, RHS_NAME)                                                \
+LHS_NAME.size1 = numRows;                                                                           \
+LHS_NAME.size2 = numCols;                                                                           \
+LHS_NAME.tda   = numCols;                                                                           \
+LHS_NAME.data  = RHS_NAME;
+
+/*****************************************************************************/
+/* FUNCTION IMPLEMENTATION - PUBLIC                                          */
+/*****************************************************************************/
+
+psImage *psMatrixLUD(psImage *outImage, psVector *outPerm, psImage *inImage)
+{
+    int signum = 0;
+    int arraySize = 0;
+    int numRows = 0;
+    int numCols = 0;
+    gsl_matrix lu;
+    gsl_permutation perm;
+
+    // Error checks
+    PS_CHECK_POINTERS(inImage, outImage, outImage);
+    PS_CHECK_NULL_IMAGE(inImage, outImage);
+    PS_CHECK_DIMEN_AND_TYPE(inImage, PS_DIMEN_IMAGE, outImage);
+    PS_CHECK_SIZE_IMAGE(inImage, outImage);
+    PS_CHECK_ALLOC_IMAGE(outImage, inImage->numCols, inImage->numRows, inImage->type.type);
+    PS_CHECK_DIMEN_AND_TYPE(outImage, PS_DIMEN_IMAGE, outImage);
+    PS_CHECK_SIZE_IMAGE(outImage, outImage);
+    PS_CHECK_ALLOC_VECTOR(outPerm, inImage->numRows, inImage->type.type);
+    PS_CHECK_NULL_VECTOR(outPerm, outImage);
+    PS_CHECK_DIMEN_AND_TYPE(outPerm, PS_DIMEN_VECTOR, outImage);
+
+    // Initialize data
+    numRows = inImage->numRows;
+    numCols = inImage->numCols;
+    arraySize = PSELEMTYPE_SIZEOF(inImage->type.type)*numRows*numCols;
+
+    // Initialize GSL data
+    perm.size = numCols;
+    outPerm->n = numCols;
+    perm.data = outPerm->data.V;
+    PS_GSL_MATRIX_INITIALIZE(lu, outImage->data.V[0]);
+
+    // Non-square matrices not allowed
+    PS_CHECK_SQUARE(inImage, outImage);
+    PS_CHECK_SQUARE(outImage, outImage);
+
+    // Copy psImage input data into GSL matrix data to keep input data pristine
+    memcpy(lu.data, inImage->data.V[0], arraySize);
+
+    // Calculate LU decomposition
+    gsl_linalg_LU_decomp(&lu, &perm, &signum);
+
+    return outImage;
+}
+
+psVector *psMatrixLUSolve(psVector *outVector, const psImage *inImage, const psVector *inVector, const
+                          psVector *inPerm)
+{
+    int arraySize = 0;
+    int numRows = 0;
+    int numCols = 0;
+    gsl_matrix lu;
+    gsl_permutation perm;
+    gsl_vector b;
+    gsl_vector x;
+
+    // Error checks
+    PS_CHECK_POINTERS(outVector, inVector, outVector);
+    PS_CHECK_POINTERS(inVector, inPerm, outVector);
+    PS_CHECK_POINTERS(outVector, inPerm, outVector);
+    PS_CHECK_NULL_IMAGE(inImage, outVector);
+    PS_CHECK_DIMEN_AND_TYPE(inImage, PS_DIMEN_IMAGE, outVector);
+    PS_CHECK_SIZE_IMAGE(inImage, outVector);
+    PS_CHECK_ALLOC_VECTOR(outVector, inImage->numRows, inImage->type.type);
+    PS_CHECK_NULL_VECTOR(outVector, outVector);
+    PS_CHECK_DIMEN_AND_TYPE(outVector, PS_DIMEN_VECTOR, outVector);
+    PS_CHECK_NULL_VECTOR(inVector, outVector);
+    PS_CHECK_DIMEN_AND_TYPE(inVector, PS_DIMEN_VECTOR, outVector);
+    PS_CHECK_NULL_VECTOR(inPerm, outVector);
+    PS_CHECK_DIMEN_AND_TYPE(inPerm, PS_DIMEN_VECTOR, outVector);
+
+    // Initialize data
+    numRows = inImage->numRows;
+    numCols = inImage->numCols;
+    arraySize = PSELEMTYPE_SIZEOF(inImage->type.type)*numRows*numCols;
+
+    // Initialize GSL data
+    PS_GSL_MATRIX_INITIALIZE(lu, inImage->data.V[0]);
+
+    outVector->n = numCols;
+
+    perm.size = inPerm->n;
+    perm.data = inPerm->data.V;
+
+    b.size = inVector->n;
+    b.stride = 1;
+    b.data = inVector->data.V;
+
+    x.size = numCols;
+    x.stride = 1;
+    x.data = outVector->data.V;
+
+    // Solve for {x} in equation: {b} = [A]{x}
+    gsl_linalg_LU_solve(&lu, &perm, &b, &x);
+
+    return outVector;
+}
+
+psImage *psMatrixInvert(psImage *outImage, const psImage *inImage, float *restrict det)
+{
+    int signum = 0;
+    int arraySize = 0;
+    int numRows = 0;
+    int numCols = 0;
+    gsl_matrix inv;
+    gsl_matrix *lu;
+    gsl_permutation *perm = NULL;
+
+    // Error checks
+    if(det == NULL) {
+        psError(__func__, "Invalid operation: determinant argument is NULL.");
+        return outImage;
+    }
+    PS_CHECK_POINTERS(inImage, outImage, outImage);
+    PS_CHECK_NULL_IMAGE(inImage, outImage);
+    PS_CHECK_DIMEN_AND_TYPE(inImage, PS_DIMEN_IMAGE, outImage);
+    PS_CHECK_SIZE_IMAGE(inImage, outImage);
+    PS_CHECK_ALLOC_IMAGE(outImage, inImage->numCols, inImage->numRows, inImage->type.type);
+    PS_CHECK_DIMEN_AND_TYPE(outImage, PS_DIMEN_IMAGE, outImage);
+    PS_CHECK_SIZE_IMAGE(outImage, outImage);
+
+    // Initialize data
+    numRows = inImage->numRows;
+    numCols = inImage->numCols;
+    arraySize = PSELEMTYPE_SIZEOF(inImage->type.type)*numRows*numCols;
+
+    // Allocate GSL structs
+    perm = gsl_permutation_alloc(inImage->numRows);
+    lu = gsl_matrix_alloc(numRows, numCols);
+
+    // Initialize GSL data
+    PS_GSL_MATRIX_INITIALIZE(inv, outImage->data.V[0]);
+
+    // Non-square matrices not allowed
+    PS_CHECK_SQUARE(inImage, outImage);
+    PS_CHECK_SQUARE(outImage, outImage);
+
+    // Copy psImage input data into GSL matrix data to keep input data pristine
+    memcpy(lu->data, inImage->data.V[0], arraySize);
+
+    // Invert data and calculate determinant
+    gsl_linalg_LU_decomp(lu, perm, &signum);
+    gsl_linalg_LU_invert(lu, perm, &inv);
+    *det = (float)gsl_linalg_LU_det(lu, signum);
+
+    // Free GSL structs
+    gsl_permutation_free(perm);
+    gsl_matrix_free(lu);
+
+    return outImage;
+}
+
+float* psMatrixDeterminant(const psImage *restrict inImage)
+{
+    int signum = 0;
+    int arraySize = 0;
+    int numRows = 0;
+    int numCols = 0;
+    float *det = NULL;
+    gsl_matrix *lu = NULL;
+    gsl_permutation *perm = NULL;
+
+    // Error checks
+    PS_CHECK_NULL_IMAGE(inImage, NULL);
+    PS_CHECK_DIMEN_AND_TYPE(inImage, PS_DIMEN_IMAGE, NULL);
+    PS_CHECK_SIZE_IMAGE(inImage, NULL);
+
+    // Initialize data
+    numRows = inImage->numRows;
+    numCols = inImage->numCols;
+    arraySize = PSELEMTYPE_SIZEOF(inImage->type.type)*numRows*numCols;
+
+    // Allocate GSL structs
+    perm = gsl_permutation_alloc(numRows);
+    lu = gsl_matrix_alloc(numRows, numCols);
+
+    // Non-square matrices not allowed
+    PS_CHECK_SQUARE(inImage, 0);
+
+    // Copy psImage input data into GSL matrix data to keep input data pristine
+    memcpy(lu->data, inImage->data.V[0], arraySize);
+
+    // Calculate determinant
+    det = (float*)psAlloc(sizeof(float));
+    gsl_linalg_LU_decomp(lu, perm, &signum);
+    *det = (float)gsl_linalg_LU_det(lu, signum);
+
+    // Free GSL structs
+    gsl_permutation_free(perm);
+    gsl_matrix_free(lu);
+
+    return det;
+}
+
+psImage* psMatrixMultiply(psImage *outImage, psImage *inImage1, psImage *inImage2)
+{
+    int arraySize = 0;
+    int numRows = 0;
+    int numCols = 0;
+    gsl_matrix m1;
+    gsl_matrix m2;
+    gsl_matrix m3;
+
+    // Error checks
+    PS_CHECK_POINTERS(inImage1, outImage, outImage);
+    PS_CHECK_POINTERS(inImage1, inImage2, outImage);
+    PS_CHECK_NULL_IMAGE(inImage1, outImage);
+    PS_CHECK_DIMEN_AND_TYPE(inImage1, PS_DIMEN_IMAGE, outImage);
+    PS_CHECK_SIZE_IMAGE(inImage1, outImage);
+    PS_CHECK_NULL_IMAGE(inImage2, outImage);
+    PS_CHECK_DIMEN_AND_TYPE(inImage2, PS_DIMEN_IMAGE, outImage);
+    PS_CHECK_SIZE_IMAGE(inImage2, outImage);
+    PS_CHECK_ALLOC_IMAGE(outImage, inImage2->numCols, inImage2->numRows, inImage2->type.type);
+    PS_CHECK_DIMEN_AND_TYPE(inImage1, PS_DIMEN_IMAGE, outImage);
+    PS_CHECK_SIZE_IMAGE(outImage, outImage);
+
+    // Initialize data
+    numRows = inImage1->numRows;
+    numCols = inImage1->numCols;
+    arraySize = PSELEMTYPE_SIZEOF(outImage->type.type)*numRows*numCols;
+
+    // Initialize GSL data
+    PS_GSL_MATRIX_INITIALIZE(m1, inImage1->data.V[0]);
+    PS_GSL_MATRIX_INITIALIZE(m2, inImage2->data.V[0]);
+    PS_GSL_MATRIX_INITIALIZE(m3, outImage->data.V[0]);
+
+    // Non-square matrices not allowed
+    PS_CHECK_SQUARE(inImage1, outImage);
+    PS_CHECK_SQUARE(inImage2, outImage);
+    PS_CHECK_SQUARE(outImage, outImage);
+
+    gsl_linalg_matmult(&m1, &m2, &m3);
+
+    return outImage;
+}
+
+psImage* psMatrixTranspose(psImage *outImage, const psImage *inImage)
+{
+    int arraySize = 0;
+    int numRows = 0;
+    int numCols = 0;
+    gsl_matrix trans;
+
+    // Error checks
+    PS_CHECK_POINTERS(inImage, outImage, outImage);
+    PS_CHECK_NULL_IMAGE(inImage, outImage);
+    PS_CHECK_DIMEN_AND_TYPE(inImage, PS_DIMEN_IMAGE, outImage);
+    PS_CHECK_SIZE_IMAGE(inImage, outImage);
+    PS_CHECK_ALLOC_IMAGE(outImage, inImage->numCols, inImage->numRows, inImage->type.type);
+    PS_CHECK_DIMEN_AND_TYPE(outImage, PS_DIMEN_IMAGE, outImage);
+    PS_CHECK_SIZE_IMAGE(outImage, outImage);
+
+    // Initialize data
+    numRows = inImage->numRows;
+    numCols = inImage->numCols;
+    arraySize = PSELEMTYPE_SIZEOF(inImage->type.type)*numRows*numCols;
+
+    // Initialize GSL data
+    PS_GSL_MATRIX_INITIALIZE(trans, outImage->data.V[0]);
+
+    // Non-square matrices not allowed
+    PS_CHECK_SQUARE(inImage, outImage);
+    PS_CHECK_SQUARE(outImage, outImage);
+
+    // Copy psImage input data into psImage output data to keep input data pristine
+    memcpy(outImage->data.V[0], inImage->data.V[0], arraySize);
+
+    // Transpose data
+    gsl_matrix_transpose(&trans);
+
+    return outImage;
+}
+
+psImage *psMatrixEigenvectors(psImage *outImage, psImage *inImage)
+{
+    int numRows = 0;
+    int numCols = 0;
+    gsl_vector *eVals = NULL;
+    gsl_eigen_symmv_workspace *w = NULL;
+    gsl_matrix out;
+    gsl_matrix in;
+
+    // Error checks
+    PS_CHECK_POINTERS(inImage, outImage, outImage);
+    PS_CHECK_NULL_IMAGE(inImage, outImage);
+    PS_CHECK_DIMEN_AND_TYPE(inImage, PS_DIMEN_IMAGE, outImage);
+    PS_CHECK_SIZE_IMAGE(inImage, outImage);
+    PS_CHECK_ALLOC_IMAGE(outImage, inImage->numCols, inImage->numRows, inImage->type.type);
+    PS_CHECK_DIMEN_AND_TYPE(outImage, PS_DIMEN_IMAGE, outImage);
+    PS_CHECK_SIZE_IMAGE(outImage, outImage);
+
+    // Initialize data
+    numRows = inImage->numRows;
+    numCols = inImage->numCols;
+
+    // Initialize GSL data
+    PS_GSL_MATRIX_INITIALIZE(in, inImage->data.V[0]);
+    PS_GSL_MATRIX_INITIALIZE(out, outImage->data.V[0]);
+
+    // Allocate GSL structs
+    eVals = gsl_vector_alloc(numRows);
+    w = gsl_eigen_symmv_alloc(numRows);
+
+    // Non-square matrices not allowed
+    PS_CHECK_SQUARE(inImage, outImage);
+    PS_CHECK_SQUARE(outImage, outImage);
+
+    // Calculate Eigenvalues and Eigenvectors...Eigenvalues not currently used
+    gsl_eigen_symmv(&in, eVals, &out, w);
+
+    // Free GSL structs
+    gsl_eigen_symmv_free(w);
+    gsl_vector_free(eVals);
+
+    return outImage;
+}
+
+psVector *psMatrixToVector(psVector *outVector, psImage *inImage)
+{
+    int size = 0;
+
+    // Error checks
+    PS_CHECK_NULL_IMAGE(inImage, outVector);
+    PS_CHECK_DIMEN_AND_TYPE(inImage, PS_DIMEN_IMAGE, outVector);
+    PS_CHECK_SIZE_IMAGE(inImage, outVector);
+
+    if(inImage->numRows == 1) {
+        // Create transposed row vector
+        PS_CHECK_ALLOC_VECTOR(outVector, inImage->numCols, inImage->type.type);
+        outVector->type.dimen = PS_DIMEN_TRANSV;
+    } else if(inImage->numCols == 1) {
+        // Create non-transposed column vector
+        PS_CHECK_ALLOC_VECTOR(outVector, inImage->numRows, inImage->type.type);
+    } else {
+        psError(__func__, "Image does not have dim with 1 col or 1 row: (%d x %d).", inImage->numRows,
+                inImage->numCols);
+        return outVector;
+    }
+
+    PS_CHECK_NULL_VECTOR(outVector, outVector);
+
+
+    // More checks
+    if(outVector->type.dimen == PS_DIMEN_VECTOR) {
+        PS_CHECK_DIMEN_AND_TYPE(outVector, PS_DIMEN_VECTOR, outVector);
+
+        if(outVector->n == 0) {
+            outVector->n = inImage->numRows;
+        }
+
+        if(outVector->n != inImage->numRows) {
+            psError(__func__, "Image and vector sizes differ: (%d vs %d).", inImage->numRows, outVector->n);
+            return outVector;
+        }
+
+        size = PSELEMTYPE_SIZEOF(inImage->type.type)*inImage->numRows;
+
+    } else if(outVector->type.dimen == PS_DIMEN_TRANSV) {
+        PS_CHECK_DIMEN_AND_TYPE(outVector, PS_DIMEN_TRANSV, outVector);
+
+        if(outVector->n == 0) {
+            outVector->n = inImage->numCols;
+        }
+
+        if(outVector->n != inImage->numCols) {
+            psError(__func__, "Image and vector sizes differ: (%d vs %d).", inImage->numCols, outVector->n);
+            return outVector;
+        }
+
+        size = PSELEMTYPE_SIZEOF(inImage->type.type)*inImage->numCols;
+    }
+
+    memcpy(outVector->data.V, inImage->data.V[0], size);
+
+    return outVector;
+}
+
+psImage *psVectorToMatrix(psImage *outImage, psVector *inVector)
+{
+    int size = 0;
+
+    // Error checks
+    PS_CHECK_NULL_VECTOR(inVector, outImage);
+
+    if(inVector->type.dimen == PS_DIMEN_VECTOR) {
+        PS_CHECK_DIMEN_AND_TYPE(inVector, PS_DIMEN_VECTOR, outImage);
+        PS_CHECK_SIZE_VECTOR(inVector, outImage);
+        PS_CHECK_ALLOC_IMAGE(outImage, 1, inVector->n, PS_TYPE_F64)
+
+        // More checks for PS_DIMEN_VECTOR
+        if(outImage->numCols > 1) {
+            psError(__func__, "Image has more than 1 column: numCols = %d.", outImage->numCols);
+            return outImage;
+        } else if(outImage->numRows != inVector->n) {
+            psError(__func__, "Image and vector sizes differ: (%d vs %d).", outImage->numRows, inVector->n);
+            return outImage;
+        }
+
+        size = PSELEMTYPE_SIZEOF(outImage->type.type)*outImage->numRows;
+
+    } else if(inVector->type.dimen == PS_DIMEN_TRANSV) {
+        PS_CHECK_DIMEN_AND_TYPE(inVector, PS_DIMEN_TRANSV, outImage);
+        PS_CHECK_SIZE_VECTOR(inVector, outImage);
+        PS_CHECK_ALLOC_IMAGE(outImage, inVector->n, 1, PS_TYPE_F64)
+
+        // More checks for PS_DIMEN_TRANSV
+        if(outImage->numRows > 1) {
+            psError(__func__, "Image has more than 1 row: numRows = %d.", outImage->numRows);
+            return outImage;
+        } else if(outImage->numCols != inVector->n) {
+            psError(__func__, "Image and vector sizes differ: (%d vs %d).", outImage->numCols, inVector->n);
+            return outImage;
+        }
+
+        size = PSELEMTYPE_SIZEOF(outImage->type.type)*outImage->numCols;
+    }
+
+    PS_CHECK_NULL_IMAGE(outImage, outImage);
+    PS_CHECK_DIMEN_AND_TYPE(outImage, PS_DIMEN_IMAGE, outImage);
+
+    memcpy(outImage->data.V[0], inVector->data.V, size);
+
+    return outImage;
+}
+
Index: /tags/rel1_1/psLib/src/dataManip/psMatrix.d
===================================================================
--- /tags/rel1_1/psLib/src/dataManip/psMatrix.d	(revision 1056)
+++ /tags/rel1_1/psLib/src/dataManip/psMatrix.d	(revision 1056)
@@ -0,0 +1,3 @@
+psMatrix.o psMatrix.d : psMatrix.c ../sysUtils/psMemory.h ../sysUtils/psError.h \
+  ../collections/psImage.h ../collections/psType.h \
+  ../collections/psVector.h psMatrix.h
Index: /tags/rel1_1/psLib/src/dataManip/psMatrix.h
===================================================================
--- /tags/rel1_1/psLib/src/dataManip/psMatrix.h	(revision 1056)
+++ /tags/rel1_1/psLib/src/dataManip/psMatrix.h	(revision 1056)
@@ -0,0 +1,165 @@
+/** @file  psMatrix.h
+ *
+ *  @brief Provides functions for linear algebra operations on psImages and psVectors. 
+ *
+ *  Functions are provided to:
+ *      Transpose a psImage
+ *      Compute LUD
+ *      Solve LUD
+ *      Matrix inversion
+ *      Calculate determinant
+ *      Matrix multiplication
+ *      Calculate Eigenvectors
+ *      Convert matrix to vector
+ *      Convert vector to matrix
+ *
+ *  These functions treat psImages as if they were matrices, therefore there is no psMatrix. These functions
+ *  operate only with the psF64 data type.
+ *
+ *  @ingroup Matrix
+ *
+ *  @author Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.6 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-10 01:58:06 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PSMATRIX_H
+#define PSMATRIX_H
+
+/// @addtogroup Matrix
+/// @{
+
+/** LU Decomposition of psImage matrix.
+ *
+ *  Performs a LU decomposition on a psImage matrix and returns the LU matrix. If the user specifies NULL for
+ *  the outImage or outPerm arguments, then they will be automatically created. The input image must 
+ *  be square. This function operates only with the psF64 data type. Input and output arguments should not be 
+ *  the same. GSL indexes the top row as the zero row, not the bottom.  
+ *
+ *  @return  psImage*: Pointer to LU decomposed psImage.
+ */
+psImage *psMatrixLUD(
+    psImage *outImage,  ///< Image to return, or NULL.
+    psVector *outPerm,  ///< Output permutation vector used by psMatrixLUSolve.
+    psImage *inImage    ///< Image to decompose.
+);
+
+/** LU Solution of psImage matrix.
+ *
+ *  Solves for and returns the psVector, {x} in the equation [A]{x} = {b}. If the user specifies NULL as the 
+ *  outVector argument, then it will automatically be created. The input image must be square. This function 
+ *  operates only with the psF64 data type. Input and output arguments should not be the same. GSL indexes 
+ *  the top row as the zero row, not the bottom.  
+ *
+ *  @return  psVector*: Pointer to psVector solution of matrix equation.
+ */
+psVector *psMatrixLUSolve(
+    psVector *outVector,        ///< Vector to return, or NULL.
+    const psImage *luImage,     ///< LU-decomposed matrix.
+    const psVector *inVector,   ///< Vector right-hand-side of equation.
+    const psVector *inPerm      ///< Permutation vector resulting from psMatrixLUD function.
+);
+
+/** Invert psImage matrix.
+ *
+ *  Inverts a psImage matrix and returns the determinant as an option through the argument list. If the user
+ *  specifies NULL as the outImage argument, then it will automatically be created. The input image must be 
+ *  square. This function operates only with the psF64 data type. Input and output arguments should not be 
+ *  the same. GSL indexes the top row as the zero row, not the bottom.  
+ *
+ *  @return  psImage*: Pointer to inverted psImage.
+ */
+psImage *psMatrixInvert(
+    psImage *outImage,      ///< Image to return, or NULL for in-place substitution.
+    const psImage *inImage, ///< Image to be inverted
+    float *restrict det     ///< Determinant to return, or NULL
+);
+
+/** Calculate psImage matrix determinant.
+ *
+ *  Calculates the determinant of a psImage matrix and returns the single precision floating point result. The
+ *  input image must be square. This function operates only with the psF64 data type. GSL indexes the top row 
+ *  as the zero row, not the bottom.  
+ *
+ *  @return  float: Determinant from psImage.
+ */
+float* psMatrixDeterminant(
+    const psImage *restrict inMatrix    ///< Image used to calculate determinant.
+);
+
+/** Performs psImage matrix multiplication.
+ *
+ *  Performs a classical matrix multiplication involving row and column operations. Input images must be square 
+ *  and the same size. If the user specifies NULL as the outImage argument, then it will automatically be 
+ *  created. This function operates only with the psF64 data type. GSL indexes the top row as the
+ *  zero row, not the bottom.  
+ *
+ *  @return  psImage*: Pointer to resulting psImage.
+ */
+psImage *psMatrixMultiply(
+    psImage *outImage,  ///< Matrix to return, or NULL.
+    psImage *inImage1,  ///< First input image.
+    psImage *inImage2   ///< Second input image.
+);
+
+/** Transpose matrix.
+ *
+ *  Performs psImage matrix transpose by substituting existing rows for columns. The input image must be 
+ *  square. If the user specifies NULL as the outImage argument, then it will automaticallty be created.
+ *  This function operates only with the psF64 data type. GSL indexes the top row as the zero 
+ *  row, not the bottom.  
+ *
+ *  @return  psImage*: Pointer to transposed psImage.
+ */
+psImage *psMatrixTranspose(
+    psImage *outImage,      ///< Image to return, or NULL
+    const psImage *inImage  ///< Image to transpose
+);
+
+/** Calculate matrix eigenvectors.
+ *
+ *  Calculates the eigenvectors for a matrix. The input image must be symmetric and square. If the user 
+ *  specifies NULL as the outImage argument, then it will automatically be created. This function operates 
+ *  only with the psF64 data type. GSL indexes the top row as the zero row, not the bottom.  
+ *
+ *  @return  psImage*: Pointer to matrix of Eigenvectors.
+ */
+psImage *psMatrixEigenvectors(
+    psImage *outImage,  ///< Eigenvectors to return, or NULL.
+    psImage *inImage    ///< Input image.
+);
+
+/** Convert matrix to vector.
+ *
+ *  Converts a 1-d psImage matrix into a vector. If the user specifies NULL as the outVector argument, then it
+ *  will automatically be created based on the input image (PS_DIMEN_VECTOR for an input image with 1 col or
+ *  PS_DIMENT_TRANSV for an input image with 1 row). Either the number of rows or the number of colums of the
+ *  input matrix must be 1. This function operates only  with the psF64 data type.
+ *
+ *  @return  psVector*: Pointer to psVector.
+ */
+psVector *psMatrixToVector(
+    psVector *outVector,    ///< Vector to return, or NULL.
+    psImage *inImage        ///< Image to convert.
+);
+
+/** Convert vector to matrix.
+ *
+ *  Converts a vector into a psImage matrix. If the dimensionality of the vector is PS_DIMEN_VECTOR, then the
+ *  resulting psImage is a 1d column. If the dimensionality of the vector is PS_DIMEN_TRANSV, then the
+ *  resulting psImage is a 1d row. If the user specifies NULL as the outImage argument,  then it will 
+ *  automatically be created. This function operates only with the psF64 data type.  
+ *
+ *  @return  psVector*: Pointer to psIamge.
+ */
+psImage *psVectorToMatrix(
+    psImage *outImage,  ///< Matrix to return, or NULL.
+    psVector *inVector  ///< Vector to convert.
+);
+
+/// @}
+
+#endif
Index: /tags/rel1_1/psLib/src/dataManip/psStats.c
===================================================================
--- /tags/rel1_1/psLib/src/dataManip/psStats.c	(revision 1056)
+++ /tags/rel1_1/psLib/src/dataManip/psStats.c	(revision 1056)
@@ -0,0 +1,1279 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <float.h>
+#include <math.h>
+
+#include "psMemory.h"
+#include "psVector.h"
+#include "psTrace.h"
+#include "psError.h"
+#include "psAbort.h"
+#include "psStats.h"
+#include "psSort.h"
+
+#include "float.h"
+#define DEFAULT_ROBUST_SIZE_THRESHOLD 30000   // Vectors that are large than this
+// will use robust statistical methods.
+#define GAUSS_WIDTH 20                  // The width of the Gaussian or boxcar smoothing.
+#define CLIPPED_NUM_ITER_LB 1
+#define CLIPPED_NUM_ITER_UB 10
+#define CLIPPED_SIGMA_LB 1.0
+#define CLIPPED_SIGMA_UB 10.0
+#define true 1
+#define false 0
+#define MYMAXFLOAT HUGE
+
+#ifndef DOXYGEN
+void p_psVectorRobustStats(const psVector *restrict myVector,
+                           const psVector *restrict maskVector,
+                           unsigned int maskVal,
+                           psStats *stats);
+#endif
+
+/******************************************************************************
+    psStatsAlloc(): This routine must create a new psStats data structure.
+ *****************************************************************************/
+psStats *psStatsAlloc(psStatsOptions options)
+{
+    psStats *newStruct = NULL;
+
+    newStruct = (psStats *) psAlloc(sizeof(psStats));
+    newStruct->sampleMean = NAN;
+    newStruct->sampleMedian = NAN;
+    newStruct->sampleStdev = NAN;
+    newStruct->sampleUQ = NAN;
+    newStruct->sampleLQ = NAN;
+    newStruct->sampleLimit = DEFAULT_ROBUST_SIZE_THRESHOLD;
+    newStruct->robustMean = NAN;
+    newStruct->robustMedian = NAN;
+    newStruct->robustMode = NAN;
+    newStruct->robustStdev = NAN;
+    newStruct->robustUQ = NAN;
+    newStruct->robustLQ = NAN;
+    newStruct->robustN50 = NAN;
+    newStruct->robustNfit = NAN;
+    newStruct->clippedMean = NAN;
+    newStruct->clippedStdev = NAN;
+    newStruct->clipSigma = 3.0;
+    newStruct->clipIter = 3.0;
+    newStruct->min = NAN;
+    newStruct->max = NAN;
+    newStruct->binsize = NAN;
+    newStruct->options = options;
+
+    return(newStruct);
+}
+
+/******************************************************************************
+    psStatsFree(): This routine must free the psStats data structure.
+ *****************************************************************************/
+void psStatsFree(psStats *stats)
+{
+    psFree(stats);
+}
+
+/******************************************************************************
+psHistogramAlloc(lower, upper, n): allocate a uniform histogram structure
+with the specifed upper and lower limits, and the specifed number of bins.
+This routine will also set the bounds for each of the bins.
+ 
+Input:
+    lower
+    upper
+    n
+Returns:
+    The histogram structure
+ *****************************************************************************/
+psHistogram *psHistogramAlloc(float lower,
+                              float upper,
+                              int n)
+{
+    int i = 0;                          // Loop index variable
+    psHistogram *newHist = NULL;        // The new histogram structure
+    float binSize = 0.0;                // The histogram bin size
+
+    // NOTE: Verify that this is the correct action.
+    if (n == 0) {
+        return(NULL);
+    }
+
+    // NOTE: Verify that this is the correct action.
+    if (lower > upper) {
+        return(NULL);
+    }
+
+    // Allocate memory for the new histogram structure.  If there are N
+    // bins, then there are N+1 bounds to those bins.
+    newHist = (psHistogram *) psAlloc(sizeof(psHistogram));
+    newHist->bounds = psVectorAlloc(n+1, PS_TYPE_F32);
+    newHist->bounds->n = newHist->bounds->nalloc;
+
+    // Calculate the bounds for each bin.
+    binSize = (upper - lower) / (float) n;
+    for (i=0;i<n+1;i++) {
+        newHist->bounds->data.F32[i] = lower + (binSize * (float) i);
+    }
+
+    // Allocate the bins, and initialize them to zero.
+    newHist->nums =  psVectorAlloc(n, PS_TYPE_S32);
+    newHist->nums->n = newHist->nums->nalloc;
+    for (i=0;i<newHist->nums->n;i++) {
+        newHist->nums->data.S32[i] = 0;
+    }
+
+    // Initialize the other members.
+    newHist->minNum = 0;
+    newHist->maxNum = 0;
+    newHist->uniform = true;
+
+    return(newHist);
+}
+
+/******************************************************************************
+psHistogramAlloc(lower, upper, n): allocate a non-uniform histogram structure
+with the specifed bounds.  The number of elements in the bounds vector is n.
+Therefore, the number of bins is n-1.
+Input:
+    bounds
+Returns:
+    The histogram structure
+ *****************************************************************************/
+psHistogram *psHistogramAllocGeneric(const psVector *restrict bounds)
+{
+    psHistogram *newHist = NULL;        // The new histogram structure
+    int i;                              // Loop index variable
+
+    // NOTE: Verify that this is the correct action.
+    if (bounds == NULL) {
+        //        psAbort(__func__, "psHistogram requested with NULL bounds");
+        return(NULL);
+    }
+
+    // NOTE: Verify that this is the correct action.
+    if (bounds->n <= 1) {
+        //        psAbort(__func__, "psHistogram requested with NULL bounds");
+        return(NULL);
+    }
+
+    // Allocate memory for the new histogram structure.
+    newHist = (psHistogram *) psAlloc(sizeof(psHistogram));
+    newHist->bounds = psVectorAlloc(bounds->n, PS_TYPE_F32);
+    newHist->bounds->n = newHist->bounds->nalloc;
+    for (i=0;i<bounds->n;i++) {
+        newHist->bounds->data.F32[i] = bounds->data.F32[i];
+    }
+
+    // Allocate the bins, and initialize them to zero.  If there are N bounds,
+    // then there are N-1 bins.
+    newHist->nums = psVectorAlloc((bounds->n)-1, PS_TYPE_S32);
+    newHist->nums->n = newHist->nums->nalloc;
+    for (i=0;i<newHist->nums->n;i++) {
+        newHist->nums->data.S32[i] = 0;
+    }
+
+    // Initialize the other members.
+    newHist->minNum = 0;
+    newHist->maxNum = 0;
+    newHist->uniform = false;
+
+    return(newHist);
+}
+
+void psHistogramFree(psHistogram *myHist)
+{
+    psVectorFree(myHist->bounds);
+    psVectorFree(myHist->nums);
+    psFree(myHist);
+}
+
+
+/*****************************************************************************
+psHistogramVector(out, in, mask, maskVal): this procedure takes as input a
+preallocated and initialized histogram structure.  It fills the bins in that
+histogram structure in accordance with the input data "in" and the, possibly
+NULL, mask vector.
+ 
+Inputs:
+    out
+    in
+    mask
+    maskVal
+Returns:
+    The histogram structure "out".
+ *****************************************************************************/
+psHistogram *psHistogramVector(psHistogram *out,
+                               const psVector *restrict in,
+                               const psVector *restrict mask,
+                               int maskVal)
+{
+    int i = 0;                                  // Loop index variable
+    int j = 0;                                  // Loop index variable
+    float binSize = 0.0;                        // Histogram bin size
+    int binNum = 0;                             // A temporary bin number
+    int numBins = 0;                            // The total number of bins
+
+    // NOTE: Verify that this is the correct action.
+    if (out == NULL) {
+        return(NULL);
+    }
+
+    // NOTE: Verify that this is the correct action.
+    if (in == NULL) {
+        return(out);
+    }
+
+    if (in->type.type != PS_TYPE_F32) {
+        psAbort(__func__,
+                "Only data type PS_TYPE_F32 is currently supported (0x%x).",
+                in->type.type);
+    }
+
+    if (mask != NULL) {
+        if (in->n != mask->n) {
+            psAbort(__func__,
+                    "Vector data and vector mask are of different sizes.");
+        }
+        if (mask->type.type != PS_TYPE_U8) {
+            psAbort(__func__, "Vector mask must be type PS_TYPE_U8");
+        }
+    }
+    // NOTE: determine the correct action for a variety of other cases:
+    // in vector has 0 elements, and histogram structure has zero bins.
+
+    numBins = out->nums->n;
+
+    for (i=0;i<in->n;i++) {
+        // Check if this pixel is masked, and if so, skip it.
+        if ((mask == NULL) ||
+                ((mask != NULL) && (!(mask->data.U8[i] & maskVal)))) {
+            // Check if this pixel is below the minimum value, and if so
+            // count it, then skip it.
+            if (in->data.F32[i] < out->bounds->data.F32[0]) {
+                out->minNum++;
+                // Check if this pixel is above the maximum value, and if so
+                // count it, then skip it.
+            } else if (in->data.F32[i] > out->bounds->data.F32[numBins]) {
+                out->maxNum++;
+            } else {
+                // If this is a uniform histogram, determining the correct
+                // number is trivial.
+                if (out->uniform == true) {
+                    binSize = out->bounds->data.F32[1] - out->bounds->data.F32[0];
+
+                    binNum = (int) ((in->data.F32[i] - out->bounds->data.F32[0]) /
+                                    binSize);
+                    (out->nums->data.S32[binNum])++;
+                    // If this is a non-uniform histogram, determining the correct
+                    // bin number requires a bit more work.
+                } else {
+                    // NOTE: This is slow.  Put a smarter algorithm here to
+                    // find the correct bin number (bin search, probably)
+                    for (j=0;j<(out->bounds->n)-1;j++) {
+                        if ((out->bounds->data.S32[j] <= in->data.F32[i]) &&
+                                (in->data.F32[i] <= out->bounds->data.S32[j+1])) {
+                            (out->nums->data.S32[j])++;
+                        }
+                    }
+                }
+            }
+        }
+    }
+    return(out);
+}
+
+/*****************************************************************************
+p_psVectorPrint(myVector, maskVector, maskVal, stats): a private internal
+function that simply prints a vector to STDOUT.  Used primarily for
+debugging.
+ *****************************************************************************/
+
+void p_psVectorPrint(psVector *myVector,
+                     psVector *maskVector,
+                     unsigned int maskVal,
+                     psStats *stats)
+{
+    int i = 0;                                  // Loop index variable.
+
+    for (i=0;i<myVector->n;i++) {
+        if (maskVector != NULL)
+            printf("Element %d is %f (mask is %d)\n", i, myVector->data.F32[i], maskVector->data.U8[i]);
+        else
+            printf("Element %d is %f\n", i, myVector->data.F32[i]);
+    }
+}
+
+
+/******************************************************************************
+ ******************************************************************************
+ ******************************************************************************
+    MISC PRIVATE STATISTICAL FUNCTIONS
+ 
+    NOTE: it is assumed that any call to these statistical functions will
+    have been preceded by a call to the psVectorStats() function.  Various
+    sanity tests will only be performed in psVectorStats().
+        Is the mask vector the same length as the data vector?
+        Is the mask vector of type PS_TYPE_U8?
+        Is the stats data structure NULL?
+        Is the in data structure NULL?
+        Is the in data structure of type PS_TYPE_F32?
+ ******************************************************************************
+ ******************************************************************************
+ *****************************************************************************/
+
+
+/******************************************************************************
+p_psVectorSampleMean(myVector, maskVector, maskVal, stats): calculates the
+mean of the input vector.
+Inputs
+Returns
+    NULL
+ASSUMPTION: the mean is always calculated exactly.  Robust means are never
+calculated in this routine.
+ *****************************************************************************/
+void p_psVectorSampleMean(const psVector *restrict myVector,
+                          const psVector *restrict maskVector,
+                          unsigned int maskVal,
+                          psStats *stats)
+{
+    int i = 0;                                  // Loop index variable
+    float mean = 0.0;                           // The mean
+    int count = 0;                              // # of points in this mean?
+    float rangeMin = 0.0;                       // Exclude data below this
+    float rangeMax = 0.0;                       // Exclude date above this
+
+    // If PS_STAT_USE_RANGE is requested, then we enter a slightly different
+    // loop.
+    if (stats->options & PS_STAT_USE_RANGE) {
+        rangeMin = stats->min;
+        rangeMax = stats->max;
+        if (maskVector != NULL) {
+            for (i=0;i<myVector->n;i++) {
+                // Check if the data is with the specified range
+                if (!(maskVal & maskVector->data.U8[i]) &&
+                        (rangeMin <= myVector->data.F32[i]) &&
+                        (myVector->data.F32[i] <= rangeMax)) {
+                    mean+= myVector->data.F32[i];
+                    count++;
+                }
+            }
+            mean/= (float) count;
+        } else {
+            for (i=0;i<myVector->n;i++) {
+                if ((rangeMin <= myVector->data.F32[i]) &&
+                        (myVector->data.F32[i] <= rangeMax)) {
+                    mean+= myVector->data.F32[i];
+                    count++;
+                }
+            }
+            mean/= (float) count;
+        }
+    } else {
+        if (maskVector != NULL) {
+            for (i=0;i<myVector->n;i++) {
+                if (!(maskVal & maskVector->data.U8[i])) {
+                    mean+= myVector->data.F32[i];
+                    count++;
+                }
+            }
+            mean/= (float) count;
+        } else {
+            for (i=0;i<myVector->n;i++) {
+                mean+= myVector->data.F32[i];
+            }
+            mean/= (float) myVector->n;
+        }
+    }
+
+    stats->sampleMean = mean;
+}
+
+/******************************************************************************
+p_psVectorSampleMax(myVector, maskVector, maskVal, stats): calculates the
+max of the input vector.
+Inputs
+    myVector
+    maskVector
+    maskVal
+    stats
+Returns
+    NULL
+ *****************************************************************************/
+void p_psVectorMax(const psVector *restrict myVector,
+                   const psVector *restrict maskVector,
+                   unsigned int maskVal,
+                   psStats *stats)
+{
+    int i = 0;                                  // Loop index variable
+    float max = -MYMAXFLOAT;                    // The calculated maximum
+    float rangeMin = 0.0;                       // Exclude data below this
+    float rangeMax = 0.0;                       // Exclude date above this
+
+    // If PS_STAT_USE_RANGE is requested, then we enter a different loop.
+    if (stats->options & PS_STAT_USE_RANGE) {
+        rangeMin = stats->min;
+        rangeMax = stats->max;
+        if (maskVector != NULL) {
+            for (i=0;i<myVector->n;i++) {
+                if (!(maskVal & maskVector->data.U8[i])) {
+                    if ((myVector->data.F32[i] > max) &&
+                            (rangeMin <= myVector->data.F32[i]) &&
+                            (myVector->data.F32[i] <= rangeMax)) {
+                        max = myVector->data.F32[i];
+                    }
+                }
+            }
+        } else {
+            for (i=0;i<myVector->n;i++) {
+                if ((myVector->data.F32[i] > max) &&
+                        (rangeMin <= myVector->data.F32[i]) &&
+                        (myVector->data.F32[i] <= rangeMax)) {
+                    max = myVector->data.F32[i];
+                }
+            }
+        }
+    } else {
+        if (maskVector != NULL) {
+            for (i=0;i<myVector->n;i++) {
+                if (!(maskVal & maskVector->data.U8[i])) {
+                    if (myVector->data.F32[i] > max) {
+                        max = myVector->data.F32[i];
+                    }
+                }
+            }
+        } else {
+            for (i=0;i<myVector->n;i++) {
+                if (myVector->data.F32[i] > max) {
+                    max = myVector->data.F32[i];
+                }
+            }
+        }
+    }
+
+    stats->max = max;
+}
+
+/******************************************************************************
+p_psVectorSampleMin(myVector, maskVector, maskVal, stats): calculates the
+minimum of the input vector.
+Inputs
+    myVector
+    maskVector
+    maskVal
+    stats
+Returns
+    NULL
+ *****************************************************************************/
+void p_psVectorMin(const psVector *restrict myVector,
+                   const psVector *restrict maskVector,
+                   unsigned int maskVal,
+                   psStats *stats)
+{
+    int i = 0;                                  // Loop index variable
+    float min = MYMAXFLOAT;                     // The calculated maximum
+    float rangeMin = 0.0;                       // Exclude data below this
+    float rangeMax = 0.0;                       // Exclude date above this
+
+    if (stats->options & PS_STAT_USE_RANGE) {
+        rangeMin = stats->min;
+        rangeMax = stats->max;
+        if (maskVector != NULL) {
+            for (i=0;i<myVector->n;i++) {
+                if (!(maskVal & maskVector->data.U8[i])) {
+                    if ((myVector->data.F32[i] < min) &&
+                            (rangeMin <= myVector->data.F32[i]) &&
+                            (myVector->data.F32[i] <= rangeMax)) {
+                        min = myVector->data.F32[i];
+                    }
+                }
+            }
+        } else {
+            for (i=0;i<myVector->n;i++) {
+                if ((myVector->data.F32[i] < min) &&
+                        (rangeMin <= myVector->data.F32[i]) &&
+                        (myVector->data.F32[i] <= rangeMax)) {
+                    min = myVector->data.F32[i];
+                }
+            }
+        }
+    } else {
+        if (maskVector != NULL) {
+            for (i=0;i<myVector->n;i++) {
+                if (!(maskVal & maskVector->data.U8[i])) {
+                    if (myVector->data.F32[i] < min) {
+                        min = myVector->data.F32[i];
+                    }
+                }
+            }
+        } else {
+            for (i=0;i<myVector->n;i++) {
+                if (myVector->data.F32[i] < min) {
+                    min = myVector->data.F32[i];
+                }
+            }
+        }
+    }
+
+    stats->min = min;
+}
+
+/******************************************************************************
+p_psVectorSampleMax(myVector, maskVector, maskVal, stats): calculates the
+number of non-masked pixels in the vector.  that fall within the min/max
+range, if given.
+Inputs
+    myVector
+    maskVector
+    maskVal
+    stats
+Returns
+    NULL
+ *****************************************************************************/
+int p_psVectorNValues(const psVector *restrict myVector,
+                      const psVector *restrict maskVector,
+                      unsigned int maskVal,
+                      psStats *stats)
+{
+    int i = 0;                                  // Loop index variable
+    int numData = 0;                            // The number of data points
+    float rangeMin = 0.0;                       // Exclude data below this
+    float rangeMax = 0.0;                       // Exclude date above this
+
+    if (stats->options & PS_STAT_USE_RANGE) {
+        rangeMin = stats->min;
+        rangeMax = stats->max;
+        if (maskVector != NULL) {
+            for (i=0;i<myVector->n;i++) {
+                if (!(maskVal & maskVector->data.U8[i]) &&
+                        (rangeMin <= myVector->data.F32[i]) &&
+                        (myVector->data.F32[i] <= rangeMax)) {
+                    numData++;
+                }
+            }
+        } else {
+            for (i=0;i<myVector->n;i++) {
+                if ((rangeMin <= myVector->data.F32[i]) &&
+                        (myVector->data.F32[i] <= rangeMax)) {
+                    numData++;
+                }
+            }
+        }
+    } else {
+        rangeMin = stats->min;
+        rangeMax = stats->max;
+        if (maskVector != NULL) {
+            for (i=0;i<myVector->n;i++) {
+                if (!(maskVal & maskVector->data.U8[i])) {
+                    numData++;
+                }
+            }
+        } else {
+            numData = myVector->n;
+        }
+    }
+    return(numData);
+}
+
+
+
+/******************************************************************************
+p_psVectorSampleMedian(myVector, maskVector, maskVal, stats): calculates the
+median of the input vector.
+Inputs
+    myVector
+    maskVector
+    maskVal
+    stats
+Returns
+    NULL
+ *****************************************************************************/
+void p_psVectorSampleMedian(const psVector *restrict myVector,
+                            const psVector *restrict maskVector,
+                            unsigned int maskVal,
+                            psStats *stats)
+{
+    psVector *unsortedVector = NULL;            // Temporary vector
+    psVector *sortedVector = NULL;              // Temporary vector
+    int i = 0;                                  // Loop index variable
+    int count = 0;                              // # of points in this mean?
+    int nValues = 0;                            // # of points in vector
+    float rangeMin = 0.0;                       // Exclude data below this
+    float rangeMax = 0.0;                       // Exclude date above this
+    psStats *stats2 = NULL;                     // Temporary stats structure
+
+
+    // Determine if the number of data points exceed a threshold which will
+    // cause to generate robust stats, as opposed to exact stats.
+
+    if (myVector->n > stats->sampleLimit) {
+        psAbort(__func__, "Robust Statistic Algorithms have not yet been defined or implemented.");
+
+        // Calculate the robust quartiles.
+        stats2 = psStatsAlloc(PS_STAT_ROBUST_MEDIAN);
+        p_psVectorRobustStats(myVector, maskVector, maskVal, stats2);
+
+        // Store the robust quartiles into the sample quartile members.
+        stats->sampleMedian = stats2->robustMedian;
+
+        // Free temporary data buffers.
+        psStatsFree(stats2);
+
+        // Set the PS_STAT_ROBUST_FOR_SAMPLE bit in the stats structure.
+        stats->options = stats->options | PS_STAT_ROBUST_FOR_SAMPLE;
+
+        return;
+    }
+
+    // Determine how many data points fit inside this min/max range
+    // and are not masked, IF the maskVector is not NULL>
+    nValues = p_psVectorNValues(myVector, maskVector, maskVal, stats);
+
+    // Allocate temporary vectors for the data.
+    unsortedVector = psVectorAlloc(nValues, PS_TYPE_F32);
+    unsortedVector->n = unsortedVector->nalloc;
+
+    sortedVector   = psVectorAlloc(nValues, PS_TYPE_F32);
+    sortedVector->n = sortedVector->nalloc;
+
+    // Determine if we must only use data points within a min/max range.
+    if (stats->options & PS_STAT_USE_RANGE) {
+        rangeMin = stats->min;
+        rangeMax = stats->max;
+
+        // Store all non-masked data points within the min/max range
+        // into the temporary vectors.
+        count = 0;
+        if (maskVector != NULL) {
+            for (i=0;i<myVector->n;i++) {
+                if (!(maskVal & maskVector->data.U8[i]) &&
+                        (rangeMin <= myVector->data.F32[i]) &&
+                        (myVector->data.F32[i] <= rangeMax)) {
+                    unsortedVector->data.F32[count++] = maskVector->data.F32[i];
+                }
+            }
+        } else {
+            for (i=0;i<myVector->n;i++) {
+                if ((rangeMin <= myVector->data.F32[i]) &&
+                        (myVector->data.F32[i] <= rangeMax)) {
+                    unsortedVector->data.F32[count++] = myVector->data.F32[i];
+                }
+            }
+        }
+    } else {
+        // Store all non-masked data points into the temporary vectors.
+        count = 0;
+        if (maskVector != NULL) {
+            for (i=0;i<myVector->n;i++) {
+                if (!(maskVal & maskVector->data.U8[i])) {
+                    unsortedVector->data.F32[count++] = myVector->data.F32[i];
+                }
+            }
+        } else {
+            for (i=0;i<myVector->n;i++) {
+                unsortedVector->data.F32[i] = myVector->data.F32[i];
+            }
+        }
+    }
+    // Sort the temporary vectors.
+    psSort(sortedVector, unsortedVector);
+
+    // Calculate the median exactly.
+    if (0 == (nValues % 2)) {
+        stats->sampleMedian = 0.5 * (sortedVector->data.F32[(nValues/2)-1] +
+                                     sortedVector->data.F32[nValues/2]);
+    } else {
+        stats->sampleMedian = sortedVector->data.F32[nValues/2];
+    }
+
+    // Free the temporary data structures.
+    psVectorFree(unsortedVector);
+    psVectorFree(sortedVector);
+}
+
+/******************************************************************************
+    This routine smoothes the data in the input robustHistogram with a
+    Gaussian of width sigma.
+ *****************************************************************************/
+void p_psVectorsmoothHistGaussian(psHistogram *robustHistogram,
+                                  float sigma)
+{
+    int i = 0;                                  // Loop index variable
+    int j = 0;                                  // Loop index variable
+    float tmpf = 0.0;                           // Temporary variable
+    float gaussianCoefs[1 + (2 * GAUSS_WIDTH)]; // The Gaussian Coefficients
+
+    for(i=0;i<(1 + (2 * GAUSS_WIDTH));i++) {
+        if (fabs(sigma) <= FLT_EPSILON) {
+            // If sigma does not equal zero, then we use Gaussian smoothing.
+            #ifdef  DARWIN
+            tmpf = (float) sqrt(2.0f * M_PI * sigma * sigma);
+            #else
+
+            tmpf = sqrtf(2.0f * M_PI * sigma * sigma);
+            #endif
+
+            gaussianCoefs[i] = (float) exp( (-((float) (i-GAUSS_WIDTH)) *
+                                             ((float) (i-GAUSS_WIDTH))) /
+                                            (2.0f * sigma * sigma)) / tmpf;
+        } else {
+            /* If sigma equals zero (all pixels have the same value)
+             * the above code will divide by zero.  Therefore, we don't need
+             * to smooth the data.
+             */
+            return;
+        }
+    }
+
+    for(i=0;i<robustHistogram->nums->n;i++) {
+        for (j=-GAUSS_WIDTH;j<=+GAUSS_WIDTH;j++) {
+            if (((j+i) >= 0) && ((j+i) < robustHistogram->nums->n)) {
+                robustHistogram->nums->data.S32[j+i]+=
+                    (gaussianCoefs[j+GAUSS_WIDTH] *
+                     (float) robustHistogram->nums->data.S32[j+i]);
+            }
+        }
+    }
+}
+
+/******************************************************************************
+p_psVectorSampleQuartiles(myVector, maskVector, maskVal, stats): calculates
+the upper and/or lower quartiles of the input vector.
+Inputs
+    myVector
+    maskVector
+    maskVal
+    stats
+Returns
+    NULL
+ *****************************************************************************/
+void p_psVectorSampleQuartiles(const psVector *restrict myVector,
+                               const psVector *restrict maskVector,
+                               unsigned int maskVal,
+                               psStats *stats)
+{
+    psVector *unsortedVector = NULL;            // Temporary vector
+    psVector *sortedVector = NULL;              // Temporary vector
+    int i = 0;                                  // Loop index variable
+    int count = 0;                              // # of points in this mean?
+    int nValues = 0;                            // # data points
+    float rangeMin = 0.0;                       // Exclude data below this
+    float rangeMax = 0.0;                       // Exclude date above this
+
+    // Determine if the number of data points exceed a threshold which will
+    // cause to generate robust stats, as opposed to exact stats.
+    if (myVector->n > stats->sampleLimit) {
+        psAbort(__func__, "Robust Statistic Algorithms have not yet been defined or implemented.");
+        psStats *stats2 = NULL;
+        // Calculate the robust quartiles.
+        stats2 = psStatsAlloc(PS_STAT_ROBUST_QUARTILE);
+        p_psVectorRobustStats(myVector, maskVector, maskVal, stats2);
+
+        // Store the robust quartiles into the sample quartile members.
+        stats->sampleUQ = stats2->robustUQ;
+        stats->sampleLQ = stats2->robustLQ;
+
+        // Free temporary data buffers.
+        psStatsFree(stats2);
+
+        // Set the PS_STAT_ROBUST_FOR_SAMPLE bit in the stats structure.
+        stats->options = stats->options | PS_STAT_ROBUST_FOR_SAMPLE;
+
+        return;
+    }
+
+    // Determine how many data points fit inside this min/max range
+    // and are not maxed, IF the maskVector is not NULL>
+    nValues = p_psVectorNValues(myVector, maskVector, maskVal, stats);
+
+    // Allocate temporary vectors for the data.
+    unsortedVector = psVectorAlloc(nValues, PS_TYPE_F32);
+    unsortedVector->n = unsortedVector->nalloc;
+    sortedVector   = psVectorAlloc(nValues, PS_TYPE_F32);
+    sortedVector->n = sortedVector->nalloc;
+
+    // Determine if we must only use data points within a min/max range.
+    if (stats->options & PS_STAT_USE_RANGE) {
+        rangeMin = stats->min;
+        rangeMax = stats->max;
+        // Store all non-masked data points within the min/max range
+        // into the temporary vectors.
+        count = 0;
+        if (maskVector != NULL) {
+            for (i=0;i<myVector->n;i++) {
+                if (!(maskVal & maskVector->data.U8[i]) &&
+                        (rangeMin <= myVector->data.F32[i]) &&
+                        (myVector->data.F32[i] <= rangeMax)) {
+                    unsortedVector->data.F32[count++] = myVector->data.F32[i];
+                }
+            }
+        } else {
+            for (i=0;i<myVector->n;i++) {
+                if ((rangeMin <= myVector->data.F32[i]) &&
+                        (myVector->data.F32[i] <= rangeMax)) {
+                    unsortedVector->data.F32[count++] = myVector->data.F32[i];
+                }
+            }
+        }
+    } else {
+        // Store all non-masked data points into the temporary vectors.
+        count = 0;
+        if (maskVector != NULL) {
+            for (i=0;i<myVector->n;i++) {
+                if (!(maskVal & maskVector->data.U8[i])) {
+                    unsortedVector->data.F32[count++] = myVector->data.F32[i];
+                }
+            }
+        } else {
+            for (i=0;i<myVector->n;i++) {
+                unsortedVector->data.F32[i] = myVector->data.F32[i];
+            }
+        }
+    }
+
+    // Sort the temporary vectors.
+    psSort(sortedVector, unsortedVector);
+
+    // Calculate the quartile points exactly.
+    stats->sampleUQ = sortedVector->data.F32[3 * (nValues / 4)];
+    stats->sampleLQ = sortedVector->data.F32[nValues / 4];
+
+    // Free the temporary data structures.
+    psVectorFree(unsortedVector);
+    psVectorFree(sortedVector);
+    // NOTE: This is the
+}
+
+
+/******************************************************************************
+p_psVectorRobustStats(myVector, maskVector, maskVal, stats): this procedure
+calculates a variety of robust stat measures:
+        PS_STAT_ROBUST_MEAN
+        PS_STAT_ROBUST_MEDIAN
+        PS_STAT_ROBUST_MODE
+        PS_STAT_ROBUST_STDEV
+        PS_STAT_ROBUST_QUARTILE
+    I have included all that computation in a single function, as opposed to
+    breaking it across several functions for one primary reason: they all
+    require the same basic initial processing steps (calculate the histogram,
+    etc.) however there is no currently defined means, in the SDRS, to
+    specify this computation as a separate step.  If the above robust stat
+    measures were calcualted in separate functiosn, then much of the initial
+    processing would be duplicated.
+Inputs
+    myVector
+    maskVector
+    maskVal
+    stats
+Returns
+    NULL
+ *****************************************************************************/
+void p_psVectorRobustStats(const psVector *restrict myVector,
+                           const psVector *restrict maskVector,
+                           unsigned int maskVal,
+                           psStats *stats)
+{
+    psHistogram *robustHistogram = NULL;
+    float binSize = 0.0;                        // Size of the histogram bins
+    float sigmaE = 0.0;
+    int LQBinNum = -1;                          // Bin num for lower quartile
+    int UQBinNum = -1;                          // Bin num for upper quartile
+    int i = 0;                                  // Loop index variable
+    int maxBinNum = 0;
+    int maxBinCount = 0;
+    float dL = 0.0;
+    int numBins = 0;
+
+    // NOTE: The SDRS states that the sample quartiles must be used to
+    // determine the initial bin sizes.  However, the sample quartiles are
+    // calculated based on a full sort of the data set, regardless of the
+    // size of the data set.  We should consult with IfA to ensure that this
+    // is really required.
+
+    if (isnan(stats->sampleUQ) ||
+            isnan(stats->sampleLQ)) {
+        stats->options = stats->options | PS_STAT_SAMPLE_QUARTILE;
+        p_psVectorSampleQuartiles(myVector,
+                                  maskVector,
+                                  maskVal,
+                                  stats);
+    }
+
+    // Compute the initial bin size of the robust histogram.
+    sigmaE = (stats->sampleUQ - stats->sampleLQ) / 1.34f;
+    binSize = sigmaE / 10.0f;
+
+    // Detemine minimum and maximum values in the data vector.
+    if (isnan(stats->min)) {
+        p_psVectorMin(myVector, maskVector, maskVal, stats);
+    }
+    if (isnan(stats->max)) {
+        p_psVectorMax(myVector, maskVector, maskVal, stats);
+    }
+
+    // Create the histogram structure (yes, 2 is necessary, not 1).
+    numBins = 2 + (int) ((stats->max - stats->min) / binSize);
+
+    robustHistogram = psHistogramAlloc(stats->min,
+                                       stats->max,
+                                       numBins);
+    // Populate the histogram array.
+    psHistogramVector(robustHistogram, myVector, maskVector, maskVal);
+
+    // Smooth the histogram.
+    p_psVectorsmoothHistGaussian(robustHistogram, sigmaE/4.0f);
+
+    LQBinNum = -1;
+    UQBinNum = -1;
+    for (i=0;i<robustHistogram->nums->n;i++) {
+        if ((robustHistogram->nums->data.S32[i] <= stats->sampleLQ) &&
+                (stats->sampleLQ <= robustHistogram->nums->data.S32[i])) {
+            LQBinNum = i;
+        }
+
+        if ((robustHistogram->nums->data.S32[i] <= stats->sampleUQ) &&
+                (stats->sampleUQ <= robustHistogram->nums->data.S32[i])) {
+            UQBinNum = i;
+        }
+    }
+
+    // Determine the bin with the peak value in the range LQ to UQ.
+    maxBinNum = LQBinNum;
+    maxBinCount = robustHistogram->nums->data.S32[maxBinNum];
+    for (i=LQBinNum;i<=UQBinNum;i++) {
+        if (robustHistogram->nums->data.S32[i] > maxBinCount) {
+            maxBinNum = i;
+            maxBinCount = robustHistogram->nums->data.S32[i];
+        }
+    }
+
+    dL = (stats->robustUQ - stats->robustLQ) / 8.0;
+
+    // Fit a Gaussian to the bins in the range MODE-dL to Mode+dL
+    // NOTE: This step is dependent on the functions in psMinimize.c being
+    // implemented.  Currently, they are not.
+
+    if (stats->options & PS_STAT_ROBUST_MEAN) {
+        stats->robustMean = 0.0;
+    }
+
+    if  (stats->options & PS_STAT_ROBUST_MEDIAN) {
+        stats->robustMedian = 0.0;
+    }
+    if  (stats->options & PS_STAT_ROBUST_MODE) {
+        stats->robustMode = maxBinNum;
+    }
+    if  (stats->options & PS_STAT_ROBUST_STDEV) {
+        stats->robustStdev = 0.0;
+    }
+    if  (stats->options & PS_STAT_ROBUST_QUARTILE) {
+        stats->robustUQ = 0.0;
+        stats->robustLQ = 0.0;
+    }
+    stats->robustNfit = 0.0;
+    stats->robustN50 = 0.0;
+    psHistogramFree(robustHistogram);
+}
+
+/******************************************************************************
+p_psVectorSampleStdev(myVector, maskVector, maskVal, stats): calculates the
+stdev of the input vector.
+Inputs
+    myVector
+    maskVector
+    maskVal
+    stats
+Returns
+    NULL
+ 
+NOTE: the mean is always calculated exactly.  Robust means are never
+calculated in this routine.
+ *****************************************************************************/
+void p_psVectorSampleStdev(const psVector *restrict myVector,
+                           const psVector *restrict maskVector,
+                           unsigned int maskVal,
+                           psStats *stats)
+{
+    int i = 0;                                  // Loop index variable
+    int countInt = 0;                           // # of data points being used
+    float countFloat = 0.0;                     // # of data points being used
+    float mean = 0.0;                           // The mean
+    float diff = 0.0;                           // Used in calculating stdev
+    float sumSquares = 0.0;                     // temporary variable
+    float sumDiffs = 0.0;                       // temporary variable
+    float rangeMin = 0.0;                       // Exclude data below this
+    float rangeMax = 0.0;                       // Exclude date above this
+
+    // This procedure requires the mean.  If it has not been already
+    // calculated, then call p_psVectorSampleMean()
+    if (0 != isnan(stats->sampleMean)) {
+        p_psVectorSampleMean(myVector, maskVector, maskVal, stats);
+    }
+    mean = stats->sampleMean;
+
+    if (stats->options & PS_STAT_USE_RANGE) {
+        if (maskVector != NULL) {
+            for (i=0;i<myVector->n;i++) {
+                if (!(maskVal & maskVector->data.U8[i]) &&
+                        (rangeMin <= myVector->data.F32[i]) &&
+                        (myVector->data.F32[i] <= rangeMax)) {
+                    diff = myVector->data.F32[i] - mean;
+                    sumSquares+= (diff * diff);
+                    sumDiffs+= diff;
+                    countInt++;
+                }
+            }
+        } else {
+            for (i=0;i<myVector->n;i++) {
+                if ((rangeMin <= myVector->data.F32[i]) &&
+                        (myVector->data.F32[i] <= rangeMax)) {
+                    diff = myVector->data.F32[i] - mean;
+                    sumSquares+= (diff * diff);
+                    sumDiffs+= diff;
+                    countInt++;
+                }
+            }
+            countInt = myVector->n;
+        }
+    } else {
+        if (maskVector != NULL) {
+            for (i=0;i<myVector->n;i++) {
+                if (!(maskVal & maskVector->data.U8[i])) {
+                    diff = myVector->data.F32[i] - mean;
+                    sumSquares+= (diff * diff);
+                    sumDiffs+= diff;
+                    countInt++;
+                }
+            }
+        } else {
+            for (i=0;i<myVector->n;i++) {
+                diff = myVector->data.F32[i] - mean;
+                sumSquares+= (diff * diff);
+                sumDiffs+= diff;
+                countInt++;
+            }
+            countInt = myVector->n;
+        }
+    }
+    countFloat = (float) countInt;
+
+    #ifdef DARWIN
+
+    stats->sampleStdev = (float) sqrt( (sumSquares-(sumDiffs *
+                                        sumDiffs/countFloat))/ (countFloat-1));
+    #else
+
+    stats->sampleStdev = sqrtf( (sumSquares-(sumDiffs *
+                                 sumDiffs/countFloat))/ (countFloat-1));
+    #endif
+}
+
+/******************************************************************************
+p_psVectorClippedStats(myVector, maskVector, maskVal, stats): calculates the
+clipped stats (mean or stdev) of the input vector.
+ 
+Inputs
+    myVector
+    maskVector
+    maskVal
+    stats
+Returns
+    NULL
+ *****************************************************************************/
+void p_psVectorClippedStats(const psVector *restrict myVector,
+                            const psVector *restrict maskVector,
+                            unsigned int maskVal,
+                            psStats *stats)
+{
+    int i = 0;                                  // Loop index variable
+    int j = 0;                                  // Loop index variable
+    float clippedMean = 0.0;                    // self-explanatory
+    float clippedStdev = 0.0;                   // self-explanatory
+    float oldStanMean = 0.0;                    // Temporary variable
+    float oldStanStdev = 0.0;                   // Temporary variable
+    psVector *tmpMask = NULL;                   // Temporary vector
+
+    // Endure that stats->clipIter is within the proper range.
+    if (!((CLIPPED_NUM_ITER_LB <= stats->clipIter ) &&
+            (stats->clipIter <= CLIPPED_NUM_ITER_UB))) {
+        psAbort(__func__, "Unallowed value for clipIter (%d).\n",
+                stats->clipIter);
+    }
+
+    // Endure that stats->clipSigma is within the proper range.
+    if (!((CLIPPED_SIGMA_LB <= stats->clipSigma ) &&
+            (stats->clipSigma <= CLIPPED_SIGMA_UB))) {
+        psAbort(__func__, "Unallowed value for clipSigma (%f).\n",
+                stats->clipSigma);
+    }
+
+    // We allocate a temporary mask vector since during the iterative
+    // steps that follow, we will be masking off additional data points.
+    // However, we do no want to modify the original mask vector.
+    tmpMask = psVectorAlloc(myVector->n, PS_TYPE_U8);
+    tmpMask->n = myVector->n;
+
+    // If we were called with a mask vector, then initialize the temporary
+    // mask vector with those values.
+    if (maskVector != NULL) {
+        for (i=0;i<tmpMask->n;i++) {
+            tmpMask->data.U8[i] = maskVector->data.U8[i];
+        }
+    }
+
+    // 1. Compute the sample median.
+    // NOTE: This seems odd.  Verify with IfA that we want to calculate the
+    // median here, not the mean.
+    p_psVectorSampleMedian(myVector, maskVector, maskVal, stats);
+
+    // 2. Compute the sample standard deviation.
+    p_psVectorSampleStdev(myVector, maskVector, maskVal, stats);
+
+    // 3. Use the sample median as the first estimator of the mean X.
+    clippedMean = stats->sampleMean;
+
+    // 4. Use the sample stdev as the first estimator of the mean stdev.
+    clippedStdev = stats->sampleStdev;
+
+    // Must save the old sampleMean and sampleStdev since the following code
+    // block overwrites them.
+    oldStanMean = stats->sampleMean;
+    oldStanStdev = stats->sampleStdev;
+
+    // 5. Repeat N times:
+    for (i=0;i<stats->clipIter;i++) {
+        for (j=0;j<myVector->n;j++) {
+            // a) Exclude all values x_i for which |x_i - x| > K * stdev
+            if (fabs(myVector->data.F32[j] - clippedMean) >
+                    (stats->clipSigma * clippedStdev)) {
+                tmpMask->data.U8[i] = 0xff;
+            }
+            // b) compute new mean and stdev
+            p_psVectorSampleMedian(myVector, tmpMask, maskVal, stats);
+            p_psVectorSampleStdev(myVector, tmpMask, maskVal, stats);
+
+            // c) Use the new mean for x
+            clippedMean = stats->sampleMean;
+
+            // d) Use the new stdev for stdev
+            clippedStdev = stats->sampleStdev;
+        }
+    }
+    stats->sampleMean = oldStanMean;
+    stats->sampleStdev= oldStanStdev;
+
+    // 7. The last calcuated value of x is the cliped mean.
+    if (stats->options & PS_STAT_CLIPPED_MEAN) {
+        stats->clippedMean = clippedMean;
+    }
+
+    // 8. The last calcuated value of stdev is the cliped stdev.
+    if (stats->options & PS_STAT_CLIPPED_STDEV) {
+        stats->clippedStdev = clippedStdev;
+    }
+
+    psVectorFree(tmpMask);
+}
+
+
+/******************************************************************************
+psVectorStats(myVector, maskVector, maskVal, stats): this is the public API
+function which calls the above private stats functions based on what bits
+were set in stats->options.
+ 
+Inputs
+    myVector
+    maskVector
+    maskVal
+    stats
+Returns
+    The stats structure.
+ 
+NOTE: The current strategy is to implement everything assuming that all
+input data is of type PS_TYPE_F32.  Once the basic code is in place, we will
+macro-ize everything and add PS_TYPE_U16 and PS_TYPE_F64.
+ *****************************************************************************/
+psStats *psVectorStats(psStats *stats,
+                       psVector *in,
+                       psVector *mask,
+                       unsigned int maskVal)
+{
+    // NOTE: Verify that this is the correct action.
+    if (in == NULL) {
+        return(stats);
+    }
+    if (stats == NULL) {
+        return(NULL);
+    }
+
+    // Ensure that the data is of type PS_TYPE_F32.  Eventually, more data
+    // types will be implemented.
+    if (in->type.type != PS_TYPE_F32) {
+        psAbort(__func__,
+                "Only data type PS_TYPE_F32 is currently supported (0x%x).",
+                in->type.type);
+    }
+
+    // Ensure that the mask vector is of the proper size and type.
+    if (mask != NULL) {
+        if (in->n != mask->n) {
+            psAbort(__func__,
+                    "Vector data and vector mask are of different sizes.");
+        }
+        if (mask->type.type != PS_TYPE_U8) {
+            psAbort(__func__,
+                    "Vector mask must be type PS_TYPE_U8");
+        }
+    }
+
+    // ************************************************************************
+    if (stats->options & PS_STAT_SAMPLE_MEAN) {
+        p_psVectorSampleMean(in, mask, maskVal, stats);
+    }
+
+    // ************************************************************************
+    if (stats->options & PS_STAT_SAMPLE_MEDIAN) {
+        p_psVectorSampleMedian(in, mask, maskVal, stats);
+    }
+
+    // ************************************************************************
+    // NOTE: The Stdev calculation requires the mean.  Should we assume the
+    // mean has already been calculated?  Or should we always calculate it?
+    if (stats->options & PS_STAT_SAMPLE_STDEV) {
+        p_psVectorSampleMean(in, mask, maskVal, stats);
+        p_psVectorSampleStdev(in, mask, maskVal, stats);
+    }
+
+    // ************************************************************************
+    if (stats->options & PS_STAT_SAMPLE_QUARTILE) {
+        p_psVectorSampleQuartiles(in, mask, maskVal, stats);
+    }
+
+    // Since the various robust stats quantities share much computation, they
+    // are grouped together in a single private function:
+    // p_psVectorRobustStats()
+    if ((stats->options & PS_STAT_ROBUST_MEAN) ||
+            (stats->options & PS_STAT_ROBUST_MEDIAN) ||
+            (stats->options & PS_STAT_ROBUST_MODE) ||
+            (stats->options & PS_STAT_ROBUST_STDEV) ||
+            (stats->options & PS_STAT_ROBUST_QUARTILE)) {
+        p_psVectorRobustStats(in, mask, maskVal, stats);
+    }
+
+    if ((stats->options & PS_STAT_CLIPPED_MEAN) ||
+            (stats->options & PS_STAT_CLIPPED_STDEV)) {
+        p_psVectorClippedStats(in, mask, maskVal, stats);
+    }
+
+    // ************************************************************************
+    if (stats->options & PS_STAT_MAX) {
+        p_psVectorMax(in, mask, maskVal, stats);
+    }
+
+    // ************************************************************************
+    if (stats->options & PS_STAT_MIN) {
+        p_psVectorMin(in, mask, maskVal, stats);
+    }
+
+    return(stats);
+}
Index: /tags/rel1_1/psLib/src/dataManip/psStats.d
===================================================================
--- /tags/rel1_1/psLib/src/dataManip/psStats.d	(revision 1056)
+++ /tags/rel1_1/psLib/src/dataManip/psStats.d	(revision 1056)
@@ -0,0 +1,3 @@
+psStats.o psStats.d : psStats.c ../sysUtils/psMemory.h ../collections/psVector.h \
+  ../collections/psType.h ../sysUtils/psTrace.h ../sysUtils/psError.h \
+  ../sysUtils/psAbort.h psStats.h ../collections/psSort.h
Index: /tags/rel1_1/psLib/src/dataManip/psStats.h
===================================================================
--- /tags/rel1_1/psLib/src/dataManip/psStats.h	(revision 1056)
+++ /tags/rel1_1/psLib/src/dataManip/psStats.h	(revision 1056)
@@ -0,0 +1,133 @@
+/** @file  psStats.h
+ *  \brief basic statistical operations
+ *  @ingroup Stats
+ *
+ *  This file will hold the definition of the histogram and stats data
+ *  structures.  It also contains prototypes for procedures which operate
+ *  on those data structures.
+ *
+ *  @author George Gusciora, MHPCC
+ *
+ *  @version $Revision: 1.12 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-14 19:33:09 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+#if !defined(PS_STATS_H)
+#define PS_STATS_H
+
+#include "psVector.h"
+
+/// @addtogroup Stats
+/// @{
+
+/******************************************************************************
+    Statistical functions and data structures.
+ *****************************************************************************/
+typedef enum {
+    PS_STAT_SAMPLE_MEAN           = 0x000001,
+    PS_STAT_SAMPLE_MEDIAN         = 0x000002,
+    PS_STAT_SAMPLE_STDEV          = 0x000004,
+    PS_STAT_SAMPLE_QUARTILE       = 0x000008,
+    PS_STAT_ROBUST_MEAN           = 0x000010,
+    PS_STAT_ROBUST_MEDIAN         = 0x000020,
+    PS_STAT_ROBUST_MODE           = 0x000040,
+    PS_STAT_ROBUST_STDEV          = 0x000080,
+    PS_STAT_ROBUST_QUARTILE       = 0x000100,
+    PS_STAT_CLIPPED_MEAN          = 0x000200,
+    PS_STAT_CLIPPED_STDEV         = 0x000400,
+    PS_STAT_MAX                   = 0x000800,
+    PS_STAT_MIN                   = 0x001000,
+    PS_STAT_USE_RANGE             = 0x002000,
+    PS_STAT_USE_BINSIZE           = 0x004000,
+    PS_STAT_ROBUST_FOR_SAMPLE     = 0x008000
+} psStatsOptions;
+
+
+/** This is the generic statistics structure.  It contails the data members
+    for the various statistic values.  It contains the options member to
+    specifiy which statistics must be calculated. */
+typedef struct
+{
+    double sampleMean;          ///< formal mean of sample
+    double sampleMedian;        ///< formal median of sample
+    double sampleStdev;         ///< standard deviation of sample
+    double sampleUQ;            ///< upper quartile of sample
+    double sampleLQ;            ///< lower quartile of sample
+    double sampleLimit;         ///<
+    double robustMean;          ///< robust mean of array
+    int    robustMeanNvalues;   ///< number of measurements used for robust mean
+    double robustMedian;        ///< robust median of array
+    double robustMode;          ///< Robust mode of array
+    double robustStdev;         ///< robust standard deviation of array
+    double robustUQ;            ///< robust upper quartile
+    double robustLQ;            ///< robust lower quartile
+    double robustN50;           ///<
+    double robustNfit;          ///<
+    double clippedMean;         ///< Nsigma clipped mean
+    double clippedStdev;        ///< standard deviation after clipping
+    double clipSigma;           ///< Nsigma used for clipping; user input
+    int    clipIter;            ///< Number of clipping iterations; user input
+    double min;                 ///< minimum data value in array
+    double max;                 ///< maximum data value in array
+    double binsize;             ///<
+    psStatsOptions options;     ///< bitmask of calculated values
+}
+psStats;
+
+
+/** Do Statistics on an array.  Returns a status value. \ingroup MathGroup */
+psStats *
+psVectorStats(psStats *stats,       ///< stats structure defines stats to be calculated and how
+              psVector *in,         ///< Vector to be analysed: must be F32
+              psVector *mask,       ///< Ignore elements where (maskVector & maskVal) != 0: must be INT or NULL
+              unsigned int maskVal ///< Only mask elements with one of these bits set in maskVector
+             );
+
+/** A constructor for the stats structure.*/
+psStats *psStatsAlloc(psStatsOptions options); ///< Statistics to measure
+
+/** A destructor for the stats structure.*/
+void psStatsFree(psStats *restrict stats); ///< Stats structure to destroy
+
+/******************************************************************************
+    Histogram functions and data structures.
+ *****************************************************************************/
+/** The basic histogram structure which contains bounds and bins. */
+typedef struct
+{
+    psVector *bounds;                ///< Bounds for the bins (type F32)
+    psVector *nums;                  ///< Number in each of the bins (INT)
+    int minNum;                      ///< Number below the minimum
+    int maxNum;                      ///< Number above the maximum
+    int uniform;                     ///< Is it a uniform distribution?
+}
+psHistogram;
+
+
+/** Constructor \ingroup MathGroup */
+psHistogram *
+psHistogramAlloc(float lower,  ///< Lower limit for the bins
+                 float upper,  ///< Upper limit for the bins
+                 int n);       ///< Number of bins
+
+
+/** Generic constructor \ingroup MathGroup */
+psHistogram * psHistogramAllocGeneric(const psVector *restrict bounds); ///< Bounds for the bins
+
+
+/** Destructor \ingroup MathGroup **/
+void psHistogramFree(psHistogram *myHist);          ///< Histogram to destroy
+
+
+/** Calculate a histogram \ingroup MathGroup **/
+psHistogram *psHistogramVector (psHistogram *out,   ///< Histogram data
+                                const psVector *restrict in,       ///< Vector to analyse
+                                const psVector *restrict mask,     ///< Mask dat for input vector
+                                int maskVal);       ///< Mask value
+
+
+/// @}
+
+#endif
+
Index: /tags/rel1_1/psLib/src/dataManip/psVectorFFT.c
===================================================================
--- /tags/rel1_1/psLib/src/dataManip/psVectorFFT.c	(revision 1056)
+++ /tags/rel1_1/psLib/src/dataManip/psVectorFFT.c	(revision 1056)
@@ -0,0 +1,755 @@
+/** @file  psFFT.c
+ *
+ *  @brief Contains FFT transforms functions
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.10 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-12 02:17:25 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include <unistd.h>
+#include <stdbool.h>
+#include <string.h>
+#include <complex.h>
+#include <fftw3.h>
+
+#include "psFFT.h"
+#include "psError.h"
+#include "psMemory.h"
+#include "psLogMsg.h"
+
+#define P_FFTW_PLAN_RIGOR FFTW_ESTIMATE
+
+static bool p_fftwWisdomImported = false;
+
+psImage* psImageFFT(psImage* out, const psImage* in, psFftDirection direction)
+{
+    unsigned int numCols;
+    unsigned int numRows;
+    psElemType type;
+    fftwf_plan plan;
+
+    /* got good image data? */
+    if (in==NULL) {
+        psImageFree(out);
+        return NULL;
+    }
+
+    type = in->type.type;
+
+    if ( (type != PS_TYPE_F32) && (type != PS_TYPE_C32) ) {
+        psError(__func__,"Input image must be a 32-bit float or complex image (type=%d)",
+                type);
+        psImageFree(out);
+        return NULL;
+    }
+
+    if ( type != PS_TYPE_C32 && direction == PS_FFT_REVERSE ) {
+        psError(__func__,"Input image must be complex image for reverse FFT (type=%d).",
+                type);
+        psImageFree(out);
+        return NULL;
+
+    }
+
+    /* make sure the system-level wisdom information is imported. */
+    if (! p_fftwWisdomImported) {
+        fftwf_import_system_wisdom();
+        p_fftwWisdomImported = true;
+    }
+
+    numRows = in->numRows;
+    numCols = in->numCols;
+
+    out = psImageCopy(out,in, PS_TYPE_C32);
+
+    plan = fftwf_plan_dft_2d(numCols, numRows,
+                             (fftwf_complex*)out->data.C32[0],
+                             (fftwf_complex*)out->data.C32[0],
+                             direction,
+                             P_FFTW_PLAN_RIGOR);
+
+    /* check if a plan exists now*/
+    if (plan == NULL) {
+        psError(__func__,"Failed to create FFTW plan.");
+        psImageFree(out);
+        return NULL;
+    }
+
+    /* finally, call FFTW with the plan made above */
+    fftwf_execute(plan);
+
+    fftwf_destroy_plan(plan);
+
+    return out;
+
+}
+
+
+psImage *psImageReal(psImage *out, const psImage* in)
+{
+    psElemType type;
+    unsigned int numCols;
+    unsigned int numRows;
+
+
+    if (in == NULL) {
+        psImageFree(out);
+        return NULL;
+    }
+
+    type = in->type.type;
+    numCols = in->numCols;
+    numRows = in->numRows;
+
+    /* if not a complex number, this is logically just a copy */
+    if (! PS_IS_PSELEMTYPE_COMPLEX(type)) {
+        // Warn user, as this is probably not expected
+        psLogMsg(__func__,PS_LOG_WARN,"Real portion of a non-Complex type called called for. "
+                 "Just an image copy was performed.");
+        return psImageCopy(out,in,type);
+    }
+
+    if (type == PS_TYPE_C32) {
+        psF32* outRow;
+        psC32* inRow;
+
+        out = psImageRecycle(out,numCols,numRows,PS_TYPE_F32);
+        for (unsigned int row=0;row<numRows;row++) {
+            outRow = out->data.F32[row];
+            inRow = in->data.C32[row];
+
+            for (unsigned int col=0;col<numCols;col++) {
+                outRow[col] = crealf(inRow[col]);
+            }
+        }
+    } else if (type == PS_TYPE_C64) {
+        psF64* outRow;
+        psC64* inRow;
+
+        out = psImageRecycle(out,numCols,numRows,PS_TYPE_F64);
+        for (unsigned int row=0;row<numRows;row++) {
+            outRow = out->data.F64[row];
+            inRow = in->data.C64[row];
+
+            for (unsigned int col=0;col<numCols;col++) {
+                outRow[col] = creal(inRow[col]);
+            }
+        }
+    } else {
+        psError(__func__,"Can not extract real component from given image type (%d).",
+                type);
+        psImageFree(out);
+        return NULL;
+    }
+
+    return out;
+}
+
+psImage *psImageImaginary(psImage *out, const psImage* in)
+{
+    psElemType type;
+    unsigned int numCols;
+    unsigned int numRows;
+
+
+    if (in == NULL) {
+        psImageFree(out);
+        return NULL;
+    }
+
+    type = in->type.type;
+    numCols = in->numCols;
+    numRows = in->numRows;
+
+    /* if not a complex number, this is logically just zeroed image of same size */
+    if (! PS_IS_PSELEMTYPE_COMPLEX(type)) {
+        // Warn user, as this is probably not expected
+        psLogMsg(__func__,PS_LOG_WARN,"Imaginary portion of a non-Complex type called for. "
+                 "A zero image was returned.");
+        out = psImageRecycle(out,numCols,numRows,type);
+        memset(out->data.V[0],0,PSELEMTYPE_SIZEOF(type)*numCols*numRows);
+        return out;
+    }
+
+    if (type == PS_TYPE_C32) {
+        psF32* outRow;
+        psC32* inRow;
+
+        out = psImageRecycle(out,numCols,numRows,PS_TYPE_F32);
+        for (unsigned int row=0;row<numRows;row++) {
+            outRow = out->data.F32[row];
+            inRow = in->data.C32[row];
+
+            for (unsigned int col=0;col<numCols;col++) {
+                outRow[col] = cimagf(inRow[col]);
+            }
+        }
+    } else if (type == PS_TYPE_C64) {
+        psF64* outRow;
+        psC64* inRow;
+
+        out = psImageRecycle(out,numCols,numRows,PS_TYPE_F64);
+        for (unsigned int row=0;row<numRows;row++) {
+            outRow = out->data.F64[row];
+            inRow = in->data.C64[row];
+
+            for (unsigned int col=0;col<numCols;col++) {
+                outRow[col] = cimag(inRow[col]);
+            }
+        }
+    } else {
+        psError(__func__,"Can not extract imaginary component from given image type (%d).",
+                type);
+        psImageFree(out);
+        return NULL;
+    }
+
+    return out;
+}
+
+psImage *psImageComplex(psImage* out, psImage *real, const psImage *imag)
+{
+    psElemType type;
+    unsigned int numCols;
+    unsigned int numRows;
+
+
+    if (real == NULL || imag == NULL) {
+        psImageFree(out);
+        return NULL;
+    }
+
+    type = real->type.type;
+    numCols = real->numCols;
+    numRows = real->numRows;
+
+    if (imag->type.type != type) {
+        psError(__func__,"The inputs to psImageComplex must be the same type.");
+        psImageFree(out);
+        return NULL;
+    }
+
+    if (imag->numCols != numCols ||
+            imag->numRows != numRows) {
+        psError(__func__,"The inputs to psImageComplex must be the same dimensions.");
+        psImageFree(out);
+        return NULL;
+    }
+
+    if (PS_IS_PSELEMTYPE_COMPLEX(type)) {
+        psError(__func__,"The inputs to psImageComplex can not be complex.");
+        psImageFree(out);
+        return NULL;
+    }
+
+    if (type != PS_TYPE_F32 && type != PS_TYPE_F64) {
+        psError(__func__,"The input type to psImageComplex must be a floating point.");
+        psImageFree(out);
+        return NULL;
+    }
+
+    if (type == PS_TYPE_F32) {
+        psC32* outRow;
+        psF32* realRow;
+        psF32* imagRow;
+
+        out = psImageRecycle(out,numCols,numRows,PS_TYPE_C32);
+
+        for (unsigned int row=0;row<numRows;row++) {
+            outRow = out->data.C32[row];
+            realRow = real->data.F32[row];
+            imagRow = imag->data.F32[row];
+
+            for (unsigned int col=0;col<numCols;col++) {
+                outRow[col] = realRow[col] + I*imagRow[col];
+            }
+        }
+    } else if (type == PS_TYPE_F64) {
+        psC64* outRow;
+        psF64* realRow;
+        psF64* imagRow;
+
+        out = psImageRecycle(out, numCols,numRows,PS_TYPE_C64);
+        for (unsigned int row=0;row<numRows;row++) {
+            outRow = out->data.C64[row];
+            realRow = real->data.F64[row];
+            imagRow = imag->data.F64[row];
+
+            for (unsigned int col=0;col<numCols;col++) {
+                outRow[col] = realRow[col] + I*imagRow[col];
+            }
+        }
+    } else {
+        psError(__func__,"Can not merge real and imaginary portions for given image type (%d).",
+                type);
+        psImageFree(out);
+        return NULL;
+    }
+
+    return out;
+}
+
+psImage *psImageConjugate(psImage *out, const psImage *in)
+{
+    psElemType type;
+    unsigned int numCols;
+    unsigned int numRows;
+
+
+    if (in == NULL) {
+        psImageFree(out);
+        return NULL;
+    }
+
+    type = in->type.type;
+    numCols = in->numCols;
+    numRows = in->numRows;
+
+    /* if not a complex number, this is logically just a image copy */
+    if (! PS_IS_PSELEMTYPE_COMPLEX(type)) {
+        // Warn user, as this is probably not expected
+        psLogMsg(__func__,PS_LOG_WARN,"Complex Conjugate of a non-Complex type called for. "
+                 "Image copy was performed instead.");
+        return psImageCopy(out,in,type);
+    }
+
+    if (type == PS_TYPE_C32) {
+        psC32* outRow;
+        psC32* inRow;
+
+        out = psImageRecycle(out,numCols,numRows,PS_TYPE_C32);
+        for (unsigned int row=0;row<numRows;row++) {
+            outRow = out->data.C32[row];
+            inRow = in->data.C32[row];
+
+            for (unsigned int col=0;col<numCols;col++) {
+                outRow[col] = crealf(inRow[col]) - I*cimagf(inRow[col]);
+            }
+        }
+    } else if (type == PS_TYPE_C64) {
+        psC64* outRow;
+        psC64* inRow;
+
+        out = psImageRecycle(out,numCols,numRows,PS_TYPE_C64);
+        for (unsigned int row=0;row<numRows;row++) {
+            outRow = out->data.C64[row];
+            inRow = in->data.C64[row];
+
+            for (unsigned int col=0;col<numCols;col++) {
+                outRow[col] = creal(inRow[col]) - I*cimag(inRow[col]);
+            }
+        }
+    } else {
+        psError(__func__,"Can not compute complex conjugate for given image type (%d).",
+                type);
+        psImageFree(out);
+        return NULL;
+    }
+
+    return out;
+}
+
+psImage *psImagePowerSpectrum(psImage* out, const psImage* in)
+{
+    psElemType type;
+    unsigned int numCols;
+    unsigned int numRows;
+    int numElementsSquared;
+
+    if (in == NULL) {
+        psImageFree(out);
+        return NULL;
+    }
+
+    type = in->type.type;
+    numCols = in->numCols;
+    numRows = in->numRows;
+    numElementsSquared = numCols*numCols*numRows*numRows;
+
+    /* if not a complex number, this is not implemented */
+    if (! PS_IS_PSELEMTYPE_COMPLEX(type)) {
+        psError(__func__,"Power Spectrum for non-complex inputs is not implemented.");
+        psImageFree(out);
+        return NULL;
+    }
+
+    if (type == PS_TYPE_C32) {
+        psF32* outRow;
+        psC32* inRow;
+        psF32 real;
+        psF32 imag;
+
+
+        out = psImageRecycle(out,numCols,numRows,PS_TYPE_F32);
+        for (unsigned int row=0;row<numRows;row++) {
+            outRow = out->data.F32[row];
+            inRow = in->data.C32[row];
+
+            for (unsigned int col=0;col<numCols;col++) {
+                real = crealf(inRow[col]);
+                imag = cimagf(inRow[col]);
+                outRow[col] = (real*real+imag*imag)/numElementsSquared;
+            }
+        }
+    } else if (type == PS_TYPE_C64) {
+        psF64* outRow;
+        psC64* inRow;
+        psF64 real;
+        psF64 imag;
+
+
+        out = psImageRecycle(out,numCols,numRows,PS_TYPE_F64);
+        for (unsigned int row=0;row<numRows;row++) {
+            outRow = out->data.F64[row];
+            inRow = in->data.C64[row];
+
+            for (unsigned int col=0;col<numCols;col++) {
+                real = crealf(inRow[col]);
+                imag = cimagf(inRow[col]);
+                outRow[col] = real*real+imag*imag/numElementsSquared;
+            }
+        }
+    } else {
+        psError(__func__,"Can not power spectrum for given image type (%d).",
+                type);
+        psImageFree(out);
+        return NULL;
+    }
+
+    return out;
+
+}
+
+/************************************** Vector Functions ***************************************/
+
+psVector* psVectorFFT(psVector* out, const psVector* in, psFftDirection direction)
+{
+    unsigned int numElements;
+    psElemType type;
+    fftwf_plan plan;
+
+    /* got good image data? */
+    if (in==NULL) {
+        psVectorFree(out);
+        return NULL;
+    }
+
+    type = in->type.type;
+
+    if ( (type != PS_TYPE_F32) && (type != PS_TYPE_C32) ) {
+        psError(__func__,"Input image must be a 32-bit float or complex image (type=%d)",
+                type);
+        psVectorFree(out);
+        return NULL;
+    }
+
+    if ( (type != PS_TYPE_C32) && (direction == PS_FFT_REVERSE) ) {
+        psError(__func__,"Input image must be complex image for reverse FFT (type=%d).",
+                type);
+        psVectorFree(out);
+        return NULL;
+
+    }
+
+    /* make sure the system-level wisdom information is imported. */
+    if (! p_fftwWisdomImported) {
+        fftwf_import_system_wisdom();
+        p_fftwWisdomImported = true;
+    }
+
+    numElements = in->n;
+
+    out = psVectorRecycle(out, PS_TYPE_C32, numElements);
+    out->n = numElements;
+
+    if (type == PS_TYPE_F32) {
+        // need to convert to complex
+        psC32* outVec = out->data.C32;
+        psF32* inVec = in->data.F32;
+        for (unsigned int i=0;i<numElements;i++) {
+            outVec[i] = inVec[i];
+        }
+    } else {
+        psC32* outVec = out->data.C32;
+        psC32* inVec = in->data.C32;
+        for (unsigned int i=0;i<numElements;i++) {
+            outVec[i] = inVec[i];
+        }
+    }
+
+    plan = fftwf_plan_dft_1d(numElements,
+                             (fftwf_complex*)out->data.C32,
+                             (fftwf_complex*)out->data.C32,
+                             direction,
+                             P_FFTW_PLAN_RIGOR);
+
+    /* check if a plan exists now*/
+    if (plan == NULL) {
+        psError(__func__,"Failed to create FFTW plan.");
+        psVectorFree(out);
+        return NULL;
+    }
+
+    /* finally, call FFTW with the plan made above */
+    fftwf_execute(plan);
+
+    fftwf_destroy_plan(plan);
+
+    return out;
+}
+
+
+psVector *psVectorReal(psVector *out, const psVector* in)
+{
+    psElemType type;
+    unsigned int numElements;
+
+    if (in == NULL) {
+        psVectorFree(out);
+        return NULL;
+    }
+
+    type = in->type.type;
+    numElements = in->n;
+
+    /* if not a complex number, this is logically just a copy */
+    if (! PS_IS_PSELEMTYPE_COMPLEX(type)) {
+        // Warn user, as this is probably not expected
+        psLogMsg(__func__,PS_LOG_WARN,"Real portion of a non-Complex type called called for. "
+                 "Just a vector copy was performed.");
+        out = psVectorRecycle(out,type,numElements);
+        out->n = numElements;
+        memcpy(out->data.V,in->data.V,numElements*PSELEMTYPE_SIZEOF(type));
+        return out;
+    }
+
+    if (type == PS_TYPE_C32) {
+        psF32* outVec;
+        psC32* inVec = in->data.C32;
+
+        out = psVectorRecycle(out,PS_TYPE_F32,numElements);
+        out->n = numElements;
+        outVec = out->data.F32;
+
+        for (unsigned int i=0;i<numElements;i++) {
+            outVec[i] = crealf(inVec[i]);
+        }
+    } else {
+        psError(__func__,"Can not extract real component from given vector type (%d).",
+                type);
+        psVectorFree(out);
+        return NULL;
+    }
+
+    return out;
+}
+
+psVector *psVectorImaginary(psVector *out, const psVector* in)
+{
+    psElemType type;
+    unsigned int numElements;
+
+
+    if (in == NULL) {
+        psVectorFree(out);
+        return NULL;
+    }
+
+    type = in->type.type;
+    numElements = in->n;
+
+    /* if not a complex number, this is logically just zeroed image of same size */
+    if (! PS_IS_PSELEMTYPE_COMPLEX(type)) {
+        // Warn user, as this is probably not expected
+        psLogMsg(__func__,PS_LOG_WARN,"Imaginary portion of a non-Complex type called for. "
+                 "A zeroed vector was returned.");
+        out = psVectorRecycle(out,type,numElements);
+        out->n = numElements;
+        memset(out->data.V,0,PSELEMTYPE_SIZEOF(type)*numElements);
+        return out;
+    }
+
+    if (type == PS_TYPE_C32) {
+        psF32* outVec;
+        psC32* inVec = in->data.C32;
+
+        out = psVectorRecycle(out,PS_TYPE_F32,numElements);
+        out->n = numElements;
+        outVec = out->data.F32;
+
+        for (unsigned int i=0;i<numElements;i++) {
+            outVec[i] = cimagf(inVec[i]);
+        }
+    } else {
+        psError(__func__,"Can not extract imaginary component from given vector type (%d).",
+                type);
+        psVectorFree(out);
+        return NULL;
+    }
+
+    return out;
+}
+
+psVector *psVectorComplex(psVector* out, psVector *real, const psVector *imag)
+{
+    psElemType type;
+    unsigned int numElements;
+
+
+    if (real == NULL || imag == NULL) {
+        psVectorFree(out);
+        return NULL;
+    }
+
+    type = real->type.type;
+    if (real->n >= imag->n) {
+        numElements = real->n;
+    } else {
+        numElements = imag->n;
+    }
+
+    if (imag->type.type != type) {
+        psError(__func__,"The inputs to psVectorComplex must be the same type.");
+        psVectorFree(out);
+        return NULL;
+    }
+
+    if (PS_IS_PSELEMTYPE_COMPLEX(type)) {
+        psError(__func__,"The inputs to psVectorComplex can not be complex.");
+        psVectorFree(out);
+        return NULL;
+    }
+
+    if (type == PS_TYPE_F32) {
+        psC32* outVec;
+        psF32* realVec = real->data.F32;
+        psF32* imagVec = imag->data.F32;
+
+        out = psVectorRecycle(out,PS_TYPE_C32,numElements);
+        out->n = numElements;
+        outVec = out->data.C32;
+
+        for (unsigned int i=0;i<numElements;i++) {
+            outVec[i] = realVec[i] + I*imagVec[i];
+        }
+    } else {
+        psError(__func__,"Can not merge real and imaginary portions for given vector type (%d).",
+                type);
+        psVectorFree(out);
+        return NULL;
+    }
+
+    return out;
+}
+
+psVector *psVectorConjugate(psVector *out, const psVector *in)
+{
+    psElemType type;
+    unsigned int numElements;
+
+
+    if (in == NULL) {
+        psVectorFree(out);
+        return NULL;
+    }
+
+    type = in->type.type;
+    numElements = in->n;
+
+    /* if not a complex number, this is logically just a image copy */
+    if (! PS_IS_PSELEMTYPE_COMPLEX(type)) {
+        // Warn user, as this is probably not expected
+        psLogMsg(__func__,PS_LOG_WARN,"Complex Conjugate of a non-Complex type called for. "
+                 "Vector copy was performed instead.");
+
+        out = psVectorRecycle(out,type,numElements);
+        out->n = numElements;
+        memcpy(out->data.V,in->data.V,PSELEMTYPE_SIZEOF(type)*numElements);
+        return out;
+    }
+
+    if (type == PS_TYPE_C32) {
+        psC32* outVec;
+        psC32* inVec = in->data.C32;
+
+        out = psVectorRecycle(out,PS_TYPE_C32, numElements);
+        out->n = numElements;
+        outVec = out->data.C32;
+
+        for (unsigned int i=0;i<numElements;i++) {
+            outVec[i] = crealf(inVec[i]) - I*cimagf(inVec[i]);
+        }
+    } else {
+        psError(__func__,"Can not compute complex conjugate for given vector type (%d).",
+                type);
+        psVectorFree(out);
+        return NULL;
+    }
+
+    return out;
+}
+
+psVector *psVectorPowerSpectrum(psVector* out, const psVector* in)
+{
+    psElemType type;
+    unsigned int outNumElements;
+    unsigned int inNumElements;
+    unsigned int inHalfNumElements;
+    unsigned int inNumElementsSquared;
+
+    if (in == NULL) {
+        psVectorFree(out);
+        return NULL;
+    }
+
+    type = in->type.type;
+    inNumElements = in->n;
+    inNumElementsSquared = inNumElements*inNumElements;
+    inHalfNumElements = inNumElements/2;
+    outNumElements = inHalfNumElements+1;
+
+    /* if not a complex number, this is not implemented */
+    if (! PS_IS_PSELEMTYPE_COMPLEX(type)) {
+        psError(__func__,"Power Spectrum for non-complex inputs is not implemented.");
+        psVectorFree(out);
+        return NULL;
+    }
+
+    if (type == PS_TYPE_C32) {
+        psF32* outVec;
+        psC32* inVec = in->data.C32;
+        psF32 inAbs1;
+        psF32 inAbs2;
+
+        out = psVectorRecycle(out,PS_TYPE_F32,outNumElements);
+        out->n = outNumElements;
+        outVec = out->data.F32;
+
+        // from ADD: P_0 = |C_0|^2/N^2
+        inAbs1 = cabsf(inVec[0]);
+        outVec[0] = inAbs1*inAbs1/inNumElementsSquared;
+
+        // from ADD: P_j = (|C_j|^2+|C_N-j|^2)/N^2, where j = 1,2,...,(N/2-1)
+        for (unsigned int i=1;i<inHalfNumElements;i++) {
+            inAbs1 = cabsf(inVec[i]);
+            inAbs2 = cabsf(inVec[inNumElements-i]);
+            outVec[i] = (inAbs1*inAbs1+inAbs2*inAbs2)/inNumElementsSquared;
+        }
+
+        // from ADD: P_N/2 = |C_N/2|^2/N^2
+        inAbs1 = cabsf(inVec[inHalfNumElements]);
+        outVec[inHalfNumElements] = inAbs1*inAbs1/inNumElementsSquared;
+    } else {
+        psError(__func__,"Can not power spectrum for given vector type (%d).",
+                type);
+        psVectorFree(out);
+        return NULL;
+    }
+
+    return out;
+
+}
Index: /tags/rel1_1/psLib/src/dataManip/psVectorFFT.h
===================================================================
--- /tags/rel1_1/psLib/src/dataManip/psVectorFFT.h	(revision 1056)
+++ /tags/rel1_1/psLib/src/dataManip/psVectorFFT.h	(revision 1056)
@@ -0,0 +1,52 @@
+/** @file  psFFT.h
+ *
+ *  @brief Contains FFT transforms functions
+ *
+ *  @ingroup Transform
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.6 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-10 01:58:06 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PS_FFT_H
+#define PS_FFT_H
+
+#include "psImage.h"
+#include "psVector.h"
+
+/// @addtogroup Transform
+/// @{
+
+/** Details on FFT implementation (private). */
+
+
+typedef enum {
+    /// psImageFFT/psVectorFFT should perform a forward FFT.
+    PS_FFT_FORWARD = (-1),
+
+    ///< psImageFFT/psVectorFFT should perform a reverse FFT.
+    PS_FFT_REVERSE = (+1)
+} psFftDirection;
+
+psImage* psImageFFT(psImage* out, const psImage* in, psFftDirection direction);
+psImage* psImageReal(psImage *out, const psImage* in);
+psImage* psImageImaginary(psImage *out, const psImage* in);
+psImage* psImageComplex(psImage* out, psImage *real, const psImage *imag);
+psImage* psImageConjugate(psImage *out, const psImage *in);
+psImage* psImagePowerSpectrum(psImage* out, const psImage* in);
+
+psVector* psVectorFFT(psVector* out, const psVector* in, psFftDirection direction);
+psVector* psVectorReal(psVector* out, const psVector* in);
+psVector* psVectorImaginary(psVector* out, const psVector* in);
+psVector* psVectorComplex(psVector* out, psVector* real, const psVector* imag);
+psVector* psVectorConjugate(psVector* out, const psVector* in);
+psVector* psVectorPowerSpectrum(psVector* out, const psVector* in);
+
+/// @}
+
+#endif
+
Index: /tags/rel1_1/psLib/src/fft/psVectorFFT.c
===================================================================
--- /tags/rel1_1/psLib/src/fft/psVectorFFT.c	(revision 1056)
+++ /tags/rel1_1/psLib/src/fft/psVectorFFT.c	(revision 1056)
@@ -0,0 +1,755 @@
+/** @file  psFFT.c
+ *
+ *  @brief Contains FFT transforms functions
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.10 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-12 02:17:25 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include <unistd.h>
+#include <stdbool.h>
+#include <string.h>
+#include <complex.h>
+#include <fftw3.h>
+
+#include "psFFT.h"
+#include "psError.h"
+#include "psMemory.h"
+#include "psLogMsg.h"
+
+#define P_FFTW_PLAN_RIGOR FFTW_ESTIMATE
+
+static bool p_fftwWisdomImported = false;
+
+psImage* psImageFFT(psImage* out, const psImage* in, psFftDirection direction)
+{
+    unsigned int numCols;
+    unsigned int numRows;
+    psElemType type;
+    fftwf_plan plan;
+
+    /* got good image data? */
+    if (in==NULL) {
+        psImageFree(out);
+        return NULL;
+    }
+
+    type = in->type.type;
+
+    if ( (type != PS_TYPE_F32) && (type != PS_TYPE_C32) ) {
+        psError(__func__,"Input image must be a 32-bit float or complex image (type=%d)",
+                type);
+        psImageFree(out);
+        return NULL;
+    }
+
+    if ( type != PS_TYPE_C32 && direction == PS_FFT_REVERSE ) {
+        psError(__func__,"Input image must be complex image for reverse FFT (type=%d).",
+                type);
+        psImageFree(out);
+        return NULL;
+
+    }
+
+    /* make sure the system-level wisdom information is imported. */
+    if (! p_fftwWisdomImported) {
+        fftwf_import_system_wisdom();
+        p_fftwWisdomImported = true;
+    }
+
+    numRows = in->numRows;
+    numCols = in->numCols;
+
+    out = psImageCopy(out,in, PS_TYPE_C32);
+
+    plan = fftwf_plan_dft_2d(numCols, numRows,
+                             (fftwf_complex*)out->data.C32[0],
+                             (fftwf_complex*)out->data.C32[0],
+                             direction,
+                             P_FFTW_PLAN_RIGOR);
+
+    /* check if a plan exists now*/
+    if (plan == NULL) {
+        psError(__func__,"Failed to create FFTW plan.");
+        psImageFree(out);
+        return NULL;
+    }
+
+    /* finally, call FFTW with the plan made above */
+    fftwf_execute(plan);
+
+    fftwf_destroy_plan(plan);
+
+    return out;
+
+}
+
+
+psImage *psImageReal(psImage *out, const psImage* in)
+{
+    psElemType type;
+    unsigned int numCols;
+    unsigned int numRows;
+
+
+    if (in == NULL) {
+        psImageFree(out);
+        return NULL;
+    }
+
+    type = in->type.type;
+    numCols = in->numCols;
+    numRows = in->numRows;
+
+    /* if not a complex number, this is logically just a copy */
+    if (! PS_IS_PSELEMTYPE_COMPLEX(type)) {
+        // Warn user, as this is probably not expected
+        psLogMsg(__func__,PS_LOG_WARN,"Real portion of a non-Complex type called called for. "
+                 "Just an image copy was performed.");
+        return psImageCopy(out,in,type);
+    }
+
+    if (type == PS_TYPE_C32) {
+        psF32* outRow;
+        psC32* inRow;
+
+        out = psImageRecycle(out,numCols,numRows,PS_TYPE_F32);
+        for (unsigned int row=0;row<numRows;row++) {
+            outRow = out->data.F32[row];
+            inRow = in->data.C32[row];
+
+            for (unsigned int col=0;col<numCols;col++) {
+                outRow[col] = crealf(inRow[col]);
+            }
+        }
+    } else if (type == PS_TYPE_C64) {
+        psF64* outRow;
+        psC64* inRow;
+
+        out = psImageRecycle(out,numCols,numRows,PS_TYPE_F64);
+        for (unsigned int row=0;row<numRows;row++) {
+            outRow = out->data.F64[row];
+            inRow = in->data.C64[row];
+
+            for (unsigned int col=0;col<numCols;col++) {
+                outRow[col] = creal(inRow[col]);
+            }
+        }
+    } else {
+        psError(__func__,"Can not extract real component from given image type (%d).",
+                type);
+        psImageFree(out);
+        return NULL;
+    }
+
+    return out;
+}
+
+psImage *psImageImaginary(psImage *out, const psImage* in)
+{
+    psElemType type;
+    unsigned int numCols;
+    unsigned int numRows;
+
+
+    if (in == NULL) {
+        psImageFree(out);
+        return NULL;
+    }
+
+    type = in->type.type;
+    numCols = in->numCols;
+    numRows = in->numRows;
+
+    /* if not a complex number, this is logically just zeroed image of same size */
+    if (! PS_IS_PSELEMTYPE_COMPLEX(type)) {
+        // Warn user, as this is probably not expected
+        psLogMsg(__func__,PS_LOG_WARN,"Imaginary portion of a non-Complex type called for. "
+                 "A zero image was returned.");
+        out = psImageRecycle(out,numCols,numRows,type);
+        memset(out->data.V[0],0,PSELEMTYPE_SIZEOF(type)*numCols*numRows);
+        return out;
+    }
+
+    if (type == PS_TYPE_C32) {
+        psF32* outRow;
+        psC32* inRow;
+
+        out = psImageRecycle(out,numCols,numRows,PS_TYPE_F32);
+        for (unsigned int row=0;row<numRows;row++) {
+            outRow = out->data.F32[row];
+            inRow = in->data.C32[row];
+
+            for (unsigned int col=0;col<numCols;col++) {
+                outRow[col] = cimagf(inRow[col]);
+            }
+        }
+    } else if (type == PS_TYPE_C64) {
+        psF64* outRow;
+        psC64* inRow;
+
+        out = psImageRecycle(out,numCols,numRows,PS_TYPE_F64);
+        for (unsigned int row=0;row<numRows;row++) {
+            outRow = out->data.F64[row];
+            inRow = in->data.C64[row];
+
+            for (unsigned int col=0;col<numCols;col++) {
+                outRow[col] = cimag(inRow[col]);
+            }
+        }
+    } else {
+        psError(__func__,"Can not extract imaginary component from given image type (%d).",
+                type);
+        psImageFree(out);
+        return NULL;
+    }
+
+    return out;
+}
+
+psImage *psImageComplex(psImage* out, psImage *real, const psImage *imag)
+{
+    psElemType type;
+    unsigned int numCols;
+    unsigned int numRows;
+
+
+    if (real == NULL || imag == NULL) {
+        psImageFree(out);
+        return NULL;
+    }
+
+    type = real->type.type;
+    numCols = real->numCols;
+    numRows = real->numRows;
+
+    if (imag->type.type != type) {
+        psError(__func__,"The inputs to psImageComplex must be the same type.");
+        psImageFree(out);
+        return NULL;
+    }
+
+    if (imag->numCols != numCols ||
+            imag->numRows != numRows) {
+        psError(__func__,"The inputs to psImageComplex must be the same dimensions.");
+        psImageFree(out);
+        return NULL;
+    }
+
+    if (PS_IS_PSELEMTYPE_COMPLEX(type)) {
+        psError(__func__,"The inputs to psImageComplex can not be complex.");
+        psImageFree(out);
+        return NULL;
+    }
+
+    if (type != PS_TYPE_F32 && type != PS_TYPE_F64) {
+        psError(__func__,"The input type to psImageComplex must be a floating point.");
+        psImageFree(out);
+        return NULL;
+    }
+
+    if (type == PS_TYPE_F32) {
+        psC32* outRow;
+        psF32* realRow;
+        psF32* imagRow;
+
+        out = psImageRecycle(out,numCols,numRows,PS_TYPE_C32);
+
+        for (unsigned int row=0;row<numRows;row++) {
+            outRow = out->data.C32[row];
+            realRow = real->data.F32[row];
+            imagRow = imag->data.F32[row];
+
+            for (unsigned int col=0;col<numCols;col++) {
+                outRow[col] = realRow[col] + I*imagRow[col];
+            }
+        }
+    } else if (type == PS_TYPE_F64) {
+        psC64* outRow;
+        psF64* realRow;
+        psF64* imagRow;
+
+        out = psImageRecycle(out, numCols,numRows,PS_TYPE_C64);
+        for (unsigned int row=0;row<numRows;row++) {
+            outRow = out->data.C64[row];
+            realRow = real->data.F64[row];
+            imagRow = imag->data.F64[row];
+
+            for (unsigned int col=0;col<numCols;col++) {
+                outRow[col] = realRow[col] + I*imagRow[col];
+            }
+        }
+    } else {
+        psError(__func__,"Can not merge real and imaginary portions for given image type (%d).",
+                type);
+        psImageFree(out);
+        return NULL;
+    }
+
+    return out;
+}
+
+psImage *psImageConjugate(psImage *out, const psImage *in)
+{
+    psElemType type;
+    unsigned int numCols;
+    unsigned int numRows;
+
+
+    if (in == NULL) {
+        psImageFree(out);
+        return NULL;
+    }
+
+    type = in->type.type;
+    numCols = in->numCols;
+    numRows = in->numRows;
+
+    /* if not a complex number, this is logically just a image copy */
+    if (! PS_IS_PSELEMTYPE_COMPLEX(type)) {
+        // Warn user, as this is probably not expected
+        psLogMsg(__func__,PS_LOG_WARN,"Complex Conjugate of a non-Complex type called for. "
+                 "Image copy was performed instead.");
+        return psImageCopy(out,in,type);
+    }
+
+    if (type == PS_TYPE_C32) {
+        psC32* outRow;
+        psC32* inRow;
+
+        out = psImageRecycle(out,numCols,numRows,PS_TYPE_C32);
+        for (unsigned int row=0;row<numRows;row++) {
+            outRow = out->data.C32[row];
+            inRow = in->data.C32[row];
+
+            for (unsigned int col=0;col<numCols;col++) {
+                outRow[col] = crealf(inRow[col]) - I*cimagf(inRow[col]);
+            }
+        }
+    } else if (type == PS_TYPE_C64) {
+        psC64* outRow;
+        psC64* inRow;
+
+        out = psImageRecycle(out,numCols,numRows,PS_TYPE_C64);
+        for (unsigned int row=0;row<numRows;row++) {
+            outRow = out->data.C64[row];
+            inRow = in->data.C64[row];
+
+            for (unsigned int col=0;col<numCols;col++) {
+                outRow[col] = creal(inRow[col]) - I*cimag(inRow[col]);
+            }
+        }
+    } else {
+        psError(__func__,"Can not compute complex conjugate for given image type (%d).",
+                type);
+        psImageFree(out);
+        return NULL;
+    }
+
+    return out;
+}
+
+psImage *psImagePowerSpectrum(psImage* out, const psImage* in)
+{
+    psElemType type;
+    unsigned int numCols;
+    unsigned int numRows;
+    int numElementsSquared;
+
+    if (in == NULL) {
+        psImageFree(out);
+        return NULL;
+    }
+
+    type = in->type.type;
+    numCols = in->numCols;
+    numRows = in->numRows;
+    numElementsSquared = numCols*numCols*numRows*numRows;
+
+    /* if not a complex number, this is not implemented */
+    if (! PS_IS_PSELEMTYPE_COMPLEX(type)) {
+        psError(__func__,"Power Spectrum for non-complex inputs is not implemented.");
+        psImageFree(out);
+        return NULL;
+    }
+
+    if (type == PS_TYPE_C32) {
+        psF32* outRow;
+        psC32* inRow;
+        psF32 real;
+        psF32 imag;
+
+
+        out = psImageRecycle(out,numCols,numRows,PS_TYPE_F32);
+        for (unsigned int row=0;row<numRows;row++) {
+            outRow = out->data.F32[row];
+            inRow = in->data.C32[row];
+
+            for (unsigned int col=0;col<numCols;col++) {
+                real = crealf(inRow[col]);
+                imag = cimagf(inRow[col]);
+                outRow[col] = (real*real+imag*imag)/numElementsSquared;
+            }
+        }
+    } else if (type == PS_TYPE_C64) {
+        psF64* outRow;
+        psC64* inRow;
+        psF64 real;
+        psF64 imag;
+
+
+        out = psImageRecycle(out,numCols,numRows,PS_TYPE_F64);
+        for (unsigned int row=0;row<numRows;row++) {
+            outRow = out->data.F64[row];
+            inRow = in->data.C64[row];
+
+            for (unsigned int col=0;col<numCols;col++) {
+                real = crealf(inRow[col]);
+                imag = cimagf(inRow[col]);
+                outRow[col] = real*real+imag*imag/numElementsSquared;
+            }
+        }
+    } else {
+        psError(__func__,"Can not power spectrum for given image type (%d).",
+                type);
+        psImageFree(out);
+        return NULL;
+    }
+
+    return out;
+
+}
+
+/************************************** Vector Functions ***************************************/
+
+psVector* psVectorFFT(psVector* out, const psVector* in, psFftDirection direction)
+{
+    unsigned int numElements;
+    psElemType type;
+    fftwf_plan plan;
+
+    /* got good image data? */
+    if (in==NULL) {
+        psVectorFree(out);
+        return NULL;
+    }
+
+    type = in->type.type;
+
+    if ( (type != PS_TYPE_F32) && (type != PS_TYPE_C32) ) {
+        psError(__func__,"Input image must be a 32-bit float or complex image (type=%d)",
+                type);
+        psVectorFree(out);
+        return NULL;
+    }
+
+    if ( (type != PS_TYPE_C32) && (direction == PS_FFT_REVERSE) ) {
+        psError(__func__,"Input image must be complex image for reverse FFT (type=%d).",
+                type);
+        psVectorFree(out);
+        return NULL;
+
+    }
+
+    /* make sure the system-level wisdom information is imported. */
+    if (! p_fftwWisdomImported) {
+        fftwf_import_system_wisdom();
+        p_fftwWisdomImported = true;
+    }
+
+    numElements = in->n;
+
+    out = psVectorRecycle(out, PS_TYPE_C32, numElements);
+    out->n = numElements;
+
+    if (type == PS_TYPE_F32) {
+        // need to convert to complex
+        psC32* outVec = out->data.C32;
+        psF32* inVec = in->data.F32;
+        for (unsigned int i=0;i<numElements;i++) {
+            outVec[i] = inVec[i];
+        }
+    } else {
+        psC32* outVec = out->data.C32;
+        psC32* inVec = in->data.C32;
+        for (unsigned int i=0;i<numElements;i++) {
+            outVec[i] = inVec[i];
+        }
+    }
+
+    plan = fftwf_plan_dft_1d(numElements,
+                             (fftwf_complex*)out->data.C32,
+                             (fftwf_complex*)out->data.C32,
+                             direction,
+                             P_FFTW_PLAN_RIGOR);
+
+    /* check if a plan exists now*/
+    if (plan == NULL) {
+        psError(__func__,"Failed to create FFTW plan.");
+        psVectorFree(out);
+        return NULL;
+    }
+
+    /* finally, call FFTW with the plan made above */
+    fftwf_execute(plan);
+
+    fftwf_destroy_plan(plan);
+
+    return out;
+}
+
+
+psVector *psVectorReal(psVector *out, const psVector* in)
+{
+    psElemType type;
+    unsigned int numElements;
+
+    if (in == NULL) {
+        psVectorFree(out);
+        return NULL;
+    }
+
+    type = in->type.type;
+    numElements = in->n;
+
+    /* if not a complex number, this is logically just a copy */
+    if (! PS_IS_PSELEMTYPE_COMPLEX(type)) {
+        // Warn user, as this is probably not expected
+        psLogMsg(__func__,PS_LOG_WARN,"Real portion of a non-Complex type called called for. "
+                 "Just a vector copy was performed.");
+        out = psVectorRecycle(out,type,numElements);
+        out->n = numElements;
+        memcpy(out->data.V,in->data.V,numElements*PSELEMTYPE_SIZEOF(type));
+        return out;
+    }
+
+    if (type == PS_TYPE_C32) {
+        psF32* outVec;
+        psC32* inVec = in->data.C32;
+
+        out = psVectorRecycle(out,PS_TYPE_F32,numElements);
+        out->n = numElements;
+        outVec = out->data.F32;
+
+        for (unsigned int i=0;i<numElements;i++) {
+            outVec[i] = crealf(inVec[i]);
+        }
+    } else {
+        psError(__func__,"Can not extract real component from given vector type (%d).",
+                type);
+        psVectorFree(out);
+        return NULL;
+    }
+
+    return out;
+}
+
+psVector *psVectorImaginary(psVector *out, const psVector* in)
+{
+    psElemType type;
+    unsigned int numElements;
+
+
+    if (in == NULL) {
+        psVectorFree(out);
+        return NULL;
+    }
+
+    type = in->type.type;
+    numElements = in->n;
+
+    /* if not a complex number, this is logically just zeroed image of same size */
+    if (! PS_IS_PSELEMTYPE_COMPLEX(type)) {
+        // Warn user, as this is probably not expected
+        psLogMsg(__func__,PS_LOG_WARN,"Imaginary portion of a non-Complex type called for. "
+                 "A zeroed vector was returned.");
+        out = psVectorRecycle(out,type,numElements);
+        out->n = numElements;
+        memset(out->data.V,0,PSELEMTYPE_SIZEOF(type)*numElements);
+        return out;
+    }
+
+    if (type == PS_TYPE_C32) {
+        psF32* outVec;
+        psC32* inVec = in->data.C32;
+
+        out = psVectorRecycle(out,PS_TYPE_F32,numElements);
+        out->n = numElements;
+        outVec = out->data.F32;
+
+        for (unsigned int i=0;i<numElements;i++) {
+            outVec[i] = cimagf(inVec[i]);
+        }
+    } else {
+        psError(__func__,"Can not extract imaginary component from given vector type (%d).",
+                type);
+        psVectorFree(out);
+        return NULL;
+    }
+
+    return out;
+}
+
+psVector *psVectorComplex(psVector* out, psVector *real, const psVector *imag)
+{
+    psElemType type;
+    unsigned int numElements;
+
+
+    if (real == NULL || imag == NULL) {
+        psVectorFree(out);
+        return NULL;
+    }
+
+    type = real->type.type;
+    if (real->n >= imag->n) {
+        numElements = real->n;
+    } else {
+        numElements = imag->n;
+    }
+
+    if (imag->type.type != type) {
+        psError(__func__,"The inputs to psVectorComplex must be the same type.");
+        psVectorFree(out);
+        return NULL;
+    }
+
+    if (PS_IS_PSELEMTYPE_COMPLEX(type)) {
+        psError(__func__,"The inputs to psVectorComplex can not be complex.");
+        psVectorFree(out);
+        return NULL;
+    }
+
+    if (type == PS_TYPE_F32) {
+        psC32* outVec;
+        psF32* realVec = real->data.F32;
+        psF32* imagVec = imag->data.F32;
+
+        out = psVectorRecycle(out,PS_TYPE_C32,numElements);
+        out->n = numElements;
+        outVec = out->data.C32;
+
+        for (unsigned int i=0;i<numElements;i++) {
+            outVec[i] = realVec[i] + I*imagVec[i];
+        }
+    } else {
+        psError(__func__,"Can not merge real and imaginary portions for given vector type (%d).",
+                type);
+        psVectorFree(out);
+        return NULL;
+    }
+
+    return out;
+}
+
+psVector *psVectorConjugate(psVector *out, const psVector *in)
+{
+    psElemType type;
+    unsigned int numElements;
+
+
+    if (in == NULL) {
+        psVectorFree(out);
+        return NULL;
+    }
+
+    type = in->type.type;
+    numElements = in->n;
+
+    /* if not a complex number, this is logically just a image copy */
+    if (! PS_IS_PSELEMTYPE_COMPLEX(type)) {
+        // Warn user, as this is probably not expected
+        psLogMsg(__func__,PS_LOG_WARN,"Complex Conjugate of a non-Complex type called for. "
+                 "Vector copy was performed instead.");
+
+        out = psVectorRecycle(out,type,numElements);
+        out->n = numElements;
+        memcpy(out->data.V,in->data.V,PSELEMTYPE_SIZEOF(type)*numElements);
+        return out;
+    }
+
+    if (type == PS_TYPE_C32) {
+        psC32* outVec;
+        psC32* inVec = in->data.C32;
+
+        out = psVectorRecycle(out,PS_TYPE_C32, numElements);
+        out->n = numElements;
+        outVec = out->data.C32;
+
+        for (unsigned int i=0;i<numElements;i++) {
+            outVec[i] = crealf(inVec[i]) - I*cimagf(inVec[i]);
+        }
+    } else {
+        psError(__func__,"Can not compute complex conjugate for given vector type (%d).",
+                type);
+        psVectorFree(out);
+        return NULL;
+    }
+
+    return out;
+}
+
+psVector *psVectorPowerSpectrum(psVector* out, const psVector* in)
+{
+    psElemType type;
+    unsigned int outNumElements;
+    unsigned int inNumElements;
+    unsigned int inHalfNumElements;
+    unsigned int inNumElementsSquared;
+
+    if (in == NULL) {
+        psVectorFree(out);
+        return NULL;
+    }
+
+    type = in->type.type;
+    inNumElements = in->n;
+    inNumElementsSquared = inNumElements*inNumElements;
+    inHalfNumElements = inNumElements/2;
+    outNumElements = inHalfNumElements+1;
+
+    /* if not a complex number, this is not implemented */
+    if (! PS_IS_PSELEMTYPE_COMPLEX(type)) {
+        psError(__func__,"Power Spectrum for non-complex inputs is not implemented.");
+        psVectorFree(out);
+        return NULL;
+    }
+
+    if (type == PS_TYPE_C32) {
+        psF32* outVec;
+        psC32* inVec = in->data.C32;
+        psF32 inAbs1;
+        psF32 inAbs2;
+
+        out = psVectorRecycle(out,PS_TYPE_F32,outNumElements);
+        out->n = outNumElements;
+        outVec = out->data.F32;
+
+        // from ADD: P_0 = |C_0|^2/N^2
+        inAbs1 = cabsf(inVec[0]);
+        outVec[0] = inAbs1*inAbs1/inNumElementsSquared;
+
+        // from ADD: P_j = (|C_j|^2+|C_N-j|^2)/N^2, where j = 1,2,...,(N/2-1)
+        for (unsigned int i=1;i<inHalfNumElements;i++) {
+            inAbs1 = cabsf(inVec[i]);
+            inAbs2 = cabsf(inVec[inNumElements-i]);
+            outVec[i] = (inAbs1*inAbs1+inAbs2*inAbs2)/inNumElementsSquared;
+        }
+
+        // from ADD: P_N/2 = |C_N/2|^2/N^2
+        inAbs1 = cabsf(inVec[inHalfNumElements]);
+        outVec[inHalfNumElements] = inAbs1*inAbs1/inNumElementsSquared;
+    } else {
+        psError(__func__,"Can not power spectrum for given vector type (%d).",
+                type);
+        psVectorFree(out);
+        return NULL;
+    }
+
+    return out;
+
+}
Index: /tags/rel1_1/psLib/src/fft/psVectorFFT.h
===================================================================
--- /tags/rel1_1/psLib/src/fft/psVectorFFT.h	(revision 1056)
+++ /tags/rel1_1/psLib/src/fft/psVectorFFT.h	(revision 1056)
@@ -0,0 +1,52 @@
+/** @file  psFFT.h
+ *
+ *  @brief Contains FFT transforms functions
+ *
+ *  @ingroup Transform
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.6 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-10 01:58:06 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PS_FFT_H
+#define PS_FFT_H
+
+#include "psImage.h"
+#include "psVector.h"
+
+/// @addtogroup Transform
+/// @{
+
+/** Details on FFT implementation (private). */
+
+
+typedef enum {
+    /// psImageFFT/psVectorFFT should perform a forward FFT.
+    PS_FFT_FORWARD = (-1),
+
+    ///< psImageFFT/psVectorFFT should perform a reverse FFT.
+    PS_FFT_REVERSE = (+1)
+} psFftDirection;
+
+psImage* psImageFFT(psImage* out, const psImage* in, psFftDirection direction);
+psImage* psImageReal(psImage *out, const psImage* in);
+psImage* psImageImaginary(psImage *out, const psImage* in);
+psImage* psImageComplex(psImage* out, psImage *real, const psImage *imag);
+psImage* psImageConjugate(psImage *out, const psImage *in);
+psImage* psImagePowerSpectrum(psImage* out, const psImage* in);
+
+psVector* psVectorFFT(psVector* out, const psVector* in, psFftDirection direction);
+psVector* psVectorReal(psVector* out, const psVector* in);
+psVector* psVectorImaginary(psVector* out, const psVector* in);
+psVector* psVectorComplex(psVector* out, psVector* real, const psVector* imag);
+psVector* psVectorConjugate(psVector* out, const psVector* in);
+psVector* psVectorPowerSpectrum(psVector* out, const psVector* in);
+
+/// @}
+
+#endif
+
Index: /tags/rel1_1/psLib/src/image/psImage.c
===================================================================
--- /tags/rel1_1/psLib/src/image/psImage.c	(revision 1056)
+++ /tags/rel1_1/psLib/src/image/psImage.c	(revision 1056)
@@ -0,0 +1,2333 @@
+/** @file  psImage.c
+ *
+ *  @brief Contains basic image definitions and operations.
+ *
+ *  This file defines the basic type for an image struct and functions useful
+ *  in manupulating images.
+ *
+ *  @author Robert DeSonia, MHPCC
+ *  @author Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.28 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-11 02:02:53 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ *  That is the routine used to generate matrices.
+ */
+
+/******************************************************************************/
+/*  INCLUDE FILES                                                             */
+/******************************************************************************/
+
+#include <string.h>
+#include <math.h>
+
+#include "psMemory.h"
+#include "psError.h"
+#include "psImage.h"
+
+
+/*****************************************************************************/
+/* FUNCTION IMPLEMENTATION - PUBLIC                                          */
+/*****************************************************************************/
+
+psImage *psImageAlloc(unsigned int numCols, unsigned int numRows,
+                      const psElemType type)
+{
+    int area = 0;
+    int elementSize = PSELEMTYPE_SIZEOF(type); // element size in bytes
+    int rowSize = numCols*elementSize;  // row size in bytes.
+
+    area = numCols*numRows;
+
+    if (area < 1) {
+        psError(__func__, "Invalid value for number of rows or columns "
+                "(numRows=%d, numCols=%d).", numRows, numCols);
+        return NULL;
+    }
+
+    psImage *image = (psImage *)psAlloc(sizeof(psImage));
+
+    image->data.V = psAlloc(sizeof(void*)*numRows);
+
+    image->data.V[0] = psAlloc(area*elementSize);
+
+    for(int i = 1; i < numRows; i++) {
+        image->data.V[i] = (void*)((int8_t*)image->data.V[i-1]+rowSize);
+    }
+
+    *(int*)&image->col0 = 0;
+    *(int*)&image->row0 = 0;
+    *(unsigned int*)&image->numCols = numCols;
+    *(unsigned int*)&image->numRows = numRows;
+    *(psDimen*)&image->type.dimen = PS_DIMEN_IMAGE;
+    *(psElemType*)&image->type.type = type;
+    image->parent = NULL;
+    image->nChildren = 0;
+    image->children = NULL;
+
+    return image;
+}
+
+void psImageFree(psImage *image)
+{
+    if (image == NULL) {
+        return;
+    }
+
+    if (image->type.type == PS_TYPE_PTR) {
+        // 2-D array of pointers -- must dereference
+        unsigned int oldNumRows = image->numRows;
+        unsigned int oldNumCols = image->numCols;
+        psPTR* rowPtr;
+
+        for(unsigned int row=0;row<oldNumRows;row++) {
+            rowPtr = image->data.PTR[row];
+            for (unsigned int col=0;col<oldNumCols;col++) {
+                psMemDecrRefCounter(rowPtr[col]);
+            }
+        }
+    }
+
+    psImageFreeChildren(image);
+
+    psFree(image->data.V[0]);
+    psFree(image->data.V);
+    image->data.V = NULL;
+
+    psFree(image);
+}
+
+psImage* psImageRecycle(psImage* old,
+                        unsigned int numCols,
+                        unsigned int numRows,
+                        const psElemType type)
+{
+    int elementSize = PSELEMTYPE_SIZEOF(type); // element size in bytes
+    int rowSize = numCols*elementSize;  // row size in bytes.
+
+    if (old == NULL) {
+        old = psImageAlloc(numCols,numRows,type);
+        return old;
+    }
+
+    if (old->type.dimen != PS_DIMEN_IMAGE) {
+        psError(__func__,"Can not realloc image because input is not an image.");
+        return NULL;
+    }
+
+    if (old->type.type == PS_TYPE_PTR) {
+        // 2-D array of pointers -- must dereference
+        unsigned int oldNumRows = old->numRows;
+        unsigned int oldNumCols = old->numCols;
+        psPTR* rowPtr;
+
+        for(unsigned int row=0;row<oldNumRows;row++) {
+            rowPtr = old->data.PTR[row];
+            for (unsigned int col=0;col<oldNumCols;col++) {
+                psMemDecrRefCounter(rowPtr[col]);
+                rowPtr[col] = NULL;
+            }
+        }
+    }
+
+    /* image already the right size/type? */
+    if (numCols == old->numCols && numRows == old->numRows &&
+            type == old->type.type) {
+        return old;
+    }
+
+    // Resize the image buffer
+    old->data.V[0] = psRealloc(old->data.V[0],numCols * numRows * elementSize);
+    old->data.V = (void**) psRealloc(old->data.V,numRows * sizeof(void*));
+
+    // recreate the row pointers
+    for(int i = 1; i < numRows; i++) {
+        old->data.V[i] = (void*)((int8_t*)old->data.V[i-1]+rowSize);
+    }
+
+    *(unsigned int*)&old->numCols = numCols;
+    *(unsigned int*)&old->numRows = numRows;
+    *(psElemType*)&old->type.type = type;
+
+    return old;
+}
+
+psImage *psImageSubset(psImage *out,psImage *image,unsigned int numCols,
+                       unsigned int numRows, unsigned int col0,
+                       unsigned int row0)
+{
+    unsigned int elementSize;           // size of image element in bytes
+    unsigned int outputRowSize;         // output row size in bytes
+    unsigned int inputColOffset;        // offset in bytes to first subset pixel in input row
+
+    if (image == NULL || image->data.V == NULL) {
+        psError(__func__,"Can not subset image because input image or its pixel buffer is NULL.");
+        return NULL;
+    }
+
+    if (image->type.dimen != PS_DIMEN_IMAGE) {
+        psError(__func__,"Can not subset image because input image is not an image.");
+        return NULL;
+    }
+
+    if (numCols < 1 || numRows < 1) {
+        psError(__func__,"Can not subset image because number of rows or columns are zero (%dx%d).",
+                numCols, numRows);
+        return NULL;
+    }
+
+    if (col0 >= image->numCols || row0 >= image->numRows) {
+        psError(__func__,"Can not subset image because col0,row0 (%d,%d) is not a valid pixel location.",
+                col0,row0);
+        return NULL;
+    }
+
+    /* validate subimage size */
+    if (col0+numCols >= image->numCols || row0+numRows >= image->numRows) {
+        psError(__func__,"Can not subset image outside of image boundaries (size=%dx%d, "
+                "subset=[%d:%d,%d:%d]).",image->numCols,image->numRows,col0,
+                col0+numCols, row0, row0+numRows);
+        return NULL;
+    }
+
+
+    elementSize = PSELEMTYPE_SIZEOF(image->type.type);
+
+    out = psImageRecycle(out,numCols,numRows,image->type.type);
+
+    // set the parent information into the child output image
+    *(int*)&out->row0 = row0;
+    *(int*)&out->col0 = col0;
+    *(psImage**)&out->parent = (psImage*)image;
+
+    // add output image as a child of the input image.
+    image->nChildren++;
+    image->children = (psImage **) psRealloc(image->children,
+                      image->nChildren * sizeof(psImage*) );
+    image->children[image->nChildren-1] = out;
+
+    inputColOffset = elementSize*col0;
+    outputRowSize = elementSize*numCols;
+
+    for (int row = 0; row < numRows; row++) {
+        memcpy(out->data.V[row],image->data.U8[row0+row] + inputColOffset,
+               outputRowSize);
+    }
+
+    return (out);
+}
+
+int psImageFreeChildren(psImage* image)
+{
+    int i = 0;
+    int nChildren = 0;
+    psImage **children = NULL;
+    int numFreed = 0;
+
+    if (image == NULL) {
+        return numFreed;
+    }
+
+    nChildren = image->nChildren;
+    children = image->children;
+
+    for(i=0; i<nChildren; i++) {
+        if (children[i] != NULL) {
+            numFreed++;
+            psImageFree(children[i]);
+        }
+    }
+    psFree(children);
+
+    image->nChildren = 0;
+    image->children = NULL;
+
+
+    return numFreed;
+}
+
+psImage *psImageCopy(psImage* restrict output, const psImage *input,
+                     psElemType type)
+{
+    psElemType inDatatype;
+    int elementSize;
+    int numRows;
+    int numCols;
+
+    if (input == NULL || input->data.V == NULL) {
+        psError(__func__,"Can not copy image because input image or its pixel buffer is NULL.");
+        return NULL;
+    }
+
+    if (input == output) {
+        psError(__func__,"Can not copy image because given input and output "
+                "parameter reference the same psImage struct.");
+        return NULL;
+    }
+
+    if (input->type.dimen != PS_DIMEN_IMAGE) {
+        psError(__func__,"Can not copy image because input image is not actually an image.");
+        return NULL;
+    }
+
+    inDatatype = input->type.type;
+    numRows = input->numRows;
+    numCols = input->numCols;
+    elementSize = PSELEMTYPE_SIZEOF(inDatatype);
+
+    if (inDatatype == PS_TYPE_PTR || type == PS_TYPE_PTR) {
+        psError(__func__,"Can not copy image to/from a void* matrix");
+        return NULL;
+    }
+
+    output = psImageRecycle(output,numCols,numRows,type);
+
+    // cover the trival case of copy of the same datatype.
+    if (type == inDatatype) {
+        memcpy(output->data.V[0],input->data.V[0],elementSize*numRows*numCols);
+        return output;
+    }
+
+    #define PSIMAGE_ELEMENT_ASSIGN_LOOP(OUT,IN,INTYPE,OUTTYPE) \
+    { \
+        ps##INTYPE *in; \
+        ps##OUTTYPE *out; \
+        for (int row=0;row<numRows;row++) { \
+            in = IN->data.INTYPE[row]; \
+            out = OUT->data.OUTTYPE[row]; \
+            for (int col=0;col<numCols;col++) { \
+                out[col] = (ps##OUTTYPE) in[col]; \
+            } \
+        } \
+    }
+
+    #define PSIMAGE_ELEMENT_ASSIGN(OUT,IN,OUTTYPE) \
+    switch (IN->type.type) { \
+    case PS_TYPE_S8: \
+        PSIMAGE_ELEMENT_ASSIGN_LOOP(OUT,IN,S8,OUTTYPE); \
+        break; \
+    case PS_TYPE_S16: \
+        PSIMAGE_ELEMENT_ASSIGN_LOOP(OUT,IN,S16,OUTTYPE); \
+        break; \
+    case PS_TYPE_S32: \
+        PSIMAGE_ELEMENT_ASSIGN_LOOP(OUT,IN,S32,OUTTYPE); \
+        break; \
+    case PS_TYPE_S64: \
+        PSIMAGE_ELEMENT_ASSIGN_LOOP(OUT,IN,S64,OUTTYPE); \
+        break; \
+    case PS_TYPE_U8: \
+        PSIMAGE_ELEMENT_ASSIGN_LOOP(OUT,IN,U8,OUTTYPE); \
+        break; \
+    case PS_TYPE_U16: \
+        PSIMAGE_ELEMENT_ASSIGN_LOOP(OUT,IN,U16,OUTTYPE); \
+        break; \
+    case PS_TYPE_U32: \
+        PSIMAGE_ELEMENT_ASSIGN_LOOP(OUT,IN,U32,OUTTYPE); \
+        break; \
+    case PS_TYPE_U64: \
+        PSIMAGE_ELEMENT_ASSIGN_LOOP(OUT,IN,U64,OUTTYPE); \
+        break; \
+    case PS_TYPE_F32: \
+        PSIMAGE_ELEMENT_ASSIGN_LOOP(OUT,IN,F32,OUTTYPE); \
+        break; \
+    case PS_TYPE_F64: \
+        PSIMAGE_ELEMENT_ASSIGN_LOOP(OUT,IN,F64,OUTTYPE); \
+        break; \
+    case PS_TYPE_C32: \
+        PSIMAGE_ELEMENT_ASSIGN_LOOP(OUT,IN,C32,OUTTYPE); \
+        break; \
+    case PS_TYPE_PTR: \
+        psError(__func__,"Can't copy image from a matrix of pointers."); \
+        psImageFree(output); \
+        return NULL; \
+    default: \
+        break; \
+    }
+
+    // XXX - GCC had problems with the length? of the above macro.  The original
+    // macro code here is commented out and the preprocessor output is pasted below it
+    // (effectively to the end of the function)
+    // We need to find out what is doing on here and move back to the macro version.
+    #if 0
+    switch (type)
+    {
+    case PS_TYPE_S8:
+        PSIMAGE_ELEMENT_ASSIGN(output,input,S8);
+        break;
+    case PS_TYPE_S16:
+        PSIMAGE_ELEMENT_ASSIGN(output,input,S16);
+        break;
+    case PS_TYPE_S32:
+        PSIMAGE_ELEMENT_ASSIGN(output,input,S32);
+        break;
+    case PS_TYPE_S64:
+        PSIMAGE_ELEMENT_ASSIGN(output,input,S64);
+        break;
+    case PS_TYPE_U8:
+        PSIMAGE_ELEMENT_ASSIGN(output,input,U8);
+    case PS_TYPE_U16:
+        PSIMAGE_ELEMENT_ASSIGN(output,input,U16);
+        break;
+    case PS_TYPE_U32:
+        PSIMAGE_ELEMENT_ASSIGN(output,input,U32);
+        break;
+    case PS_TYPE_U64:
+        PSIMAGE_ELEMENT_ASSIGN(output,input,U64);
+        break;
+    case PS_TYPE_F32:
+        PSIMAGE_ELEMENT_ASSIGN(output,input,F32);
+        break;
+    case PS_TYPE_F64:
+        PSIMAGE_ELEMENT_ASSIGN(output,input,F64);
+        break;
+    case PS_TYPE_C32:
+        PSIMAGE_ELEMENT_ASSIGN(output,input,C32);
+        break;
+    case PS_TYPE_C64:
+        PSIMAGE_ELEMENT_ASSIGN(output,input,C64);
+        break;
+    case PS_TYPE_PTR:
+        psError(__func__,"Can't copy image into a matrix of pointers.");
+        psImageFree(output);
+        return NULL;
+    }
+    #endif
+
+    #if 1
+    switch (type) {
+    case PS_TYPE_S8:
+        switch (input->type.type) {
+        case PS_TYPE_S8: {
+                psS8 *in;
+                psS8 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S8[row];
+                    out = output->data.S8[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS8) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S16: {
+                psS16 *in;
+                psS8 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S16[row];
+                    out = output->data.S8[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS8) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S32: {
+                psS32 *in;
+                psS8 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S32[row];
+                    out = output->data.S8[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS8) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S64: {
+                psS64 *in;
+                psS8 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S64[row];
+                    out = output->data.S8[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS8) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U8: {
+                psU8 *in;
+                psS8 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U8[row];
+                    out = output->data.S8[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS8) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U16: {
+                psU16 *in;
+                psS8 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U16[row];
+                    out = output->data.S8[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS8) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U32: {
+                psU32 *in;
+                psS8 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U32[row];
+                    out = output->data.S8[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS8) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U64: {
+                psU64 *in;
+                psS8 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U64[row];
+                    out = output->data.S8[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS8) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_F32: {
+                psF32 *in;
+                psS8 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.F32[row];
+                    out = output->data.S8[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS8) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_F64: {
+                psF64 *in;
+                psS8 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.F64[row];
+                    out = output->data.S8[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS8) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_C32: {
+                psC32 *in;
+                psS8 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.C32[row];
+                    out = output->data.S8[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS8) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_PTR:
+            psError (__func__, "Can't copy image from a matrix of pointers.");
+            psImageFree (output);
+            return ((void *) 0);
+        default:
+            break;
+        };
+        break;
+    case PS_TYPE_S16:
+        switch (input->type.type) {
+        case PS_TYPE_S8: {
+                psS8 *in;
+                psS16 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S8[row];
+                    out = output->data.S16[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS16) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S16: {
+                psS16 *in;
+                psS16 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S16[row];
+                    out = output->data.S16[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS16) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S32: {
+                psS32 *in;
+                psS16 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S32[row];
+                    out = output->data.S16[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS16) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S64: {
+                psS64 *in;
+                psS16 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S64[row];
+                    out = output->data.S16[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS16) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U8: {
+                psU8 *in;
+                psS16 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U8[row];
+                    out = output->data.S16[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS16) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U16: {
+                psU16 *in;
+                psS16 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U16[row];
+                    out = output->data.S16[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS16) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U32: {
+                psU32 *in;
+                psS16 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U32[row];
+                    out = output->data.S16[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS16) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U64: {
+                psU64 *in;
+                psS16 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U64[row];
+                    out = output->data.S16[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS16) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_F32: {
+                psF32 *in;
+                psS16 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.F32[row];
+                    out = output->data.S16[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS16) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_F64: {
+                psF64 *in;
+                psS16 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.F64[row];
+                    out = output->data.S16[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS16) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_C32: {
+                psC32 *in;
+                psS16 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.C32[row];
+                    out = output->data.S16[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS16) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_PTR:
+            psError (__func__, "Can't copy image from a matrix of pointers.");
+            psImageFree (output);
+            return ((void *) 0);
+        default:
+            break;
+        };
+        break;
+    case PS_TYPE_S32:
+        switch (input->type.type) {
+        case PS_TYPE_S8: {
+                psS8 *in;
+                psS32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S8[row];
+                    out = output->data.S32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S16: {
+                psS16 *in;
+                psS32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S16[row];
+                    out = output->data.S32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S32: {
+                psS32 *in;
+                psS32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S32[row];
+                    out = output->data.S32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S64: {
+                psS64 *in;
+                psS32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S64[row];
+                    out = output->data.S32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U8: {
+                psU8 *in;
+                psS32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U8[row];
+                    out = output->data.S32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U16: {
+                psU16 *in;
+                psS32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U16[row];
+                    out = output->data.S32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U32: {
+                psU32 *in;
+                psS32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U32[row];
+                    out = output->data.S32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U64: {
+                psU64 *in;
+                psS32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U64[row];
+                    out = output->data.S32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_F32: {
+                psF32 *in;
+                psS32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.F32[row];
+                    out = output->data.S32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_F64: {
+                psF64 *in;
+                psS32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.F64[row];
+                    out = output->data.S32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_C32: {
+                psC32 *in;
+                psS32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.C32[row];
+                    out = output->data.S32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_PTR:
+            psError (__func__, "Can't copy image from a matrix of pointers.");
+            psImageFree (output);
+            return ((void *) 0);
+        default:
+            break;
+        };
+        break;
+    case PS_TYPE_S64:
+        switch (input->type.type) {
+        case PS_TYPE_S8: {
+                psS8 *in;
+                psS64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S8[row];
+                    out = output->data.S64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S16: {
+                psS16 *in;
+                psS64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S16[row];
+                    out = output->data.S64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S32: {
+                psS32 *in;
+                psS64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S32[row];
+                    out = output->data.S64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S64: {
+                psS64 *in;
+                psS64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S64[row];
+                    out = output->data.S64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U8: {
+                psU8 *in;
+                psS64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U8[row];
+                    out = output->data.S64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U16: {
+                psU16 *in;
+                psS64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U16[row];
+                    out = output->data.S64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U32: {
+                psU32 *in;
+                psS64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U32[row];
+                    out = output->data.S64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U64: {
+                psU64 *in;
+                psS64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U64[row];
+                    out = output->data.S64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_F32: {
+                psF32 *in;
+                psS64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.F32[row];
+                    out = output->data.S64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_F64: {
+                psF64 *in;
+                psS64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.F64[row];
+                    out = output->data.S64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_C32: {
+                psC32 *in;
+                psS64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.C32[row];
+                    out = output->data.S64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_PTR:
+            psError (__func__, "Can't copy image from a matrix of pointers.");
+            psImageFree (output);
+            return ((void *) 0);
+        default:
+            break;
+        };
+        break;
+    case PS_TYPE_U8:
+        switch (input->type.type) {
+        case PS_TYPE_S8: {
+                psS8 *in;
+                psU8 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S8[row];
+                    out = output->data.U8[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU8) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S16: {
+                psS16 *in;
+                psU8 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S16[row];
+                    out = output->data.U8[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU8) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S32: {
+                psS32 *in;
+                psU8 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S32[row];
+                    out = output->data.U8[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU8) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S64: {
+                psS64 *in;
+                psU8 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S64[row];
+                    out = output->data.U8[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU8) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U8: {
+                psU8 *in;
+                psU8 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U8[row];
+                    out = output->data.U8[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU8) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U16: {
+                psU16 *in;
+                psU8 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U16[row];
+                    out = output->data.U8[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU8) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U32: {
+                psU32 *in;
+                psU8 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U32[row];
+                    out = output->data.U8[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU8) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U64: {
+                psU64 *in;
+                psU8 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U64[row];
+                    out = output->data.U8[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU8) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_F32: {
+                psF32 *in;
+                psU8 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.F32[row];
+                    out = output->data.U8[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU8) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_F64: {
+                psF64 *in;
+                psU8 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.F64[row];
+                    out = output->data.U8[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU8) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_C32: {
+                psC32 *in;
+                psU8 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.C32[row];
+                    out = output->data.U8[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU8) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_PTR:
+            psError (__func__, "Can't copy image from a matrix of pointers.");
+            psImageFree (output);
+            return ((void *) 0);
+        default:
+            break;
+        };
+        break;
+    case PS_TYPE_U16:
+        switch (input->type.type) {
+        case PS_TYPE_S8: {
+                psS8 *in;
+                psU16 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S8[row];
+                    out = output->data.U16[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU16) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S16: {
+                psS16 *in;
+                psU16 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S16[row];
+                    out = output->data.U16[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU16) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S32: {
+                psS32 *in;
+                psU16 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S32[row];
+                    out = output->data.U16[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU16) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S64: {
+                psS64 *in;
+                psU16 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S64[row];
+                    out = output->data.U16[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU16) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U8: {
+                psU8 *in;
+                psU16 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U8[row];
+                    out = output->data.U16[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU16) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U16: {
+                psU16 *in;
+                psU16 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U16[row];
+                    out = output->data.U16[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU16) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U32: {
+                psU32 *in;
+                psU16 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U32[row];
+                    out = output->data.U16[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU16) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U64: {
+                psU64 *in;
+                psU16 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U64[row];
+                    out = output->data.U16[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU16) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_F32: {
+                psF32 *in;
+                psU16 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.F32[row];
+                    out = output->data.U16[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU16) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_F64: {
+                psF64 *in;
+                psU16 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.F64[row];
+                    out = output->data.U16[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU16) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_C32: {
+                psC32 *in;
+                psU16 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.C32[row];
+                    out = output->data.U16[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU16) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_PTR:
+            psError (__func__, "Can't copy image from a matrix of pointers.");
+            psImageFree (output);
+            return ((void *) 0);
+        default:
+            break;
+        };
+        break;
+    case PS_TYPE_U32:
+        switch (input->type.type) {
+        case PS_TYPE_S8: {
+                psS8 *in;
+                psU32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S8[row];
+                    out = output->data.U32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S16: {
+                psS16 *in;
+                psU32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S16[row];
+                    out = output->data.U32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S32: {
+                psS32 *in;
+                psU32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S32[row];
+                    out = output->data.U32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S64: {
+                psS64 *in;
+                psU32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S64[row];
+                    out = output->data.U32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U8: {
+                psU8 *in;
+                psU32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U8[row];
+                    out = output->data.U32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U16: {
+                psU16 *in;
+                psU32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U16[row];
+                    out = output->data.U32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U32: {
+                psU32 *in;
+                psU32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U32[row];
+                    out = output->data.U32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U64: {
+                psU64 *in;
+                psU32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U64[row];
+                    out = output->data.U32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_F32: {
+                psF32 *in;
+                psU32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.F32[row];
+                    out = output->data.U32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_F64: {
+                psF64 *in;
+                psU32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.F64[row];
+                    out = output->data.U32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_C32: {
+                psC32 *in;
+                psU32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.C32[row];
+                    out = output->data.U32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_PTR:
+            psError (__func__, "Can't copy image from a matrix of pointers.");
+            psImageFree (output);
+            return ((void *) 0);
+        default:
+            break;
+        };
+        break;
+    case PS_TYPE_U64:
+        switch (input->type.type) {
+        case PS_TYPE_S8: {
+                psS8 *in;
+                psU64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S8[row];
+                    out = output->data.U64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S16: {
+                psS16 *in;
+                psU64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S16[row];
+                    out = output->data.U64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S32: {
+                psS32 *in;
+                psU64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S32[row];
+                    out = output->data.U64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S64: {
+                psS64 *in;
+                psU64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S64[row];
+                    out = output->data.U64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U8: {
+                psU8 *in;
+                psU64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U8[row];
+                    out = output->data.U64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U16: {
+                psU16 *in;
+                psU64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U16[row];
+                    out = output->data.U64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U32: {
+                psU32 *in;
+                psU64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U32[row];
+                    out = output->data.U64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U64: {
+                psU64 *in;
+                psU64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U64[row];
+                    out = output->data.U64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_F32: {
+                psF32 *in;
+                psU64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.F32[row];
+                    out = output->data.U64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_F64: {
+                psF64 *in;
+                psU64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.F64[row];
+                    out = output->data.U64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_C32: {
+                psC32 *in;
+                psU64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.C32[row];
+                    out = output->data.U64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_PTR:
+            psError (__func__, "Can't copy image from a matrix of pointers.");
+            psImageFree (output);
+            return ((void *) 0);
+        default:
+            break;
+        };
+        break;
+    case PS_TYPE_F32:
+        switch (input->type.type) {
+        case PS_TYPE_S8: {
+                psS8 *in;
+                psF32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S8[row];
+                    out = output->data.F32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psF32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S16: {
+                psS16 *in;
+                psF32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S16[row];
+                    out = output->data.F32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psF32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S32: {
+                psS32 *in;
+                psF32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S32[row];
+                    out = output->data.F32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psF32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S64: {
+                psS64 *in;
+                psF32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S64[row];
+                    out = output->data.F32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psF32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U8: {
+                psU8 *in;
+                psF32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U8[row];
+                    out = output->data.F32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psF32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U16: {
+                psU16 *in;
+                psF32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U16[row];
+                    out = output->data.F32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psF32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U32: {
+                psU32 *in;
+                psF32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U32[row];
+                    out = output->data.F32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psF32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U64: {
+                psU64 *in;
+                psF32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U64[row];
+                    out = output->data.F32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psF32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_F32: {
+                psF32 *in;
+                psF32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.F32[row];
+                    out = output->data.F32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psF32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_F64: {
+                psF64 *in;
+                psF32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.F64[row];
+                    out = output->data.F32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psF32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_C32: {
+                psC32 *in;
+                psF32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.C32[row];
+                    out = output->data.F32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psF32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_PTR:
+            psError (__func__, "Can't copy image from a matrix of pointers.");
+            psImageFree (output);
+            return ((void *) 0);
+        default:
+            break;
+        };
+        break;
+    case PS_TYPE_F64:
+        switch (input->type.type) {
+        case PS_TYPE_S8: {
+                psS8 *in;
+                psF64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S8[row];
+                    out = output->data.F64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psF64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S16: {
+                psS16 *in;
+                psF64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S16[row];
+                    out = output->data.F64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psF64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S32: {
+                psS32 *in;
+                psF64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S32[row];
+                    out = output->data.F64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psF64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S64: {
+                psS64 *in;
+                psF64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S64[row];
+                    out = output->data.F64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psF64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U8: {
+                psU8 *in;
+                psF64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U8[row];
+                    out = output->data.F64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psF64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U16: {
+                psU16 *in;
+                psF64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U16[row];
+                    out = output->data.F64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psF64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U32: {
+                psU32 *in;
+                psF64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U32[row];
+                    out = output->data.F64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psF64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U64: {
+                psU64 *in;
+                psF64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U64[row];
+                    out = output->data.F64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psF64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_F32: {
+                psF32 *in;
+                psF64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.F32[row];
+                    out = output->data.F64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psF64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_F64: {
+                psF64 *in;
+                psF64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.F64[row];
+                    out = output->data.F64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psF64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_C32: {
+                psC32 *in;
+                psF64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.C32[row];
+                    out = output->data.F64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psF64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_PTR:
+            psError (__func__, "Can't copy image from a matrix of pointers.");
+            psImageFree (output);
+            return ((void *) 0);
+        default:
+            break;
+        };
+        break;
+    case PS_TYPE_C32:
+        switch (input->type.type) {
+        case PS_TYPE_S8: {
+                psS8 *in;
+                psC32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S8[row];
+                    out = output->data.C32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psC32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S16: {
+                psS16 *in;
+                psC32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S16[row];
+                    out = output->data.C32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psC32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S32: {
+                psS32 *in;
+                psC32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S32[row];
+                    out = output->data.C32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psC32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S64: {
+                psS64 *in;
+                psC32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S64[row];
+                    out = output->data.C32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psC32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U8: {
+                psU8 *in;
+                psC32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U8[row];
+                    out = output->data.C32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psC32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U16: {
+                psU16 *in;
+                psC32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U16[row];
+                    out = output->data.C32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psC32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U32: {
+                psU32 *in;
+                psC32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U32[row];
+                    out = output->data.C32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psC32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U64: {
+                psU64 *in;
+                psC32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U64[row];
+                    out = output->data.C32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psC32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_F32: {
+                psF32 *in;
+                psC32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.F32[row];
+                    out = output->data.C32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psC32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_F64: {
+                psF64 *in;
+                psC32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.F64[row];
+                    out = output->data.C32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psC32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_C32: {
+                psC32 *in;
+                psC32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.C32[row];
+                    out = output->data.C32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psC32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_PTR:
+            psError (__func__, "Can't copy image from a matrix of pointers.");
+            psImageFree (output);
+            return ((void *) 0);
+        default:
+            break;
+        };
+        break;
+    case PS_TYPE_C64:
+        switch (input->type.type) {
+        case PS_TYPE_S8: {
+                psS8 *in;
+                psC64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S8[row];
+                    out = output->data.C64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psC64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S16: {
+                psS16 *in;
+                psC64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S16[row];
+                    out = output->data.C64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psC64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S32: {
+                psS32 *in;
+                psC64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S32[row];
+                    out = output->data.C64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psC64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S64: {
+                psS64 *in;
+                psC64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S64[row];
+                    out = output->data.C64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psC64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U8: {
+                psU8 *in;
+                psC64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U8[row];
+                    out = output->data.C64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psC64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U16: {
+                psU16 *in;
+                psC64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U16[row];
+                    out = output->data.C64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psC64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U32: {
+                psU32 *in;
+                psC64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U32[row];
+                    out = output->data.C64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psC64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U64: {
+                psU64 *in;
+                psC64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U64[row];
+                    out = output->data.C64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psC64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_F32: {
+                psF32 *in;
+                psC64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.F32[row];
+                    out = output->data.C64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psC64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_F64: {
+                psF64 *in;
+                psC64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.F64[row];
+                    out = output->data.C64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psC64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_C32: {
+                psC32 *in;
+                psC64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.C32[row];
+                    out = output->data.C64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psC64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_PTR:
+            psError (__func__, "Can't copy image from a matrix of pointers.");
+            psImageFree (output);
+            return ((void *) 0);
+        default:
+            break;
+        };
+        break;
+    case PS_TYPE_PTR:
+        psError (__func__, "Can't copy image into a matrix of pointers.");
+        psImageFree (output);
+        return ((void *) 0);
+    }
+
+    return output;
+}
+
+int psImageClip(psImage* input,float min,float vmin,float max,float vmax)
+{
+    int numClipped = 0;
+    unsigned int numRows;
+    unsigned int numCols;
+
+    if (input == NULL) {
+        return 0;
+    }
+
+    if (max < min) {
+        psError(__func__,"psImageClip can not be invoked with max < min.");
+        return 0;
+    }
+
+    numRows = input->numRows;
+    numCols = input->numCols;
+
+    switch (input->type.type) {
+
+        #define psImageClipCase(type)\
+    case PS_TYPE_##type: { \
+            ps##type minimum = (ps##type) min; \
+            ps##type maximum = (ps##type) max; \
+            for (unsigned int row = 0;row<numRows;row++) { \
+                ps##type* inputRow = input->data.type[row]; \
+                for (unsigned int col = 0; col < numCols; col++) { \
+                    if (inputRow[col] < minimum) { \
+                        inputRow[col] = (ps##type)vmin; \
+                        numClipped++; \
+                    } else if (inputRow[col] > maximum) { \
+                        inputRow[col] = (ps##type)vmax; \
+                        numClipped++; \
+                    } \
+                } \
+            } \
+        } \
+        break;
+        #define psImageClipCaseComplex(type)\
+    case PS_TYPE_##type: { \
+            for (unsigned int row = 0;row<numRows;row++) { \
+                ps##type* inputRow = input->data.type[row]; \
+                for (unsigned int col = 0; col < numCols; col++) { \
+                    if (cabsf(inputRow[col]) < min) { \
+                        inputRow[col] = (ps##type)vmin; \
+                        numClipped++; \
+                    } else if (cabsf(inputRow[col]) > max) { \
+                        inputRow[col] = (ps##type)vmax; \
+                        numClipped++; \
+                    } \
+                } \
+            } \
+        } \
+        break;
+
+        psImageClipCase(S8)
+        psImageClipCase(S16)
+        psImageClipCase(S32)
+        psImageClipCase(S64)
+        psImageClipCase(U8)
+        psImageClipCase(U16)
+        psImageClipCase(U32)
+        psImageClipCase(U64)
+        psImageClipCase(F32)
+        psImageClipCase(F64)
+        psImageClipCaseComplex(C32)
+        psImageClipCaseComplex(C64)
+
+    default:
+        psError(__func__,"psImageClip does not support the given datatype (%d)",
+                input->type.type);
+    }
+
+    return numClipped;
+}
+
+int psImageClipNaN(psImage* input,float value)
+{
+    int numClipped = 0;
+    unsigned int numRows;
+    unsigned int numCols;
+
+    if (input == NULL) {
+        return 0;
+    }
+    numRows = input->numRows;
+    numCols = input->numCols;
+
+    switch (input->type.type) {
+
+        #define psImageClipNaNCase(type) \
+    case PS_TYPE_##type: \
+        for (unsigned int row = 0;row<numRows;row++) { \
+            ps##type* inputRow = input->data.type[row]; \
+            for (unsigned int col = 0; col < numCols; col++) { \
+                if (! isfinite(inputRow[col])) { \
+                    inputRow[col] = (ps##type)value; \
+                    numClipped++; \
+                } \
+            } \
+        } \
+        break;
+
+        psImageClipNaNCase(F32)
+        psImageClipNaNCase(F64)
+        psImageClipNaNCase(C32)
+        psImageClipNaNCase(C64)
+
+    default:
+        psError(__func__,"psImageClip does not support the given datatype (%d)",
+                input->type.type);
+    }
+
+    return numClipped;
+}
+
+int psImageOverlaySection(psImage* image, const psImage* overlay, int col0,
+                          int row0, const char* op)
+{
+    unsigned int imageNumRows;
+    unsigned int imageNumCols;
+    unsigned int overlayNumRows;
+    unsigned int overlayNumCols;
+    unsigned int imageRowLimit;
+    unsigned int imageColLimit;
+    psElemType  type;
+
+    if (image == NULL || overlay == NULL) {
+        psError(__func__,"one of the input images was NULL.");
+        return 1;
+    }
+
+    if (op == NULL) {
+        psError(__func__,"Operation can not be NULL.");
+        return 1;
+    }
+
+    type = image->type.type;
+
+    if (type != overlay->type.type) {
+        psError(__func__,"Image and overlay datatypes must match. (%d vs %d)",
+                type,overlay->type.type);
+        return 2;
+    }
+
+    imageNumRows = image->numRows;
+    imageNumCols = image->numCols;
+    overlayNumRows = overlay->numRows;
+    overlayNumCols = overlay->numCols;
+
+    /* check row0/col0 to see if it is within the image size */
+    if (row0 < 0 || col0 < 0 || row0 >= imageNumRows || col0 >= imageNumCols) {
+        psError(__func__, "Overlay origin of (%d,%d) is outside of the image dimensions (%d x %d).",
+                col0, row0, imageNumCols, imageNumRows);
+        return 3;
+    }
+
+    /* check if overlay is totally withing input image */
+    imageRowLimit = row0+overlayNumRows;
+    imageColLimit = col0+overlayNumCols;
+    if (imageRowLimit > imageNumRows || imageColLimit > imageNumCols) {
+        psError(__func__, "Overlay image (%d,%d -> %d,%d) is partially outside"
+                " of the input image (%d x %d).",
+                col0, row0, col0+overlayNumCols-1, row0+overlayNumRows-1,
+                imageNumCols,imageNumRows);
+        return 4;
+    }
+
+    switch (type) {
+
+        #define psImageOverlayCase(DATATYPE) \
+    case PS_TYPE_##DATATYPE: \
+        for (unsigned int row=row0;row<imageRowLimit;row++) { \
+            ps##DATATYPE* imageRow = image->data.DATATYPE[row]; \
+            ps##DATATYPE* overlayRow = overlay->data.DATATYPE[row-row0]; \
+            for (unsigned int col=col0;col<imageColLimit;col++) { \
+                switch (*op) { \
+                case '+': \
+                    imageRow[col] += overlayRow[col-col0]; \
+                    break; \
+                case '-': \
+                    imageRow[col] -= overlayRow[col-col0]; \
+                    break; \
+                case '*': \
+                    imageRow[col] *= overlayRow[col-col0]; \
+                    break; \
+                case '/': \
+                    imageRow[col] /= overlayRow[col-col0]; \
+                    break; \
+                case '=': \
+                    imageRow[col] = overlayRow[col-col0]; \
+                    break; \
+                default: \
+                    psError(__func__,"Unknown operation %s",op); \
+                    return 5; \
+                } \
+            } \
+        } \
+        break;
+
+        psImageOverlayCase(U8);
+        psImageOverlayCase(U16);
+        psImageOverlayCase(U32);
+        psImageOverlayCase(U64);
+        psImageOverlayCase(S8);
+        psImageOverlayCase(S16);
+        psImageOverlayCase(S32);
+        psImageOverlayCase(S64);
+        psImageOverlayCase(F32);
+        psImageOverlayCase(F64);
+        psImageOverlayCase(C32);
+        psImageOverlayCase(C64);
+
+    default:
+        psError(__func__,"Can not operate on type %d.",type);
+    }
+
+    #endif
+
+    return 0;
+}
Index: /tags/rel1_1/psLib/src/image/psImage.d
===================================================================
--- /tags/rel1_1/psLib/src/image/psImage.d	(revision 1056)
+++ /tags/rel1_1/psLib/src/image/psImage.d	(revision 1056)
@@ -0,0 +1,2 @@
+psImage.o psImage.d : psImage.c ../sysUtils/psMemory.h ../sysUtils/psError.h \
+  psImage.h psType.h
Index: /tags/rel1_1/psLib/src/image/psImage.h
===================================================================
--- /tags/rel1_1/psLib/src/image/psImage.h	(revision 1056)
+++ /tags/rel1_1/psLib/src/image/psImage.h	(revision 1056)
@@ -0,0 +1,198 @@
+/** @file  psImage.h
+ *
+ *  @brief Contains basic image definitions and operations
+ *
+ *  This file defines the basic type for an image struct and functions useful
+ *  in manupulating images.
+ *
+ *  @ingroup Image
+ *
+ *  @author Robert DeSonia, MHPCC
+ *  @author Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.21 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-10 01:58:06 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+# ifndef PS_IMAGE_H
+# define PS_IMAGE_H
+
+#include <complex.h>
+
+#include "psType.h"
+
+/// @addtogroup Image
+/// @{
+
+/** Basic image data structure.
+ *
+ * Struct for maintaining image data of varying types. It also contains
+ * information about image size, parent images and children images.
+ *
+ */
+typedef struct psImage
+{
+    const psType type;                  ///< Image data type and dimension.
+    const unsigned int numCols;         ///< Number of columns in image
+    const unsigned int numRows;         ///< Number of rows in image.
+    const int col0;                     ///< Column position relative to parent.
+    const int row0;                     ///< Row position relative to parent.
+
+    union {
+        psU8    **U8;                   ///< Unsigned 8-bit integer data.
+        psU16   **U16;                  ///< Unsigned 16-bit integer data.
+        psU32   **U32;                  ///< Unsigned 32-bit integer data.
+        psU64   **U64;                  ///< Unsigned 64-bit integer data.
+        psS8    **S8;                   ///< Signed 8-bit integer data.
+        psS16   **S16;                  ///< Signed 16-bit integer data.
+        psS32   **S32;                  ///< Signed 32-bit integer data.
+        psS64   **S64;                  ///< Signed 64-bit integer data.
+        psF32   **F32;                  ///< Single-precision float data.
+        psF64   **F64;                  ///< Double-precision float data.
+        psC32   **C32;                  ///< Single-precision complex data.
+        psC64   **C64;                  ///< Double-precision complex data.
+        psPTR   **PTR;                  ///< Void pointers.
+        psPTR    *V;                    ///< Pointer to data.
+    } data;                             ///< Union for data types.
+    const struct psImage *parent;       ///< Parent, if a subimage.
+    int nChildren;                      ///< Number of subimages.
+    struct psImage** children;          ///< Children of this region.
+}
+psImage;
+
+/*****************************************************************************/
+/* FUNCTION PROTOTYPES                                                       */
+/*****************************************************************************/
+
+
+/** Create an image of the specified size and type.
+ *
+ * Uses psLib memory allocation functions to create an image struct of the
+ * specified size and type.
+ *
+ * @return psImage*: Pointer to psImage.
+ *
+ */
+psImage *psImageAlloc(
+    unsigned int numCols,               ///< Number of rows in image.
+    unsigned int numRows,               ///< Number of columns in image.
+    const psElemType type               ///< Type of data for image.
+);
+
+/** Resize a given image to the given size/type.
+ *
+ *  @return psImage* Resized psImage.
+ *
+ */
+psImage* psImageRecycle(
+    psImage* old,                       ///< the psImage to recycle by resizing image buffer
+    unsigned int numCols,               ///< the desired number of columns in image
+    unsigned int numRows,               ///< the desired number of rows in image
+    const psElemType type               ///< the desired datatype of the image
+);
+
+/** Create a subimage of the specified area.
+ *
+ * Uses psLib memory allocation functions to create an image based on a larger
+ * one.
+ *
+ * @return psImage*: Pointer to psImage.
+ *
+ */
+psImage *psImageSubset(
+    psImage *out,                       ///< Subimage to return, or NULL.
+    psImage *image,                     ///< Parent image.
+    unsigned int numCols,               ///< Subimage width (<= image.nCols - col0).
+    unsigned int numRows,               ///< Subimage height (<= image.nRows - row0).
+    unsigned int col0,                  ///< Subimage col-offset (0 <= col0 < nCol).
+    unsigned int row0                   ///< Subimage row-offset (0 <= row0 < nCol).
+);
+
+/** Destroy the specified image.
+ *
+ *  Uses psLib memory deallocation functions to free an image and any existing
+ *  children.
+ *
+ */
+void psImageFree(
+    psImage *restrict image             ///< Free psImage
+);
+
+/** Frees all children of a psImage.
+ *
+ *  @return int      Number of children freed.
+ *
+ */
+int psImageFreeChildren(
+    psImage* image
+    /**< psImage in which all children shall be deallocated */
+);
+
+/** Makes a copy of a psImage
+ *
+ * @return psImage*  Copy of the input psImage.  This may not be equal to the
+ * output parameter
+ *
+ */
+psImage *psImageCopy(
+    psImage* restrict output,
+    /**< if not NULL, a psImage that could be recycled.  If it can not be used,
+     *   it will be freed via psImageFree
+     */
+    const psImage *input,
+    /**< the psImage to copy */
+    psElemType type
+    /**< the desired datatype of the returned copy */
+);
+
+/** Clip image values outside of tange to given values
+ *
+ *  All pixels with values less than min are set to the value vmin.  all pixels
+ *  with values greater than max are set to the value vmax. This function is
+ *  defined for psU8, psU16, psS8, psS16, psF32, psF64, psC32, and psC64.
+ *
+ *  @return int     The number of clipped pixels
+ */
+int psImageClip(
+    psImage* input,                 ///< the image to clip
+    psF32 min,                      ///< the minimum image value allowed
+    psF32 vmin,                     ///< the value pixels < min are set to
+    psF32 max,                      ///< the maximum image value allowed
+    psF32 vmax                      ///< the value pixels > max are set to
+);
+
+/** Clip NaN image pixels to given value.
+ *
+ *  Pixels with NaN, +Inf, or -Inf values are set to the specified value. This
+ *  function is defined for psF32, psF64, psC32, and psC64.
+ *
+ *  @return int     The number of clipped pixels
+ */
+int psImageClipNaN(
+    psImage* input,                 ///< the image to clip
+    psF32 value                     ///< the value to set all NaN/Inf values to
+);
+
+/** Overlay subregion of image with another image
+ *
+ *  Replace the pixels in the image which correspond to the pixels in OVERLAY
+ *  with values derived from the IMAGE and OVERLAY based on the given operator
+ *  OP.  Valid operators are "=" (set image value to OVERLAY value), "+" (add
+ *  OVERLAY value to image value), "-" (subtract OVERLAY from image), "*"
+ *  (multiply OVERLAY times image), "/" (divide image by OVERLAY).  This
+ *  function is defined for psU8, psS8, psS16, psF32, psF64, psC32, and psC64.
+ *
+ *  @return int         0 if success, non-zero if failed.
+ */
+int psImageOverlaySection(
+    psImage* image,                 ///< target image
+    const psImage* overlay,         ///< the overlay image
+    int col0,                       ///< the column to start overlay
+    int row0,                       ///< the row to start overlay
+    const char* op                  ///< the operation to perform for overlay
+);
+
+/// @}
+
+#endif
Index: /tags/rel1_1/psLib/src/image/psImageIO.c
===================================================================
--- /tags/rel1_1/psLib/src/image/psImageIO.c	(revision 1056)
+++ /tags/rel1_1/psLib/src/image/psImageIO.c	(revision 1056)
@@ -0,0 +1,381 @@
+/** @file  psImageIO.c
+ *
+ *  @brief Contains image I/O routines.
+ *
+ *  This file defines the file input/output functions for the psImage structure.
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.3 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-11 03:45:07 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include <fitsio.h>
+#include <unistd.h>
+#include <stdbool.h>
+
+#include "psImageIO.h"
+#include "psError.h"
+
+psImage* psImageReadSection(psImage* output, int col, int row, int numCols,
+                            int numRows, int z, char* extname, int extnum, char* filename)
+{
+    fitsfile    *fptr=NULL;                 /*Pointer to the FITS file*/
+    int         status=0;                   /*CFITSIO file vars*/
+    int         nAxis=0;
+    int         anynull=0;
+    int         bitPix=0;                   /*Pixel type*/
+    long        nAxes[3];
+    long        firstPixel[3];              /* lower-left corner of image subset */
+    long        lastPixel[3];               /* upper-right corner of image subset */
+    long        increment[3];               /* increment for image subset */
+    char        fitsErr[80] = "";           /*CFITSIO error message string */
+    int         hduType = IMAGE_HDU;
+    int         fitsDatatype = 0;
+    int         datatype = 0;
+
+    if (filename == NULL) {
+        psError(__func__,"Must specify filename; it can not be NULL.");
+        psImageFree(output);
+        return NULL;
+    }
+
+    /* Open the FITS file */
+    (void)fits_open_file(&fptr, filename, READONLY, &status);
+    if (fptr == NULL || status != 0) {
+        fits_get_errstatus(status,fitsErr);
+        psError(__func__,"Could not open file '%s'. (%s)",
+                filename, fitsErr);
+        psImageFree(output);
+        return NULL;
+    }
+
+    /* find the specified extension */
+    if (extname != NULL) {
+        if (fits_movnam_hdu(fptr, hduType, extname, 0,&status) != 0) {
+            fits_get_errstatus(status, fitsErr);
+            status = 0;
+            (void)fits_close_file(fptr, &status);
+            psError(__func__,"Could not index to '%s' HDU for file %s. (%s)",
+                    extname, filename, fitsErr);
+            psImageFree(output);
+            return NULL;
+        }
+    } else {
+        if (fits_movabs_hdu(fptr, extnum+1, &hduType, &status) != 0) {
+            fits_get_errstatus(status, fitsErr);
+            status = 0;
+            (void)fits_close_file(fptr, &status);
+            psError(__func__,"Could not index to HDU #%d for file %s. (%s)",
+                    extnum, filename, fitsErr);
+            psImageFree(output);
+            return NULL;
+        }
+    }
+
+    /* Get the data type 'bitPix' from the FITS image */
+    if (fits_get_img_equivtype(fptr, &bitPix, &status) != 0) {
+        fits_get_errstatus(status, fitsErr);
+        status = 0;
+        (void)fits_close_file(fptr, &status);
+        psError("Could not determine image data type of '%s'. (%s)",
+                filename, fitsErr);
+        psImageFree(output);
+        return NULL;
+    }
+
+    /* Get the dimensions 'nAxis' from the FITS image */
+    if (fits_get_img_dim(fptr, &nAxis, &status) != 0) {
+        (void)fits_get_errstatus(status, fitsErr);
+        status = 0;
+        (void)fits_close_file(fptr, &status);
+        psError("Could not determine dimensions of '%s'. (%s)",
+                filename,fitsErr);
+        psImageFree(output);
+        return NULL;
+    }
+
+    /* Validate the number of axis */
+    if ( (nAxis < 2) || (nAxis > 3) ) {
+        status=0;
+        (void)fits_close_file(fptr, &status);
+        psError("Dimensions of '%s' are not supported (NAXIS=%i).",
+                filename, nAxis);
+        psImageFree(output);
+        return NULL;
+    }
+
+    /* Get the Image size from the FITS file  */
+    if ( fits_get_img_size(fptr, nAxis, nAxes, &status) != 0) {
+        (void)fits_get_errstatus(status, fitsErr);
+        status = 0;
+        (void)fits_close_file(fptr, &status);
+        psError("Could not determine image size of '%s'. (%s)",
+                filename,fitsErr);
+        psImageFree(output);
+        return NULL;
+    }
+
+    if (numCols < 1) {
+        numCols += nAxes[0];
+    }
+    if (numRows < 1) {
+        numRows += nAxes[1];
+    }
+
+    firstPixel[0] = col+1;
+    firstPixel[1] = row+1;
+    firstPixel[2] = z+1;
+
+    lastPixel[0] = firstPixel[0] + numCols - 1;
+    lastPixel[1] = firstPixel[1] + numRows - 1;
+    lastPixel[2] = z+1;
+
+    increment[0] = 1;
+    increment[1] = 1;
+    increment[2] = 1;
+
+    // turn off the BSCALE/BZERO processing in CFITSIO
+    // (void)fits_set_bscale(fptr, 1.0,0.0,&status);
+
+    switch (bitPix) {
+    case BYTE_IMG:
+        datatype = PS_TYPE_U8;
+        fitsDatatype = TBYTE;
+        break;
+    case SBYTE_IMG:
+        datatype = PS_TYPE_S8;
+        fitsDatatype = TSBYTE;
+        break;
+    case USHORT_IMG:
+        datatype = PS_TYPE_U16;
+        fitsDatatype = TUSHORT;
+        break;
+    case SHORT_IMG:
+        datatype = PS_TYPE_S16;
+        fitsDatatype = TSHORT;
+        break;
+    case ULONG_IMG:
+        datatype = PS_TYPE_U32;
+        fitsDatatype = TUINT;
+        break;
+    case LONG_IMG:
+        datatype = PS_TYPE_S32;
+        fitsDatatype = TINT;
+        break;
+    case LONGLONG_IMG:
+        datatype = PS_TYPE_S64;
+        fitsDatatype = TLONGLONG;
+        break;
+    case FLOAT_IMG:
+        datatype = PS_TYPE_F32;
+        fitsDatatype = TFLOAT;
+        break;
+    case DOUBLE_IMG:
+        datatype = PS_TYPE_F64;
+        fitsDatatype = TDOUBLE;
+        break;
+    default:
+        psError(__func__,"Unsupported bitpix value (%d) in FITS file %s.",
+                bitPix,filename);
+        psImageFree(output);
+        return NULL;
+    }
+    output = psImageRecycle(output,numCols,numRows,datatype);
+    if (fits_read_subset(fptr, fitsDatatype, firstPixel, lastPixel, increment,
+                         NULL, output->data.V[0], &anynull, &status) != 0) {
+        psImageFree(output);
+        (void)fits_get_errstatus(status, fitsErr);
+        status = 0;
+        (void)fits_close_file(fptr, &status);
+        psError(__func__,"Failed to read image [%s]",
+                filename, fitsErr);
+        return NULL;
+    }
+
+    (void)fits_close_file(fptr, &status);
+
+    return output;
+}
+
+
+int psImageWriteSection(psImage* input, int col0,int row0,int z,
+                        char* extname, int extnum, char* filename)
+{
+    int         numCols = 0;
+    int         numRows = 0;
+
+    int         status=0;               /* CFITSIO  status */
+    fitsfile    *fptr=NULL;             /* pointer to the FITS file */
+    long        nAxes[3];               /* Image axis vars */
+    long        firstPixel[3];          /* First Pixel to read */
+    long        lastPixel[3];           /* Last Pixel to read */
+    char        fitsErr[80];            /* FITSIO message string */
+    int         datatype = 0;           /* the datatype of the image */
+    int         bitPix = 0;             /* FITS bitPix value */
+    int         hduType = IMAGE_HDU;    /* the HDU type (image,table, etc.) */
+    double      bscale = 1.0;
+    double      bzero = 0.0;
+    bool        createNewHDU = false;
+
+    /* need a valid image to write */
+    if(input==NULL) {
+        psError(__func__, "Can not write %s.  Input psImage is NULL.",
+                filename);
+        return 1;
+    }
+
+    numRows = input->numRows;
+    numCols = input->numCols;
+
+    switch (input->type.type) {
+    case PS_TYPE_U8:
+        bitPix = BYTE_IMG;
+        datatype = TBYTE;
+        break;
+    case PS_TYPE_S8:
+        bitPix = BYTE_IMG;
+        bzero = INT8_MIN;
+        datatype = TSBYTE;
+        break;
+    case PS_TYPE_U16:
+        bitPix = SHORT_IMG;
+        bzero = -1.0f*INT16_MIN;
+        datatype = TUSHORT;
+        break;
+    case PS_TYPE_S16:
+        bitPix = SHORT_IMG;
+        datatype = TSHORT;
+        break;
+    case PS_TYPE_U32:
+        bitPix = LONG_IMG;
+        bzero = -1.0f*INT32_MIN;
+        datatype = TUINT;
+        break;
+    case PS_TYPE_S32:
+        bitPix = LONG_IMG;
+        datatype = TINT;
+        break;
+    case PS_TYPE_F32:
+        bitPix = FLOAT_IMG;
+        datatype = TFLOAT;
+        break;
+    case PS_TYPE_F64:
+        bitPix = DOUBLE_IMG;
+        datatype = TDOUBLE;
+        break;
+    default:
+        psError(__func__, "psImage datatype (%d) not supported.  File %s not written.",
+                input->type.type,filename);
+        return 1;
+    }
+
+    /* Open the FITS file */
+    if (access(filename, F_OK) == 0) { // file exists
+        (void)fits_open_file(&fptr, filename, READWRITE, &status);
+        if (fptr == NULL || status != 0) {
+            fits_get_errstatus(status,fitsErr);
+            psError(__func__,"Could not open file '%s'. FITS error:%s",
+                    filename, fitsErr);
+            return 2;
+        }
+
+        /* find the specified extension */
+        if (extname != NULL) {
+            if (fits_movnam_hdu(fptr, hduType, extname, 0,&status) != 0) {
+                fits_get_errstatus(status, fitsErr);
+                status = 0;
+                (void)fits_close_file(fptr, &status);
+                psError(__func__,"Could not index to '%s' HDU for file %s. (%s)",
+                        extname, filename, fitsErr);
+                return 3;
+            }
+        } else {
+            int numHDUs = 0;
+            fits_get_num_hdus(fptr,&numHDUs,&status);
+            if (numHDUs < extnum) {
+                status = 0;
+                (void)fits_close_file(fptr, &status);
+                psError(__func__,"extnum (%d) must not exceed number of HDUs (%d) by more than one.",
+                        extnum, numHDUs);
+                return 3;
+            } else if (numHDUs == extnum) {
+                createNewHDU = true;
+            } else if (fits_movabs_hdu(fptr, extnum+1, &hduType, &status) != 0) {
+                fits_get_errstatus(status, fitsErr);
+                status = 0;
+                (void)fits_close_file(fptr, &status);
+                psError(__func__,"Could not index to HDU #%d for file %s. (%s)",
+                        extnum, filename, fitsErr);
+                return 3;
+            }
+        }
+
+    } else { // file does not exist
+
+        (void)fits_create_file(&fptr,filename,&status);
+        if (fptr == NULL || status != 0) {
+            fits_get_errstatus(status,fitsErr);
+            psError(__func__,"Could not create file '%s'. (%s)",
+                    filename, fitsErr);
+            return 5;
+        }
+        createNewHDU = true;
+    }
+
+    if (createNewHDU) {
+        /*  create the mandatory image keywords */
+        nAxes[0] = col0+numCols;
+        nAxes[1] = row0+numRows;
+        nAxes[2] = z+1;
+        if (fits_create_img(fptr, bitPix, 3, nAxes, &status) != 0) {
+            (void)fits_get_errstatus(status, fitsErr);
+            status = 0;
+            (void)fits_close_file(fptr, &status);
+            psError(__func__,"Could not create image HDU in FITS file '%s'. %s",
+                    filename, fitsErr);
+            return 5;
+        }
+
+        // set the bscale/bzero
+        fits_write_key_dbl(fptr, "BZERO",bzero,12,"Pixel Value Offset",&status);
+        fits_write_key_dbl(fptr, "BSCALE",bscale,12,"Pixel Value Scale",&status);
+        fits_set_bscale(fptr,bscale,bzero,&status);
+
+        if (extname != NULL) {
+            /* create the extension for the Primary HDU */
+            if (fits_write_key_str(fptr, "EXTNAME", extname, "Extension Name", &status) != 0) {
+                (void)fits_get_errstatus(status, fitsErr);
+                status = 0;
+                (void)fits_close_file(fptr, &status);
+                psError(__func__,"Could not create EXTNAME keyword in FITS file '%s'. (%s)",
+                        filename, fitsErr);
+                return 5;
+            }
+        }
+    }
+
+    firstPixel[0] = col0+1;
+    firstPixel[1] = row0+1;
+    firstPixel[2] = z+1;
+
+    lastPixel[0] = firstPixel[0] + numCols - 1;
+    lastPixel[1] = firstPixel[1] + numRows - 1;
+    lastPixel[2] = z+1;
+
+    if ( fits_write_subset(fptr, datatype, firstPixel, lastPixel, input->data.V[0], &status) != 0) {
+        (void)fits_get_errstatus(status, fitsErr);
+        status = 0;
+        (void)fits_close_file(fptr, &status);
+        psError(__func__, "Could not write image data to '%s'. (%s)",
+                filename, fitsErr);
+        return 6;
+    }
+
+    status = 0;
+    (void)fits_close_file(fptr, &status);
+
+    return 0;
+}
Index: /tags/rel1_1/psLib/src/image/psImageIO.d
===================================================================
--- /tags/rel1_1/psLib/src/image/psImageIO.d	(revision 1056)
+++ /tags/rel1_1/psLib/src/image/psImageIO.d	(revision 1056)
@@ -0,0 +1,2 @@
+psImageIO.o psImageIO.d : psImageIO.c psImageIO.h ../collections/psImage.h \
+  ../collections/psType.h ../sysUtils/psError.h
Index: /tags/rel1_1/psLib/src/image/psImageIO.h
===================================================================
--- /tags/rel1_1/psLib/src/image/psImageIO.h	(revision 1056)
+++ /tags/rel1_1/psLib/src/image/psImageIO.h	(revision 1056)
@@ -0,0 +1,81 @@
+/** @file  psImageIO.h
+ *
+ *  @brief Contains image input/output routines
+ *
+ *  This file defines the file input/output functions for the psImage structure.
+ *
+ *  @ingroup ImageIO
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.2 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-10 01:58:06 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+# ifndef PS_IMAGEIO_H
+# define PS_IMAGEIO_H
+
+#include "psImage.h"
+
+/// @addtogroup ImageIO
+/// @{
+
+/** Read an image or subimage from a FITS file specified by a filename.
+ *
+ *  return psImage*         The image read from the specified file.  NULL
+ *                          signifies that a problem had occured.
+ */
+psImage* psImageReadSection(
+    psImage* output,
+    /**< the output psImage to recycle, or NULL if new psImage desired */
+    int col0,
+    /**< the column index of the origin to start reading */
+    int row0,
+    /**< the row index of the origin to start reading */
+    int numCols,
+    /**< the number of desired columns to read */
+    int numRows,
+    /**< the number of desired rows to read */
+    int z,
+    /**< the z index to read if file is organized as a 3D image cube. */
+    char* extname,
+    /**< the image extension to read (this should match the EXTNAME keyword in
+     *   the extension If NULL, the extnum parameter is to be used instead
+     */
+    int extnum,
+    /**< the image extension to read (0=PHU, 1=first extension, etc.)  This is
+     *   only used if extname is NULL
+     */
+    char* filename
+    /**< the filename of the FITS image file to read */
+);
+
+/** Read an image or subimage from a FITS file specified by a filename.
+ *
+ *  return psImage*         NULL if an error, otherwise same as input psImage
+ */
+int psImageWriteSection(
+    psImage* input,
+    /**< the psImage to write */
+    int col0,
+    /**< the column index of the origin to start writing */
+    int row0,
+    /**< the row index of the origin to start writing */
+    int z,
+    /**< the z index to start writing */
+    char* extname,
+    /**< the image extension to write (this should match the EXTNAME keyword in
+     *   the extension If NULL, the extnum parameter is to be used instead
+     */
+    int extnum,
+    /**< the image extension to write (0=PHU, 1=first extension, etc.)  This is
+     *   only used if extname is NULL.
+     */
+    char* filename
+    /**< the filename of the FITS image file to write */
+);
+
+/// @}
+
+#endif
Index: /tags/rel1_1/psLib/src/image/psImageStats.c
===================================================================
--- /tags/rel1_1/psLib/src/image/psImageStats.c	(revision 1056)
+++ /tags/rel1_1/psLib/src/image/psImageStats.c	(revision 1056)
@@ -0,0 +1,413 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <float.h>
+#include <math.h>
+#include "psMemory.h"
+#include "psVector.h"
+#include "psTrace.h"
+#include "psError.h"
+#include "psAbort.h"
+#include "psStats.h"
+#include "psSort.h"
+#include "psImage.h"
+#include "psFunctions.h"
+#include "float.h"
+#include <math.h>
+
+/// This routine must determine the various statistics for the image.
+/*****************************************************************************
+    NOTE: verify that image/mask have the correct types, and sizes.
+ *****************************************************************************/
+psStats *psImageStats(psStats *stats,
+                      psImage *in,
+                      psImage *mask,
+                      int maskVal)
+{
+    psVector *junkData=NULL;
+    psVector *junkMask=NULL;
+    int ptr = 0;
+    int i = 0;
+    int j = 0;
+
+    // NOTE: Verify this action.
+    if ((stats == NULL) ||
+            (in == NULL)) {
+        return(NULL);
+    }
+    // NOTE: Verify this action.
+    if (stats->options == 0) {
+        return(stats);
+    }
+
+    junkData = psVectorAlloc(in->numRows * in->numCols, in->type.type);
+    junkData->n = junkData->nalloc;
+    ptr=0;
+    for (i=0;i<in->numRows;i++) {
+        for (j=0;j<in->numCols;j++) {
+            junkData->data.F32[ptr++] = in->data.F32[i][j];
+        }
+    }
+
+    if (mask != NULL) {
+        // NOTE: verify that mask data is PS_TYPE_U8.
+        // NOTE: figure out mask types
+
+        junkMask = psVectorAlloc(mask->numRows * mask->numCols,
+                                 mask->type.type);
+        junkMask->n = junkMask->nalloc;
+        // NOTE: Is there a more efficient way to do this?
+        ptr=0;
+        for (i=0;i<mask->numRows;i++) {
+            for (j=0;j<mask->numCols;j++) {
+                junkMask->data.U8[ptr++] = mask->data.U8[i][j];
+            }
+        }
+
+        stats = psVectorStats(stats, junkData, junkMask, maskVal);
+        psVectorFree(junkMask);
+    } else {
+        stats = psVectorStats(stats, junkData, NULL, 0);
+    }
+    psVectorFree(junkData);
+    return(stats);
+}
+
+/*****************************************************************************
+    NOTE: We assume that the psHistogram structure out has already been
+    allocated and initialized.
+    NOTE: verify that image/mask have the, correct types and  sizes.
+ *****************************************************************************/
+psHistogram *psImageHistogram(psHistogram *out,
+                              psImage *in,
+                              psImage *mask,
+                              int maskVal)
+{
+    psVector *junkData=NULL;
+    psVector *junkMask=NULL;
+    int ptr = 0;
+    int i = 0;
+    int j = 0;
+
+    // NOTE: Verify this action.
+    if ((out == NULL) ||
+            (in == NULL)) {
+        return(NULL);
+    }
+
+    junkData = psVectorAlloc(in->numRows * in->numCols, in->type.type);
+    junkData->n = junkData->nalloc;
+
+    // NOTE: Is there a more efficient way to do this?  memcopy() won't work.
+    // Can we trick the junkData structure to use the image buffer, then
+    // untrick it before we deallocate it (so we won't deallocate that buffer
+    // twice?
+
+    // NOTE: Make sure you have the numRows/NumCols in the right place.
+    ptr=0;
+    for (i=0;i<in->numRows;i++) {
+        for (j=0;j<in->numCols;j++) {
+            junkData->data.F32[ptr++] = in->data.F32[i][j];
+        }
+    }
+
+    if (mask != NULL) {
+        // NOTE: verify that mask data is PS_TYPE_U8.
+        // NOTE: figure out mask types
+
+        junkMask = psVectorAlloc(mask->numRows * mask->numCols,
+                                 mask->type.type);
+        junkMask->n = junkMask->nalloc;
+
+        // NOTE: Is there a more efficient way to do this?
+        ptr=0;
+        for (i=0;i<mask->numRows;i++) {
+            for (j=0;j<mask->numCols;j++) {
+                junkMask->data.U8[ptr++] = mask->data.U8[i][j];
+            }
+        }
+        out = psHistogramVector(out, junkData, junkMask, maskVal);
+        psVectorFree(junkMask);
+    } else {
+        out = psHistogramVector(out, junkData, NULL, 0);
+    }
+    psVectorFree(junkData);
+
+    return(out);
+}
+
+float *p_psCalcScaleFactorsFit(int n)
+{
+    int i = 0;
+    float tmp = 0.0;
+    float *scalingFactors = (float *) psAlloc(n * sizeof(float));
+
+    for (i=0;i<n;i++) {
+        //     ((2.0 * (float) i) / ((float) (n-1))) - 1.0;
+        //        tmp = (float) (i + 1);
+        tmp = (float) (n - i);
+        tmp = (M_PI * (tmp - 0.5)) / ((float) n);
+        scalingFactors[i] = cos(tmp);
+    }
+
+    return(scalingFactors);
+}
+
+float *p_psCalcScaleFactorsEval(int n)
+{
+    return p_psCalcScaleFactorsFit(n);
+    float tmp = 0.0;
+    int i = 0;
+    //    float tmp = 0.0;
+    float *scalingFactors = (float *) psAlloc(n * sizeof(float));
+    for (i=0;i<n;i++) {
+        //          scalingFactors[i] = ((2.0 * (float) i) / ((float) (n-1))) - 1.0;
+        tmp = (float) (i + 1);
+        tmp = (M_PI * (tmp - 0.5)) / ((float) n);
+        scalingFactors[i] = cos(tmp);
+    }
+    return(scalingFactors);
+}
+
+psPolynomial1D **p_psCreateChebyshevPolys(int maxChebyPoly)
+{
+    psPolynomial1D **chebPolys = NULL;
+    int i = 0;
+    int j = 0;
+
+    chebPolys = (psPolynomial1D **) psAlloc(maxChebyPoly *
+                                            sizeof(psPolynomial1D *));
+    for (i=0;i<maxChebyPoly;i++) {
+        chebPolys[i] = psPolynomial1DAlloc(i+1);
+    }
+
+    // Create the Chebyshev polynomials.  Polynomial i has i-th order.
+    chebPolys[0]->coeff[0] = 1;
+    chebPolys[1]->coeff[1] = 1;
+    for (i=2;i<maxChebyPoly;i++) {
+        for (j=0;j<chebPolys[i-1]->n;j++) {
+            chebPolys[i]->coeff[j+1] = 2 * chebPolys[i-1]->coeff[j];
+        }
+        for (j=0;j<chebPolys[i-2]->n;j++) {
+            chebPolys[i]->coeff[j]-= chebPolys[i-2]->coeff[j];
+        }
+    }
+
+    return(chebPolys);
+}
+
+
+/*****************************************************************************
+    psImageFitPolynomial():
+ This routine takes as input a 2-D image and produces as output
+ the coefficients of the Chebyshev polynomials which match that
+ input image.
+    Input:
+    Output:
+    Internal Data Structures:
+ 
+ chebPolys[i][j] 
+ 
+ sums[i][j]: This will contain the sum of 
+  input->data.F32[x][y] *
+                psEvalPolynomial1D((float) x, chebPolys[i]) *
+                psEvalPolynomial1D((float) y, chebPolys[j]);
+      over all pixels (x,y) in the image.
+ 
+ 
+ *****************************************************************************/
+psPolynomial2D *
+psImageFitPolynomial(const psImage *input,
+                     psPolynomial2D *coeffs)
+{
+    int k = 0;
+    int l = 0;
+    int x = 0;
+    int y = 0;
+    int i = 0;
+    int j = 0;
+    float **sums = NULL;
+    psPolynomial1D **chebPolys = NULL;
+    int maxChebyPoly = 0;
+    float *cScalingFactors = NULL;
+    float *rScalingFactors = NULL;
+    float tmp = 0.0;
+
+    // Create the sums[][] data structure.  This will hold the LHS of equation
+    // 29 in the ADD: sums[k][l] = SUM { image(x,y) * Tk(x) * Tl(y) }
+    sums = (float **) psAlloc(coeffs->nX * sizeof(float *));
+    for (i=0;i<coeffs->nX;i++) {
+        sums[i] = (float *) psAlloc(coeffs->nY * sizeof(float));
+    }
+
+    // We scale the pixel positions to values between -1.0 and 1.0
+    cScalingFactors = p_psCalcScaleFactorsFit(input->numRows);
+    rScalingFactors = p_psCalcScaleFactorsFit(input->numCols);
+
+    // Determine how many Chebyshev polynomials are needed, then create them.
+    maxChebyPoly = coeffs->nX;
+    if (coeffs->nY > coeffs->nX) {
+        maxChebyPoly = coeffs->nY;
+    }
+    chebPolys = p_psCreateChebyshevPolys(maxChebyPoly);
+
+    // Sanity check for the Chebyshevs
+    for (i=0;i<coeffs->nX;i++) {
+        for (j=0;j<coeffs->nY;j++) {
+            tmp = 0.0;
+            for (x=0;x<input->numRows;x++) {
+                tmp+= psEvalPolynomial1D(rScalingFactors[x], chebPolys[i]) *
+                      psEvalPolynomial1D(rScalingFactors[x], chebPolys[j]);
+
+            }
+        }
+    }
+
+    for (i=0;i<coeffs->nX;i++) {
+        for (j=0;j<coeffs->nY;j++) {
+            sums[i][j] = 0.0;
+            for (x=0;x<input->numRows;x++) {
+                for (y=0;y<input->numCols;y++) {
+                    sums[i][j]+= input->data.F32[x][y] *
+                                 psEvalPolynomial1D(rScalingFactors[x], chebPolys[i]) *
+                                 psEvalPolynomial1D(cScalingFactors[y], chebPolys[j]);
+                }
+            }
+        }
+    }
+
+    // NOTE: Check the math on this at a later date.
+    coeffs->coeff[0][0] = sums[0][0] / ((float) (coeffs->nX * coeffs->nY));
+    for (i=0;i<coeffs->nX;i++) {
+        coeffs->coeff[i][0] = ((sums[i][0] * 2.0) /
+                               ((float) (coeffs->nX * coeffs->nY))) -
+                              coeffs->coeff[0][0];
+    }
+    for (j=0;j<coeffs->nY;j++) {
+        coeffs->coeff[0][j] =
+            ((sums[0][j] * 2.0) /
+             ((float) (coeffs->nX * coeffs->nY))) -
+            coeffs->coeff[0][0];
+    }
+    for (i=1;i<coeffs->nX;i++) {
+        for (j=1;j<coeffs->nY;j++) {
+            coeffs->coeff[i][j] =
+                ((sums[i][0] * 4.0) / ((float) (coeffs->nX * coeffs->nY))) -
+                (coeffs->coeff[0][0] +
+                 coeffs->coeff[i][0] +
+                 coeffs->coeff[0][j]);
+        }
+    }
+
+    for (k=0;k<coeffs->nX;k++) {
+        for (l=0;l<coeffs->nY;l++) {
+            tmp = 0.0;
+            for (i=0;i<coeffs->nX;i++) {
+                for (j=0;j<coeffs->nY;j++) {
+                    for (x=0;x<input->numRows;x++) {
+                        for (y=0;y<input->numCols;y++) {
+                            tmp+= (coeffs->coeff[i][j] *
+                                   psEvalPolynomial1D(rScalingFactors[x], chebPolys[i]) *
+                                   psEvalPolynomial1D(rScalingFactors[y], chebPolys[j]) *
+                                   psEvalPolynomial1D(rScalingFactors[x], chebPolys[k]) *
+                                   psEvalPolynomial1D(rScalingFactors[y], chebPolys[l]));
+
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+
+    // Free the Chebyshev polynomials that were created in this routine.
+    for (i=0;i<maxChebyPoly;i++) {
+        psPolynomial1DFree(chebPolys[i]);
+    }
+    psFree(chebPolys);
+
+    // Free some data
+    for (i=0;i<coeffs->nX;i++) {
+        psFree(sums[i]);
+    }
+    psFree(sums);
+    psFree(cScalingFactors);
+    psFree(rScalingFactors);
+
+    return(coeffs);
+}
+
+/*****************************************************************************
+ 
+ *****************************************************************************/
+int
+psImageEvalPolynomial(const psImage *input,
+                      const psPolynomial2D *coeffs)
+{
+    int x = 0;
+    int y = 0;
+    int i = 0;
+    int j = 0;
+    float **sums = NULL;
+    psPolynomial1D **chebPolys = NULL;
+    int maxChebyPoly = 0;
+    float *cScalingFactors = NULL;
+    float *rScalingFactors = NULL;
+    float polySum = 0.0;
+
+    // Create the sums[][] data structure.  This will hold the LHS of equation
+    // 29 in the ADD: sums[k][l] = SUM { image(x,y) * Tk(x) * Tl(y) }
+    sums = (float **) psAlloc(coeffs->nX * sizeof(float *));
+    for (i=0;i<coeffs->nX;i++) {
+        sums[i] = (float *) psAlloc(coeffs->nY * sizeof(float));
+    }
+    for (i=0;i<coeffs->nX;i++) {
+        for (j=0;j<coeffs->nY;j++) {
+            sums[i][j] = 0.0;
+        }
+    }
+
+    // We scale the pixel positions to values between -1.0 and 1.0
+    cScalingFactors = p_psCalcScaleFactorsEval(input->numRows);
+    rScalingFactors = p_psCalcScaleFactorsEval(input->numCols);
+
+    // Determine how many Chebyshev polynomials are needed, then create them.
+    maxChebyPoly = coeffs->nX;
+    if (coeffs->nY > coeffs->nX) {
+        maxChebyPoly = coeffs->nY;
+    }
+
+    chebPolys = p_psCreateChebyshevPolys(maxChebyPoly);
+
+    for (x=0;x<input->numRows;x++) {
+        for (y=0;y<input->numCols;y++) {
+            polySum = 0.0;
+            for (i=0;i<coeffs->nX;i++) {
+                for (j=0;j<coeffs->nY;j++) {
+                    polySum+= psEvalPolynomial1D(rScalingFactors[x], chebPolys[i]) *
+                              psEvalPolynomial1D(cScalingFactors[y], chebPolys[j]) *
+                              coeffs->coeff[i][j];
+
+                }
+            }
+            input->data.F32[x][y] = polySum;
+        }
+    }
+
+    // Free the Chebyshev polynomials that were created in this routine.
+    for (i=0;i<maxChebyPoly;i++) {
+        psPolynomial1DFree(chebPolys[i]);
+    }
+    psFree(chebPolys);
+
+    // Free some data
+    for (i=0;i<coeffs->nX;i++) {
+        psFree(sums[i]);
+    }
+    psFree(sums);
+    psFree(cScalingFactors);
+    psFree(rScalingFactors);
+
+    return(0);
+}
Index: /tags/rel1_1/psLib/src/image/psImageStats.d
===================================================================
--- /tags/rel1_1/psLib/src/image/psImageStats.d	(revision 1056)
+++ /tags/rel1_1/psLib/src/image/psImageStats.d	(revision 1056)
@@ -0,0 +1,4 @@
+psImageStats.o psImageStats.d : psImageStats.c ../sysUtils/psMemory.h \
+  ../collections/psVector.h ../collections/psType.h ../sysUtils/psTrace.h \
+  ../sysUtils/psError.h ../sysUtils/psAbort.h psStats.h \
+  ../collections/psSort.h ../collections/psImage.h psFunctions.h
Index: /tags/rel1_1/psLib/src/image/psImageStats.h
===================================================================
--- /tags/rel1_1/psLib/src/image/psImageStats.h	(revision 1056)
+++ /tags/rel1_1/psLib/src/image/psImageStats.h	(revision 1056)
@@ -0,0 +1,50 @@
+/** @file psImageStats.h
+ *  \brief Routines for calculating statistics on images.
+ *  \ingroup Stats
+ *  @ingroup Stats
+ *
+ *  This file will hold the prototypes for procedures which calculate
+ *  statistic on images, histograms on images, and fit/evaluate Chebyshev
+ *  polynomials to images.
+ *
+ *  @author George Gusciora, MHPCC
+ *
+ *  @version $Revision: 1.3 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-14 19:40:14 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+#if !defined(PS_IMAGE_STATS_H)
+#define PS_IMAGE_STATS_H
+
+
+#include "psVector.h"
+#include "psImage.h"
+#include "psStats.h"
+#include "psFunctions.h"
+
+/// This routine must determine the various statistics for the image.
+psStats *psImageStats(psStats *stats, ///< defines statistics to be calculated
+                      psImage *in,    ///< image (or subimage) to calculate stats
+                      psImage *mask,  ///< mask data for image (NULL ok)
+                      int maskVal);   ///< mask Mask for mask
+
+
+psHistogram *psImageHistogram(psHistogram *out,  ///< input histogram description & target
+                              psImage *in,       ///< Image data to be histogramed.
+                              psImage *mask,     ///< mask data for image (NULL ok)
+                              int maskVal);      ///< mask Mask for mask
+
+/// Fit a 2-D polynomial surface to an image.
+psPolynomial2D *
+psImageFitPolynomial(const psImage *input, ///< image to fit
+                     psPolynomial2D *coeffs ///< coefficient structure carries in desired terms & target
+                    );
+
+/// Evaluate a 2-D polynomial surface to image pixels.
+int
+psImageEvalPolynomial(const psImage *input, ///< image to fit
+                      const psPolynomial2D *coeffs ///< coefficient structure carries in desired terms
+                     );
+
+#endif
Index: /tags/rel1_1/psLib/src/imageops/psImageStats.c
===================================================================
--- /tags/rel1_1/psLib/src/imageops/psImageStats.c	(revision 1056)
+++ /tags/rel1_1/psLib/src/imageops/psImageStats.c	(revision 1056)
@@ -0,0 +1,413 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <float.h>
+#include <math.h>
+#include "psMemory.h"
+#include "psVector.h"
+#include "psTrace.h"
+#include "psError.h"
+#include "psAbort.h"
+#include "psStats.h"
+#include "psSort.h"
+#include "psImage.h"
+#include "psFunctions.h"
+#include "float.h"
+#include <math.h>
+
+/// This routine must determine the various statistics for the image.
+/*****************************************************************************
+    NOTE: verify that image/mask have the correct types, and sizes.
+ *****************************************************************************/
+psStats *psImageStats(psStats *stats,
+                      psImage *in,
+                      psImage *mask,
+                      int maskVal)
+{
+    psVector *junkData=NULL;
+    psVector *junkMask=NULL;
+    int ptr = 0;
+    int i = 0;
+    int j = 0;
+
+    // NOTE: Verify this action.
+    if ((stats == NULL) ||
+            (in == NULL)) {
+        return(NULL);
+    }
+    // NOTE: Verify this action.
+    if (stats->options == 0) {
+        return(stats);
+    }
+
+    junkData = psVectorAlloc(in->numRows * in->numCols, in->type.type);
+    junkData->n = junkData->nalloc;
+    ptr=0;
+    for (i=0;i<in->numRows;i++) {
+        for (j=0;j<in->numCols;j++) {
+            junkData->data.F32[ptr++] = in->data.F32[i][j];
+        }
+    }
+
+    if (mask != NULL) {
+        // NOTE: verify that mask data is PS_TYPE_U8.
+        // NOTE: figure out mask types
+
+        junkMask = psVectorAlloc(mask->numRows * mask->numCols,
+                                 mask->type.type);
+        junkMask->n = junkMask->nalloc;
+        // NOTE: Is there a more efficient way to do this?
+        ptr=0;
+        for (i=0;i<mask->numRows;i++) {
+            for (j=0;j<mask->numCols;j++) {
+                junkMask->data.U8[ptr++] = mask->data.U8[i][j];
+            }
+        }
+
+        stats = psVectorStats(stats, junkData, junkMask, maskVal);
+        psVectorFree(junkMask);
+    } else {
+        stats = psVectorStats(stats, junkData, NULL, 0);
+    }
+    psVectorFree(junkData);
+    return(stats);
+}
+
+/*****************************************************************************
+    NOTE: We assume that the psHistogram structure out has already been
+    allocated and initialized.
+    NOTE: verify that image/mask have the, correct types and  sizes.
+ *****************************************************************************/
+psHistogram *psImageHistogram(psHistogram *out,
+                              psImage *in,
+                              psImage *mask,
+                              int maskVal)
+{
+    psVector *junkData=NULL;
+    psVector *junkMask=NULL;
+    int ptr = 0;
+    int i = 0;
+    int j = 0;
+
+    // NOTE: Verify this action.
+    if ((out == NULL) ||
+            (in == NULL)) {
+        return(NULL);
+    }
+
+    junkData = psVectorAlloc(in->numRows * in->numCols, in->type.type);
+    junkData->n = junkData->nalloc;
+
+    // NOTE: Is there a more efficient way to do this?  memcopy() won't work.
+    // Can we trick the junkData structure to use the image buffer, then
+    // untrick it before we deallocate it (so we won't deallocate that buffer
+    // twice?
+
+    // NOTE: Make sure you have the numRows/NumCols in the right place.
+    ptr=0;
+    for (i=0;i<in->numRows;i++) {
+        for (j=0;j<in->numCols;j++) {
+            junkData->data.F32[ptr++] = in->data.F32[i][j];
+        }
+    }
+
+    if (mask != NULL) {
+        // NOTE: verify that mask data is PS_TYPE_U8.
+        // NOTE: figure out mask types
+
+        junkMask = psVectorAlloc(mask->numRows * mask->numCols,
+                                 mask->type.type);
+        junkMask->n = junkMask->nalloc;
+
+        // NOTE: Is there a more efficient way to do this?
+        ptr=0;
+        for (i=0;i<mask->numRows;i++) {
+            for (j=0;j<mask->numCols;j++) {
+                junkMask->data.U8[ptr++] = mask->data.U8[i][j];
+            }
+        }
+        out = psHistogramVector(out, junkData, junkMask, maskVal);
+        psVectorFree(junkMask);
+    } else {
+        out = psHistogramVector(out, junkData, NULL, 0);
+    }
+    psVectorFree(junkData);
+
+    return(out);
+}
+
+float *p_psCalcScaleFactorsFit(int n)
+{
+    int i = 0;
+    float tmp = 0.0;
+    float *scalingFactors = (float *) psAlloc(n * sizeof(float));
+
+    for (i=0;i<n;i++) {
+        //     ((2.0 * (float) i) / ((float) (n-1))) - 1.0;
+        //        tmp = (float) (i + 1);
+        tmp = (float) (n - i);
+        tmp = (M_PI * (tmp - 0.5)) / ((float) n);
+        scalingFactors[i] = cos(tmp);
+    }
+
+    return(scalingFactors);
+}
+
+float *p_psCalcScaleFactorsEval(int n)
+{
+    return p_psCalcScaleFactorsFit(n);
+    float tmp = 0.0;
+    int i = 0;
+    //    float tmp = 0.0;
+    float *scalingFactors = (float *) psAlloc(n * sizeof(float));
+    for (i=0;i<n;i++) {
+        //          scalingFactors[i] = ((2.0 * (float) i) / ((float) (n-1))) - 1.0;
+        tmp = (float) (i + 1);
+        tmp = (M_PI * (tmp - 0.5)) / ((float) n);
+        scalingFactors[i] = cos(tmp);
+    }
+    return(scalingFactors);
+}
+
+psPolynomial1D **p_psCreateChebyshevPolys(int maxChebyPoly)
+{
+    psPolynomial1D **chebPolys = NULL;
+    int i = 0;
+    int j = 0;
+
+    chebPolys = (psPolynomial1D **) psAlloc(maxChebyPoly *
+                                            sizeof(psPolynomial1D *));
+    for (i=0;i<maxChebyPoly;i++) {
+        chebPolys[i] = psPolynomial1DAlloc(i+1);
+    }
+
+    // Create the Chebyshev polynomials.  Polynomial i has i-th order.
+    chebPolys[0]->coeff[0] = 1;
+    chebPolys[1]->coeff[1] = 1;
+    for (i=2;i<maxChebyPoly;i++) {
+        for (j=0;j<chebPolys[i-1]->n;j++) {
+            chebPolys[i]->coeff[j+1] = 2 * chebPolys[i-1]->coeff[j];
+        }
+        for (j=0;j<chebPolys[i-2]->n;j++) {
+            chebPolys[i]->coeff[j]-= chebPolys[i-2]->coeff[j];
+        }
+    }
+
+    return(chebPolys);
+}
+
+
+/*****************************************************************************
+    psImageFitPolynomial():
+ This routine takes as input a 2-D image and produces as output
+ the coefficients of the Chebyshev polynomials which match that
+ input image.
+    Input:
+    Output:
+    Internal Data Structures:
+ 
+ chebPolys[i][j] 
+ 
+ sums[i][j]: This will contain the sum of 
+  input->data.F32[x][y] *
+                psEvalPolynomial1D((float) x, chebPolys[i]) *
+                psEvalPolynomial1D((float) y, chebPolys[j]);
+      over all pixels (x,y) in the image.
+ 
+ 
+ *****************************************************************************/
+psPolynomial2D *
+psImageFitPolynomial(const psImage *input,
+                     psPolynomial2D *coeffs)
+{
+    int k = 0;
+    int l = 0;
+    int x = 0;
+    int y = 0;
+    int i = 0;
+    int j = 0;
+    float **sums = NULL;
+    psPolynomial1D **chebPolys = NULL;
+    int maxChebyPoly = 0;
+    float *cScalingFactors = NULL;
+    float *rScalingFactors = NULL;
+    float tmp = 0.0;
+
+    // Create the sums[][] data structure.  This will hold the LHS of equation
+    // 29 in the ADD: sums[k][l] = SUM { image(x,y) * Tk(x) * Tl(y) }
+    sums = (float **) psAlloc(coeffs->nX * sizeof(float *));
+    for (i=0;i<coeffs->nX;i++) {
+        sums[i] = (float *) psAlloc(coeffs->nY * sizeof(float));
+    }
+
+    // We scale the pixel positions to values between -1.0 and 1.0
+    cScalingFactors = p_psCalcScaleFactorsFit(input->numRows);
+    rScalingFactors = p_psCalcScaleFactorsFit(input->numCols);
+
+    // Determine how many Chebyshev polynomials are needed, then create them.
+    maxChebyPoly = coeffs->nX;
+    if (coeffs->nY > coeffs->nX) {
+        maxChebyPoly = coeffs->nY;
+    }
+    chebPolys = p_psCreateChebyshevPolys(maxChebyPoly);
+
+    // Sanity check for the Chebyshevs
+    for (i=0;i<coeffs->nX;i++) {
+        for (j=0;j<coeffs->nY;j++) {
+            tmp = 0.0;
+            for (x=0;x<input->numRows;x++) {
+                tmp+= psEvalPolynomial1D(rScalingFactors[x], chebPolys[i]) *
+                      psEvalPolynomial1D(rScalingFactors[x], chebPolys[j]);
+
+            }
+        }
+    }
+
+    for (i=0;i<coeffs->nX;i++) {
+        for (j=0;j<coeffs->nY;j++) {
+            sums[i][j] = 0.0;
+            for (x=0;x<input->numRows;x++) {
+                for (y=0;y<input->numCols;y++) {
+                    sums[i][j]+= input->data.F32[x][y] *
+                                 psEvalPolynomial1D(rScalingFactors[x], chebPolys[i]) *
+                                 psEvalPolynomial1D(cScalingFactors[y], chebPolys[j]);
+                }
+            }
+        }
+    }
+
+    // NOTE: Check the math on this at a later date.
+    coeffs->coeff[0][0] = sums[0][0] / ((float) (coeffs->nX * coeffs->nY));
+    for (i=0;i<coeffs->nX;i++) {
+        coeffs->coeff[i][0] = ((sums[i][0] * 2.0) /
+                               ((float) (coeffs->nX * coeffs->nY))) -
+                              coeffs->coeff[0][0];
+    }
+    for (j=0;j<coeffs->nY;j++) {
+        coeffs->coeff[0][j] =
+            ((sums[0][j] * 2.0) /
+             ((float) (coeffs->nX * coeffs->nY))) -
+            coeffs->coeff[0][0];
+    }
+    for (i=1;i<coeffs->nX;i++) {
+        for (j=1;j<coeffs->nY;j++) {
+            coeffs->coeff[i][j] =
+                ((sums[i][0] * 4.0) / ((float) (coeffs->nX * coeffs->nY))) -
+                (coeffs->coeff[0][0] +
+                 coeffs->coeff[i][0] +
+                 coeffs->coeff[0][j]);
+        }
+    }
+
+    for (k=0;k<coeffs->nX;k++) {
+        for (l=0;l<coeffs->nY;l++) {
+            tmp = 0.0;
+            for (i=0;i<coeffs->nX;i++) {
+                for (j=0;j<coeffs->nY;j++) {
+                    for (x=0;x<input->numRows;x++) {
+                        for (y=0;y<input->numCols;y++) {
+                            tmp+= (coeffs->coeff[i][j] *
+                                   psEvalPolynomial1D(rScalingFactors[x], chebPolys[i]) *
+                                   psEvalPolynomial1D(rScalingFactors[y], chebPolys[j]) *
+                                   psEvalPolynomial1D(rScalingFactors[x], chebPolys[k]) *
+                                   psEvalPolynomial1D(rScalingFactors[y], chebPolys[l]));
+
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+
+    // Free the Chebyshev polynomials that were created in this routine.
+    for (i=0;i<maxChebyPoly;i++) {
+        psPolynomial1DFree(chebPolys[i]);
+    }
+    psFree(chebPolys);
+
+    // Free some data
+    for (i=0;i<coeffs->nX;i++) {
+        psFree(sums[i]);
+    }
+    psFree(sums);
+    psFree(cScalingFactors);
+    psFree(rScalingFactors);
+
+    return(coeffs);
+}
+
+/*****************************************************************************
+ 
+ *****************************************************************************/
+int
+psImageEvalPolynomial(const psImage *input,
+                      const psPolynomial2D *coeffs)
+{
+    int x = 0;
+    int y = 0;
+    int i = 0;
+    int j = 0;
+    float **sums = NULL;
+    psPolynomial1D **chebPolys = NULL;
+    int maxChebyPoly = 0;
+    float *cScalingFactors = NULL;
+    float *rScalingFactors = NULL;
+    float polySum = 0.0;
+
+    // Create the sums[][] data structure.  This will hold the LHS of equation
+    // 29 in the ADD: sums[k][l] = SUM { image(x,y) * Tk(x) * Tl(y) }
+    sums = (float **) psAlloc(coeffs->nX * sizeof(float *));
+    for (i=0;i<coeffs->nX;i++) {
+        sums[i] = (float *) psAlloc(coeffs->nY * sizeof(float));
+    }
+    for (i=0;i<coeffs->nX;i++) {
+        for (j=0;j<coeffs->nY;j++) {
+            sums[i][j] = 0.0;
+        }
+    }
+
+    // We scale the pixel positions to values between -1.0 and 1.0
+    cScalingFactors = p_psCalcScaleFactorsEval(input->numRows);
+    rScalingFactors = p_psCalcScaleFactorsEval(input->numCols);
+
+    // Determine how many Chebyshev polynomials are needed, then create them.
+    maxChebyPoly = coeffs->nX;
+    if (coeffs->nY > coeffs->nX) {
+        maxChebyPoly = coeffs->nY;
+    }
+
+    chebPolys = p_psCreateChebyshevPolys(maxChebyPoly);
+
+    for (x=0;x<input->numRows;x++) {
+        for (y=0;y<input->numCols;y++) {
+            polySum = 0.0;
+            for (i=0;i<coeffs->nX;i++) {
+                for (j=0;j<coeffs->nY;j++) {
+                    polySum+= psEvalPolynomial1D(rScalingFactors[x], chebPolys[i]) *
+                              psEvalPolynomial1D(cScalingFactors[y], chebPolys[j]) *
+                              coeffs->coeff[i][j];
+
+                }
+            }
+            input->data.F32[x][y] = polySum;
+        }
+    }
+
+    // Free the Chebyshev polynomials that were created in this routine.
+    for (i=0;i<maxChebyPoly;i++) {
+        psPolynomial1DFree(chebPolys[i]);
+    }
+    psFree(chebPolys);
+
+    // Free some data
+    for (i=0;i<coeffs->nX;i++) {
+        psFree(sums[i]);
+    }
+    psFree(sums);
+    psFree(cScalingFactors);
+    psFree(rScalingFactors);
+
+    return(0);
+}
Index: /tags/rel1_1/psLib/src/imageops/psImageStats.h
===================================================================
--- /tags/rel1_1/psLib/src/imageops/psImageStats.h	(revision 1056)
+++ /tags/rel1_1/psLib/src/imageops/psImageStats.h	(revision 1056)
@@ -0,0 +1,50 @@
+/** @file psImageStats.h
+ *  \brief Routines for calculating statistics on images.
+ *  \ingroup Stats
+ *  @ingroup Stats
+ *
+ *  This file will hold the prototypes for procedures which calculate
+ *  statistic on images, histograms on images, and fit/evaluate Chebyshev
+ *  polynomials to images.
+ *
+ *  @author George Gusciora, MHPCC
+ *
+ *  @version $Revision: 1.3 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-14 19:40:14 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+#if !defined(PS_IMAGE_STATS_H)
+#define PS_IMAGE_STATS_H
+
+
+#include "psVector.h"
+#include "psImage.h"
+#include "psStats.h"
+#include "psFunctions.h"
+
+/// This routine must determine the various statistics for the image.
+psStats *psImageStats(psStats *stats, ///< defines statistics to be calculated
+                      psImage *in,    ///< image (or subimage) to calculate stats
+                      psImage *mask,  ///< mask data for image (NULL ok)
+                      int maskVal);   ///< mask Mask for mask
+
+
+psHistogram *psImageHistogram(psHistogram *out,  ///< input histogram description & target
+                              psImage *in,       ///< Image data to be histogramed.
+                              psImage *mask,     ///< mask data for image (NULL ok)
+                              int maskVal);      ///< mask Mask for mask
+
+/// Fit a 2-D polynomial surface to an image.
+psPolynomial2D *
+psImageFitPolynomial(const psImage *input, ///< image to fit
+                     psPolynomial2D *coeffs ///< coefficient structure carries in desired terms & target
+                    );
+
+/// Evaluate a 2-D polynomial surface to image pixels.
+int
+psImageEvalPolynomial(const psImage *input, ///< image to fit
+                      const psPolynomial2D *coeffs ///< coefficient structure carries in desired terms
+                     );
+
+#endif
Index: /tags/rel1_1/psLib/src/mainpage.dox
===================================================================
--- /tags/rel1_1/psLib/src/mainpage.dox	(revision 1056)
+++ /tags/rel1_1/psLib/src/mainpage.dox	(revision 1056)
@@ -0,0 +1,132 @@
+/** @mainpage psLib Image Processing Library - Release 1
+
+
+@section intro Introduction
+
+This library contains the Pan-STARRS Library, "psLib". The intended use is to
+provide a set of basic software functions which can be used throughout the 
+Pan-STARRS project to simplify programming tasks. Among the benefits are: 
+<ul>
+<li>Reuse of code</li>
+<li>Simplification of testing</li>
+<li>Streamlining of code</li>
+<li>Isolation of functionality that may be subject to change</li>
+</ul>     
+
+The capabilities provided by psLib are grouped into the following areas which
+are also reflected in the source files' directory structure:
+<ul>
+<li>System Utilities</li>
+<li>Data Collections</li>
+<li>Data Manipulation</li>
+</ul>
+
+This list is sorted in hierarchical order: The later entries depend on the 
+functions and data types of the earlier entries.
+
+The installed code for psLib consists of header files and binary libraries 
+in the form of static (libpslib.a) and shared (libpslib.so or libpslib.dylib 
+depending on the operating system). Assuming these components have been built
+and installed in the standard library path, psLib may be used within a program
+by including the pslib.h header in your C file and linking with -lpslib.
+
+
+@section extinstall Required 3rd Party Libraries
+
+Before building psLib from source, several 3rd party software libraries must 
+be installed. These include: 
+<ul>
+<li>GNU Scientific Library (GSL), version 1.4</li>
+<ul><li>Available at http://www.gnu.org/software/gsl</li></ul>
+<li>Fastest Fourier Transform in the West (FFTW), version 3.0.1</li>
+<ul><li>Available at http://www.fftw.org</li></ul>
+<li>C Flexible Image Transport System Input output (CFITSIO), version 2.4.9
+<ul><li>Available at http://heasarc.gsfc.nasa.gov/docs/software/fitsio</li></ul>
+</ul>
+
+If you use a Macintosh OS X 10.2 or earlier system, a dlfcn compatability 
+library may need to be installed on the system. This can be obtained from the
+Fink project on SourceForge (the dlcompat package at http://www.sf.net/projects/fink).
+The Darwin 7.0 (OS X 10.3) 'devtools' package includes dlfcn support, so 
+explicit installation of a dlfcn compatibility layer may not be required for 
+this version of Darwin with the devtools package installed. 
+
+
+@section obtain How to Obtain the Code
+
+The psLib code should to be downloaded from either the tar files posted the
+MHPCC webserver or CVS.  
+
+Via the web server, point your browser to https://mhpcc.pan-starrs.org/cgi-bin/viewcvs.cgi/releases/rel1 .
+There are two files available there:
+<ul>
+<li>pslib-rel1-src.tar.gz</li>
+<ul><li>The source package - equivalent to getting the source from the CVS via export.</li></ul>
+<li>pslib-rel1-linux-x86.tar.gz</li>
+<ul><li>The binary package - precompiled for x86 Linux machines.  Contains 
+prebuilt libraries, documentation, and test suite.</li></ul>
+</ul>
+
+Download the appropriate package for your needs and untar the files where
+one sees fit.
+
+To obtain the source directly from the CVS server with the following command:
+<pre>
+$ export CVS_RSH=ssh
+$ cvs -d:ext:username@mhpcc.pan-starrs.org:/data/panstarrs/cvsroot export -r rel1_1 psLib
+</pre>
+This requires having an SSH login account on mhpcc.pan-starrs.org.
+
+
+@section build How to Build from Source Code
+
+Once the release package is obtained, the library should build from the 
+Makefile in the psLib/src directory.  The recommended steps are:
+<pre>
+$ cd psLib/src
+$ make
+$ make install
+</pre>
+This builds the library and installs files to psLib/lib and psLib/include.
+
+
+@section buildTests How to Build the Tests
+
+Since psLib is a library, there is no executable, per se. However, to test 
+the installation and functionality, users may create a suite of unit tests 
+with the following steps:
+<pre>
+$ cd psLib/test
+$ make
+$ make install
+$ make installtests
+</pre>
+This builds and installs test files for each of the psLib functional areas
+into the psLib/bin/test directory.
+
+
+@section runTests How to Run the Unit Tests
+
+To execute the unit test suite, after building them, users may use the
+following steps:
+<pre>
+$ cd psLib/testbin
+$ ./FullUnitTest
+</pre>
+One can also run individual test executables, which concentrate on a logical
+set of functionality of the library, via the 'runTest' script in the bin/test
+directory or by executing the test from the shell.  If running the test directly
+in the shell, make sure that the LD_LIBRARY_PATH (or DYLD_LIBRARY_PATH if on the
+Macintosh) contains the path to the psLib/lib directory.
+
+@section doc How to Create Documentation
+
+Both HTML and man page documentation may also be generated:
+<pre>
+$ cd psLib/src
+$ make docs
+</pre>
+This places the Doxygen generated documentation in psLib/docs. The doxygen is
+also available online at: https://mhpcc.pan-starrs.org/docs/psLib-rel1 .
+
+*/
Index: /tags/rel1_1/psLib/src/math/psMatrix.c
===================================================================
--- /tags/rel1_1/psLib/src/math/psMatrix.c	(revision 1056)
+++ /tags/rel1_1/psLib/src/math/psMatrix.c	(revision 1056)
@@ -0,0 +1,571 @@
+/** @file  psMatrix.c
+ *
+ *  @brief Provides functions for linear algebra operations on psImages and psVectors. 
+ *
+ *  Functions are provided to:
+ *      Transpose a psImage
+ *      Compute LUD
+ *      Solve LUD
+ *      Matrix inversion
+ *      Calculate determinant
+ *      Matrix addition
+ *      Matrix subtraction
+ *      Matrix multiplication
+ *      Calculate Eigenvectors
+ *      Convert matrix to vector
+ *      Convert vector to matrix
+ *
+ *  These functions treat psImages as if they were matrices, therefore there is no psMatrix.
+ *
+ *  @author Ross Harman, MHPCC
+ *   
+ *  @version $Revision: 1.8 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-08 01:57:52 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+/******************************************************************************/
+/*  INCLUDE FILES                                                             */
+/******************************************************************************/
+#include <string.h>
+#include <gsl/gsl_matrix.h>
+#include <gsl/gsl_linalg.h>
+#include <gsl/gsl_permutation.h>
+#include <gsl/gsl_eigen.h>
+
+#include "psMemory.h"
+#include "psError.h"
+#include "psImage.h"
+#include "psVector.h"
+#include "psMatrix.h"
+
+/******************************************************************************/
+/*  DEFINE STATEMENTS                                                         */
+/******************************************************************************/
+
+// None
+
+/******************************************************************************/
+/*  TYPE DEFINITIONS                                                          */
+/******************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  GLOBAL VARIABLES                                                         */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  FILE STATIC VARIABLES                                                    */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  FUNCTION IMPLEMENTATION - LOCAL                                          */
+/*****************************************************************************/
+
+/** Preprocessor macro to generate error a NULL image */
+#define PS_CHECK_NULL_VECTOR(NAME, RETURN)                                                          \
+if (NAME == NULL || NAME->data.V == NULL) {                                                         \
+    psError(__func__,"Invalid operation: %s or its data is NULL.", #NAME);                          \
+    return RETURN;                                                                                  \
+}
+
+/** Preprocessor macro to create vector based on another */
+#define PS_CHECK_ALLOC_VECTOR(NAME, SIZE, PS_TYPE)                                                  \
+if(NAME == NULL) {                                                                                  \
+    NAME = psVectorAlloc(SIZE, PS_TYPE);                                                            \
+}
+
+/** Preprocessor macro to generate error for zero length vector */
+#define PS_CHECK_SIZE_VECTOR(NAME, RETURN)                                                          \
+if (NAME->n < 1) {                                                                                  \
+    psError(__func__,"Invalid operation: %s has zero n value.", #NAME);                             \
+    return RETURN;                                                                                  \
+}
+
+/** Preprocessor macro to generate error a NULL image */
+#define PS_CHECK_NULL_IMAGE(NAME, RETURN)                                                           \
+if (NAME == NULL || NAME->data.V == NULL) {                                                         \
+    psError(__func__,"Invalid operation: %s or its data is NULL.", #NAME);                          \
+    return RETURN;                                                                                  \
+}
+
+/** Preprocessor macro to create image based on another */
+#define PS_CHECK_ALLOC_IMAGE(NAME, NCOLS, NROWS, PS_TYPE)                                           \
+if(NAME == NULL) {                                                                                  \
+    NAME = psImageAlloc(NCOLS, NROWS, PS_TYPE);                                                     \
+}
+
+/** Preprocessor macro to generate error for zero length rows or columns */
+#define PS_CHECK_SIZE_IMAGE(NAME, RETURN)                                                           \
+if (NAME->numCols < 1 || NAME->numRows < 1) {                                                       \
+    psError(__func__,"Invalid operation: %s has zero rows or columns (%dx%d).", #NAME,              \
+            NAME->numCols, NAME->numRows);                                                          \
+    return RETURN;                                                                                  \
+}
+
+/** Preprocessor macro to generate error for image dimensionality not set to PS_DIMEN_IMAGE */
+#define PS_CHECK_DIMEN_AND_TYPE(NAME, PS_DIMEN, RETURN)                                             \
+if (NAME->type.dimen != PS_DIMEN) {                                                                 \
+    psError(__func__,"Invalid operation: %s incorrect dimensionality %d.", #NAME, PS_DIMEN);        \
+    return RETURN;                                                                                  \
+} else if(NAME->type.type != PS_TYPE_F64) {                                                         \
+    psError(__func__, "Invalid operation: %s not PS_TYPE_F64.", #NAME);                             \
+    return RETURN;                                                                                  \
+}
+
+/** Preprocessor macro to check that input is not equal to output */
+#define PS_CHECK_POINTERS(NAME1, NAME2, RETURN)                                                     \
+if (NAME1 == NAME2) {                                                                               \
+    psError(__func__,"Invalid operation: Pointer to %s is same as %s.", #NAME1, #NAME2);            \
+    return RETURN;                                                                                  \
+}
+
+/** Preprocessor macro to check that an image is square */
+#define PS_CHECK_SQUARE(NAME, RETURN)                                                               \
+if (NAME->numCols != NAME->numRows) {                                                               \
+    psError(__func__,"Invalid operation: %s not square array.", #NAME);                             \
+    return RETURN;                                                                                  \
+}
+
+/** Preprocessor macro to initalize a GSL matrix. */
+#define PS_GSL_MATRIX_INITIALIZE(LHS_NAME, RHS_NAME)                                                \
+LHS_NAME.size1 = numRows;                                                                           \
+LHS_NAME.size2 = numCols;                                                                           \
+LHS_NAME.tda   = numCols;                                                                           \
+LHS_NAME.data  = RHS_NAME;
+
+/*****************************************************************************/
+/* FUNCTION IMPLEMENTATION - PUBLIC                                          */
+/*****************************************************************************/
+
+psImage *psMatrixLUD(psImage *outImage, psVector *outPerm, psImage *inImage)
+{
+    int signum = 0;
+    int arraySize = 0;
+    int numRows = 0;
+    int numCols = 0;
+    gsl_matrix lu;
+    gsl_permutation perm;
+
+    // Error checks
+    PS_CHECK_POINTERS(inImage, outImage, outImage);
+    PS_CHECK_NULL_IMAGE(inImage, outImage);
+    PS_CHECK_DIMEN_AND_TYPE(inImage, PS_DIMEN_IMAGE, outImage);
+    PS_CHECK_SIZE_IMAGE(inImage, outImage);
+    PS_CHECK_ALLOC_IMAGE(outImage, inImage->numCols, inImage->numRows, inImage->type.type);
+    PS_CHECK_DIMEN_AND_TYPE(outImage, PS_DIMEN_IMAGE, outImage);
+    PS_CHECK_SIZE_IMAGE(outImage, outImage);
+    PS_CHECK_ALLOC_VECTOR(outPerm, inImage->numRows, inImage->type.type);
+    PS_CHECK_NULL_VECTOR(outPerm, outImage);
+    PS_CHECK_DIMEN_AND_TYPE(outPerm, PS_DIMEN_VECTOR, outImage);
+
+    // Initialize data
+    numRows = inImage->numRows;
+    numCols = inImage->numCols;
+    arraySize = PSELEMTYPE_SIZEOF(inImage->type.type)*numRows*numCols;
+
+    // Initialize GSL data
+    perm.size = numCols;
+    outPerm->n = numCols;
+    perm.data = outPerm->data.V;
+    PS_GSL_MATRIX_INITIALIZE(lu, outImage->data.V[0]);
+
+    // Non-square matrices not allowed
+    PS_CHECK_SQUARE(inImage, outImage);
+    PS_CHECK_SQUARE(outImage, outImage);
+
+    // Copy psImage input data into GSL matrix data to keep input data pristine
+    memcpy(lu.data, inImage->data.V[0], arraySize);
+
+    // Calculate LU decomposition
+    gsl_linalg_LU_decomp(&lu, &perm, &signum);
+
+    return outImage;
+}
+
+psVector *psMatrixLUSolve(psVector *outVector, const psImage *inImage, const psVector *inVector, const
+                          psVector *inPerm)
+{
+    int arraySize = 0;
+    int numRows = 0;
+    int numCols = 0;
+    gsl_matrix lu;
+    gsl_permutation perm;
+    gsl_vector b;
+    gsl_vector x;
+
+    // Error checks
+    PS_CHECK_POINTERS(outVector, inVector, outVector);
+    PS_CHECK_POINTERS(inVector, inPerm, outVector);
+    PS_CHECK_POINTERS(outVector, inPerm, outVector);
+    PS_CHECK_NULL_IMAGE(inImage, outVector);
+    PS_CHECK_DIMEN_AND_TYPE(inImage, PS_DIMEN_IMAGE, outVector);
+    PS_CHECK_SIZE_IMAGE(inImage, outVector);
+    PS_CHECK_ALLOC_VECTOR(outVector, inImage->numRows, inImage->type.type);
+    PS_CHECK_NULL_VECTOR(outVector, outVector);
+    PS_CHECK_DIMEN_AND_TYPE(outVector, PS_DIMEN_VECTOR, outVector);
+    PS_CHECK_NULL_VECTOR(inVector, outVector);
+    PS_CHECK_DIMEN_AND_TYPE(inVector, PS_DIMEN_VECTOR, outVector);
+    PS_CHECK_NULL_VECTOR(inPerm, outVector);
+    PS_CHECK_DIMEN_AND_TYPE(inPerm, PS_DIMEN_VECTOR, outVector);
+
+    // Initialize data
+    numRows = inImage->numRows;
+    numCols = inImage->numCols;
+    arraySize = PSELEMTYPE_SIZEOF(inImage->type.type)*numRows*numCols;
+
+    // Initialize GSL data
+    PS_GSL_MATRIX_INITIALIZE(lu, inImage->data.V[0]);
+
+    outVector->n = numCols;
+
+    perm.size = inPerm->n;
+    perm.data = inPerm->data.V;
+
+    b.size = inVector->n;
+    b.stride = 1;
+    b.data = inVector->data.V;
+
+    x.size = numCols;
+    x.stride = 1;
+    x.data = outVector->data.V;
+
+    // Solve for {x} in equation: {b} = [A]{x}
+    gsl_linalg_LU_solve(&lu, &perm, &b, &x);
+
+    return outVector;
+}
+
+psImage *psMatrixInvert(psImage *outImage, const psImage *inImage, float *restrict det)
+{
+    int signum = 0;
+    int arraySize = 0;
+    int numRows = 0;
+    int numCols = 0;
+    gsl_matrix inv;
+    gsl_matrix *lu;
+    gsl_permutation *perm = NULL;
+
+    // Error checks
+    if(det == NULL) {
+        psError(__func__, "Invalid operation: determinant argument is NULL.");
+        return outImage;
+    }
+    PS_CHECK_POINTERS(inImage, outImage, outImage);
+    PS_CHECK_NULL_IMAGE(inImage, outImage);
+    PS_CHECK_DIMEN_AND_TYPE(inImage, PS_DIMEN_IMAGE, outImage);
+    PS_CHECK_SIZE_IMAGE(inImage, outImage);
+    PS_CHECK_ALLOC_IMAGE(outImage, inImage->numCols, inImage->numRows, inImage->type.type);
+    PS_CHECK_DIMEN_AND_TYPE(outImage, PS_DIMEN_IMAGE, outImage);
+    PS_CHECK_SIZE_IMAGE(outImage, outImage);
+
+    // Initialize data
+    numRows = inImage->numRows;
+    numCols = inImage->numCols;
+    arraySize = PSELEMTYPE_SIZEOF(inImage->type.type)*numRows*numCols;
+
+    // Allocate GSL structs
+    perm = gsl_permutation_alloc(inImage->numRows);
+    lu = gsl_matrix_alloc(numRows, numCols);
+
+    // Initialize GSL data
+    PS_GSL_MATRIX_INITIALIZE(inv, outImage->data.V[0]);
+
+    // Non-square matrices not allowed
+    PS_CHECK_SQUARE(inImage, outImage);
+    PS_CHECK_SQUARE(outImage, outImage);
+
+    // Copy psImage input data into GSL matrix data to keep input data pristine
+    memcpy(lu->data, inImage->data.V[0], arraySize);
+
+    // Invert data and calculate determinant
+    gsl_linalg_LU_decomp(lu, perm, &signum);
+    gsl_linalg_LU_invert(lu, perm, &inv);
+    *det = (float)gsl_linalg_LU_det(lu, signum);
+
+    // Free GSL structs
+    gsl_permutation_free(perm);
+    gsl_matrix_free(lu);
+
+    return outImage;
+}
+
+float* psMatrixDeterminant(const psImage *restrict inImage)
+{
+    int signum = 0;
+    int arraySize = 0;
+    int numRows = 0;
+    int numCols = 0;
+    float *det = NULL;
+    gsl_matrix *lu = NULL;
+    gsl_permutation *perm = NULL;
+
+    // Error checks
+    PS_CHECK_NULL_IMAGE(inImage, NULL);
+    PS_CHECK_DIMEN_AND_TYPE(inImage, PS_DIMEN_IMAGE, NULL);
+    PS_CHECK_SIZE_IMAGE(inImage, NULL);
+
+    // Initialize data
+    numRows = inImage->numRows;
+    numCols = inImage->numCols;
+    arraySize = PSELEMTYPE_SIZEOF(inImage->type.type)*numRows*numCols;
+
+    // Allocate GSL structs
+    perm = gsl_permutation_alloc(numRows);
+    lu = gsl_matrix_alloc(numRows, numCols);
+
+    // Non-square matrices not allowed
+    PS_CHECK_SQUARE(inImage, 0);
+
+    // Copy psImage input data into GSL matrix data to keep input data pristine
+    memcpy(lu->data, inImage->data.V[0], arraySize);
+
+    // Calculate determinant
+    det = (float*)psAlloc(sizeof(float));
+    gsl_linalg_LU_decomp(lu, perm, &signum);
+    *det = (float)gsl_linalg_LU_det(lu, signum);
+
+    // Free GSL structs
+    gsl_permutation_free(perm);
+    gsl_matrix_free(lu);
+
+    return det;
+}
+
+psImage* psMatrixMultiply(psImage *outImage, psImage *inImage1, psImage *inImage2)
+{
+    int arraySize = 0;
+    int numRows = 0;
+    int numCols = 0;
+    gsl_matrix m1;
+    gsl_matrix m2;
+    gsl_matrix m3;
+
+    // Error checks
+    PS_CHECK_POINTERS(inImage1, outImage, outImage);
+    PS_CHECK_POINTERS(inImage1, inImage2, outImage);
+    PS_CHECK_NULL_IMAGE(inImage1, outImage);
+    PS_CHECK_DIMEN_AND_TYPE(inImage1, PS_DIMEN_IMAGE, outImage);
+    PS_CHECK_SIZE_IMAGE(inImage1, outImage);
+    PS_CHECK_NULL_IMAGE(inImage2, outImage);
+    PS_CHECK_DIMEN_AND_TYPE(inImage2, PS_DIMEN_IMAGE, outImage);
+    PS_CHECK_SIZE_IMAGE(inImage2, outImage);
+    PS_CHECK_ALLOC_IMAGE(outImage, inImage2->numCols, inImage2->numRows, inImage2->type.type);
+    PS_CHECK_DIMEN_AND_TYPE(inImage1, PS_DIMEN_IMAGE, outImage);
+    PS_CHECK_SIZE_IMAGE(outImage, outImage);
+
+    // Initialize data
+    numRows = inImage1->numRows;
+    numCols = inImage1->numCols;
+    arraySize = PSELEMTYPE_SIZEOF(outImage->type.type)*numRows*numCols;
+
+    // Initialize GSL data
+    PS_GSL_MATRIX_INITIALIZE(m1, inImage1->data.V[0]);
+    PS_GSL_MATRIX_INITIALIZE(m2, inImage2->data.V[0]);
+    PS_GSL_MATRIX_INITIALIZE(m3, outImage->data.V[0]);
+
+    // Non-square matrices not allowed
+    PS_CHECK_SQUARE(inImage1, outImage);
+    PS_CHECK_SQUARE(inImage2, outImage);
+    PS_CHECK_SQUARE(outImage, outImage);
+
+    gsl_linalg_matmult(&m1, &m2, &m3);
+
+    return outImage;
+}
+
+psImage* psMatrixTranspose(psImage *outImage, const psImage *inImage)
+{
+    int arraySize = 0;
+    int numRows = 0;
+    int numCols = 0;
+    gsl_matrix trans;
+
+    // Error checks
+    PS_CHECK_POINTERS(inImage, outImage, outImage);
+    PS_CHECK_NULL_IMAGE(inImage, outImage);
+    PS_CHECK_DIMEN_AND_TYPE(inImage, PS_DIMEN_IMAGE, outImage);
+    PS_CHECK_SIZE_IMAGE(inImage, outImage);
+    PS_CHECK_ALLOC_IMAGE(outImage, inImage->numCols, inImage->numRows, inImage->type.type);
+    PS_CHECK_DIMEN_AND_TYPE(outImage, PS_DIMEN_IMAGE, outImage);
+    PS_CHECK_SIZE_IMAGE(outImage, outImage);
+
+    // Initialize data
+    numRows = inImage->numRows;
+    numCols = inImage->numCols;
+    arraySize = PSELEMTYPE_SIZEOF(inImage->type.type)*numRows*numCols;
+
+    // Initialize GSL data
+    PS_GSL_MATRIX_INITIALIZE(trans, outImage->data.V[0]);
+
+    // Non-square matrices not allowed
+    PS_CHECK_SQUARE(inImage, outImage);
+    PS_CHECK_SQUARE(outImage, outImage);
+
+    // Copy psImage input data into psImage output data to keep input data pristine
+    memcpy(outImage->data.V[0], inImage->data.V[0], arraySize);
+
+    // Transpose data
+    gsl_matrix_transpose(&trans);
+
+    return outImage;
+}
+
+psImage *psMatrixEigenvectors(psImage *outImage, psImage *inImage)
+{
+    int numRows = 0;
+    int numCols = 0;
+    gsl_vector *eVals = NULL;
+    gsl_eigen_symmv_workspace *w = NULL;
+    gsl_matrix out;
+    gsl_matrix in;
+
+    // Error checks
+    PS_CHECK_POINTERS(inImage, outImage, outImage);
+    PS_CHECK_NULL_IMAGE(inImage, outImage);
+    PS_CHECK_DIMEN_AND_TYPE(inImage, PS_DIMEN_IMAGE, outImage);
+    PS_CHECK_SIZE_IMAGE(inImage, outImage);
+    PS_CHECK_ALLOC_IMAGE(outImage, inImage->numCols, inImage->numRows, inImage->type.type);
+    PS_CHECK_DIMEN_AND_TYPE(outImage, PS_DIMEN_IMAGE, outImage);
+    PS_CHECK_SIZE_IMAGE(outImage, outImage);
+
+    // Initialize data
+    numRows = inImage->numRows;
+    numCols = inImage->numCols;
+
+    // Initialize GSL data
+    PS_GSL_MATRIX_INITIALIZE(in, inImage->data.V[0]);
+    PS_GSL_MATRIX_INITIALIZE(out, outImage->data.V[0]);
+
+    // Allocate GSL structs
+    eVals = gsl_vector_alloc(numRows);
+    w = gsl_eigen_symmv_alloc(numRows);
+
+    // Non-square matrices not allowed
+    PS_CHECK_SQUARE(inImage, outImage);
+    PS_CHECK_SQUARE(outImage, outImage);
+
+    // Calculate Eigenvalues and Eigenvectors...Eigenvalues not currently used
+    gsl_eigen_symmv(&in, eVals, &out, w);
+
+    // Free GSL structs
+    gsl_eigen_symmv_free(w);
+    gsl_vector_free(eVals);
+
+    return outImage;
+}
+
+psVector *psMatrixToVector(psVector *outVector, psImage *inImage)
+{
+    int size = 0;
+
+    // Error checks
+    PS_CHECK_NULL_IMAGE(inImage, outVector);
+    PS_CHECK_DIMEN_AND_TYPE(inImage, PS_DIMEN_IMAGE, outVector);
+    PS_CHECK_SIZE_IMAGE(inImage, outVector);
+
+    if(inImage->numRows == 1) {
+        // Create transposed row vector
+        PS_CHECK_ALLOC_VECTOR(outVector, inImage->numCols, inImage->type.type);
+        outVector->type.dimen = PS_DIMEN_TRANSV;
+    } else if(inImage->numCols == 1) {
+        // Create non-transposed column vector
+        PS_CHECK_ALLOC_VECTOR(outVector, inImage->numRows, inImage->type.type);
+    } else {
+        psError(__func__, "Image does not have dim with 1 col or 1 row: (%d x %d).", inImage->numRows,
+                inImage->numCols);
+        return outVector;
+    }
+
+    PS_CHECK_NULL_VECTOR(outVector, outVector);
+
+
+    // More checks
+    if(outVector->type.dimen == PS_DIMEN_VECTOR) {
+        PS_CHECK_DIMEN_AND_TYPE(outVector, PS_DIMEN_VECTOR, outVector);
+
+        if(outVector->n == 0) {
+            outVector->n = inImage->numRows;
+        }
+
+        if(outVector->n != inImage->numRows) {
+            psError(__func__, "Image and vector sizes differ: (%d vs %d).", inImage->numRows, outVector->n);
+            return outVector;
+        }
+
+        size = PSELEMTYPE_SIZEOF(inImage->type.type)*inImage->numRows;
+
+    } else if(outVector->type.dimen == PS_DIMEN_TRANSV) {
+        PS_CHECK_DIMEN_AND_TYPE(outVector, PS_DIMEN_TRANSV, outVector);
+
+        if(outVector->n == 0) {
+            outVector->n = inImage->numCols;
+        }
+
+        if(outVector->n != inImage->numCols) {
+            psError(__func__, "Image and vector sizes differ: (%d vs %d).", inImage->numCols, outVector->n);
+            return outVector;
+        }
+
+        size = PSELEMTYPE_SIZEOF(inImage->type.type)*inImage->numCols;
+    }
+
+    memcpy(outVector->data.V, inImage->data.V[0], size);
+
+    return outVector;
+}
+
+psImage *psVectorToMatrix(psImage *outImage, psVector *inVector)
+{
+    int size = 0;
+
+    // Error checks
+    PS_CHECK_NULL_VECTOR(inVector, outImage);
+
+    if(inVector->type.dimen == PS_DIMEN_VECTOR) {
+        PS_CHECK_DIMEN_AND_TYPE(inVector, PS_DIMEN_VECTOR, outImage);
+        PS_CHECK_SIZE_VECTOR(inVector, outImage);
+        PS_CHECK_ALLOC_IMAGE(outImage, 1, inVector->n, PS_TYPE_F64)
+
+        // More checks for PS_DIMEN_VECTOR
+        if(outImage->numCols > 1) {
+            psError(__func__, "Image has more than 1 column: numCols = %d.", outImage->numCols);
+            return outImage;
+        } else if(outImage->numRows != inVector->n) {
+            psError(__func__, "Image and vector sizes differ: (%d vs %d).", outImage->numRows, inVector->n);
+            return outImage;
+        }
+
+        size = PSELEMTYPE_SIZEOF(outImage->type.type)*outImage->numRows;
+
+    } else if(inVector->type.dimen == PS_DIMEN_TRANSV) {
+        PS_CHECK_DIMEN_AND_TYPE(inVector, PS_DIMEN_TRANSV, outImage);
+        PS_CHECK_SIZE_VECTOR(inVector, outImage);
+        PS_CHECK_ALLOC_IMAGE(outImage, inVector->n, 1, PS_TYPE_F64)
+
+        // More checks for PS_DIMEN_TRANSV
+        if(outImage->numRows > 1) {
+            psError(__func__, "Image has more than 1 row: numRows = %d.", outImage->numRows);
+            return outImage;
+        } else if(outImage->numCols != inVector->n) {
+            psError(__func__, "Image and vector sizes differ: (%d vs %d).", outImage->numCols, inVector->n);
+            return outImage;
+        }
+
+        size = PSELEMTYPE_SIZEOF(outImage->type.type)*outImage->numCols;
+    }
+
+    PS_CHECK_NULL_IMAGE(outImage, outImage);
+    PS_CHECK_DIMEN_AND_TYPE(outImage, PS_DIMEN_IMAGE, outImage);
+
+    memcpy(outImage->data.V[0], inVector->data.V, size);
+
+    return outImage;
+}
+
Index: /tags/rel1_1/psLib/src/math/psMatrix.h
===================================================================
--- /tags/rel1_1/psLib/src/math/psMatrix.h	(revision 1056)
+++ /tags/rel1_1/psLib/src/math/psMatrix.h	(revision 1056)
@@ -0,0 +1,165 @@
+/** @file  psMatrix.h
+ *
+ *  @brief Provides functions for linear algebra operations on psImages and psVectors. 
+ *
+ *  Functions are provided to:
+ *      Transpose a psImage
+ *      Compute LUD
+ *      Solve LUD
+ *      Matrix inversion
+ *      Calculate determinant
+ *      Matrix multiplication
+ *      Calculate Eigenvectors
+ *      Convert matrix to vector
+ *      Convert vector to matrix
+ *
+ *  These functions treat psImages as if they were matrices, therefore there is no psMatrix. These functions
+ *  operate only with the psF64 data type.
+ *
+ *  @ingroup Matrix
+ *
+ *  @author Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.6 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-10 01:58:06 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PSMATRIX_H
+#define PSMATRIX_H
+
+/// @addtogroup Matrix
+/// @{
+
+/** LU Decomposition of psImage matrix.
+ *
+ *  Performs a LU decomposition on a psImage matrix and returns the LU matrix. If the user specifies NULL for
+ *  the outImage or outPerm arguments, then they will be automatically created. The input image must 
+ *  be square. This function operates only with the psF64 data type. Input and output arguments should not be 
+ *  the same. GSL indexes the top row as the zero row, not the bottom.  
+ *
+ *  @return  psImage*: Pointer to LU decomposed psImage.
+ */
+psImage *psMatrixLUD(
+    psImage *outImage,  ///< Image to return, or NULL.
+    psVector *outPerm,  ///< Output permutation vector used by psMatrixLUSolve.
+    psImage *inImage    ///< Image to decompose.
+);
+
+/** LU Solution of psImage matrix.
+ *
+ *  Solves for and returns the psVector, {x} in the equation [A]{x} = {b}. If the user specifies NULL as the 
+ *  outVector argument, then it will automatically be created. The input image must be square. This function 
+ *  operates only with the psF64 data type. Input and output arguments should not be the same. GSL indexes 
+ *  the top row as the zero row, not the bottom.  
+ *
+ *  @return  psVector*: Pointer to psVector solution of matrix equation.
+ */
+psVector *psMatrixLUSolve(
+    psVector *outVector,        ///< Vector to return, or NULL.
+    const psImage *luImage,     ///< LU-decomposed matrix.
+    const psVector *inVector,   ///< Vector right-hand-side of equation.
+    const psVector *inPerm      ///< Permutation vector resulting from psMatrixLUD function.
+);
+
+/** Invert psImage matrix.
+ *
+ *  Inverts a psImage matrix and returns the determinant as an option through the argument list. If the user
+ *  specifies NULL as the outImage argument, then it will automatically be created. The input image must be 
+ *  square. This function operates only with the psF64 data type. Input and output arguments should not be 
+ *  the same. GSL indexes the top row as the zero row, not the bottom.  
+ *
+ *  @return  psImage*: Pointer to inverted psImage.
+ */
+psImage *psMatrixInvert(
+    psImage *outImage,      ///< Image to return, or NULL for in-place substitution.
+    const psImage *inImage, ///< Image to be inverted
+    float *restrict det     ///< Determinant to return, or NULL
+);
+
+/** Calculate psImage matrix determinant.
+ *
+ *  Calculates the determinant of a psImage matrix and returns the single precision floating point result. The
+ *  input image must be square. This function operates only with the psF64 data type. GSL indexes the top row 
+ *  as the zero row, not the bottom.  
+ *
+ *  @return  float: Determinant from psImage.
+ */
+float* psMatrixDeterminant(
+    const psImage *restrict inMatrix    ///< Image used to calculate determinant.
+);
+
+/** Performs psImage matrix multiplication.
+ *
+ *  Performs a classical matrix multiplication involving row and column operations. Input images must be square 
+ *  and the same size. If the user specifies NULL as the outImage argument, then it will automatically be 
+ *  created. This function operates only with the psF64 data type. GSL indexes the top row as the
+ *  zero row, not the bottom.  
+ *
+ *  @return  psImage*: Pointer to resulting psImage.
+ */
+psImage *psMatrixMultiply(
+    psImage *outImage,  ///< Matrix to return, or NULL.
+    psImage *inImage1,  ///< First input image.
+    psImage *inImage2   ///< Second input image.
+);
+
+/** Transpose matrix.
+ *
+ *  Performs psImage matrix transpose by substituting existing rows for columns. The input image must be 
+ *  square. If the user specifies NULL as the outImage argument, then it will automaticallty be created.
+ *  This function operates only with the psF64 data type. GSL indexes the top row as the zero 
+ *  row, not the bottom.  
+ *
+ *  @return  psImage*: Pointer to transposed psImage.
+ */
+psImage *psMatrixTranspose(
+    psImage *outImage,      ///< Image to return, or NULL
+    const psImage *inImage  ///< Image to transpose
+);
+
+/** Calculate matrix eigenvectors.
+ *
+ *  Calculates the eigenvectors for a matrix. The input image must be symmetric and square. If the user 
+ *  specifies NULL as the outImage argument, then it will automatically be created. This function operates 
+ *  only with the psF64 data type. GSL indexes the top row as the zero row, not the bottom.  
+ *
+ *  @return  psImage*: Pointer to matrix of Eigenvectors.
+ */
+psImage *psMatrixEigenvectors(
+    psImage *outImage,  ///< Eigenvectors to return, or NULL.
+    psImage *inImage    ///< Input image.
+);
+
+/** Convert matrix to vector.
+ *
+ *  Converts a 1-d psImage matrix into a vector. If the user specifies NULL as the outVector argument, then it
+ *  will automatically be created based on the input image (PS_DIMEN_VECTOR for an input image with 1 col or
+ *  PS_DIMENT_TRANSV for an input image with 1 row). Either the number of rows or the number of colums of the
+ *  input matrix must be 1. This function operates only  with the psF64 data type.
+ *
+ *  @return  psVector*: Pointer to psVector.
+ */
+psVector *psMatrixToVector(
+    psVector *outVector,    ///< Vector to return, or NULL.
+    psImage *inImage        ///< Image to convert.
+);
+
+/** Convert vector to matrix.
+ *
+ *  Converts a vector into a psImage matrix. If the dimensionality of the vector is PS_DIMEN_VECTOR, then the
+ *  resulting psImage is a 1d column. If the dimensionality of the vector is PS_DIMEN_TRANSV, then the
+ *  resulting psImage is a 1d row. If the user specifies NULL as the outImage argument,  then it will 
+ *  automatically be created. This function operates only with the psF64 data type.  
+ *
+ *  @return  psVector*: Pointer to psIamge.
+ */
+psImage *psVectorToMatrix(
+    psImage *outImage,  ///< Matrix to return, or NULL.
+    psVector *inVector  ///< Vector to convert.
+);
+
+/// @}
+
+#endif
Index: /tags/rel1_1/psLib/src/math/psPolynomial.c
===================================================================
--- /tags/rel1_1/psLib/src/math/psPolynomial.c	(revision 1056)
+++ /tags/rel1_1/psLib/src/math/psPolynomial.c	(revision 1056)
@@ -0,0 +1,751 @@
+/** @file  psFunctions.c
+ *
+ *  @brief Contains basic function allocation, deallocation, and evaluation
+ *         routines.
+ *
+ *  This file will hold the functions for allocated, freeing, and evaluating
+ *  polynomials.  It also contains a Gaussian functions.
+ *
+ *  @version $Revision: 1.13 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-14 19:40:14 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+/*****************************************************************************/
+/*  INCLUDE FILES                                                            */
+/*****************************************************************************/
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <float.h>
+#include <math.h>
+
+#include "psMemory.h"
+#include "psVector.h"
+#include "psTrace.h"
+#include "psError.h"
+#include "psAbort.h"
+#include "psFunctions.h"
+#include "psSort.h"
+
+#include "float.h"
+#include <math.h>
+#include <gsl/gsl_rng.h>
+#include <gsl/gsl_randist.h>
+/*****************************************************************************/
+/*  FUNCTION IMPLEMENTATION - PUBLIC                                         */
+/*****************************************************************************/
+
+/*****************************************************************************
+    Evaluate a non-normalized Gaussian with the given mean and sigma at the
+    given coordianate.  Note that this is not a Gaussian deviate.  The
+    evaluated Gaussian is: \f[ exp(-\frac{(x-mean)^2}{2\sigma^2}) \f]
+ *****************************************************************************/
+float
+psGaussian(float x,
+           float mean,
+           float stddev,
+           int normal)
+{
+    float tmp = 0.0;
+
+    if (normal == 1) {
+        #ifdef DARWIN
+        tmp = 1.0 / (float)sqrt(2.0 * M_PI * (stddev * stddev));
+        #else
+
+        tmp = 1.0 / sqrtf(2.0 * M_PI * (stddev * stddev));
+        #endif
+
+        return(tmp * exp(-((x-mean) * (x-mean)) / (2.0 * stddev * stddev)));
+    } else {
+        return(exp(-((x-mean) * (x-mean)) / (2.0 * stddev * stddev)));
+    }
+}
+
+/*****************************************************************************
+    psGaussianDev()
+ This routine creates a psVector of the specified size and type F32
+ and fills it with a random Gaussian distribution of numbers with
+ the specified mean and sigma.  This routine makes use of the GSL
+ routines for generating both uniformly distributed numbers and the
+ Gaussian distribution as well.
+ 
+ NOTE: There is no way to seed the random generator.
+ *****************************************************************************/
+psVector *psGaussianDev(float mean,
+                        float sigma,
+                        int Npts)
+{
+    psVector *gauss = NULL;
+    const gsl_rng_type *T = NULL;
+    gsl_rng *r = NULL;
+    int i = 0;
+
+    gauss = psVectorAlloc(Npts, PS_TYPE_F32);
+    gauss->n = Npts;
+    gsl_rng_env_setup();
+    T = gsl_rng_default;
+    r = gsl_rng_alloc(T);
+
+    for (i = 0; i < Npts; i++) {
+        gauss->data.F32[i] = mean + gsl_ran_gaussian(r, sigma);
+    }
+
+    // NOTE: Should I free r as well?
+    return(gauss);
+}
+
+
+/*****************************************************************************
+    This routine must allocate memory for the polynomial structures.
+ *****************************************************************************/
+psPolynomial1D *psPolynomial1DAlloc(int n)
+{
+    int i = 0;
+    psPolynomial1D *newPoly = NULL;
+
+    newPoly = (psPolynomial1D *) psAlloc(sizeof(psPolynomial1D));
+    newPoly->n = n;
+    newPoly->coeff    = (float *) psAlloc(n * sizeof(float));
+    newPoly->coeffErr = (float *) psAlloc(n * sizeof(float));
+    newPoly->mask     = (char *)  psAlloc(n * sizeof(char));
+    for (i=0;i<n;i++) {
+        newPoly->coeff[i] = 0.0;
+        newPoly->coeffErr[i] = 0.0;
+        newPoly->mask[i] = 0.0;
+    }
+
+    return(newPoly);
+}
+
+psPolynomial2D *psPolynomial2DAlloc(int nX, int nY)
+{
+    int x = 0;
+    int y = 0;
+    psPolynomial2D *newPoly = NULL;
+
+    newPoly = (psPolynomial2D *) psAlloc(sizeof(psPolynomial2D));
+    newPoly->nX = nX;
+    newPoly->nY = nY;
+
+    newPoly->coeff    = (float **) psAlloc(nX * sizeof(float *));
+    newPoly->coeffErr = (float **) psAlloc(nX * sizeof(float *));
+    newPoly->mask     = (char **)  psAlloc(nX * sizeof(char *));
+    for (x=0;x<nX;x++) {
+        newPoly->coeff[x]    = (float *) psAlloc(nY * sizeof(float));
+        newPoly->coeffErr[x] = (float *) psAlloc(nY * sizeof(float));
+        newPoly->mask[x]     = (char *)  psAlloc(nY * sizeof(char));
+    }
+    for (x=0;x<nX;x++) {
+        for (y=0;y<nY;y++) {
+            newPoly->coeff[x][y] = 0.0;
+            newPoly->coeffErr[x][y] = 0.0;
+            newPoly->mask[x][y] = 0;
+        }
+    }
+
+    return(newPoly);
+}
+
+psPolynomial3D *psPolynomial3DAlloc(int nX, int nY, int nZ)
+{
+    int x = 0;
+    int y = 0;
+    int z = 0;
+    psPolynomial3D *newPoly = NULL;
+
+    newPoly = (psPolynomial3D *) psAlloc(sizeof(psPolynomial3D));
+    newPoly->nX = nX;
+    newPoly->nY = nY;
+    newPoly->nZ = nZ;
+
+    newPoly->coeff    = (float ***) psAlloc(nX * sizeof(float **));
+    newPoly->coeffErr = (float ***) psAlloc(nX * sizeof(float **));
+    newPoly->mask     = (char ***)  psAlloc(nX * sizeof(char **));
+    for (x=0;x<nX;x++) {
+        newPoly->coeff[x]    = (float **) psAlloc(nY * sizeof(float *));
+        newPoly->coeffErr[x] = (float **) psAlloc(nY * sizeof(float *));
+        newPoly->mask[x]     = (char **)  psAlloc(nY * sizeof(char *));
+        for (y=0;y<nY;y++) {
+            newPoly->coeff[x][y]    = (float *) psAlloc(nZ * sizeof(float));
+            newPoly->coeffErr[x][y] = (float *) psAlloc(nZ * sizeof(float));
+            newPoly->mask[x][y]     = (char *)  psAlloc(nZ * sizeof(char));
+        }
+    }
+    for (x=0;x<nX;x++) {
+        for (y=0;y<nY;y++) {
+            for (z=0;z<nZ;z++) {
+                newPoly->coeff[x][y][z] = 0.0;
+                newPoly->coeffErr[x][y][z] = 0.0;
+                newPoly->mask[x][y][z] = 0;
+            }
+        }
+    }
+
+    return(newPoly);
+}
+
+psPolynomial4D *psPolynomial4DAlloc(int nW, int nX, int nY, int nZ)
+{
+    int w = 0;
+    int x = 0;
+    int y = 0;
+    int z = 0;
+    psPolynomial4D *newPoly = NULL;
+
+    newPoly = (psPolynomial4D *) psAlloc(sizeof(psPolynomial4D));
+    newPoly->nW = nW;
+    newPoly->nX = nX;
+    newPoly->nY = nY;
+    newPoly->nZ = nZ;
+
+    newPoly->coeff    = (float ****) psAlloc(nW * sizeof(float ***));
+    newPoly->coeffErr = (float ****) psAlloc(nW * sizeof(float ***));
+    newPoly->mask     = (char ****)  psAlloc(nW * sizeof(char ***));
+    for (w=0;w<nW;w++) {
+        newPoly->coeff[w]    = (float ***) psAlloc(nX * sizeof(float **));
+        newPoly->coeffErr[w] = (float ***) psAlloc(nX * sizeof(float **));
+        newPoly->mask[w]     = (char ***)  psAlloc(nX * sizeof(char **));
+        for (x=0;x<nX;x++) {
+            newPoly->coeff[w][x]    = (float **) psAlloc(nY * sizeof(float *));
+            newPoly->coeffErr[w][x] = (float **) psAlloc(nY * sizeof(float *));
+            newPoly->mask[w][x]     = (char **) psAlloc(nY * sizeof(char *));
+            for (y=0;y<nY;y++) {
+                newPoly->coeff[w][x][y]    = (float *) psAlloc(nZ * sizeof(float));
+                newPoly->coeffErr[w][x][y] = (float *) psAlloc(nZ * sizeof(float));
+                newPoly->mask[w][x][y]     = (char *) psAlloc(nZ * sizeof(char));
+            }
+        }
+    }
+    for (w=0;w<nW;w++) {
+        for (x=0;x<nX;x++) {
+            for (y=0;y<nY;y++) {
+                for (z=0;z<nZ;z++) {
+                    newPoly->coeff[w][x][y][z] = 0.0;
+                    newPoly->coeffErr[w][x][y][z] = 0.0;
+                    newPoly->mask[w][x][y][z] = 0;
+                }
+            }
+        }
+    }
+
+    return(newPoly);
+}
+
+void psPolynomial1DFree(psPolynomial1D *myPoly)
+{
+    psFree(myPoly->coeff);
+    psFree(myPoly->coeffErr);
+    psFree(myPoly->mask);
+    psFree(myPoly);
+}
+
+void psPolynomial2DFree(psPolynomial2D *myPoly)
+{
+    int x = 0;
+
+    for (x=0;x<myPoly->nX;x++) {
+        psFree(myPoly->coeff[x]);
+        psFree(myPoly->coeffErr[x]);
+        psFree(myPoly->mask[x]);
+    }
+    psFree(myPoly->coeff);
+    psFree(myPoly->coeffErr);
+    psFree(myPoly->mask);
+
+    psFree(myPoly);
+}
+
+void psPolynomial3DFree(psPolynomial3D *myPoly)
+{
+    int x = 0;
+    int y = 0;
+
+    for (x=0;x<myPoly->nX;x++) {
+        for (y=0;y<myPoly->nY;y++) {
+            psFree(myPoly->coeff[x][y]);
+            psFree(myPoly->coeffErr[x][y]);
+            psFree(myPoly->mask[x][y]);
+        }
+        psFree(myPoly->coeff[x]);
+        psFree(myPoly->coeffErr[x]);
+        psFree(myPoly->mask[x]);
+    }
+
+    psFree(myPoly->coeff);
+    psFree(myPoly->coeffErr);
+    psFree(myPoly->mask);
+    psFree(myPoly);
+}
+
+void psPolynomial4DFree(psPolynomial4D *myPoly)
+{
+    int w = 0;
+    int x = 0;
+    int y = 0;
+
+    for (w=0;w<myPoly->nW;w++) {
+        for (x=0;x<myPoly->nX;x++) {
+            for (y=0;y<myPoly->nY;y++) {
+                psFree(myPoly->coeff[w][x][y]);
+                psFree(myPoly->coeffErr[w][x][y]);
+                psFree(myPoly->mask[w][x][y]);
+            }
+            psFree(myPoly->coeff[w][x]);
+            psFree(myPoly->coeffErr[w][x]);
+            psFree(myPoly->mask[w][x]);
+        }
+        psFree(myPoly->coeff[w]);
+        psFree(myPoly->coeffErr[w]);
+        psFree(myPoly->mask[w]);
+    }
+
+    psFree(myPoly->coeff);
+    psFree(myPoly->coeffErr);
+    psFree(myPoly->mask);
+    psFree(myPoly);
+}
+
+/*****************************************************************************
+    Polynomial coefficients will be accessed in [w][x][y][z] fashion.
+ *****************************************************************************/
+float
+psEvalPolynomial1D(float x,
+                   const psPolynomial1D *myPoly)
+{
+    int loop_x = 0;
+    float polySum = 0.0;
+    float xSum = 1.0;
+
+    // NOTE: Do we want to flag this case?
+    if (myPoly->n == 0) {
+        return(1.0);
+    }
+
+    for (loop_x=0;loop_x<myPoly->n;loop_x++) {
+        polySum+= xSum * myPoly->coeff[loop_x];
+        xSum*=x;
+    }
+
+    return(polySum);
+}
+
+
+float
+psEvalPolynomial2D(float x,
+                   float y,
+                   const psPolynomial2D *myPoly)
+{
+    int loop_x = 0;
+    int loop_y = 0;
+    float polySum = 0.0;
+    float xSum = 1.0;
+    float ySum = 1.0;
+
+    for (loop_x=0;loop_x<myPoly->nX;loop_x++) {
+        ySum = xSum;
+        for (loop_y=0;loop_y<myPoly->nY;loop_y++) {
+            polySum+= ySum * myPoly->coeff[loop_x][loop_y];
+            ySum*=y;
+        }
+        xSum*=x;
+    }
+
+    return(polySum);
+}
+
+float
+psEvalPolynomial3D(float x,
+                   float y,
+                   float z,
+                   const psPolynomial3D *myPoly)
+{
+    int loop_x = 0;
+    int loop_y = 0;
+    int loop_z = 0;
+    float polySum = 0.0;
+    float xSum = 1.0;
+    float ySum = 1.0;
+    float zSum = 1.0;
+
+    for (loop_x=0;loop_x<myPoly->nX;loop_x++) {
+        ySum = xSum;
+        for (loop_y=0;loop_y<myPoly->nY;loop_y++) {
+            zSum = ySum;
+            for (loop_z=0;loop_z<myPoly->nZ;loop_z++) {
+                polySum+= zSum * myPoly->coeff[loop_x][loop_y][loop_z];
+                zSum*=z;
+            }
+            ySum*=y;
+        }
+        xSum*=x;
+    }
+
+    return(polySum);
+}
+
+float
+psEvalPolynomial4D(float w,
+                   float x,
+                   float y,
+                   float z,
+                   const psPolynomial4D *myPoly)
+{
+    int loop_w = 0;
+    int loop_x = 0;
+    int loop_y = 0;
+    int loop_z = 0;
+    float polySum = 0.0;
+    float wSum = 1.0;
+    float xSum = 1.0;
+    float ySum = 1.0;
+    float zSum = 1.0;
+
+    for (loop_w=0;loop_w<myPoly->nW;loop_w++) {
+        xSum = wSum;
+        for (loop_x=0;loop_x<myPoly->nX;loop_x++) {
+            ySum = xSum;
+            for (loop_y=0;loop_y<myPoly->nY;loop_y++) {
+                zSum = ySum;
+                for (loop_z=0;loop_z<myPoly->nZ;loop_z++) {
+                    polySum+= zSum *
+                              myPoly->coeff[loop_w][loop_x][loop_y][loop_z];
+                    zSum*=z;
+                }
+                ySum*=y;
+            }
+            xSum*=x;
+        }
+        wSum*=w;
+    }
+
+    return(polySum);
+}
+
+
+
+
+psDPolynomial1D *psDPolynomial1DAlloc(int n)
+{
+    int i = 0;
+    psDPolynomial1D *newPoly = NULL;
+
+    newPoly = (psDPolynomial1D *) psAlloc(sizeof(psDPolynomial1D));
+    newPoly->n = n;
+    newPoly->coeff    = (double *) psAlloc(n * sizeof(double));
+    newPoly->coeffErr = (double *) psAlloc(n * sizeof(double));
+    newPoly->mask     = (char *)  psAlloc(n * sizeof(char));
+    for (i=0;i<n;i++) {
+        newPoly->coeff[i] = 0.0;
+        newPoly->coeffErr[i] = 0.0;
+        newPoly->mask[i] = 0.0;
+    }
+
+    return(newPoly);
+}
+
+psDPolynomial2D *psDPolynomial2DAlloc(int nX, int nY)
+{
+    int x = 0;
+    int y = 0;
+    psDPolynomial2D *newPoly = NULL;
+
+    newPoly = (psDPolynomial2D *) psAlloc(sizeof(psDPolynomial2D));
+    newPoly->nX = nX;
+    newPoly->nY = nY;
+
+    newPoly->coeff    = (double **) psAlloc(nX * sizeof(double *));
+    newPoly->coeffErr = (double **) psAlloc(nX * sizeof(double *));
+    newPoly->mask     = (char **)  psAlloc(nX * sizeof(char *));
+    for (x=0;x<nX;x++) {
+        newPoly->coeff[x]    = (double *) psAlloc(nY * sizeof(double));
+        newPoly->coeffErr[x] = (double *) psAlloc(nY * sizeof(double));
+        newPoly->mask[x]     = (char *)  psAlloc(nY * sizeof(char));
+    }
+    for (x=0;x<nX;x++) {
+        for (y=0;y<nY;y++) {
+            newPoly->coeff[x][y] = 0.0;
+            newPoly->coeffErr[x][y] = 0.0;
+            newPoly->mask[x][y] = 0;
+        }
+    }
+
+    return(newPoly);
+}
+
+psDPolynomial3D *psDPolynomial3DAlloc(int nX, int nY, int nZ)
+{
+    int x = 0;
+    int y = 0;
+    int z = 0;
+    psDPolynomial3D *newPoly = NULL;
+
+    newPoly = (psDPolynomial3D *) psAlloc(sizeof(psDPolynomial3D));
+    newPoly->nX = nX;
+    newPoly->nY = nY;
+    newPoly->nZ = nZ;
+
+    newPoly->coeff    = (double ***) psAlloc(nX * sizeof(double **));
+    newPoly->coeffErr = (double ***) psAlloc(nX * sizeof(double **));
+    newPoly->mask     = (char ***)  psAlloc(nX * sizeof(char **));
+    for (x=0;x<nX;x++) {
+        newPoly->coeff[x]    = (double **) psAlloc(nY * sizeof(double *));
+        newPoly->coeffErr[x] = (double **) psAlloc(nY * sizeof(double *));
+        newPoly->mask[x]     = (char **)  psAlloc(nY * sizeof(char *));
+        for (y=0;y<nY;y++) {
+            newPoly->coeff[x][y]    = (double *) psAlloc(nZ * sizeof(double));
+            newPoly->coeffErr[x][y] = (double *) psAlloc(nZ * sizeof(double));
+            newPoly->mask[x][y]     = (char *)  psAlloc(nZ * sizeof(char));
+        }
+    }
+    for (x=0;x<nX;x++) {
+        for (y=0;y<nY;y++) {
+            for (z=0;z<nZ;z++) {
+                newPoly->coeff[x][y][z] = 0.0;
+                newPoly->coeffErr[x][y][z] = 0.0;
+                newPoly->mask[x][y][z] = 0;
+            }
+        }
+    }
+
+    return(newPoly);
+}
+
+psDPolynomial4D *psDPolynomial4DAlloc(int nW, int nX, int nY, int nZ)
+{
+    int w = 0;
+    int x = 0;
+    int y = 0;
+    int z = 0;
+    psDPolynomial4D *newPoly = NULL;
+
+    newPoly = (psDPolynomial4D *) psAlloc(sizeof(psDPolynomial4D));
+    newPoly->nW = nW;
+    newPoly->nX = nX;
+    newPoly->nY = nY;
+    newPoly->nZ = nZ;
+
+    newPoly->coeff    = (double ****) psAlloc(nW * sizeof(double ***));
+    newPoly->coeffErr = (double ****) psAlloc(nW * sizeof(double ***));
+    newPoly->mask     = (char ****)  psAlloc(nW * sizeof(char ***));
+    for (w=0;w<nW;w++) {
+        newPoly->coeff[w]    = (double ***) psAlloc(nX * sizeof(double **));
+        newPoly->coeffErr[w] = (double ***) psAlloc(nX * sizeof(double **));
+        newPoly->mask[w]     = (char ***)  psAlloc(nX * sizeof(char **));
+        for (x=0;x<nX;x++) {
+            newPoly->coeff[w][x]    = (double **) psAlloc(nY * sizeof(double *));
+            newPoly->coeffErr[w][x] = (double **) psAlloc(nY * sizeof(double *));
+            newPoly->mask[w][x]     = (char **) psAlloc(nY * sizeof(char *));
+            for (y=0;y<nY;y++) {
+                newPoly->coeff[w][x][y]    = (double *) psAlloc(nZ * sizeof(double));
+                newPoly->coeffErr[w][x][y] = (double *) psAlloc(nZ * sizeof(double));
+                newPoly->mask[w][x][y]     = (char *) psAlloc(nZ * sizeof(char));
+            }
+        }
+    }
+    for (w=0;w<nW;w++) {
+        for (x=0;x<nX;x++) {
+            for (y=0;y<nY;y++) {
+                for (z=0;z<nZ;z++) {
+                    newPoly->coeff[w][x][y][z] = 0.0;
+                    newPoly->coeffErr[w][x][y][z] = 0.0;
+                    newPoly->mask[w][x][y][z] = 0;
+                }
+            }
+        }
+    }
+
+    return(newPoly);
+}
+
+void psDPolynomial1DFree(psDPolynomial1D *myPoly)
+{
+    psFree(myPoly->coeff);
+    psFree(myPoly->coeffErr);
+    psFree(myPoly->mask);
+    psFree(myPoly);
+}
+
+void psDPolynomial2DFree(psDPolynomial2D *myPoly)
+{
+    int x = 0;
+
+    for (x=0;x<myPoly->nX;x++) {
+        psFree(myPoly->coeff[x]);
+        psFree(myPoly->coeffErr[x]);
+        psFree(myPoly->mask[x]);
+    }
+    psFree(myPoly->coeff);
+    psFree(myPoly->coeffErr);
+    psFree(myPoly->mask);
+
+    psFree(myPoly);
+}
+
+void psDPolynomial3DFree(psDPolynomial3D *myPoly)
+{
+    int x = 0;
+    int y = 0;
+
+    for (x=0;x<myPoly->nX;x++) {
+        for (y=0;y<myPoly->nY;y++) {
+            psFree(myPoly->coeff[x][y]);
+            psFree(myPoly->coeffErr[x][y]);
+            psFree(myPoly->mask[x][y]);
+        }
+        psFree(myPoly->coeff[x]);
+        psFree(myPoly->coeffErr[x]);
+        psFree(myPoly->mask[x]);
+    }
+
+    psFree(myPoly->coeff);
+    psFree(myPoly->coeffErr);
+    psFree(myPoly->mask);
+    psFree(myPoly);
+}
+
+void psDPolynomial4DFree(psDPolynomial4D *myPoly)
+{
+    int w = 0;
+    int x = 0;
+    int y = 0;
+
+    for (w=0;w<myPoly->nW;w++) {
+        for (x=0;x<myPoly->nX;x++) {
+            for (y=0;y<myPoly->nY;y++) {
+                psFree(myPoly->coeff[w][x][y]);
+                psFree(myPoly->coeffErr[w][x][y]);
+                psFree(myPoly->mask[w][x][y]);
+            }
+            psFree(myPoly->coeff[w][x]);
+            psFree(myPoly->coeffErr[w][x]);
+            psFree(myPoly->mask[w][x]);
+        }
+        psFree(myPoly->coeff[w]);
+        psFree(myPoly->coeffErr[w]);
+        psFree(myPoly->mask[w]);
+    }
+
+    psFree(myPoly->coeff);
+    psFree(myPoly->coeffErr);
+    psFree(myPoly->mask);
+    psFree(myPoly);
+}
+
+/*****************************************************************************
+    Polynomial coefficients will be accessed in [w][x][y][z] fashion.
+ *****************************************************************************/
+double
+psDEvalPolynomial1D(double x,
+                    const psDPolynomial1D *myPoly)
+{
+    int loop_x = 0;
+    double polySum = 0.0;
+    double xSum = 1.0;
+
+    // NOTE: Do we want to flag this case?
+    if (myPoly->n == 0) {
+        return(1.0);
+    }
+
+    for (loop_x=0;loop_x<myPoly->n;loop_x++) {
+        polySum+= xSum * myPoly->coeff[loop_x];
+        xSum*=x;
+    }
+
+    return(polySum);
+}
+
+
+double
+psDEvalPolynomial2D(double x,
+                    double y,
+                    const psDPolynomial2D *myPoly)
+{
+    int loop_x = 0;
+    int loop_y = 0;
+    double polySum = 0.0;
+    double xSum = 1.0;
+    double ySum = 1.0;
+
+    for (loop_x=0;loop_x<myPoly->nX;loop_x++) {
+        ySum = xSum;
+        for (loop_y=0;loop_y<myPoly->nY;loop_y++) {
+            polySum+= ySum * myPoly->coeff[loop_x][loop_y];
+            ySum*=y;
+        }
+        xSum*=x;
+    }
+
+    return(polySum);
+}
+
+double
+psDEvalPolynomial3D(double x,
+                    double y,
+                    double z,
+                    const psDPolynomial3D *myPoly)
+{
+    int loop_x = 0;
+    int loop_y = 0;
+    int loop_z = 0;
+    double polySum = 0.0;
+    double xSum = 1.0;
+    double ySum = 1.0;
+    double zSum = 1.0;
+
+    for (loop_x=0;loop_x<myPoly->nX;loop_x++) {
+        ySum = xSum;
+        for (loop_y=0;loop_y<myPoly->nY;loop_y++) {
+            zSum = ySum;
+            for (loop_z=0;loop_z<myPoly->nZ;loop_z++) {
+                polySum+= zSum * myPoly->coeff[loop_x][loop_y][loop_z];
+                zSum*=z;
+            }
+            ySum*=y;
+        }
+        xSum*=x;
+    }
+
+    return(polySum);
+}
+
+double
+psDEvalPolynomial4D(double w,
+                    double x,
+                    double y,
+                    double z,
+                    const psDPolynomial4D *myPoly)
+{
+    int loop_w = 0;
+    int loop_x = 0;
+    int loop_y = 0;
+    int loop_z = 0;
+    double polySum = 0.0;
+    double wSum = 1.0;
+    double xSum = 1.0;
+    double ySum = 1.0;
+    double zSum = 1.0;
+
+    for (loop_w=0;loop_w<myPoly->nW;loop_w++) {
+        xSum = wSum;
+        for (loop_x=0;loop_x<myPoly->nX;loop_x++) {
+            ySum = xSum;
+            for (loop_y=0;loop_y<myPoly->nY;loop_y++) {
+                zSum = ySum;
+                for (loop_z=0;loop_z<myPoly->nZ;loop_z++) {
+                    polySum+= zSum *
+                              myPoly->coeff[loop_w][loop_x][loop_y][loop_z];
+                    zSum*=z;
+                }
+                ySum*=y;
+            }
+            xSum*=x;
+        }
+        wSum*=w;
+    }
+
+    return(polySum);
+}
Index: /tags/rel1_1/psLib/src/math/psPolynomial.h
===================================================================
--- /tags/rel1_1/psLib/src/math/psPolynomial.h	(revision 1056)
+++ /tags/rel1_1/psLib/src/math/psPolynomial.h	(revision 1056)
@@ -0,0 +1,255 @@
+/** @file psFunctions.h
+ *  \brief Standard Mathematical Functions.
+ *  \ingroup Stats
+ *
+ *  This file will hold the prototypes for procedures which allocate, free,
+ *  and evaluate various polynomials.  Those polynomial structures are also
+ *  defined here.
+ *
+ *  @ingroup Stats
+ *
+ *  @author Someone at IfA
+ *  @author George Gusciora, MHPCC
+ *
+ *  @version $Revision: 1.6 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-14 19:32:42 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#if !defined(PS_FUNCTIONS_H)
+#define PS_FUNCTIONS_H
+
+
+/** \addtogroup Stats
+ *  \{
+ */
+
+/** Evaluate a non-normalized Gaussian with the given mean and sigma at the
+    given coordianate.  Note that this is not a Gaussian deviate.  The
+    evaluated Gaussian is: \f[ exp(-\frac{(x-mean)^2}{2\sigma^2}) \f] */
+
+float
+psGaussian(float x,        ///< Value at which to evaluate
+           float mean,     ///< Mean for the Gaussian
+           float stddev,   ///< Standard deviation for the Gaussian
+           int normal      ///< Indicates whether result should be normalized
+          );
+
+
+/** Produce a vector of random numbers from a Gaussian distribution with
+    the specified mean and sigma */
+psVector *psGaussianDev(float mean,    ///< The mean of the Gaussian
+                        float sigma,   ///< The sigma of the Gaussian
+                        int Npts);     ///< The size of the vector
+
+
+
+
+
+/** One-dimensional polynomial */
+typedef struct
+{
+    int n;           ///< Number of terms
+    float *coeff;    ///< Coefficients
+    float *coeffErr; ///< Error in coefficients
+    char *mask;      ///< Coefficient mask
+}
+psPolynomial1D;
+
+/** Two-dimensional polynomial */
+typedef struct
+{
+    int nX, nY;    ///< Number of terms in x and y
+    float **coeff;   ///< Coefficients
+    float **coeffErr;   ///< Error in coefficients
+    char **mask;   ///< Coefficients mask
+}
+psPolynomial2D;
+
+/** Three-dimensional polynomial */
+typedef struct
+{
+    int nX, nY, nZ;   ///< Number of terms in x, y and z
+    float ***coeff;    ///< Coefficients
+    float ***coeffErr;    ///< Error in coefficients
+    char ***mask;    ///< Coefficients mask
+}
+psPolynomial3D;
+
+/** Four-dimensional polynomial */
+typedef struct
+{
+    int nW, nX, nY, nZ;   ///< Number of terms in w, x, y and z
+    float ****coeff;    ///< Coefficients
+    float ****coeffErr;   ///< Error in coefficients
+    char ****mask;    ///< Coefficients mask
+}
+psPolynomial4D;
+
+
+/** Functions **************************************************************/
+
+/** Constructor */
+psPolynomial1D *psPolynomial1DAlloc(int n ///< Number of terms
+                                   );
+/** Constructor */
+psPolynomial2D *psPolynomial2DAlloc(int nX, int nY ///< Number of terms in x and y
+                                   );
+/** Constructor */
+psPolynomial3D *psPolynomial3DAlloc(int nX, int nY, int nZ ///< Number of terms in x, y and z
+                                   );
+/** Constructor */
+psPolynomial4D *psPolynomial4DAlloc(int nW, int nX, int nY, int nZ ///< Number of terms in w, x, y and z
+                                   );
+
+/** Destructor */
+void psPolynomial1DFree(psPolynomial1D *myPoly ///< Polynomial to destroy
+                       );
+
+/** Destructor */
+void psPolynomial2DFree(psPolynomial2D *myPoly ///< Polynomial to destroy
+                       );
+/** Destructor */
+void psPolynomial3DFree(psPolynomial3D *myPoly ///< Polynomial to destroy
+                       );
+/** Destructor */
+void psPolynomial4DFree(psPolynomial4D *myPoly ///< Polynomial to destroy
+                       );
+
+
+/** Evaluate 1D polynomial */
+float
+psEvalPolynomial1D(float x,  ///< Value at which to evaluate
+                   const psPolynomial1D *myPoly ///< Coefficients for the polynomial
+                  );
+
+/** Evaluate 2D polynomial */
+float
+psEvalPolynomial2D(float x,  ///< Value x at which to evaluate
+                   float y,  ///< Value y at which to evaluate
+                   const psPolynomial2D *myPoly ///< Coefficients for the polynomial
+                  );
+
+/** Evaluate 3D polynomial */
+float
+psEvalPolynomial3D(float x,  ///< Value x at which to evaluate
+                   float y,  ///< Value y at which to evaluate
+                   float z,  ///< Value z at which to evaluate
+                   const psPolynomial3D *myPoly ///< Coefficients for the polynomial
+                  );
+
+/** Evaluate 4D polynomial */
+float
+psEvalPolynomial4D(float w,  ///< Value w at which to evaluate
+                   float x,  ///< Value x at which to evaluate
+                   float y,  ///< Value y at which to evaluate
+                   float z,  ///< Value z at which to evaluate
+                   const psPolynomial4D *myPoly ///< Coefficients for the polynomial
+                  );
+
+/*****************************************************************************/
+
+/* Double-precision polynomials, mainly for use in astrometry */
+
+/** Double-precision one-dimensional polynomial */
+typedef struct
+{
+    int n;    ///< Number of terms
+    double *coeff;   ///< Coefficients
+    double *coeffErr;   ///< Error in coefficients
+    char *mask;    ///< Coefficient mask
+}
+psDPolynomial1D;
+
+/** Double-precision two-dimensional polynomial */
+typedef struct
+{
+    int nX, nY;    ///< Number of terms in x and y
+    double **coeff;   ///< Coefficients
+    double **coeffErr;    ///< Error in coefficients
+    char **mask;   ///< Coefficients mask
+}
+psDPolynomial2D;
+
+/** Double-precision three-dimensional polynomial */
+typedef struct
+{
+    int nX, nY, nZ;   ///< Number of terms in x, y and z
+    double ***coeff;   ///< Coefficients
+    double ***coeffErr;   ///< Error in coefficients
+    char ***mask;    ///< Coefficient mask
+}
+psDPolynomial3D;
+
+/** Double-precision four-dimensional polynomial */
+typedef struct
+{
+    int nW, nX, nY, nZ;   ///< Number of terms in w, x, y and z
+    double ****coeff;    ///< Coefficients
+    double ****coeffErr;   ///< Error in coefficients
+    char ****mask;    ///< Coefficients mask
+}
+psDPolynomial4D;
+
+/** Constructor */
+psDPolynomial1D *psDPolynomial1DAlloc(int n ///< Number of terms
+                                     );
+/** Constructor */
+psDPolynomial2D *psDPolynomial2DAlloc(int nX, int nY ///< Number of terms in x and y
+                                     );
+/** Constructor */
+psDPolynomial3D *psDPolynomial3DAlloc(int nX, int nY, int nZ ///< Number of terms in x, y and z
+                                     );
+/** Constructor */
+psDPolynomial4D *psDPolynomial4DAlloc(int nW, int nX, int nY, int nZ ///< Number of terms in w, x, y and z
+                                     );
+
+
+/** Destructor */
+void psDPolynomial1DFree(psDPolynomial1D *myPoly ///< Polynomial to destroy
+                        );
+/** Destructor */
+void psDPolynomial2DFree(psDPolynomial2D *myPoly ///< Polynomial to destroy
+                        );
+/** Destructor */
+void psDPolynomial3DFree(psDPolynomial3D *myPoly ///< Polynomial to destroy
+                        );
+/** Destructor */
+void psDPolynomial4DFree(psDPolynomial4D *myPoly ///< Polynomial to destroy
+                        );
+
+
+/** Evaluate 1D polynomial (double precision) */
+double
+psDEvalPolynomial1D(double x,  ///< Value at which to evaluate
+                    const psDPolynomial1D *myPoly ///< Coefficients for the polynomial
+                   );
+
+/** Evaluate 2D polynomial (double precision) */
+double
+psDEvalPolynomial2D(double x,  ///< Value x at which to evaluate
+                    double y,  ///< Value y at which to evaluate
+                    const psDPolynomial2D *myPoly ///< Coefficients for the polynomial
+                   );
+
+/** Evaluate 3D polynomial (double precision) */
+double
+psDEvalPolynomial3D(double x,  ///< Value x at which to evaluate
+                    double y,  ///< Value y at which to evaluate
+                    double z,  ///< Value z at which to evaluate
+                    const psDPolynomial3D *myPoly ///< Coefficients for the polynomial
+                   );
+
+/** Evaluate 4D polynomial (double precision) */
+double
+psDEvalPolynomial4D(double w,  ///< Value w at which to evaluate
+                    double x,  ///< Value x at which to evaluate
+                    double y,  ///< Value y at which to evaluate
+                    double z,  ///< Value z at which to evaluate
+                    const psDPolynomial4D *myPoly ///< Coefficients for the polynomial
+                   );
+
+/* \} */ // End of MathGroup Functions
+
+#endif
Index: /tags/rel1_1/psLib/src/math/psSpline.c
===================================================================
--- /tags/rel1_1/psLib/src/math/psSpline.c	(revision 1056)
+++ /tags/rel1_1/psLib/src/math/psSpline.c	(revision 1056)
@@ -0,0 +1,751 @@
+/** @file  psFunctions.c
+ *
+ *  @brief Contains basic function allocation, deallocation, and evaluation
+ *         routines.
+ *
+ *  This file will hold the functions for allocated, freeing, and evaluating
+ *  polynomials.  It also contains a Gaussian functions.
+ *
+ *  @version $Revision: 1.13 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-14 19:40:14 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+/*****************************************************************************/
+/*  INCLUDE FILES                                                            */
+/*****************************************************************************/
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <float.h>
+#include <math.h>
+
+#include "psMemory.h"
+#include "psVector.h"
+#include "psTrace.h"
+#include "psError.h"
+#include "psAbort.h"
+#include "psFunctions.h"
+#include "psSort.h"
+
+#include "float.h"
+#include <math.h>
+#include <gsl/gsl_rng.h>
+#include <gsl/gsl_randist.h>
+/*****************************************************************************/
+/*  FUNCTION IMPLEMENTATION - PUBLIC                                         */
+/*****************************************************************************/
+
+/*****************************************************************************
+    Evaluate a non-normalized Gaussian with the given mean and sigma at the
+    given coordianate.  Note that this is not a Gaussian deviate.  The
+    evaluated Gaussian is: \f[ exp(-\frac{(x-mean)^2}{2\sigma^2}) \f]
+ *****************************************************************************/
+float
+psGaussian(float x,
+           float mean,
+           float stddev,
+           int normal)
+{
+    float tmp = 0.0;
+
+    if (normal == 1) {
+        #ifdef DARWIN
+        tmp = 1.0 / (float)sqrt(2.0 * M_PI * (stddev * stddev));
+        #else
+
+        tmp = 1.0 / sqrtf(2.0 * M_PI * (stddev * stddev));
+        #endif
+
+        return(tmp * exp(-((x-mean) * (x-mean)) / (2.0 * stddev * stddev)));
+    } else {
+        return(exp(-((x-mean) * (x-mean)) / (2.0 * stddev * stddev)));
+    }
+}
+
+/*****************************************************************************
+    psGaussianDev()
+ This routine creates a psVector of the specified size and type F32
+ and fills it with a random Gaussian distribution of numbers with
+ the specified mean and sigma.  This routine makes use of the GSL
+ routines for generating both uniformly distributed numbers and the
+ Gaussian distribution as well.
+ 
+ NOTE: There is no way to seed the random generator.
+ *****************************************************************************/
+psVector *psGaussianDev(float mean,
+                        float sigma,
+                        int Npts)
+{
+    psVector *gauss = NULL;
+    const gsl_rng_type *T = NULL;
+    gsl_rng *r = NULL;
+    int i = 0;
+
+    gauss = psVectorAlloc(Npts, PS_TYPE_F32);
+    gauss->n = Npts;
+    gsl_rng_env_setup();
+    T = gsl_rng_default;
+    r = gsl_rng_alloc(T);
+
+    for (i = 0; i < Npts; i++) {
+        gauss->data.F32[i] = mean + gsl_ran_gaussian(r, sigma);
+    }
+
+    // NOTE: Should I free r as well?
+    return(gauss);
+}
+
+
+/*****************************************************************************
+    This routine must allocate memory for the polynomial structures.
+ *****************************************************************************/
+psPolynomial1D *psPolynomial1DAlloc(int n)
+{
+    int i = 0;
+    psPolynomial1D *newPoly = NULL;
+
+    newPoly = (psPolynomial1D *) psAlloc(sizeof(psPolynomial1D));
+    newPoly->n = n;
+    newPoly->coeff    = (float *) psAlloc(n * sizeof(float));
+    newPoly->coeffErr = (float *) psAlloc(n * sizeof(float));
+    newPoly->mask     = (char *)  psAlloc(n * sizeof(char));
+    for (i=0;i<n;i++) {
+        newPoly->coeff[i] = 0.0;
+        newPoly->coeffErr[i] = 0.0;
+        newPoly->mask[i] = 0.0;
+    }
+
+    return(newPoly);
+}
+
+psPolynomial2D *psPolynomial2DAlloc(int nX, int nY)
+{
+    int x = 0;
+    int y = 0;
+    psPolynomial2D *newPoly = NULL;
+
+    newPoly = (psPolynomial2D *) psAlloc(sizeof(psPolynomial2D));
+    newPoly->nX = nX;
+    newPoly->nY = nY;
+
+    newPoly->coeff    = (float **) psAlloc(nX * sizeof(float *));
+    newPoly->coeffErr = (float **) psAlloc(nX * sizeof(float *));
+    newPoly->mask     = (char **)  psAlloc(nX * sizeof(char *));
+    for (x=0;x<nX;x++) {
+        newPoly->coeff[x]    = (float *) psAlloc(nY * sizeof(float));
+        newPoly->coeffErr[x] = (float *) psAlloc(nY * sizeof(float));
+        newPoly->mask[x]     = (char *)  psAlloc(nY * sizeof(char));
+    }
+    for (x=0;x<nX;x++) {
+        for (y=0;y<nY;y++) {
+            newPoly->coeff[x][y] = 0.0;
+            newPoly->coeffErr[x][y] = 0.0;
+            newPoly->mask[x][y] = 0;
+        }
+    }
+
+    return(newPoly);
+}
+
+psPolynomial3D *psPolynomial3DAlloc(int nX, int nY, int nZ)
+{
+    int x = 0;
+    int y = 0;
+    int z = 0;
+    psPolynomial3D *newPoly = NULL;
+
+    newPoly = (psPolynomial3D *) psAlloc(sizeof(psPolynomial3D));
+    newPoly->nX = nX;
+    newPoly->nY = nY;
+    newPoly->nZ = nZ;
+
+    newPoly->coeff    = (float ***) psAlloc(nX * sizeof(float **));
+    newPoly->coeffErr = (float ***) psAlloc(nX * sizeof(float **));
+    newPoly->mask     = (char ***)  psAlloc(nX * sizeof(char **));
+    for (x=0;x<nX;x++) {
+        newPoly->coeff[x]    = (float **) psAlloc(nY * sizeof(float *));
+        newPoly->coeffErr[x] = (float **) psAlloc(nY * sizeof(float *));
+        newPoly->mask[x]     = (char **)  psAlloc(nY * sizeof(char *));
+        for (y=0;y<nY;y++) {
+            newPoly->coeff[x][y]    = (float *) psAlloc(nZ * sizeof(float));
+            newPoly->coeffErr[x][y] = (float *) psAlloc(nZ * sizeof(float));
+            newPoly->mask[x][y]     = (char *)  psAlloc(nZ * sizeof(char));
+        }
+    }
+    for (x=0;x<nX;x++) {
+        for (y=0;y<nY;y++) {
+            for (z=0;z<nZ;z++) {
+                newPoly->coeff[x][y][z] = 0.0;
+                newPoly->coeffErr[x][y][z] = 0.0;
+                newPoly->mask[x][y][z] = 0;
+            }
+        }
+    }
+
+    return(newPoly);
+}
+
+psPolynomial4D *psPolynomial4DAlloc(int nW, int nX, int nY, int nZ)
+{
+    int w = 0;
+    int x = 0;
+    int y = 0;
+    int z = 0;
+    psPolynomial4D *newPoly = NULL;
+
+    newPoly = (psPolynomial4D *) psAlloc(sizeof(psPolynomial4D));
+    newPoly->nW = nW;
+    newPoly->nX = nX;
+    newPoly->nY = nY;
+    newPoly->nZ = nZ;
+
+    newPoly->coeff    = (float ****) psAlloc(nW * sizeof(float ***));
+    newPoly->coeffErr = (float ****) psAlloc(nW * sizeof(float ***));
+    newPoly->mask     = (char ****)  psAlloc(nW * sizeof(char ***));
+    for (w=0;w<nW;w++) {
+        newPoly->coeff[w]    = (float ***) psAlloc(nX * sizeof(float **));
+        newPoly->coeffErr[w] = (float ***) psAlloc(nX * sizeof(float **));
+        newPoly->mask[w]     = (char ***)  psAlloc(nX * sizeof(char **));
+        for (x=0;x<nX;x++) {
+            newPoly->coeff[w][x]    = (float **) psAlloc(nY * sizeof(float *));
+            newPoly->coeffErr[w][x] = (float **) psAlloc(nY * sizeof(float *));
+            newPoly->mask[w][x]     = (char **) psAlloc(nY * sizeof(char *));
+            for (y=0;y<nY;y++) {
+                newPoly->coeff[w][x][y]    = (float *) psAlloc(nZ * sizeof(float));
+                newPoly->coeffErr[w][x][y] = (float *) psAlloc(nZ * sizeof(float));
+                newPoly->mask[w][x][y]     = (char *) psAlloc(nZ * sizeof(char));
+            }
+        }
+    }
+    for (w=0;w<nW;w++) {
+        for (x=0;x<nX;x++) {
+            for (y=0;y<nY;y++) {
+                for (z=0;z<nZ;z++) {
+                    newPoly->coeff[w][x][y][z] = 0.0;
+                    newPoly->coeffErr[w][x][y][z] = 0.0;
+                    newPoly->mask[w][x][y][z] = 0;
+                }
+            }
+        }
+    }
+
+    return(newPoly);
+}
+
+void psPolynomial1DFree(psPolynomial1D *myPoly)
+{
+    psFree(myPoly->coeff);
+    psFree(myPoly->coeffErr);
+    psFree(myPoly->mask);
+    psFree(myPoly);
+}
+
+void psPolynomial2DFree(psPolynomial2D *myPoly)
+{
+    int x = 0;
+
+    for (x=0;x<myPoly->nX;x++) {
+        psFree(myPoly->coeff[x]);
+        psFree(myPoly->coeffErr[x]);
+        psFree(myPoly->mask[x]);
+    }
+    psFree(myPoly->coeff);
+    psFree(myPoly->coeffErr);
+    psFree(myPoly->mask);
+
+    psFree(myPoly);
+}
+
+void psPolynomial3DFree(psPolynomial3D *myPoly)
+{
+    int x = 0;
+    int y = 0;
+
+    for (x=0;x<myPoly->nX;x++) {
+        for (y=0;y<myPoly->nY;y++) {
+            psFree(myPoly->coeff[x][y]);
+            psFree(myPoly->coeffErr[x][y]);
+            psFree(myPoly->mask[x][y]);
+        }
+        psFree(myPoly->coeff[x]);
+        psFree(myPoly->coeffErr[x]);
+        psFree(myPoly->mask[x]);
+    }
+
+    psFree(myPoly->coeff);
+    psFree(myPoly->coeffErr);
+    psFree(myPoly->mask);
+    psFree(myPoly);
+}
+
+void psPolynomial4DFree(psPolynomial4D *myPoly)
+{
+    int w = 0;
+    int x = 0;
+    int y = 0;
+
+    for (w=0;w<myPoly->nW;w++) {
+        for (x=0;x<myPoly->nX;x++) {
+            for (y=0;y<myPoly->nY;y++) {
+                psFree(myPoly->coeff[w][x][y]);
+                psFree(myPoly->coeffErr[w][x][y]);
+                psFree(myPoly->mask[w][x][y]);
+            }
+            psFree(myPoly->coeff[w][x]);
+            psFree(myPoly->coeffErr[w][x]);
+            psFree(myPoly->mask[w][x]);
+        }
+        psFree(myPoly->coeff[w]);
+        psFree(myPoly->coeffErr[w]);
+        psFree(myPoly->mask[w]);
+    }
+
+    psFree(myPoly->coeff);
+    psFree(myPoly->coeffErr);
+    psFree(myPoly->mask);
+    psFree(myPoly);
+}
+
+/*****************************************************************************
+    Polynomial coefficients will be accessed in [w][x][y][z] fashion.
+ *****************************************************************************/
+float
+psEvalPolynomial1D(float x,
+                   const psPolynomial1D *myPoly)
+{
+    int loop_x = 0;
+    float polySum = 0.0;
+    float xSum = 1.0;
+
+    // NOTE: Do we want to flag this case?
+    if (myPoly->n == 0) {
+        return(1.0);
+    }
+
+    for (loop_x=0;loop_x<myPoly->n;loop_x++) {
+        polySum+= xSum * myPoly->coeff[loop_x];
+        xSum*=x;
+    }
+
+    return(polySum);
+}
+
+
+float
+psEvalPolynomial2D(float x,
+                   float y,
+                   const psPolynomial2D *myPoly)
+{
+    int loop_x = 0;
+    int loop_y = 0;
+    float polySum = 0.0;
+    float xSum = 1.0;
+    float ySum = 1.0;
+
+    for (loop_x=0;loop_x<myPoly->nX;loop_x++) {
+        ySum = xSum;
+        for (loop_y=0;loop_y<myPoly->nY;loop_y++) {
+            polySum+= ySum * myPoly->coeff[loop_x][loop_y];
+            ySum*=y;
+        }
+        xSum*=x;
+    }
+
+    return(polySum);
+}
+
+float
+psEvalPolynomial3D(float x,
+                   float y,
+                   float z,
+                   const psPolynomial3D *myPoly)
+{
+    int loop_x = 0;
+    int loop_y = 0;
+    int loop_z = 0;
+    float polySum = 0.0;
+    float xSum = 1.0;
+    float ySum = 1.0;
+    float zSum = 1.0;
+
+    for (loop_x=0;loop_x<myPoly->nX;loop_x++) {
+        ySum = xSum;
+        for (loop_y=0;loop_y<myPoly->nY;loop_y++) {
+            zSum = ySum;
+            for (loop_z=0;loop_z<myPoly->nZ;loop_z++) {
+                polySum+= zSum * myPoly->coeff[loop_x][loop_y][loop_z];
+                zSum*=z;
+            }
+            ySum*=y;
+        }
+        xSum*=x;
+    }
+
+    return(polySum);
+}
+
+float
+psEvalPolynomial4D(float w,
+                   float x,
+                   float y,
+                   float z,
+                   const psPolynomial4D *myPoly)
+{
+    int loop_w = 0;
+    int loop_x = 0;
+    int loop_y = 0;
+    int loop_z = 0;
+    float polySum = 0.0;
+    float wSum = 1.0;
+    float xSum = 1.0;
+    float ySum = 1.0;
+    float zSum = 1.0;
+
+    for (loop_w=0;loop_w<myPoly->nW;loop_w++) {
+        xSum = wSum;
+        for (loop_x=0;loop_x<myPoly->nX;loop_x++) {
+            ySum = xSum;
+            for (loop_y=0;loop_y<myPoly->nY;loop_y++) {
+                zSum = ySum;
+                for (loop_z=0;loop_z<myPoly->nZ;loop_z++) {
+                    polySum+= zSum *
+                              myPoly->coeff[loop_w][loop_x][loop_y][loop_z];
+                    zSum*=z;
+                }
+                ySum*=y;
+            }
+            xSum*=x;
+        }
+        wSum*=w;
+    }
+
+    return(polySum);
+}
+
+
+
+
+psDPolynomial1D *psDPolynomial1DAlloc(int n)
+{
+    int i = 0;
+    psDPolynomial1D *newPoly = NULL;
+
+    newPoly = (psDPolynomial1D *) psAlloc(sizeof(psDPolynomial1D));
+    newPoly->n = n;
+    newPoly->coeff    = (double *) psAlloc(n * sizeof(double));
+    newPoly->coeffErr = (double *) psAlloc(n * sizeof(double));
+    newPoly->mask     = (char *)  psAlloc(n * sizeof(char));
+    for (i=0;i<n;i++) {
+        newPoly->coeff[i] = 0.0;
+        newPoly->coeffErr[i] = 0.0;
+        newPoly->mask[i] = 0.0;
+    }
+
+    return(newPoly);
+}
+
+psDPolynomial2D *psDPolynomial2DAlloc(int nX, int nY)
+{
+    int x = 0;
+    int y = 0;
+    psDPolynomial2D *newPoly = NULL;
+
+    newPoly = (psDPolynomial2D *) psAlloc(sizeof(psDPolynomial2D));
+    newPoly->nX = nX;
+    newPoly->nY = nY;
+
+    newPoly->coeff    = (double **) psAlloc(nX * sizeof(double *));
+    newPoly->coeffErr = (double **) psAlloc(nX * sizeof(double *));
+    newPoly->mask     = (char **)  psAlloc(nX * sizeof(char *));
+    for (x=0;x<nX;x++) {
+        newPoly->coeff[x]    = (double *) psAlloc(nY * sizeof(double));
+        newPoly->coeffErr[x] = (double *) psAlloc(nY * sizeof(double));
+        newPoly->mask[x]     = (char *)  psAlloc(nY * sizeof(char));
+    }
+    for (x=0;x<nX;x++) {
+        for (y=0;y<nY;y++) {
+            newPoly->coeff[x][y] = 0.0;
+            newPoly->coeffErr[x][y] = 0.0;
+            newPoly->mask[x][y] = 0;
+        }
+    }
+
+    return(newPoly);
+}
+
+psDPolynomial3D *psDPolynomial3DAlloc(int nX, int nY, int nZ)
+{
+    int x = 0;
+    int y = 0;
+    int z = 0;
+    psDPolynomial3D *newPoly = NULL;
+
+    newPoly = (psDPolynomial3D *) psAlloc(sizeof(psDPolynomial3D));
+    newPoly->nX = nX;
+    newPoly->nY = nY;
+    newPoly->nZ = nZ;
+
+    newPoly->coeff    = (double ***) psAlloc(nX * sizeof(double **));
+    newPoly->coeffErr = (double ***) psAlloc(nX * sizeof(double **));
+    newPoly->mask     = (char ***)  psAlloc(nX * sizeof(char **));
+    for (x=0;x<nX;x++) {
+        newPoly->coeff[x]    = (double **) psAlloc(nY * sizeof(double *));
+        newPoly->coeffErr[x] = (double **) psAlloc(nY * sizeof(double *));
+        newPoly->mask[x]     = (char **)  psAlloc(nY * sizeof(char *));
+        for (y=0;y<nY;y++) {
+            newPoly->coeff[x][y]    = (double *) psAlloc(nZ * sizeof(double));
+            newPoly->coeffErr[x][y] = (double *) psAlloc(nZ * sizeof(double));
+            newPoly->mask[x][y]     = (char *)  psAlloc(nZ * sizeof(char));
+        }
+    }
+    for (x=0;x<nX;x++) {
+        for (y=0;y<nY;y++) {
+            for (z=0;z<nZ;z++) {
+                newPoly->coeff[x][y][z] = 0.0;
+                newPoly->coeffErr[x][y][z] = 0.0;
+                newPoly->mask[x][y][z] = 0;
+            }
+        }
+    }
+
+    return(newPoly);
+}
+
+psDPolynomial4D *psDPolynomial4DAlloc(int nW, int nX, int nY, int nZ)
+{
+    int w = 0;
+    int x = 0;
+    int y = 0;
+    int z = 0;
+    psDPolynomial4D *newPoly = NULL;
+
+    newPoly = (psDPolynomial4D *) psAlloc(sizeof(psDPolynomial4D));
+    newPoly->nW = nW;
+    newPoly->nX = nX;
+    newPoly->nY = nY;
+    newPoly->nZ = nZ;
+
+    newPoly->coeff    = (double ****) psAlloc(nW * sizeof(double ***));
+    newPoly->coeffErr = (double ****) psAlloc(nW * sizeof(double ***));
+    newPoly->mask     = (char ****)  psAlloc(nW * sizeof(char ***));
+    for (w=0;w<nW;w++) {
+        newPoly->coeff[w]    = (double ***) psAlloc(nX * sizeof(double **));
+        newPoly->coeffErr[w] = (double ***) psAlloc(nX * sizeof(double **));
+        newPoly->mask[w]     = (char ***)  psAlloc(nX * sizeof(char **));
+        for (x=0;x<nX;x++) {
+            newPoly->coeff[w][x]    = (double **) psAlloc(nY * sizeof(double *));
+            newPoly->coeffErr[w][x] = (double **) psAlloc(nY * sizeof(double *));
+            newPoly->mask[w][x]     = (char **) psAlloc(nY * sizeof(char *));
+            for (y=0;y<nY;y++) {
+                newPoly->coeff[w][x][y]    = (double *) psAlloc(nZ * sizeof(double));
+                newPoly->coeffErr[w][x][y] = (double *) psAlloc(nZ * sizeof(double));
+                newPoly->mask[w][x][y]     = (char *) psAlloc(nZ * sizeof(char));
+            }
+        }
+    }
+    for (w=0;w<nW;w++) {
+        for (x=0;x<nX;x++) {
+            for (y=0;y<nY;y++) {
+                for (z=0;z<nZ;z++) {
+                    newPoly->coeff[w][x][y][z] = 0.0;
+                    newPoly->coeffErr[w][x][y][z] = 0.0;
+                    newPoly->mask[w][x][y][z] = 0;
+                }
+            }
+        }
+    }
+
+    return(newPoly);
+}
+
+void psDPolynomial1DFree(psDPolynomial1D *myPoly)
+{
+    psFree(myPoly->coeff);
+    psFree(myPoly->coeffErr);
+    psFree(myPoly->mask);
+    psFree(myPoly);
+}
+
+void psDPolynomial2DFree(psDPolynomial2D *myPoly)
+{
+    int x = 0;
+
+    for (x=0;x<myPoly->nX;x++) {
+        psFree(myPoly->coeff[x]);
+        psFree(myPoly->coeffErr[x]);
+        psFree(myPoly->mask[x]);
+    }
+    psFree(myPoly->coeff);
+    psFree(myPoly->coeffErr);
+    psFree(myPoly->mask);
+
+    psFree(myPoly);
+}
+
+void psDPolynomial3DFree(psDPolynomial3D *myPoly)
+{
+    int x = 0;
+    int y = 0;
+
+    for (x=0;x<myPoly->nX;x++) {
+        for (y=0;y<myPoly->nY;y++) {
+            psFree(myPoly->coeff[x][y]);
+            psFree(myPoly->coeffErr[x][y]);
+            psFree(myPoly->mask[x][y]);
+        }
+        psFree(myPoly->coeff[x]);
+        psFree(myPoly->coeffErr[x]);
+        psFree(myPoly->mask[x]);
+    }
+
+    psFree(myPoly->coeff);
+    psFree(myPoly->coeffErr);
+    psFree(myPoly->mask);
+    psFree(myPoly);
+}
+
+void psDPolynomial4DFree(psDPolynomial4D *myPoly)
+{
+    int w = 0;
+    int x = 0;
+    int y = 0;
+
+    for (w=0;w<myPoly->nW;w++) {
+        for (x=0;x<myPoly->nX;x++) {
+            for (y=0;y<myPoly->nY;y++) {
+                psFree(myPoly->coeff[w][x][y]);
+                psFree(myPoly->coeffErr[w][x][y]);
+                psFree(myPoly->mask[w][x][y]);
+            }
+            psFree(myPoly->coeff[w][x]);
+            psFree(myPoly->coeffErr[w][x]);
+            psFree(myPoly->mask[w][x]);
+        }
+        psFree(myPoly->coeff[w]);
+        psFree(myPoly->coeffErr[w]);
+        psFree(myPoly->mask[w]);
+    }
+
+    psFree(myPoly->coeff);
+    psFree(myPoly->coeffErr);
+    psFree(myPoly->mask);
+    psFree(myPoly);
+}
+
+/*****************************************************************************
+    Polynomial coefficients will be accessed in [w][x][y][z] fashion.
+ *****************************************************************************/
+double
+psDEvalPolynomial1D(double x,
+                    const psDPolynomial1D *myPoly)
+{
+    int loop_x = 0;
+    double polySum = 0.0;
+    double xSum = 1.0;
+
+    // NOTE: Do we want to flag this case?
+    if (myPoly->n == 0) {
+        return(1.0);
+    }
+
+    for (loop_x=0;loop_x<myPoly->n;loop_x++) {
+        polySum+= xSum * myPoly->coeff[loop_x];
+        xSum*=x;
+    }
+
+    return(polySum);
+}
+
+
+double
+psDEvalPolynomial2D(double x,
+                    double y,
+                    const psDPolynomial2D *myPoly)
+{
+    int loop_x = 0;
+    int loop_y = 0;
+    double polySum = 0.0;
+    double xSum = 1.0;
+    double ySum = 1.0;
+
+    for (loop_x=0;loop_x<myPoly->nX;loop_x++) {
+        ySum = xSum;
+        for (loop_y=0;loop_y<myPoly->nY;loop_y++) {
+            polySum+= ySum * myPoly->coeff[loop_x][loop_y];
+            ySum*=y;
+        }
+        xSum*=x;
+    }
+
+    return(polySum);
+}
+
+double
+psDEvalPolynomial3D(double x,
+                    double y,
+                    double z,
+                    const psDPolynomial3D *myPoly)
+{
+    int loop_x = 0;
+    int loop_y = 0;
+    int loop_z = 0;
+    double polySum = 0.0;
+    double xSum = 1.0;
+    double ySum = 1.0;
+    double zSum = 1.0;
+
+    for (loop_x=0;loop_x<myPoly->nX;loop_x++) {
+        ySum = xSum;
+        for (loop_y=0;loop_y<myPoly->nY;loop_y++) {
+            zSum = ySum;
+            for (loop_z=0;loop_z<myPoly->nZ;loop_z++) {
+                polySum+= zSum * myPoly->coeff[loop_x][loop_y][loop_z];
+                zSum*=z;
+            }
+            ySum*=y;
+        }
+        xSum*=x;
+    }
+
+    return(polySum);
+}
+
+double
+psDEvalPolynomial4D(double w,
+                    double x,
+                    double y,
+                    double z,
+                    const psDPolynomial4D *myPoly)
+{
+    int loop_w = 0;
+    int loop_x = 0;
+    int loop_y = 0;
+    int loop_z = 0;
+    double polySum = 0.0;
+    double wSum = 1.0;
+    double xSum = 1.0;
+    double ySum = 1.0;
+    double zSum = 1.0;
+
+    for (loop_w=0;loop_w<myPoly->nW;loop_w++) {
+        xSum = wSum;
+        for (loop_x=0;loop_x<myPoly->nX;loop_x++) {
+            ySum = xSum;
+            for (loop_y=0;loop_y<myPoly->nY;loop_y++) {
+                zSum = ySum;
+                for (loop_z=0;loop_z<myPoly->nZ;loop_z++) {
+                    polySum+= zSum *
+                              myPoly->coeff[loop_w][loop_x][loop_y][loop_z];
+                    zSum*=z;
+                }
+                ySum*=y;
+            }
+            xSum*=x;
+        }
+        wSum*=w;
+    }
+
+    return(polySum);
+}
Index: /tags/rel1_1/psLib/src/math/psSpline.h
===================================================================
--- /tags/rel1_1/psLib/src/math/psSpline.h	(revision 1056)
+++ /tags/rel1_1/psLib/src/math/psSpline.h	(revision 1056)
@@ -0,0 +1,255 @@
+/** @file psFunctions.h
+ *  \brief Standard Mathematical Functions.
+ *  \ingroup Stats
+ *
+ *  This file will hold the prototypes for procedures which allocate, free,
+ *  and evaluate various polynomials.  Those polynomial structures are also
+ *  defined here.
+ *
+ *  @ingroup Stats
+ *
+ *  @author Someone at IfA
+ *  @author George Gusciora, MHPCC
+ *
+ *  @version $Revision: 1.6 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-14 19:32:42 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#if !defined(PS_FUNCTIONS_H)
+#define PS_FUNCTIONS_H
+
+
+/** \addtogroup Stats
+ *  \{
+ */
+
+/** Evaluate a non-normalized Gaussian with the given mean and sigma at the
+    given coordianate.  Note that this is not a Gaussian deviate.  The
+    evaluated Gaussian is: \f[ exp(-\frac{(x-mean)^2}{2\sigma^2}) \f] */
+
+float
+psGaussian(float x,        ///< Value at which to evaluate
+           float mean,     ///< Mean for the Gaussian
+           float stddev,   ///< Standard deviation for the Gaussian
+           int normal      ///< Indicates whether result should be normalized
+          );
+
+
+/** Produce a vector of random numbers from a Gaussian distribution with
+    the specified mean and sigma */
+psVector *psGaussianDev(float mean,    ///< The mean of the Gaussian
+                        float sigma,   ///< The sigma of the Gaussian
+                        int Npts);     ///< The size of the vector
+
+
+
+
+
+/** One-dimensional polynomial */
+typedef struct
+{
+    int n;           ///< Number of terms
+    float *coeff;    ///< Coefficients
+    float *coeffErr; ///< Error in coefficients
+    char *mask;      ///< Coefficient mask
+}
+psPolynomial1D;
+
+/** Two-dimensional polynomial */
+typedef struct
+{
+    int nX, nY;    ///< Number of terms in x and y
+    float **coeff;   ///< Coefficients
+    float **coeffErr;   ///< Error in coefficients
+    char **mask;   ///< Coefficients mask
+}
+psPolynomial2D;
+
+/** Three-dimensional polynomial */
+typedef struct
+{
+    int nX, nY, nZ;   ///< Number of terms in x, y and z
+    float ***coeff;    ///< Coefficients
+    float ***coeffErr;    ///< Error in coefficients
+    char ***mask;    ///< Coefficients mask
+}
+psPolynomial3D;
+
+/** Four-dimensional polynomial */
+typedef struct
+{
+    int nW, nX, nY, nZ;   ///< Number of terms in w, x, y and z
+    float ****coeff;    ///< Coefficients
+    float ****coeffErr;   ///< Error in coefficients
+    char ****mask;    ///< Coefficients mask
+}
+psPolynomial4D;
+
+
+/** Functions **************************************************************/
+
+/** Constructor */
+psPolynomial1D *psPolynomial1DAlloc(int n ///< Number of terms
+                                   );
+/** Constructor */
+psPolynomial2D *psPolynomial2DAlloc(int nX, int nY ///< Number of terms in x and y
+                                   );
+/** Constructor */
+psPolynomial3D *psPolynomial3DAlloc(int nX, int nY, int nZ ///< Number of terms in x, y and z
+                                   );
+/** Constructor */
+psPolynomial4D *psPolynomial4DAlloc(int nW, int nX, int nY, int nZ ///< Number of terms in w, x, y and z
+                                   );
+
+/** Destructor */
+void psPolynomial1DFree(psPolynomial1D *myPoly ///< Polynomial to destroy
+                       );
+
+/** Destructor */
+void psPolynomial2DFree(psPolynomial2D *myPoly ///< Polynomial to destroy
+                       );
+/** Destructor */
+void psPolynomial3DFree(psPolynomial3D *myPoly ///< Polynomial to destroy
+                       );
+/** Destructor */
+void psPolynomial4DFree(psPolynomial4D *myPoly ///< Polynomial to destroy
+                       );
+
+
+/** Evaluate 1D polynomial */
+float
+psEvalPolynomial1D(float x,  ///< Value at which to evaluate
+                   const psPolynomial1D *myPoly ///< Coefficients for the polynomial
+                  );
+
+/** Evaluate 2D polynomial */
+float
+psEvalPolynomial2D(float x,  ///< Value x at which to evaluate
+                   float y,  ///< Value y at which to evaluate
+                   const psPolynomial2D *myPoly ///< Coefficients for the polynomial
+                  );
+
+/** Evaluate 3D polynomial */
+float
+psEvalPolynomial3D(float x,  ///< Value x at which to evaluate
+                   float y,  ///< Value y at which to evaluate
+                   float z,  ///< Value z at which to evaluate
+                   const psPolynomial3D *myPoly ///< Coefficients for the polynomial
+                  );
+
+/** Evaluate 4D polynomial */
+float
+psEvalPolynomial4D(float w,  ///< Value w at which to evaluate
+                   float x,  ///< Value x at which to evaluate
+                   float y,  ///< Value y at which to evaluate
+                   float z,  ///< Value z at which to evaluate
+                   const psPolynomial4D *myPoly ///< Coefficients for the polynomial
+                  );
+
+/*****************************************************************************/
+
+/* Double-precision polynomials, mainly for use in astrometry */
+
+/** Double-precision one-dimensional polynomial */
+typedef struct
+{
+    int n;    ///< Number of terms
+    double *coeff;   ///< Coefficients
+    double *coeffErr;   ///< Error in coefficients
+    char *mask;    ///< Coefficient mask
+}
+psDPolynomial1D;
+
+/** Double-precision two-dimensional polynomial */
+typedef struct
+{
+    int nX, nY;    ///< Number of terms in x and y
+    double **coeff;   ///< Coefficients
+    double **coeffErr;    ///< Error in coefficients
+    char **mask;   ///< Coefficients mask
+}
+psDPolynomial2D;
+
+/** Double-precision three-dimensional polynomial */
+typedef struct
+{
+    int nX, nY, nZ;   ///< Number of terms in x, y and z
+    double ***coeff;   ///< Coefficients
+    double ***coeffErr;   ///< Error in coefficients
+    char ***mask;    ///< Coefficient mask
+}
+psDPolynomial3D;
+
+/** Double-precision four-dimensional polynomial */
+typedef struct
+{
+    int nW, nX, nY, nZ;   ///< Number of terms in w, x, y and z
+    double ****coeff;    ///< Coefficients
+    double ****coeffErr;   ///< Error in coefficients
+    char ****mask;    ///< Coefficients mask
+}
+psDPolynomial4D;
+
+/** Constructor */
+psDPolynomial1D *psDPolynomial1DAlloc(int n ///< Number of terms
+                                     );
+/** Constructor */
+psDPolynomial2D *psDPolynomial2DAlloc(int nX, int nY ///< Number of terms in x and y
+                                     );
+/** Constructor */
+psDPolynomial3D *psDPolynomial3DAlloc(int nX, int nY, int nZ ///< Number of terms in x, y and z
+                                     );
+/** Constructor */
+psDPolynomial4D *psDPolynomial4DAlloc(int nW, int nX, int nY, int nZ ///< Number of terms in w, x, y and z
+                                     );
+
+
+/** Destructor */
+void psDPolynomial1DFree(psDPolynomial1D *myPoly ///< Polynomial to destroy
+                        );
+/** Destructor */
+void psDPolynomial2DFree(psDPolynomial2D *myPoly ///< Polynomial to destroy
+                        );
+/** Destructor */
+void psDPolynomial3DFree(psDPolynomial3D *myPoly ///< Polynomial to destroy
+                        );
+/** Destructor */
+void psDPolynomial4DFree(psDPolynomial4D *myPoly ///< Polynomial to destroy
+                        );
+
+
+/** Evaluate 1D polynomial (double precision) */
+double
+psDEvalPolynomial1D(double x,  ///< Value at which to evaluate
+                    const psDPolynomial1D *myPoly ///< Coefficients for the polynomial
+                   );
+
+/** Evaluate 2D polynomial (double precision) */
+double
+psDEvalPolynomial2D(double x,  ///< Value x at which to evaluate
+                    double y,  ///< Value y at which to evaluate
+                    const psDPolynomial2D *myPoly ///< Coefficients for the polynomial
+                   );
+
+/** Evaluate 3D polynomial (double precision) */
+double
+psDEvalPolynomial3D(double x,  ///< Value x at which to evaluate
+                    double y,  ///< Value y at which to evaluate
+                    double z,  ///< Value z at which to evaluate
+                    const psDPolynomial3D *myPoly ///< Coefficients for the polynomial
+                   );
+
+/** Evaluate 4D polynomial (double precision) */
+double
+psDEvalPolynomial4D(double w,  ///< Value w at which to evaluate
+                    double x,  ///< Value x at which to evaluate
+                    double y,  ///< Value y at which to evaluate
+                    double z,  ///< Value z at which to evaluate
+                    const psDPolynomial4D *myPoly ///< Coefficients for the polynomial
+                   );
+
+/* \} */ // End of MathGroup Functions
+
+#endif
Index: /tags/rel1_1/psLib/src/math/psStats.c
===================================================================
--- /tags/rel1_1/psLib/src/math/psStats.c	(revision 1056)
+++ /tags/rel1_1/psLib/src/math/psStats.c	(revision 1056)
@@ -0,0 +1,1279 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <float.h>
+#include <math.h>
+
+#include "psMemory.h"
+#include "psVector.h"
+#include "psTrace.h"
+#include "psError.h"
+#include "psAbort.h"
+#include "psStats.h"
+#include "psSort.h"
+
+#include "float.h"
+#define DEFAULT_ROBUST_SIZE_THRESHOLD 30000   // Vectors that are large than this
+// will use robust statistical methods.
+#define GAUSS_WIDTH 20                  // The width of the Gaussian or boxcar smoothing.
+#define CLIPPED_NUM_ITER_LB 1
+#define CLIPPED_NUM_ITER_UB 10
+#define CLIPPED_SIGMA_LB 1.0
+#define CLIPPED_SIGMA_UB 10.0
+#define true 1
+#define false 0
+#define MYMAXFLOAT HUGE
+
+#ifndef DOXYGEN
+void p_psVectorRobustStats(const psVector *restrict myVector,
+                           const psVector *restrict maskVector,
+                           unsigned int maskVal,
+                           psStats *stats);
+#endif
+
+/******************************************************************************
+    psStatsAlloc(): This routine must create a new psStats data structure.
+ *****************************************************************************/
+psStats *psStatsAlloc(psStatsOptions options)
+{
+    psStats *newStruct = NULL;
+
+    newStruct = (psStats *) psAlloc(sizeof(psStats));
+    newStruct->sampleMean = NAN;
+    newStruct->sampleMedian = NAN;
+    newStruct->sampleStdev = NAN;
+    newStruct->sampleUQ = NAN;
+    newStruct->sampleLQ = NAN;
+    newStruct->sampleLimit = DEFAULT_ROBUST_SIZE_THRESHOLD;
+    newStruct->robustMean = NAN;
+    newStruct->robustMedian = NAN;
+    newStruct->robustMode = NAN;
+    newStruct->robustStdev = NAN;
+    newStruct->robustUQ = NAN;
+    newStruct->robustLQ = NAN;
+    newStruct->robustN50 = NAN;
+    newStruct->robustNfit = NAN;
+    newStruct->clippedMean = NAN;
+    newStruct->clippedStdev = NAN;
+    newStruct->clipSigma = 3.0;
+    newStruct->clipIter = 3.0;
+    newStruct->min = NAN;
+    newStruct->max = NAN;
+    newStruct->binsize = NAN;
+    newStruct->options = options;
+
+    return(newStruct);
+}
+
+/******************************************************************************
+    psStatsFree(): This routine must free the psStats data structure.
+ *****************************************************************************/
+void psStatsFree(psStats *stats)
+{
+    psFree(stats);
+}
+
+/******************************************************************************
+psHistogramAlloc(lower, upper, n): allocate a uniform histogram structure
+with the specifed upper and lower limits, and the specifed number of bins.
+This routine will also set the bounds for each of the bins.
+ 
+Input:
+    lower
+    upper
+    n
+Returns:
+    The histogram structure
+ *****************************************************************************/
+psHistogram *psHistogramAlloc(float lower,
+                              float upper,
+                              int n)
+{
+    int i = 0;                          // Loop index variable
+    psHistogram *newHist = NULL;        // The new histogram structure
+    float binSize = 0.0;                // The histogram bin size
+
+    // NOTE: Verify that this is the correct action.
+    if (n == 0) {
+        return(NULL);
+    }
+
+    // NOTE: Verify that this is the correct action.
+    if (lower > upper) {
+        return(NULL);
+    }
+
+    // Allocate memory for the new histogram structure.  If there are N
+    // bins, then there are N+1 bounds to those bins.
+    newHist = (psHistogram *) psAlloc(sizeof(psHistogram));
+    newHist->bounds = psVectorAlloc(n+1, PS_TYPE_F32);
+    newHist->bounds->n = newHist->bounds->nalloc;
+
+    // Calculate the bounds for each bin.
+    binSize = (upper - lower) / (float) n;
+    for (i=0;i<n+1;i++) {
+        newHist->bounds->data.F32[i] = lower + (binSize * (float) i);
+    }
+
+    // Allocate the bins, and initialize them to zero.
+    newHist->nums =  psVectorAlloc(n, PS_TYPE_S32);
+    newHist->nums->n = newHist->nums->nalloc;
+    for (i=0;i<newHist->nums->n;i++) {
+        newHist->nums->data.S32[i] = 0;
+    }
+
+    // Initialize the other members.
+    newHist->minNum = 0;
+    newHist->maxNum = 0;
+    newHist->uniform = true;
+
+    return(newHist);
+}
+
+/******************************************************************************
+psHistogramAlloc(lower, upper, n): allocate a non-uniform histogram structure
+with the specifed bounds.  The number of elements in the bounds vector is n.
+Therefore, the number of bins is n-1.
+Input:
+    bounds
+Returns:
+    The histogram structure
+ *****************************************************************************/
+psHistogram *psHistogramAllocGeneric(const psVector *restrict bounds)
+{
+    psHistogram *newHist = NULL;        // The new histogram structure
+    int i;                              // Loop index variable
+
+    // NOTE: Verify that this is the correct action.
+    if (bounds == NULL) {
+        //        psAbort(__func__, "psHistogram requested with NULL bounds");
+        return(NULL);
+    }
+
+    // NOTE: Verify that this is the correct action.
+    if (bounds->n <= 1) {
+        //        psAbort(__func__, "psHistogram requested with NULL bounds");
+        return(NULL);
+    }
+
+    // Allocate memory for the new histogram structure.
+    newHist = (psHistogram *) psAlloc(sizeof(psHistogram));
+    newHist->bounds = psVectorAlloc(bounds->n, PS_TYPE_F32);
+    newHist->bounds->n = newHist->bounds->nalloc;
+    for (i=0;i<bounds->n;i++) {
+        newHist->bounds->data.F32[i] = bounds->data.F32[i];
+    }
+
+    // Allocate the bins, and initialize them to zero.  If there are N bounds,
+    // then there are N-1 bins.
+    newHist->nums = psVectorAlloc((bounds->n)-1, PS_TYPE_S32);
+    newHist->nums->n = newHist->nums->nalloc;
+    for (i=0;i<newHist->nums->n;i++) {
+        newHist->nums->data.S32[i] = 0;
+    }
+
+    // Initialize the other members.
+    newHist->minNum = 0;
+    newHist->maxNum = 0;
+    newHist->uniform = false;
+
+    return(newHist);
+}
+
+void psHistogramFree(psHistogram *myHist)
+{
+    psVectorFree(myHist->bounds);
+    psVectorFree(myHist->nums);
+    psFree(myHist);
+}
+
+
+/*****************************************************************************
+psHistogramVector(out, in, mask, maskVal): this procedure takes as input a
+preallocated and initialized histogram structure.  It fills the bins in that
+histogram structure in accordance with the input data "in" and the, possibly
+NULL, mask vector.
+ 
+Inputs:
+    out
+    in
+    mask
+    maskVal
+Returns:
+    The histogram structure "out".
+ *****************************************************************************/
+psHistogram *psHistogramVector(psHistogram *out,
+                               const psVector *restrict in,
+                               const psVector *restrict mask,
+                               int maskVal)
+{
+    int i = 0;                                  // Loop index variable
+    int j = 0;                                  // Loop index variable
+    float binSize = 0.0;                        // Histogram bin size
+    int binNum = 0;                             // A temporary bin number
+    int numBins = 0;                            // The total number of bins
+
+    // NOTE: Verify that this is the correct action.
+    if (out == NULL) {
+        return(NULL);
+    }
+
+    // NOTE: Verify that this is the correct action.
+    if (in == NULL) {
+        return(out);
+    }
+
+    if (in->type.type != PS_TYPE_F32) {
+        psAbort(__func__,
+                "Only data type PS_TYPE_F32 is currently supported (0x%x).",
+                in->type.type);
+    }
+
+    if (mask != NULL) {
+        if (in->n != mask->n) {
+            psAbort(__func__,
+                    "Vector data and vector mask are of different sizes.");
+        }
+        if (mask->type.type != PS_TYPE_U8) {
+            psAbort(__func__, "Vector mask must be type PS_TYPE_U8");
+        }
+    }
+    // NOTE: determine the correct action for a variety of other cases:
+    // in vector has 0 elements, and histogram structure has zero bins.
+
+    numBins = out->nums->n;
+
+    for (i=0;i<in->n;i++) {
+        // Check if this pixel is masked, and if so, skip it.
+        if ((mask == NULL) ||
+                ((mask != NULL) && (!(mask->data.U8[i] & maskVal)))) {
+            // Check if this pixel is below the minimum value, and if so
+            // count it, then skip it.
+            if (in->data.F32[i] < out->bounds->data.F32[0]) {
+                out->minNum++;
+                // Check if this pixel is above the maximum value, and if so
+                // count it, then skip it.
+            } else if (in->data.F32[i] > out->bounds->data.F32[numBins]) {
+                out->maxNum++;
+            } else {
+                // If this is a uniform histogram, determining the correct
+                // number is trivial.
+                if (out->uniform == true) {
+                    binSize = out->bounds->data.F32[1] - out->bounds->data.F32[0];
+
+                    binNum = (int) ((in->data.F32[i] - out->bounds->data.F32[0]) /
+                                    binSize);
+                    (out->nums->data.S32[binNum])++;
+                    // If this is a non-uniform histogram, determining the correct
+                    // bin number requires a bit more work.
+                } else {
+                    // NOTE: This is slow.  Put a smarter algorithm here to
+                    // find the correct bin number (bin search, probably)
+                    for (j=0;j<(out->bounds->n)-1;j++) {
+                        if ((out->bounds->data.S32[j] <= in->data.F32[i]) &&
+                                (in->data.F32[i] <= out->bounds->data.S32[j+1])) {
+                            (out->nums->data.S32[j])++;
+                        }
+                    }
+                }
+            }
+        }
+    }
+    return(out);
+}
+
+/*****************************************************************************
+p_psVectorPrint(myVector, maskVector, maskVal, stats): a private internal
+function that simply prints a vector to STDOUT.  Used primarily for
+debugging.
+ *****************************************************************************/
+
+void p_psVectorPrint(psVector *myVector,
+                     psVector *maskVector,
+                     unsigned int maskVal,
+                     psStats *stats)
+{
+    int i = 0;                                  // Loop index variable.
+
+    for (i=0;i<myVector->n;i++) {
+        if (maskVector != NULL)
+            printf("Element %d is %f (mask is %d)\n", i, myVector->data.F32[i], maskVector->data.U8[i]);
+        else
+            printf("Element %d is %f\n", i, myVector->data.F32[i]);
+    }
+}
+
+
+/******************************************************************************
+ ******************************************************************************
+ ******************************************************************************
+    MISC PRIVATE STATISTICAL FUNCTIONS
+ 
+    NOTE: it is assumed that any call to these statistical functions will
+    have been preceded by a call to the psVectorStats() function.  Various
+    sanity tests will only be performed in psVectorStats().
+        Is the mask vector the same length as the data vector?
+        Is the mask vector of type PS_TYPE_U8?
+        Is the stats data structure NULL?
+        Is the in data structure NULL?
+        Is the in data structure of type PS_TYPE_F32?
+ ******************************************************************************
+ ******************************************************************************
+ *****************************************************************************/
+
+
+/******************************************************************************
+p_psVectorSampleMean(myVector, maskVector, maskVal, stats): calculates the
+mean of the input vector.
+Inputs
+Returns
+    NULL
+ASSUMPTION: the mean is always calculated exactly.  Robust means are never
+calculated in this routine.
+ *****************************************************************************/
+void p_psVectorSampleMean(const psVector *restrict myVector,
+                          const psVector *restrict maskVector,
+                          unsigned int maskVal,
+                          psStats *stats)
+{
+    int i = 0;                                  // Loop index variable
+    float mean = 0.0;                           // The mean
+    int count = 0;                              // # of points in this mean?
+    float rangeMin = 0.0;                       // Exclude data below this
+    float rangeMax = 0.0;                       // Exclude date above this
+
+    // If PS_STAT_USE_RANGE is requested, then we enter a slightly different
+    // loop.
+    if (stats->options & PS_STAT_USE_RANGE) {
+        rangeMin = stats->min;
+        rangeMax = stats->max;
+        if (maskVector != NULL) {
+            for (i=0;i<myVector->n;i++) {
+                // Check if the data is with the specified range
+                if (!(maskVal & maskVector->data.U8[i]) &&
+                        (rangeMin <= myVector->data.F32[i]) &&
+                        (myVector->data.F32[i] <= rangeMax)) {
+                    mean+= myVector->data.F32[i];
+                    count++;
+                }
+            }
+            mean/= (float) count;
+        } else {
+            for (i=0;i<myVector->n;i++) {
+                if ((rangeMin <= myVector->data.F32[i]) &&
+                        (myVector->data.F32[i] <= rangeMax)) {
+                    mean+= myVector->data.F32[i];
+                    count++;
+                }
+            }
+            mean/= (float) count;
+        }
+    } else {
+        if (maskVector != NULL) {
+            for (i=0;i<myVector->n;i++) {
+                if (!(maskVal & maskVector->data.U8[i])) {
+                    mean+= myVector->data.F32[i];
+                    count++;
+                }
+            }
+            mean/= (float) count;
+        } else {
+            for (i=0;i<myVector->n;i++) {
+                mean+= myVector->data.F32[i];
+            }
+            mean/= (float) myVector->n;
+        }
+    }
+
+    stats->sampleMean = mean;
+}
+
+/******************************************************************************
+p_psVectorSampleMax(myVector, maskVector, maskVal, stats): calculates the
+max of the input vector.
+Inputs
+    myVector
+    maskVector
+    maskVal
+    stats
+Returns
+    NULL
+ *****************************************************************************/
+void p_psVectorMax(const psVector *restrict myVector,
+                   const psVector *restrict maskVector,
+                   unsigned int maskVal,
+                   psStats *stats)
+{
+    int i = 0;                                  // Loop index variable
+    float max = -MYMAXFLOAT;                    // The calculated maximum
+    float rangeMin = 0.0;                       // Exclude data below this
+    float rangeMax = 0.0;                       // Exclude date above this
+
+    // If PS_STAT_USE_RANGE is requested, then we enter a different loop.
+    if (stats->options & PS_STAT_USE_RANGE) {
+        rangeMin = stats->min;
+        rangeMax = stats->max;
+        if (maskVector != NULL) {
+            for (i=0;i<myVector->n;i++) {
+                if (!(maskVal & maskVector->data.U8[i])) {
+                    if ((myVector->data.F32[i] > max) &&
+                            (rangeMin <= myVector->data.F32[i]) &&
+                            (myVector->data.F32[i] <= rangeMax)) {
+                        max = myVector->data.F32[i];
+                    }
+                }
+            }
+        } else {
+            for (i=0;i<myVector->n;i++) {
+                if ((myVector->data.F32[i] > max) &&
+                        (rangeMin <= myVector->data.F32[i]) &&
+                        (myVector->data.F32[i] <= rangeMax)) {
+                    max = myVector->data.F32[i];
+                }
+            }
+        }
+    } else {
+        if (maskVector != NULL) {
+            for (i=0;i<myVector->n;i++) {
+                if (!(maskVal & maskVector->data.U8[i])) {
+                    if (myVector->data.F32[i] > max) {
+                        max = myVector->data.F32[i];
+                    }
+                }
+            }
+        } else {
+            for (i=0;i<myVector->n;i++) {
+                if (myVector->data.F32[i] > max) {
+                    max = myVector->data.F32[i];
+                }
+            }
+        }
+    }
+
+    stats->max = max;
+}
+
+/******************************************************************************
+p_psVectorSampleMin(myVector, maskVector, maskVal, stats): calculates the
+minimum of the input vector.
+Inputs
+    myVector
+    maskVector
+    maskVal
+    stats
+Returns
+    NULL
+ *****************************************************************************/
+void p_psVectorMin(const psVector *restrict myVector,
+                   const psVector *restrict maskVector,
+                   unsigned int maskVal,
+                   psStats *stats)
+{
+    int i = 0;                                  // Loop index variable
+    float min = MYMAXFLOAT;                     // The calculated maximum
+    float rangeMin = 0.0;                       // Exclude data below this
+    float rangeMax = 0.0;                       // Exclude date above this
+
+    if (stats->options & PS_STAT_USE_RANGE) {
+        rangeMin = stats->min;
+        rangeMax = stats->max;
+        if (maskVector != NULL) {
+            for (i=0;i<myVector->n;i++) {
+                if (!(maskVal & maskVector->data.U8[i])) {
+                    if ((myVector->data.F32[i] < min) &&
+                            (rangeMin <= myVector->data.F32[i]) &&
+                            (myVector->data.F32[i] <= rangeMax)) {
+                        min = myVector->data.F32[i];
+                    }
+                }
+            }
+        } else {
+            for (i=0;i<myVector->n;i++) {
+                if ((myVector->data.F32[i] < min) &&
+                        (rangeMin <= myVector->data.F32[i]) &&
+                        (myVector->data.F32[i] <= rangeMax)) {
+                    min = myVector->data.F32[i];
+                }
+            }
+        }
+    } else {
+        if (maskVector != NULL) {
+            for (i=0;i<myVector->n;i++) {
+                if (!(maskVal & maskVector->data.U8[i])) {
+                    if (myVector->data.F32[i] < min) {
+                        min = myVector->data.F32[i];
+                    }
+                }
+            }
+        } else {
+            for (i=0;i<myVector->n;i++) {
+                if (myVector->data.F32[i] < min) {
+                    min = myVector->data.F32[i];
+                }
+            }
+        }
+    }
+
+    stats->min = min;
+}
+
+/******************************************************************************
+p_psVectorSampleMax(myVector, maskVector, maskVal, stats): calculates the
+number of non-masked pixels in the vector.  that fall within the min/max
+range, if given.
+Inputs
+    myVector
+    maskVector
+    maskVal
+    stats
+Returns
+    NULL
+ *****************************************************************************/
+int p_psVectorNValues(const psVector *restrict myVector,
+                      const psVector *restrict maskVector,
+                      unsigned int maskVal,
+                      psStats *stats)
+{
+    int i = 0;                                  // Loop index variable
+    int numData = 0;                            // The number of data points
+    float rangeMin = 0.0;                       // Exclude data below this
+    float rangeMax = 0.0;                       // Exclude date above this
+
+    if (stats->options & PS_STAT_USE_RANGE) {
+        rangeMin = stats->min;
+        rangeMax = stats->max;
+        if (maskVector != NULL) {
+            for (i=0;i<myVector->n;i++) {
+                if (!(maskVal & maskVector->data.U8[i]) &&
+                        (rangeMin <= myVector->data.F32[i]) &&
+                        (myVector->data.F32[i] <= rangeMax)) {
+                    numData++;
+                }
+            }
+        } else {
+            for (i=0;i<myVector->n;i++) {
+                if ((rangeMin <= myVector->data.F32[i]) &&
+                        (myVector->data.F32[i] <= rangeMax)) {
+                    numData++;
+                }
+            }
+        }
+    } else {
+        rangeMin = stats->min;
+        rangeMax = stats->max;
+        if (maskVector != NULL) {
+            for (i=0;i<myVector->n;i++) {
+                if (!(maskVal & maskVector->data.U8[i])) {
+                    numData++;
+                }
+            }
+        } else {
+            numData = myVector->n;
+        }
+    }
+    return(numData);
+}
+
+
+
+/******************************************************************************
+p_psVectorSampleMedian(myVector, maskVector, maskVal, stats): calculates the
+median of the input vector.
+Inputs
+    myVector
+    maskVector
+    maskVal
+    stats
+Returns
+    NULL
+ *****************************************************************************/
+void p_psVectorSampleMedian(const psVector *restrict myVector,
+                            const psVector *restrict maskVector,
+                            unsigned int maskVal,
+                            psStats *stats)
+{
+    psVector *unsortedVector = NULL;            // Temporary vector
+    psVector *sortedVector = NULL;              // Temporary vector
+    int i = 0;                                  // Loop index variable
+    int count = 0;                              // # of points in this mean?
+    int nValues = 0;                            // # of points in vector
+    float rangeMin = 0.0;                       // Exclude data below this
+    float rangeMax = 0.0;                       // Exclude date above this
+    psStats *stats2 = NULL;                     // Temporary stats structure
+
+
+    // Determine if the number of data points exceed a threshold which will
+    // cause to generate robust stats, as opposed to exact stats.
+
+    if (myVector->n > stats->sampleLimit) {
+        psAbort(__func__, "Robust Statistic Algorithms have not yet been defined or implemented.");
+
+        // Calculate the robust quartiles.
+        stats2 = psStatsAlloc(PS_STAT_ROBUST_MEDIAN);
+        p_psVectorRobustStats(myVector, maskVector, maskVal, stats2);
+
+        // Store the robust quartiles into the sample quartile members.
+        stats->sampleMedian = stats2->robustMedian;
+
+        // Free temporary data buffers.
+        psStatsFree(stats2);
+
+        // Set the PS_STAT_ROBUST_FOR_SAMPLE bit in the stats structure.
+        stats->options = stats->options | PS_STAT_ROBUST_FOR_SAMPLE;
+
+        return;
+    }
+
+    // Determine how many data points fit inside this min/max range
+    // and are not masked, IF the maskVector is not NULL>
+    nValues = p_psVectorNValues(myVector, maskVector, maskVal, stats);
+
+    // Allocate temporary vectors for the data.
+    unsortedVector = psVectorAlloc(nValues, PS_TYPE_F32);
+    unsortedVector->n = unsortedVector->nalloc;
+
+    sortedVector   = psVectorAlloc(nValues, PS_TYPE_F32);
+    sortedVector->n = sortedVector->nalloc;
+
+    // Determine if we must only use data points within a min/max range.
+    if (stats->options & PS_STAT_USE_RANGE) {
+        rangeMin = stats->min;
+        rangeMax = stats->max;
+
+        // Store all non-masked data points within the min/max range
+        // into the temporary vectors.
+        count = 0;
+        if (maskVector != NULL) {
+            for (i=0;i<myVector->n;i++) {
+                if (!(maskVal & maskVector->data.U8[i]) &&
+                        (rangeMin <= myVector->data.F32[i]) &&
+                        (myVector->data.F32[i] <= rangeMax)) {
+                    unsortedVector->data.F32[count++] = maskVector->data.F32[i];
+                }
+            }
+        } else {
+            for (i=0;i<myVector->n;i++) {
+                if ((rangeMin <= myVector->data.F32[i]) &&
+                        (myVector->data.F32[i] <= rangeMax)) {
+                    unsortedVector->data.F32[count++] = myVector->data.F32[i];
+                }
+            }
+        }
+    } else {
+        // Store all non-masked data points into the temporary vectors.
+        count = 0;
+        if (maskVector != NULL) {
+            for (i=0;i<myVector->n;i++) {
+                if (!(maskVal & maskVector->data.U8[i])) {
+                    unsortedVector->data.F32[count++] = myVector->data.F32[i];
+                }
+            }
+        } else {
+            for (i=0;i<myVector->n;i++) {
+                unsortedVector->data.F32[i] = myVector->data.F32[i];
+            }
+        }
+    }
+    // Sort the temporary vectors.
+    psSort(sortedVector, unsortedVector);
+
+    // Calculate the median exactly.
+    if (0 == (nValues % 2)) {
+        stats->sampleMedian = 0.5 * (sortedVector->data.F32[(nValues/2)-1] +
+                                     sortedVector->data.F32[nValues/2]);
+    } else {
+        stats->sampleMedian = sortedVector->data.F32[nValues/2];
+    }
+
+    // Free the temporary data structures.
+    psVectorFree(unsortedVector);
+    psVectorFree(sortedVector);
+}
+
+/******************************************************************************
+    This routine smoothes the data in the input robustHistogram with a
+    Gaussian of width sigma.
+ *****************************************************************************/
+void p_psVectorsmoothHistGaussian(psHistogram *robustHistogram,
+                                  float sigma)
+{
+    int i = 0;                                  // Loop index variable
+    int j = 0;                                  // Loop index variable
+    float tmpf = 0.0;                           // Temporary variable
+    float gaussianCoefs[1 + (2 * GAUSS_WIDTH)]; // The Gaussian Coefficients
+
+    for(i=0;i<(1 + (2 * GAUSS_WIDTH));i++) {
+        if (fabs(sigma) <= FLT_EPSILON) {
+            // If sigma does not equal zero, then we use Gaussian smoothing.
+            #ifdef  DARWIN
+            tmpf = (float) sqrt(2.0f * M_PI * sigma * sigma);
+            #else
+
+            tmpf = sqrtf(2.0f * M_PI * sigma * sigma);
+            #endif
+
+            gaussianCoefs[i] = (float) exp( (-((float) (i-GAUSS_WIDTH)) *
+                                             ((float) (i-GAUSS_WIDTH))) /
+                                            (2.0f * sigma * sigma)) / tmpf;
+        } else {
+            /* If sigma equals zero (all pixels have the same value)
+             * the above code will divide by zero.  Therefore, we don't need
+             * to smooth the data.
+             */
+            return;
+        }
+    }
+
+    for(i=0;i<robustHistogram->nums->n;i++) {
+        for (j=-GAUSS_WIDTH;j<=+GAUSS_WIDTH;j++) {
+            if (((j+i) >= 0) && ((j+i) < robustHistogram->nums->n)) {
+                robustHistogram->nums->data.S32[j+i]+=
+                    (gaussianCoefs[j+GAUSS_WIDTH] *
+                     (float) robustHistogram->nums->data.S32[j+i]);
+            }
+        }
+    }
+}
+
+/******************************************************************************
+p_psVectorSampleQuartiles(myVector, maskVector, maskVal, stats): calculates
+the upper and/or lower quartiles of the input vector.
+Inputs
+    myVector
+    maskVector
+    maskVal
+    stats
+Returns
+    NULL
+ *****************************************************************************/
+void p_psVectorSampleQuartiles(const psVector *restrict myVector,
+                               const psVector *restrict maskVector,
+                               unsigned int maskVal,
+                               psStats *stats)
+{
+    psVector *unsortedVector = NULL;            // Temporary vector
+    psVector *sortedVector = NULL;              // Temporary vector
+    int i = 0;                                  // Loop index variable
+    int count = 0;                              // # of points in this mean?
+    int nValues = 0;                            // # data points
+    float rangeMin = 0.0;                       // Exclude data below this
+    float rangeMax = 0.0;                       // Exclude date above this
+
+    // Determine if the number of data points exceed a threshold which will
+    // cause to generate robust stats, as opposed to exact stats.
+    if (myVector->n > stats->sampleLimit) {
+        psAbort(__func__, "Robust Statistic Algorithms have not yet been defined or implemented.");
+        psStats *stats2 = NULL;
+        // Calculate the robust quartiles.
+        stats2 = psStatsAlloc(PS_STAT_ROBUST_QUARTILE);
+        p_psVectorRobustStats(myVector, maskVector, maskVal, stats2);
+
+        // Store the robust quartiles into the sample quartile members.
+        stats->sampleUQ = stats2->robustUQ;
+        stats->sampleLQ = stats2->robustLQ;
+
+        // Free temporary data buffers.
+        psStatsFree(stats2);
+
+        // Set the PS_STAT_ROBUST_FOR_SAMPLE bit in the stats structure.
+        stats->options = stats->options | PS_STAT_ROBUST_FOR_SAMPLE;
+
+        return;
+    }
+
+    // Determine how many data points fit inside this min/max range
+    // and are not maxed, IF the maskVector is not NULL>
+    nValues = p_psVectorNValues(myVector, maskVector, maskVal, stats);
+
+    // Allocate temporary vectors for the data.
+    unsortedVector = psVectorAlloc(nValues, PS_TYPE_F32);
+    unsortedVector->n = unsortedVector->nalloc;
+    sortedVector   = psVectorAlloc(nValues, PS_TYPE_F32);
+    sortedVector->n = sortedVector->nalloc;
+
+    // Determine if we must only use data points within a min/max range.
+    if (stats->options & PS_STAT_USE_RANGE) {
+        rangeMin = stats->min;
+        rangeMax = stats->max;
+        // Store all non-masked data points within the min/max range
+        // into the temporary vectors.
+        count = 0;
+        if (maskVector != NULL) {
+            for (i=0;i<myVector->n;i++) {
+                if (!(maskVal & maskVector->data.U8[i]) &&
+                        (rangeMin <= myVector->data.F32[i]) &&
+                        (myVector->data.F32[i] <= rangeMax)) {
+                    unsortedVector->data.F32[count++] = myVector->data.F32[i];
+                }
+            }
+        } else {
+            for (i=0;i<myVector->n;i++) {
+                if ((rangeMin <= myVector->data.F32[i]) &&
+                        (myVector->data.F32[i] <= rangeMax)) {
+                    unsortedVector->data.F32[count++] = myVector->data.F32[i];
+                }
+            }
+        }
+    } else {
+        // Store all non-masked data points into the temporary vectors.
+        count = 0;
+        if (maskVector != NULL) {
+            for (i=0;i<myVector->n;i++) {
+                if (!(maskVal & maskVector->data.U8[i])) {
+                    unsortedVector->data.F32[count++] = myVector->data.F32[i];
+                }
+            }
+        } else {
+            for (i=0;i<myVector->n;i++) {
+                unsortedVector->data.F32[i] = myVector->data.F32[i];
+            }
+        }
+    }
+
+    // Sort the temporary vectors.
+    psSort(sortedVector, unsortedVector);
+
+    // Calculate the quartile points exactly.
+    stats->sampleUQ = sortedVector->data.F32[3 * (nValues / 4)];
+    stats->sampleLQ = sortedVector->data.F32[nValues / 4];
+
+    // Free the temporary data structures.
+    psVectorFree(unsortedVector);
+    psVectorFree(sortedVector);
+    // NOTE: This is the
+}
+
+
+/******************************************************************************
+p_psVectorRobustStats(myVector, maskVector, maskVal, stats): this procedure
+calculates a variety of robust stat measures:
+        PS_STAT_ROBUST_MEAN
+        PS_STAT_ROBUST_MEDIAN
+        PS_STAT_ROBUST_MODE
+        PS_STAT_ROBUST_STDEV
+        PS_STAT_ROBUST_QUARTILE
+    I have included all that computation in a single function, as opposed to
+    breaking it across several functions for one primary reason: they all
+    require the same basic initial processing steps (calculate the histogram,
+    etc.) however there is no currently defined means, in the SDRS, to
+    specify this computation as a separate step.  If the above robust stat
+    measures were calcualted in separate functiosn, then much of the initial
+    processing would be duplicated.
+Inputs
+    myVector
+    maskVector
+    maskVal
+    stats
+Returns
+    NULL
+ *****************************************************************************/
+void p_psVectorRobustStats(const psVector *restrict myVector,
+                           const psVector *restrict maskVector,
+                           unsigned int maskVal,
+                           psStats *stats)
+{
+    psHistogram *robustHistogram = NULL;
+    float binSize = 0.0;                        // Size of the histogram bins
+    float sigmaE = 0.0;
+    int LQBinNum = -1;                          // Bin num for lower quartile
+    int UQBinNum = -1;                          // Bin num for upper quartile
+    int i = 0;                                  // Loop index variable
+    int maxBinNum = 0;
+    int maxBinCount = 0;
+    float dL = 0.0;
+    int numBins = 0;
+
+    // NOTE: The SDRS states that the sample quartiles must be used to
+    // determine the initial bin sizes.  However, the sample quartiles are
+    // calculated based on a full sort of the data set, regardless of the
+    // size of the data set.  We should consult with IfA to ensure that this
+    // is really required.
+
+    if (isnan(stats->sampleUQ) ||
+            isnan(stats->sampleLQ)) {
+        stats->options = stats->options | PS_STAT_SAMPLE_QUARTILE;
+        p_psVectorSampleQuartiles(myVector,
+                                  maskVector,
+                                  maskVal,
+                                  stats);
+    }
+
+    // Compute the initial bin size of the robust histogram.
+    sigmaE = (stats->sampleUQ - stats->sampleLQ) / 1.34f;
+    binSize = sigmaE / 10.0f;
+
+    // Detemine minimum and maximum values in the data vector.
+    if (isnan(stats->min)) {
+        p_psVectorMin(myVector, maskVector, maskVal, stats);
+    }
+    if (isnan(stats->max)) {
+        p_psVectorMax(myVector, maskVector, maskVal, stats);
+    }
+
+    // Create the histogram structure (yes, 2 is necessary, not 1).
+    numBins = 2 + (int) ((stats->max - stats->min) / binSize);
+
+    robustHistogram = psHistogramAlloc(stats->min,
+                                       stats->max,
+                                       numBins);
+    // Populate the histogram array.
+    psHistogramVector(robustHistogram, myVector, maskVector, maskVal);
+
+    // Smooth the histogram.
+    p_psVectorsmoothHistGaussian(robustHistogram, sigmaE/4.0f);
+
+    LQBinNum = -1;
+    UQBinNum = -1;
+    for (i=0;i<robustHistogram->nums->n;i++) {
+        if ((robustHistogram->nums->data.S32[i] <= stats->sampleLQ) &&
+                (stats->sampleLQ <= robustHistogram->nums->data.S32[i])) {
+            LQBinNum = i;
+        }
+
+        if ((robustHistogram->nums->data.S32[i] <= stats->sampleUQ) &&
+                (stats->sampleUQ <= robustHistogram->nums->data.S32[i])) {
+            UQBinNum = i;
+        }
+    }
+
+    // Determine the bin with the peak value in the range LQ to UQ.
+    maxBinNum = LQBinNum;
+    maxBinCount = robustHistogram->nums->data.S32[maxBinNum];
+    for (i=LQBinNum;i<=UQBinNum;i++) {
+        if (robustHistogram->nums->data.S32[i] > maxBinCount) {
+            maxBinNum = i;
+            maxBinCount = robustHistogram->nums->data.S32[i];
+        }
+    }
+
+    dL = (stats->robustUQ - stats->robustLQ) / 8.0;
+
+    // Fit a Gaussian to the bins in the range MODE-dL to Mode+dL
+    // NOTE: This step is dependent on the functions in psMinimize.c being
+    // implemented.  Currently, they are not.
+
+    if (stats->options & PS_STAT_ROBUST_MEAN) {
+        stats->robustMean = 0.0;
+    }
+
+    if  (stats->options & PS_STAT_ROBUST_MEDIAN) {
+        stats->robustMedian = 0.0;
+    }
+    if  (stats->options & PS_STAT_ROBUST_MODE) {
+        stats->robustMode = maxBinNum;
+    }
+    if  (stats->options & PS_STAT_ROBUST_STDEV) {
+        stats->robustStdev = 0.0;
+    }
+    if  (stats->options & PS_STAT_ROBUST_QUARTILE) {
+        stats->robustUQ = 0.0;
+        stats->robustLQ = 0.0;
+    }
+    stats->robustNfit = 0.0;
+    stats->robustN50 = 0.0;
+    psHistogramFree(robustHistogram);
+}
+
+/******************************************************************************
+p_psVectorSampleStdev(myVector, maskVector, maskVal, stats): calculates the
+stdev of the input vector.
+Inputs
+    myVector
+    maskVector
+    maskVal
+    stats
+Returns
+    NULL
+ 
+NOTE: the mean is always calculated exactly.  Robust means are never
+calculated in this routine.
+ *****************************************************************************/
+void p_psVectorSampleStdev(const psVector *restrict myVector,
+                           const psVector *restrict maskVector,
+                           unsigned int maskVal,
+                           psStats *stats)
+{
+    int i = 0;                                  // Loop index variable
+    int countInt = 0;                           // # of data points being used
+    float countFloat = 0.0;                     // # of data points being used
+    float mean = 0.0;                           // The mean
+    float diff = 0.0;                           // Used in calculating stdev
+    float sumSquares = 0.0;                     // temporary variable
+    float sumDiffs = 0.0;                       // temporary variable
+    float rangeMin = 0.0;                       // Exclude data below this
+    float rangeMax = 0.0;                       // Exclude date above this
+
+    // This procedure requires the mean.  If it has not been already
+    // calculated, then call p_psVectorSampleMean()
+    if (0 != isnan(stats->sampleMean)) {
+        p_psVectorSampleMean(myVector, maskVector, maskVal, stats);
+    }
+    mean = stats->sampleMean;
+
+    if (stats->options & PS_STAT_USE_RANGE) {
+        if (maskVector != NULL) {
+            for (i=0;i<myVector->n;i++) {
+                if (!(maskVal & maskVector->data.U8[i]) &&
+                        (rangeMin <= myVector->data.F32[i]) &&
+                        (myVector->data.F32[i] <= rangeMax)) {
+                    diff = myVector->data.F32[i] - mean;
+                    sumSquares+= (diff * diff);
+                    sumDiffs+= diff;
+                    countInt++;
+                }
+            }
+        } else {
+            for (i=0;i<myVector->n;i++) {
+                if ((rangeMin <= myVector->data.F32[i]) &&
+                        (myVector->data.F32[i] <= rangeMax)) {
+                    diff = myVector->data.F32[i] - mean;
+                    sumSquares+= (diff * diff);
+                    sumDiffs+= diff;
+                    countInt++;
+                }
+            }
+            countInt = myVector->n;
+        }
+    } else {
+        if (maskVector != NULL) {
+            for (i=0;i<myVector->n;i++) {
+                if (!(maskVal & maskVector->data.U8[i])) {
+                    diff = myVector->data.F32[i] - mean;
+                    sumSquares+= (diff * diff);
+                    sumDiffs+= diff;
+                    countInt++;
+                }
+            }
+        } else {
+            for (i=0;i<myVector->n;i++) {
+                diff = myVector->data.F32[i] - mean;
+                sumSquares+= (diff * diff);
+                sumDiffs+= diff;
+                countInt++;
+            }
+            countInt = myVector->n;
+        }
+    }
+    countFloat = (float) countInt;
+
+    #ifdef DARWIN
+
+    stats->sampleStdev = (float) sqrt( (sumSquares-(sumDiffs *
+                                        sumDiffs/countFloat))/ (countFloat-1));
+    #else
+
+    stats->sampleStdev = sqrtf( (sumSquares-(sumDiffs *
+                                 sumDiffs/countFloat))/ (countFloat-1));
+    #endif
+}
+
+/******************************************************************************
+p_psVectorClippedStats(myVector, maskVector, maskVal, stats): calculates the
+clipped stats (mean or stdev) of the input vector.
+ 
+Inputs
+    myVector
+    maskVector
+    maskVal
+    stats
+Returns
+    NULL
+ *****************************************************************************/
+void p_psVectorClippedStats(const psVector *restrict myVector,
+                            const psVector *restrict maskVector,
+                            unsigned int maskVal,
+                            psStats *stats)
+{
+    int i = 0;                                  // Loop index variable
+    int j = 0;                                  // Loop index variable
+    float clippedMean = 0.0;                    // self-explanatory
+    float clippedStdev = 0.0;                   // self-explanatory
+    float oldStanMean = 0.0;                    // Temporary variable
+    float oldStanStdev = 0.0;                   // Temporary variable
+    psVector *tmpMask = NULL;                   // Temporary vector
+
+    // Endure that stats->clipIter is within the proper range.
+    if (!((CLIPPED_NUM_ITER_LB <= stats->clipIter ) &&
+            (stats->clipIter <= CLIPPED_NUM_ITER_UB))) {
+        psAbort(__func__, "Unallowed value for clipIter (%d).\n",
+                stats->clipIter);
+    }
+
+    // Endure that stats->clipSigma is within the proper range.
+    if (!((CLIPPED_SIGMA_LB <= stats->clipSigma ) &&
+            (stats->clipSigma <= CLIPPED_SIGMA_UB))) {
+        psAbort(__func__, "Unallowed value for clipSigma (%f).\n",
+                stats->clipSigma);
+    }
+
+    // We allocate a temporary mask vector since during the iterative
+    // steps that follow, we will be masking off additional data points.
+    // However, we do no want to modify the original mask vector.
+    tmpMask = psVectorAlloc(myVector->n, PS_TYPE_U8);
+    tmpMask->n = myVector->n;
+
+    // If we were called with a mask vector, then initialize the temporary
+    // mask vector with those values.
+    if (maskVector != NULL) {
+        for (i=0;i<tmpMask->n;i++) {
+            tmpMask->data.U8[i] = maskVector->data.U8[i];
+        }
+    }
+
+    // 1. Compute the sample median.
+    // NOTE: This seems odd.  Verify with IfA that we want to calculate the
+    // median here, not the mean.
+    p_psVectorSampleMedian(myVector, maskVector, maskVal, stats);
+
+    // 2. Compute the sample standard deviation.
+    p_psVectorSampleStdev(myVector, maskVector, maskVal, stats);
+
+    // 3. Use the sample median as the first estimator of the mean X.
+    clippedMean = stats->sampleMean;
+
+    // 4. Use the sample stdev as the first estimator of the mean stdev.
+    clippedStdev = stats->sampleStdev;
+
+    // Must save the old sampleMean and sampleStdev since the following code
+    // block overwrites them.
+    oldStanMean = stats->sampleMean;
+    oldStanStdev = stats->sampleStdev;
+
+    // 5. Repeat N times:
+    for (i=0;i<stats->clipIter;i++) {
+        for (j=0;j<myVector->n;j++) {
+            // a) Exclude all values x_i for which |x_i - x| > K * stdev
+            if (fabs(myVector->data.F32[j] - clippedMean) >
+                    (stats->clipSigma * clippedStdev)) {
+                tmpMask->data.U8[i] = 0xff;
+            }
+            // b) compute new mean and stdev
+            p_psVectorSampleMedian(myVector, tmpMask, maskVal, stats);
+            p_psVectorSampleStdev(myVector, tmpMask, maskVal, stats);
+
+            // c) Use the new mean for x
+            clippedMean = stats->sampleMean;
+
+            // d) Use the new stdev for stdev
+            clippedStdev = stats->sampleStdev;
+        }
+    }
+    stats->sampleMean = oldStanMean;
+    stats->sampleStdev= oldStanStdev;
+
+    // 7. The last calcuated value of x is the cliped mean.
+    if (stats->options & PS_STAT_CLIPPED_MEAN) {
+        stats->clippedMean = clippedMean;
+    }
+
+    // 8. The last calcuated value of stdev is the cliped stdev.
+    if (stats->options & PS_STAT_CLIPPED_STDEV) {
+        stats->clippedStdev = clippedStdev;
+    }
+
+    psVectorFree(tmpMask);
+}
+
+
+/******************************************************************************
+psVectorStats(myVector, maskVector, maskVal, stats): this is the public API
+function which calls the above private stats functions based on what bits
+were set in stats->options.
+ 
+Inputs
+    myVector
+    maskVector
+    maskVal
+    stats
+Returns
+    The stats structure.
+ 
+NOTE: The current strategy is to implement everything assuming that all
+input data is of type PS_TYPE_F32.  Once the basic code is in place, we will
+macro-ize everything and add PS_TYPE_U16 and PS_TYPE_F64.
+ *****************************************************************************/
+psStats *psVectorStats(psStats *stats,
+                       psVector *in,
+                       psVector *mask,
+                       unsigned int maskVal)
+{
+    // NOTE: Verify that this is the correct action.
+    if (in == NULL) {
+        return(stats);
+    }
+    if (stats == NULL) {
+        return(NULL);
+    }
+
+    // Ensure that the data is of type PS_TYPE_F32.  Eventually, more data
+    // types will be implemented.
+    if (in->type.type != PS_TYPE_F32) {
+        psAbort(__func__,
+                "Only data type PS_TYPE_F32 is currently supported (0x%x).",
+                in->type.type);
+    }
+
+    // Ensure that the mask vector is of the proper size and type.
+    if (mask != NULL) {
+        if (in->n != mask->n) {
+            psAbort(__func__,
+                    "Vector data and vector mask are of different sizes.");
+        }
+        if (mask->type.type != PS_TYPE_U8) {
+            psAbort(__func__,
+                    "Vector mask must be type PS_TYPE_U8");
+        }
+    }
+
+    // ************************************************************************
+    if (stats->options & PS_STAT_SAMPLE_MEAN) {
+        p_psVectorSampleMean(in, mask, maskVal, stats);
+    }
+
+    // ************************************************************************
+    if (stats->options & PS_STAT_SAMPLE_MEDIAN) {
+        p_psVectorSampleMedian(in, mask, maskVal, stats);
+    }
+
+    // ************************************************************************
+    // NOTE: The Stdev calculation requires the mean.  Should we assume the
+    // mean has already been calculated?  Or should we always calculate it?
+    if (stats->options & PS_STAT_SAMPLE_STDEV) {
+        p_psVectorSampleMean(in, mask, maskVal, stats);
+        p_psVectorSampleStdev(in, mask, maskVal, stats);
+    }
+
+    // ************************************************************************
+    if (stats->options & PS_STAT_SAMPLE_QUARTILE) {
+        p_psVectorSampleQuartiles(in, mask, maskVal, stats);
+    }
+
+    // Since the various robust stats quantities share much computation, they
+    // are grouped together in a single private function:
+    // p_psVectorRobustStats()
+    if ((stats->options & PS_STAT_ROBUST_MEAN) ||
+            (stats->options & PS_STAT_ROBUST_MEDIAN) ||
+            (stats->options & PS_STAT_ROBUST_MODE) ||
+            (stats->options & PS_STAT_ROBUST_STDEV) ||
+            (stats->options & PS_STAT_ROBUST_QUARTILE)) {
+        p_psVectorRobustStats(in, mask, maskVal, stats);
+    }
+
+    if ((stats->options & PS_STAT_CLIPPED_MEAN) ||
+            (stats->options & PS_STAT_CLIPPED_STDEV)) {
+        p_psVectorClippedStats(in, mask, maskVal, stats);
+    }
+
+    // ************************************************************************
+    if (stats->options & PS_STAT_MAX) {
+        p_psVectorMax(in, mask, maskVal, stats);
+    }
+
+    // ************************************************************************
+    if (stats->options & PS_STAT_MIN) {
+        p_psVectorMin(in, mask, maskVal, stats);
+    }
+
+    return(stats);
+}
Index: /tags/rel1_1/psLib/src/math/psStats.h
===================================================================
--- /tags/rel1_1/psLib/src/math/psStats.h	(revision 1056)
+++ /tags/rel1_1/psLib/src/math/psStats.h	(revision 1056)
@@ -0,0 +1,133 @@
+/** @file  psStats.h
+ *  \brief basic statistical operations
+ *  @ingroup Stats
+ *
+ *  This file will hold the definition of the histogram and stats data
+ *  structures.  It also contains prototypes for procedures which operate
+ *  on those data structures.
+ *
+ *  @author George Gusciora, MHPCC
+ *
+ *  @version $Revision: 1.12 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-14 19:33:09 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+#if !defined(PS_STATS_H)
+#define PS_STATS_H
+
+#include "psVector.h"
+
+/// @addtogroup Stats
+/// @{
+
+/******************************************************************************
+    Statistical functions and data structures.
+ *****************************************************************************/
+typedef enum {
+    PS_STAT_SAMPLE_MEAN           = 0x000001,
+    PS_STAT_SAMPLE_MEDIAN         = 0x000002,
+    PS_STAT_SAMPLE_STDEV          = 0x000004,
+    PS_STAT_SAMPLE_QUARTILE       = 0x000008,
+    PS_STAT_ROBUST_MEAN           = 0x000010,
+    PS_STAT_ROBUST_MEDIAN         = 0x000020,
+    PS_STAT_ROBUST_MODE           = 0x000040,
+    PS_STAT_ROBUST_STDEV          = 0x000080,
+    PS_STAT_ROBUST_QUARTILE       = 0x000100,
+    PS_STAT_CLIPPED_MEAN          = 0x000200,
+    PS_STAT_CLIPPED_STDEV         = 0x000400,
+    PS_STAT_MAX                   = 0x000800,
+    PS_STAT_MIN                   = 0x001000,
+    PS_STAT_USE_RANGE             = 0x002000,
+    PS_STAT_USE_BINSIZE           = 0x004000,
+    PS_STAT_ROBUST_FOR_SAMPLE     = 0x008000
+} psStatsOptions;
+
+
+/** This is the generic statistics structure.  It contails the data members
+    for the various statistic values.  It contains the options member to
+    specifiy which statistics must be calculated. */
+typedef struct
+{
+    double sampleMean;          ///< formal mean of sample
+    double sampleMedian;        ///< formal median of sample
+    double sampleStdev;         ///< standard deviation of sample
+    double sampleUQ;            ///< upper quartile of sample
+    double sampleLQ;            ///< lower quartile of sample
+    double sampleLimit;         ///<
+    double robustMean;          ///< robust mean of array
+    int    robustMeanNvalues;   ///< number of measurements used for robust mean
+    double robustMedian;        ///< robust median of array
+    double robustMode;          ///< Robust mode of array
+    double robustStdev;         ///< robust standard deviation of array
+    double robustUQ;            ///< robust upper quartile
+    double robustLQ;            ///< robust lower quartile
+    double robustN50;           ///<
+    double robustNfit;          ///<
+    double clippedMean;         ///< Nsigma clipped mean
+    double clippedStdev;        ///< standard deviation after clipping
+    double clipSigma;           ///< Nsigma used for clipping; user input
+    int    clipIter;            ///< Number of clipping iterations; user input
+    double min;                 ///< minimum data value in array
+    double max;                 ///< maximum data value in array
+    double binsize;             ///<
+    psStatsOptions options;     ///< bitmask of calculated values
+}
+psStats;
+
+
+/** Do Statistics on an array.  Returns a status value. \ingroup MathGroup */
+psStats *
+psVectorStats(psStats *stats,       ///< stats structure defines stats to be calculated and how
+              psVector *in,         ///< Vector to be analysed: must be F32
+              psVector *mask,       ///< Ignore elements where (maskVector & maskVal) != 0: must be INT or NULL
+              unsigned int maskVal ///< Only mask elements with one of these bits set in maskVector
+             );
+
+/** A constructor for the stats structure.*/
+psStats *psStatsAlloc(psStatsOptions options); ///< Statistics to measure
+
+/** A destructor for the stats structure.*/
+void psStatsFree(psStats *restrict stats); ///< Stats structure to destroy
+
+/******************************************************************************
+    Histogram functions and data structures.
+ *****************************************************************************/
+/** The basic histogram structure which contains bounds and bins. */
+typedef struct
+{
+    psVector *bounds;                ///< Bounds for the bins (type F32)
+    psVector *nums;                  ///< Number in each of the bins (INT)
+    int minNum;                      ///< Number below the minimum
+    int maxNum;                      ///< Number above the maximum
+    int uniform;                     ///< Is it a uniform distribution?
+}
+psHistogram;
+
+
+/** Constructor \ingroup MathGroup */
+psHistogram *
+psHistogramAlloc(float lower,  ///< Lower limit for the bins
+                 float upper,  ///< Upper limit for the bins
+                 int n);       ///< Number of bins
+
+
+/** Generic constructor \ingroup MathGroup */
+psHistogram * psHistogramAllocGeneric(const psVector *restrict bounds); ///< Bounds for the bins
+
+
+/** Destructor \ingroup MathGroup **/
+void psHistogramFree(psHistogram *myHist);          ///< Histogram to destroy
+
+
+/** Calculate a histogram \ingroup MathGroup **/
+psHistogram *psHistogramVector (psHistogram *out,   ///< Histogram data
+                                const psVector *restrict in,       ///< Vector to analyse
+                                const psVector *restrict mask,     ///< Mask dat for input vector
+                                int maskVal);       ///< Mask value
+
+
+/// @}
+
+#endif
+
Index: /tags/rel1_1/psLib/src/mathtypes/psImage.c
===================================================================
--- /tags/rel1_1/psLib/src/mathtypes/psImage.c	(revision 1056)
+++ /tags/rel1_1/psLib/src/mathtypes/psImage.c	(revision 1056)
@@ -0,0 +1,2333 @@
+/** @file  psImage.c
+ *
+ *  @brief Contains basic image definitions and operations.
+ *
+ *  This file defines the basic type for an image struct and functions useful
+ *  in manupulating images.
+ *
+ *  @author Robert DeSonia, MHPCC
+ *  @author Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.28 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-11 02:02:53 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ *  That is the routine used to generate matrices.
+ */
+
+/******************************************************************************/
+/*  INCLUDE FILES                                                             */
+/******************************************************************************/
+
+#include <string.h>
+#include <math.h>
+
+#include "psMemory.h"
+#include "psError.h"
+#include "psImage.h"
+
+
+/*****************************************************************************/
+/* FUNCTION IMPLEMENTATION - PUBLIC                                          */
+/*****************************************************************************/
+
+psImage *psImageAlloc(unsigned int numCols, unsigned int numRows,
+                      const psElemType type)
+{
+    int area = 0;
+    int elementSize = PSELEMTYPE_SIZEOF(type); // element size in bytes
+    int rowSize = numCols*elementSize;  // row size in bytes.
+
+    area = numCols*numRows;
+
+    if (area < 1) {
+        psError(__func__, "Invalid value for number of rows or columns "
+                "(numRows=%d, numCols=%d).", numRows, numCols);
+        return NULL;
+    }
+
+    psImage *image = (psImage *)psAlloc(sizeof(psImage));
+
+    image->data.V = psAlloc(sizeof(void*)*numRows);
+
+    image->data.V[0] = psAlloc(area*elementSize);
+
+    for(int i = 1; i < numRows; i++) {
+        image->data.V[i] = (void*)((int8_t*)image->data.V[i-1]+rowSize);
+    }
+
+    *(int*)&image->col0 = 0;
+    *(int*)&image->row0 = 0;
+    *(unsigned int*)&image->numCols = numCols;
+    *(unsigned int*)&image->numRows = numRows;
+    *(psDimen*)&image->type.dimen = PS_DIMEN_IMAGE;
+    *(psElemType*)&image->type.type = type;
+    image->parent = NULL;
+    image->nChildren = 0;
+    image->children = NULL;
+
+    return image;
+}
+
+void psImageFree(psImage *image)
+{
+    if (image == NULL) {
+        return;
+    }
+
+    if (image->type.type == PS_TYPE_PTR) {
+        // 2-D array of pointers -- must dereference
+        unsigned int oldNumRows = image->numRows;
+        unsigned int oldNumCols = image->numCols;
+        psPTR* rowPtr;
+
+        for(unsigned int row=0;row<oldNumRows;row++) {
+            rowPtr = image->data.PTR[row];
+            for (unsigned int col=0;col<oldNumCols;col++) {
+                psMemDecrRefCounter(rowPtr[col]);
+            }
+        }
+    }
+
+    psImageFreeChildren(image);
+
+    psFree(image->data.V[0]);
+    psFree(image->data.V);
+    image->data.V = NULL;
+
+    psFree(image);
+}
+
+psImage* psImageRecycle(psImage* old,
+                        unsigned int numCols,
+                        unsigned int numRows,
+                        const psElemType type)
+{
+    int elementSize = PSELEMTYPE_SIZEOF(type); // element size in bytes
+    int rowSize = numCols*elementSize;  // row size in bytes.
+
+    if (old == NULL) {
+        old = psImageAlloc(numCols,numRows,type);
+        return old;
+    }
+
+    if (old->type.dimen != PS_DIMEN_IMAGE) {
+        psError(__func__,"Can not realloc image because input is not an image.");
+        return NULL;
+    }
+
+    if (old->type.type == PS_TYPE_PTR) {
+        // 2-D array of pointers -- must dereference
+        unsigned int oldNumRows = old->numRows;
+        unsigned int oldNumCols = old->numCols;
+        psPTR* rowPtr;
+
+        for(unsigned int row=0;row<oldNumRows;row++) {
+            rowPtr = old->data.PTR[row];
+            for (unsigned int col=0;col<oldNumCols;col++) {
+                psMemDecrRefCounter(rowPtr[col]);
+                rowPtr[col] = NULL;
+            }
+        }
+    }
+
+    /* image already the right size/type? */
+    if (numCols == old->numCols && numRows == old->numRows &&
+            type == old->type.type) {
+        return old;
+    }
+
+    // Resize the image buffer
+    old->data.V[0] = psRealloc(old->data.V[0],numCols * numRows * elementSize);
+    old->data.V = (void**) psRealloc(old->data.V,numRows * sizeof(void*));
+
+    // recreate the row pointers
+    for(int i = 1; i < numRows; i++) {
+        old->data.V[i] = (void*)((int8_t*)old->data.V[i-1]+rowSize);
+    }
+
+    *(unsigned int*)&old->numCols = numCols;
+    *(unsigned int*)&old->numRows = numRows;
+    *(psElemType*)&old->type.type = type;
+
+    return old;
+}
+
+psImage *psImageSubset(psImage *out,psImage *image,unsigned int numCols,
+                       unsigned int numRows, unsigned int col0,
+                       unsigned int row0)
+{
+    unsigned int elementSize;           // size of image element in bytes
+    unsigned int outputRowSize;         // output row size in bytes
+    unsigned int inputColOffset;        // offset in bytes to first subset pixel in input row
+
+    if (image == NULL || image->data.V == NULL) {
+        psError(__func__,"Can not subset image because input image or its pixel buffer is NULL.");
+        return NULL;
+    }
+
+    if (image->type.dimen != PS_DIMEN_IMAGE) {
+        psError(__func__,"Can not subset image because input image is not an image.");
+        return NULL;
+    }
+
+    if (numCols < 1 || numRows < 1) {
+        psError(__func__,"Can not subset image because number of rows or columns are zero (%dx%d).",
+                numCols, numRows);
+        return NULL;
+    }
+
+    if (col0 >= image->numCols || row0 >= image->numRows) {
+        psError(__func__,"Can not subset image because col0,row0 (%d,%d) is not a valid pixel location.",
+                col0,row0);
+        return NULL;
+    }
+
+    /* validate subimage size */
+    if (col0+numCols >= image->numCols || row0+numRows >= image->numRows) {
+        psError(__func__,"Can not subset image outside of image boundaries (size=%dx%d, "
+                "subset=[%d:%d,%d:%d]).",image->numCols,image->numRows,col0,
+                col0+numCols, row0, row0+numRows);
+        return NULL;
+    }
+
+
+    elementSize = PSELEMTYPE_SIZEOF(image->type.type);
+
+    out = psImageRecycle(out,numCols,numRows,image->type.type);
+
+    // set the parent information into the child output image
+    *(int*)&out->row0 = row0;
+    *(int*)&out->col0 = col0;
+    *(psImage**)&out->parent = (psImage*)image;
+
+    // add output image as a child of the input image.
+    image->nChildren++;
+    image->children = (psImage **) psRealloc(image->children,
+                      image->nChildren * sizeof(psImage*) );
+    image->children[image->nChildren-1] = out;
+
+    inputColOffset = elementSize*col0;
+    outputRowSize = elementSize*numCols;
+
+    for (int row = 0; row < numRows; row++) {
+        memcpy(out->data.V[row],image->data.U8[row0+row] + inputColOffset,
+               outputRowSize);
+    }
+
+    return (out);
+}
+
+int psImageFreeChildren(psImage* image)
+{
+    int i = 0;
+    int nChildren = 0;
+    psImage **children = NULL;
+    int numFreed = 0;
+
+    if (image == NULL) {
+        return numFreed;
+    }
+
+    nChildren = image->nChildren;
+    children = image->children;
+
+    for(i=0; i<nChildren; i++) {
+        if (children[i] != NULL) {
+            numFreed++;
+            psImageFree(children[i]);
+        }
+    }
+    psFree(children);
+
+    image->nChildren = 0;
+    image->children = NULL;
+
+
+    return numFreed;
+}
+
+psImage *psImageCopy(psImage* restrict output, const psImage *input,
+                     psElemType type)
+{
+    psElemType inDatatype;
+    int elementSize;
+    int numRows;
+    int numCols;
+
+    if (input == NULL || input->data.V == NULL) {
+        psError(__func__,"Can not copy image because input image or its pixel buffer is NULL.");
+        return NULL;
+    }
+
+    if (input == output) {
+        psError(__func__,"Can not copy image because given input and output "
+                "parameter reference the same psImage struct.");
+        return NULL;
+    }
+
+    if (input->type.dimen != PS_DIMEN_IMAGE) {
+        psError(__func__,"Can not copy image because input image is not actually an image.");
+        return NULL;
+    }
+
+    inDatatype = input->type.type;
+    numRows = input->numRows;
+    numCols = input->numCols;
+    elementSize = PSELEMTYPE_SIZEOF(inDatatype);
+
+    if (inDatatype == PS_TYPE_PTR || type == PS_TYPE_PTR) {
+        psError(__func__,"Can not copy image to/from a void* matrix");
+        return NULL;
+    }
+
+    output = psImageRecycle(output,numCols,numRows,type);
+
+    // cover the trival case of copy of the same datatype.
+    if (type == inDatatype) {
+        memcpy(output->data.V[0],input->data.V[0],elementSize*numRows*numCols);
+        return output;
+    }
+
+    #define PSIMAGE_ELEMENT_ASSIGN_LOOP(OUT,IN,INTYPE,OUTTYPE) \
+    { \
+        ps##INTYPE *in; \
+        ps##OUTTYPE *out; \
+        for (int row=0;row<numRows;row++) { \
+            in = IN->data.INTYPE[row]; \
+            out = OUT->data.OUTTYPE[row]; \
+            for (int col=0;col<numCols;col++) { \
+                out[col] = (ps##OUTTYPE) in[col]; \
+            } \
+        } \
+    }
+
+    #define PSIMAGE_ELEMENT_ASSIGN(OUT,IN,OUTTYPE) \
+    switch (IN->type.type) { \
+    case PS_TYPE_S8: \
+        PSIMAGE_ELEMENT_ASSIGN_LOOP(OUT,IN,S8,OUTTYPE); \
+        break; \
+    case PS_TYPE_S16: \
+        PSIMAGE_ELEMENT_ASSIGN_LOOP(OUT,IN,S16,OUTTYPE); \
+        break; \
+    case PS_TYPE_S32: \
+        PSIMAGE_ELEMENT_ASSIGN_LOOP(OUT,IN,S32,OUTTYPE); \
+        break; \
+    case PS_TYPE_S64: \
+        PSIMAGE_ELEMENT_ASSIGN_LOOP(OUT,IN,S64,OUTTYPE); \
+        break; \
+    case PS_TYPE_U8: \
+        PSIMAGE_ELEMENT_ASSIGN_LOOP(OUT,IN,U8,OUTTYPE); \
+        break; \
+    case PS_TYPE_U16: \
+        PSIMAGE_ELEMENT_ASSIGN_LOOP(OUT,IN,U16,OUTTYPE); \
+        break; \
+    case PS_TYPE_U32: \
+        PSIMAGE_ELEMENT_ASSIGN_LOOP(OUT,IN,U32,OUTTYPE); \
+        break; \
+    case PS_TYPE_U64: \
+        PSIMAGE_ELEMENT_ASSIGN_LOOP(OUT,IN,U64,OUTTYPE); \
+        break; \
+    case PS_TYPE_F32: \
+        PSIMAGE_ELEMENT_ASSIGN_LOOP(OUT,IN,F32,OUTTYPE); \
+        break; \
+    case PS_TYPE_F64: \
+        PSIMAGE_ELEMENT_ASSIGN_LOOP(OUT,IN,F64,OUTTYPE); \
+        break; \
+    case PS_TYPE_C32: \
+        PSIMAGE_ELEMENT_ASSIGN_LOOP(OUT,IN,C32,OUTTYPE); \
+        break; \
+    case PS_TYPE_PTR: \
+        psError(__func__,"Can't copy image from a matrix of pointers."); \
+        psImageFree(output); \
+        return NULL; \
+    default: \
+        break; \
+    }
+
+    // XXX - GCC had problems with the length? of the above macro.  The original
+    // macro code here is commented out and the preprocessor output is pasted below it
+    // (effectively to the end of the function)
+    // We need to find out what is doing on here and move back to the macro version.
+    #if 0
+    switch (type)
+    {
+    case PS_TYPE_S8:
+        PSIMAGE_ELEMENT_ASSIGN(output,input,S8);
+        break;
+    case PS_TYPE_S16:
+        PSIMAGE_ELEMENT_ASSIGN(output,input,S16);
+        break;
+    case PS_TYPE_S32:
+        PSIMAGE_ELEMENT_ASSIGN(output,input,S32);
+        break;
+    case PS_TYPE_S64:
+        PSIMAGE_ELEMENT_ASSIGN(output,input,S64);
+        break;
+    case PS_TYPE_U8:
+        PSIMAGE_ELEMENT_ASSIGN(output,input,U8);
+    case PS_TYPE_U16:
+        PSIMAGE_ELEMENT_ASSIGN(output,input,U16);
+        break;
+    case PS_TYPE_U32:
+        PSIMAGE_ELEMENT_ASSIGN(output,input,U32);
+        break;
+    case PS_TYPE_U64:
+        PSIMAGE_ELEMENT_ASSIGN(output,input,U64);
+        break;
+    case PS_TYPE_F32:
+        PSIMAGE_ELEMENT_ASSIGN(output,input,F32);
+        break;
+    case PS_TYPE_F64:
+        PSIMAGE_ELEMENT_ASSIGN(output,input,F64);
+        break;
+    case PS_TYPE_C32:
+        PSIMAGE_ELEMENT_ASSIGN(output,input,C32);
+        break;
+    case PS_TYPE_C64:
+        PSIMAGE_ELEMENT_ASSIGN(output,input,C64);
+        break;
+    case PS_TYPE_PTR:
+        psError(__func__,"Can't copy image into a matrix of pointers.");
+        psImageFree(output);
+        return NULL;
+    }
+    #endif
+
+    #if 1
+    switch (type) {
+    case PS_TYPE_S8:
+        switch (input->type.type) {
+        case PS_TYPE_S8: {
+                psS8 *in;
+                psS8 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S8[row];
+                    out = output->data.S8[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS8) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S16: {
+                psS16 *in;
+                psS8 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S16[row];
+                    out = output->data.S8[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS8) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S32: {
+                psS32 *in;
+                psS8 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S32[row];
+                    out = output->data.S8[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS8) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S64: {
+                psS64 *in;
+                psS8 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S64[row];
+                    out = output->data.S8[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS8) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U8: {
+                psU8 *in;
+                psS8 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U8[row];
+                    out = output->data.S8[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS8) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U16: {
+                psU16 *in;
+                psS8 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U16[row];
+                    out = output->data.S8[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS8) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U32: {
+                psU32 *in;
+                psS8 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U32[row];
+                    out = output->data.S8[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS8) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U64: {
+                psU64 *in;
+                psS8 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U64[row];
+                    out = output->data.S8[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS8) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_F32: {
+                psF32 *in;
+                psS8 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.F32[row];
+                    out = output->data.S8[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS8) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_F64: {
+                psF64 *in;
+                psS8 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.F64[row];
+                    out = output->data.S8[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS8) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_C32: {
+                psC32 *in;
+                psS8 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.C32[row];
+                    out = output->data.S8[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS8) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_PTR:
+            psError (__func__, "Can't copy image from a matrix of pointers.");
+            psImageFree (output);
+            return ((void *) 0);
+        default:
+            break;
+        };
+        break;
+    case PS_TYPE_S16:
+        switch (input->type.type) {
+        case PS_TYPE_S8: {
+                psS8 *in;
+                psS16 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S8[row];
+                    out = output->data.S16[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS16) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S16: {
+                psS16 *in;
+                psS16 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S16[row];
+                    out = output->data.S16[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS16) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S32: {
+                psS32 *in;
+                psS16 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S32[row];
+                    out = output->data.S16[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS16) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S64: {
+                psS64 *in;
+                psS16 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S64[row];
+                    out = output->data.S16[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS16) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U8: {
+                psU8 *in;
+                psS16 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U8[row];
+                    out = output->data.S16[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS16) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U16: {
+                psU16 *in;
+                psS16 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U16[row];
+                    out = output->data.S16[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS16) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U32: {
+                psU32 *in;
+                psS16 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U32[row];
+                    out = output->data.S16[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS16) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U64: {
+                psU64 *in;
+                psS16 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U64[row];
+                    out = output->data.S16[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS16) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_F32: {
+                psF32 *in;
+                psS16 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.F32[row];
+                    out = output->data.S16[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS16) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_F64: {
+                psF64 *in;
+                psS16 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.F64[row];
+                    out = output->data.S16[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS16) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_C32: {
+                psC32 *in;
+                psS16 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.C32[row];
+                    out = output->data.S16[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS16) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_PTR:
+            psError (__func__, "Can't copy image from a matrix of pointers.");
+            psImageFree (output);
+            return ((void *) 0);
+        default:
+            break;
+        };
+        break;
+    case PS_TYPE_S32:
+        switch (input->type.type) {
+        case PS_TYPE_S8: {
+                psS8 *in;
+                psS32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S8[row];
+                    out = output->data.S32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S16: {
+                psS16 *in;
+                psS32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S16[row];
+                    out = output->data.S32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S32: {
+                psS32 *in;
+                psS32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S32[row];
+                    out = output->data.S32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S64: {
+                psS64 *in;
+                psS32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S64[row];
+                    out = output->data.S32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U8: {
+                psU8 *in;
+                psS32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U8[row];
+                    out = output->data.S32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U16: {
+                psU16 *in;
+                psS32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U16[row];
+                    out = output->data.S32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U32: {
+                psU32 *in;
+                psS32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U32[row];
+                    out = output->data.S32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U64: {
+                psU64 *in;
+                psS32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U64[row];
+                    out = output->data.S32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_F32: {
+                psF32 *in;
+                psS32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.F32[row];
+                    out = output->data.S32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_F64: {
+                psF64 *in;
+                psS32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.F64[row];
+                    out = output->data.S32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_C32: {
+                psC32 *in;
+                psS32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.C32[row];
+                    out = output->data.S32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_PTR:
+            psError (__func__, "Can't copy image from a matrix of pointers.");
+            psImageFree (output);
+            return ((void *) 0);
+        default:
+            break;
+        };
+        break;
+    case PS_TYPE_S64:
+        switch (input->type.type) {
+        case PS_TYPE_S8: {
+                psS8 *in;
+                psS64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S8[row];
+                    out = output->data.S64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S16: {
+                psS16 *in;
+                psS64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S16[row];
+                    out = output->data.S64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S32: {
+                psS32 *in;
+                psS64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S32[row];
+                    out = output->data.S64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S64: {
+                psS64 *in;
+                psS64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S64[row];
+                    out = output->data.S64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U8: {
+                psU8 *in;
+                psS64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U8[row];
+                    out = output->data.S64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U16: {
+                psU16 *in;
+                psS64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U16[row];
+                    out = output->data.S64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U32: {
+                psU32 *in;
+                psS64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U32[row];
+                    out = output->data.S64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U64: {
+                psU64 *in;
+                psS64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U64[row];
+                    out = output->data.S64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_F32: {
+                psF32 *in;
+                psS64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.F32[row];
+                    out = output->data.S64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_F64: {
+                psF64 *in;
+                psS64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.F64[row];
+                    out = output->data.S64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_C32: {
+                psC32 *in;
+                psS64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.C32[row];
+                    out = output->data.S64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psS64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_PTR:
+            psError (__func__, "Can't copy image from a matrix of pointers.");
+            psImageFree (output);
+            return ((void *) 0);
+        default:
+            break;
+        };
+        break;
+    case PS_TYPE_U8:
+        switch (input->type.type) {
+        case PS_TYPE_S8: {
+                psS8 *in;
+                psU8 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S8[row];
+                    out = output->data.U8[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU8) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S16: {
+                psS16 *in;
+                psU8 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S16[row];
+                    out = output->data.U8[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU8) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S32: {
+                psS32 *in;
+                psU8 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S32[row];
+                    out = output->data.U8[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU8) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S64: {
+                psS64 *in;
+                psU8 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S64[row];
+                    out = output->data.U8[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU8) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U8: {
+                psU8 *in;
+                psU8 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U8[row];
+                    out = output->data.U8[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU8) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U16: {
+                psU16 *in;
+                psU8 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U16[row];
+                    out = output->data.U8[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU8) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U32: {
+                psU32 *in;
+                psU8 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U32[row];
+                    out = output->data.U8[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU8) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U64: {
+                psU64 *in;
+                psU8 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U64[row];
+                    out = output->data.U8[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU8) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_F32: {
+                psF32 *in;
+                psU8 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.F32[row];
+                    out = output->data.U8[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU8) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_F64: {
+                psF64 *in;
+                psU8 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.F64[row];
+                    out = output->data.U8[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU8) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_C32: {
+                psC32 *in;
+                psU8 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.C32[row];
+                    out = output->data.U8[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU8) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_PTR:
+            psError (__func__, "Can't copy image from a matrix of pointers.");
+            psImageFree (output);
+            return ((void *) 0);
+        default:
+            break;
+        };
+        break;
+    case PS_TYPE_U16:
+        switch (input->type.type) {
+        case PS_TYPE_S8: {
+                psS8 *in;
+                psU16 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S8[row];
+                    out = output->data.U16[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU16) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S16: {
+                psS16 *in;
+                psU16 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S16[row];
+                    out = output->data.U16[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU16) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S32: {
+                psS32 *in;
+                psU16 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S32[row];
+                    out = output->data.U16[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU16) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S64: {
+                psS64 *in;
+                psU16 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S64[row];
+                    out = output->data.U16[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU16) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U8: {
+                psU8 *in;
+                psU16 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U8[row];
+                    out = output->data.U16[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU16) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U16: {
+                psU16 *in;
+                psU16 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U16[row];
+                    out = output->data.U16[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU16) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U32: {
+                psU32 *in;
+                psU16 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U32[row];
+                    out = output->data.U16[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU16) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U64: {
+                psU64 *in;
+                psU16 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U64[row];
+                    out = output->data.U16[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU16) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_F32: {
+                psF32 *in;
+                psU16 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.F32[row];
+                    out = output->data.U16[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU16) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_F64: {
+                psF64 *in;
+                psU16 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.F64[row];
+                    out = output->data.U16[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU16) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_C32: {
+                psC32 *in;
+                psU16 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.C32[row];
+                    out = output->data.U16[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU16) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_PTR:
+            psError (__func__, "Can't copy image from a matrix of pointers.");
+            psImageFree (output);
+            return ((void *) 0);
+        default:
+            break;
+        };
+        break;
+    case PS_TYPE_U32:
+        switch (input->type.type) {
+        case PS_TYPE_S8: {
+                psS8 *in;
+                psU32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S8[row];
+                    out = output->data.U32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S16: {
+                psS16 *in;
+                psU32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S16[row];
+                    out = output->data.U32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S32: {
+                psS32 *in;
+                psU32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S32[row];
+                    out = output->data.U32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S64: {
+                psS64 *in;
+                psU32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S64[row];
+                    out = output->data.U32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U8: {
+                psU8 *in;
+                psU32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U8[row];
+                    out = output->data.U32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U16: {
+                psU16 *in;
+                psU32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U16[row];
+                    out = output->data.U32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U32: {
+                psU32 *in;
+                psU32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U32[row];
+                    out = output->data.U32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U64: {
+                psU64 *in;
+                psU32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U64[row];
+                    out = output->data.U32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_F32: {
+                psF32 *in;
+                psU32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.F32[row];
+                    out = output->data.U32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_F64: {
+                psF64 *in;
+                psU32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.F64[row];
+                    out = output->data.U32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_C32: {
+                psC32 *in;
+                psU32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.C32[row];
+                    out = output->data.U32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_PTR:
+            psError (__func__, "Can't copy image from a matrix of pointers.");
+            psImageFree (output);
+            return ((void *) 0);
+        default:
+            break;
+        };
+        break;
+    case PS_TYPE_U64:
+        switch (input->type.type) {
+        case PS_TYPE_S8: {
+                psS8 *in;
+                psU64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S8[row];
+                    out = output->data.U64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S16: {
+                psS16 *in;
+                psU64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S16[row];
+                    out = output->data.U64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S32: {
+                psS32 *in;
+                psU64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S32[row];
+                    out = output->data.U64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S64: {
+                psS64 *in;
+                psU64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S64[row];
+                    out = output->data.U64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U8: {
+                psU8 *in;
+                psU64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U8[row];
+                    out = output->data.U64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U16: {
+                psU16 *in;
+                psU64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U16[row];
+                    out = output->data.U64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U32: {
+                psU32 *in;
+                psU64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U32[row];
+                    out = output->data.U64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U64: {
+                psU64 *in;
+                psU64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U64[row];
+                    out = output->data.U64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_F32: {
+                psF32 *in;
+                psU64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.F32[row];
+                    out = output->data.U64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_F64: {
+                psF64 *in;
+                psU64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.F64[row];
+                    out = output->data.U64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_C32: {
+                psC32 *in;
+                psU64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.C32[row];
+                    out = output->data.U64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psU64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_PTR:
+            psError (__func__, "Can't copy image from a matrix of pointers.");
+            psImageFree (output);
+            return ((void *) 0);
+        default:
+            break;
+        };
+        break;
+    case PS_TYPE_F32:
+        switch (input->type.type) {
+        case PS_TYPE_S8: {
+                psS8 *in;
+                psF32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S8[row];
+                    out = output->data.F32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psF32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S16: {
+                psS16 *in;
+                psF32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S16[row];
+                    out = output->data.F32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psF32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S32: {
+                psS32 *in;
+                psF32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S32[row];
+                    out = output->data.F32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psF32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S64: {
+                psS64 *in;
+                psF32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S64[row];
+                    out = output->data.F32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psF32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U8: {
+                psU8 *in;
+                psF32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U8[row];
+                    out = output->data.F32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psF32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U16: {
+                psU16 *in;
+                psF32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U16[row];
+                    out = output->data.F32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psF32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U32: {
+                psU32 *in;
+                psF32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U32[row];
+                    out = output->data.F32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psF32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U64: {
+                psU64 *in;
+                psF32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U64[row];
+                    out = output->data.F32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psF32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_F32: {
+                psF32 *in;
+                psF32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.F32[row];
+                    out = output->data.F32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psF32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_F64: {
+                psF64 *in;
+                psF32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.F64[row];
+                    out = output->data.F32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psF32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_C32: {
+                psC32 *in;
+                psF32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.C32[row];
+                    out = output->data.F32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psF32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_PTR:
+            psError (__func__, "Can't copy image from a matrix of pointers.");
+            psImageFree (output);
+            return ((void *) 0);
+        default:
+            break;
+        };
+        break;
+    case PS_TYPE_F64:
+        switch (input->type.type) {
+        case PS_TYPE_S8: {
+                psS8 *in;
+                psF64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S8[row];
+                    out = output->data.F64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psF64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S16: {
+                psS16 *in;
+                psF64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S16[row];
+                    out = output->data.F64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psF64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S32: {
+                psS32 *in;
+                psF64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S32[row];
+                    out = output->data.F64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psF64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S64: {
+                psS64 *in;
+                psF64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S64[row];
+                    out = output->data.F64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psF64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U8: {
+                psU8 *in;
+                psF64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U8[row];
+                    out = output->data.F64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psF64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U16: {
+                psU16 *in;
+                psF64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U16[row];
+                    out = output->data.F64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psF64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U32: {
+                psU32 *in;
+                psF64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U32[row];
+                    out = output->data.F64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psF64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U64: {
+                psU64 *in;
+                psF64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U64[row];
+                    out = output->data.F64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psF64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_F32: {
+                psF32 *in;
+                psF64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.F32[row];
+                    out = output->data.F64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psF64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_F64: {
+                psF64 *in;
+                psF64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.F64[row];
+                    out = output->data.F64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psF64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_C32: {
+                psC32 *in;
+                psF64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.C32[row];
+                    out = output->data.F64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psF64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_PTR:
+            psError (__func__, "Can't copy image from a matrix of pointers.");
+            psImageFree (output);
+            return ((void *) 0);
+        default:
+            break;
+        };
+        break;
+    case PS_TYPE_C32:
+        switch (input->type.type) {
+        case PS_TYPE_S8: {
+                psS8 *in;
+                psC32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S8[row];
+                    out = output->data.C32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psC32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S16: {
+                psS16 *in;
+                psC32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S16[row];
+                    out = output->data.C32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psC32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S32: {
+                psS32 *in;
+                psC32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S32[row];
+                    out = output->data.C32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psC32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S64: {
+                psS64 *in;
+                psC32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S64[row];
+                    out = output->data.C32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psC32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U8: {
+                psU8 *in;
+                psC32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U8[row];
+                    out = output->data.C32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psC32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U16: {
+                psU16 *in;
+                psC32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U16[row];
+                    out = output->data.C32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psC32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U32: {
+                psU32 *in;
+                psC32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U32[row];
+                    out = output->data.C32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psC32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U64: {
+                psU64 *in;
+                psC32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U64[row];
+                    out = output->data.C32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psC32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_F32: {
+                psF32 *in;
+                psC32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.F32[row];
+                    out = output->data.C32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psC32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_F64: {
+                psF64 *in;
+                psC32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.F64[row];
+                    out = output->data.C32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psC32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_C32: {
+                psC32 *in;
+                psC32 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.C32[row];
+                    out = output->data.C32[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psC32) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_PTR:
+            psError (__func__, "Can't copy image from a matrix of pointers.");
+            psImageFree (output);
+            return ((void *) 0);
+        default:
+            break;
+        };
+        break;
+    case PS_TYPE_C64:
+        switch (input->type.type) {
+        case PS_TYPE_S8: {
+                psS8 *in;
+                psC64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S8[row];
+                    out = output->data.C64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psC64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S16: {
+                psS16 *in;
+                psC64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S16[row];
+                    out = output->data.C64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psC64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S32: {
+                psS32 *in;
+                psC64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S32[row];
+                    out = output->data.C64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psC64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_S64: {
+                psS64 *in;
+                psC64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.S64[row];
+                    out = output->data.C64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psC64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U8: {
+                psU8 *in;
+                psC64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U8[row];
+                    out = output->data.C64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psC64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U16: {
+                psU16 *in;
+                psC64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U16[row];
+                    out = output->data.C64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psC64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U32: {
+                psU32 *in;
+                psC64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U32[row];
+                    out = output->data.C64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psC64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_U64: {
+                psU64 *in;
+                psC64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.U64[row];
+                    out = output->data.C64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psC64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_F32: {
+                psF32 *in;
+                psC64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.F32[row];
+                    out = output->data.C64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psC64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_F64: {
+                psF64 *in;
+                psC64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.F64[row];
+                    out = output->data.C64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psC64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_C32: {
+                psC32 *in;
+                psC64 *out;
+                for (int row = 0; row < numRows; row++) {
+                    in = input->data.C32[row];
+                    out = output->data.C64[row];
+                    for (int col = 0; col < numCols; col++) {
+                        out[col] = (psC64) in[col];
+                    }
+                }
+            };
+            break;
+        case PS_TYPE_PTR:
+            psError (__func__, "Can't copy image from a matrix of pointers.");
+            psImageFree (output);
+            return ((void *) 0);
+        default:
+            break;
+        };
+        break;
+    case PS_TYPE_PTR:
+        psError (__func__, "Can't copy image into a matrix of pointers.");
+        psImageFree (output);
+        return ((void *) 0);
+    }
+
+    return output;
+}
+
+int psImageClip(psImage* input,float min,float vmin,float max,float vmax)
+{
+    int numClipped = 0;
+    unsigned int numRows;
+    unsigned int numCols;
+
+    if (input == NULL) {
+        return 0;
+    }
+
+    if (max < min) {
+        psError(__func__,"psImageClip can not be invoked with max < min.");
+        return 0;
+    }
+
+    numRows = input->numRows;
+    numCols = input->numCols;
+
+    switch (input->type.type) {
+
+        #define psImageClipCase(type)\
+    case PS_TYPE_##type: { \
+            ps##type minimum = (ps##type) min; \
+            ps##type maximum = (ps##type) max; \
+            for (unsigned int row = 0;row<numRows;row++) { \
+                ps##type* inputRow = input->data.type[row]; \
+                for (unsigned int col = 0; col < numCols; col++) { \
+                    if (inputRow[col] < minimum) { \
+                        inputRow[col] = (ps##type)vmin; \
+                        numClipped++; \
+                    } else if (inputRow[col] > maximum) { \
+                        inputRow[col] = (ps##type)vmax; \
+                        numClipped++; \
+                    } \
+                } \
+            } \
+        } \
+        break;
+        #define psImageClipCaseComplex(type)\
+    case PS_TYPE_##type: { \
+            for (unsigned int row = 0;row<numRows;row++) { \
+                ps##type* inputRow = input->data.type[row]; \
+                for (unsigned int col = 0; col < numCols; col++) { \
+                    if (cabsf(inputRow[col]) < min) { \
+                        inputRow[col] = (ps##type)vmin; \
+                        numClipped++; \
+                    } else if (cabsf(inputRow[col]) > max) { \
+                        inputRow[col] = (ps##type)vmax; \
+                        numClipped++; \
+                    } \
+                } \
+            } \
+        } \
+        break;
+
+        psImageClipCase(S8)
+        psImageClipCase(S16)
+        psImageClipCase(S32)
+        psImageClipCase(S64)
+        psImageClipCase(U8)
+        psImageClipCase(U16)
+        psImageClipCase(U32)
+        psImageClipCase(U64)
+        psImageClipCase(F32)
+        psImageClipCase(F64)
+        psImageClipCaseComplex(C32)
+        psImageClipCaseComplex(C64)
+
+    default:
+        psError(__func__,"psImageClip does not support the given datatype (%d)",
+                input->type.type);
+    }
+
+    return numClipped;
+}
+
+int psImageClipNaN(psImage* input,float value)
+{
+    int numClipped = 0;
+    unsigned int numRows;
+    unsigned int numCols;
+
+    if (input == NULL) {
+        return 0;
+    }
+    numRows = input->numRows;
+    numCols = input->numCols;
+
+    switch (input->type.type) {
+
+        #define psImageClipNaNCase(type) \
+    case PS_TYPE_##type: \
+        for (unsigned int row = 0;row<numRows;row++) { \
+            ps##type* inputRow = input->data.type[row]; \
+            for (unsigned int col = 0; col < numCols; col++) { \
+                if (! isfinite(inputRow[col])) { \
+                    inputRow[col] = (ps##type)value; \
+                    numClipped++; \
+                } \
+            } \
+        } \
+        break;
+
+        psImageClipNaNCase(F32)
+        psImageClipNaNCase(F64)
+        psImageClipNaNCase(C32)
+        psImageClipNaNCase(C64)
+
+    default:
+        psError(__func__,"psImageClip does not support the given datatype (%d)",
+                input->type.type);
+    }
+
+    return numClipped;
+}
+
+int psImageOverlaySection(psImage* image, const psImage* overlay, int col0,
+                          int row0, const char* op)
+{
+    unsigned int imageNumRows;
+    unsigned int imageNumCols;
+    unsigned int overlayNumRows;
+    unsigned int overlayNumCols;
+    unsigned int imageRowLimit;
+    unsigned int imageColLimit;
+    psElemType  type;
+
+    if (image == NULL || overlay == NULL) {
+        psError(__func__,"one of the input images was NULL.");
+        return 1;
+    }
+
+    if (op == NULL) {
+        psError(__func__,"Operation can not be NULL.");
+        return 1;
+    }
+
+    type = image->type.type;
+
+    if (type != overlay->type.type) {
+        psError(__func__,"Image and overlay datatypes must match. (%d vs %d)",
+                type,overlay->type.type);
+        return 2;
+    }
+
+    imageNumRows = image->numRows;
+    imageNumCols = image->numCols;
+    overlayNumRows = overlay->numRows;
+    overlayNumCols = overlay->numCols;
+
+    /* check row0/col0 to see if it is within the image size */
+    if (row0 < 0 || col0 < 0 || row0 >= imageNumRows || col0 >= imageNumCols) {
+        psError(__func__, "Overlay origin of (%d,%d) is outside of the image dimensions (%d x %d).",
+                col0, row0, imageNumCols, imageNumRows);
+        return 3;
+    }
+
+    /* check if overlay is totally withing input image */
+    imageRowLimit = row0+overlayNumRows;
+    imageColLimit = col0+overlayNumCols;
+    if (imageRowLimit > imageNumRows || imageColLimit > imageNumCols) {
+        psError(__func__, "Overlay image (%d,%d -> %d,%d) is partially outside"
+                " of the input image (%d x %d).",
+                col0, row0, col0+overlayNumCols-1, row0+overlayNumRows-1,
+                imageNumCols,imageNumRows);
+        return 4;
+    }
+
+    switch (type) {
+
+        #define psImageOverlayCase(DATATYPE) \
+    case PS_TYPE_##DATATYPE: \
+        for (unsigned int row=row0;row<imageRowLimit;row++) { \
+            ps##DATATYPE* imageRow = image->data.DATATYPE[row]; \
+            ps##DATATYPE* overlayRow = overlay->data.DATATYPE[row-row0]; \
+            for (unsigned int col=col0;col<imageColLimit;col++) { \
+                switch (*op) { \
+                case '+': \
+                    imageRow[col] += overlayRow[col-col0]; \
+                    break; \
+                case '-': \
+                    imageRow[col] -= overlayRow[col-col0]; \
+                    break; \
+                case '*': \
+                    imageRow[col] *= overlayRow[col-col0]; \
+                    break; \
+                case '/': \
+                    imageRow[col] /= overlayRow[col-col0]; \
+                    break; \
+                case '=': \
+                    imageRow[col] = overlayRow[col-col0]; \
+                    break; \
+                default: \
+                    psError(__func__,"Unknown operation %s",op); \
+                    return 5; \
+                } \
+            } \
+        } \
+        break;
+
+        psImageOverlayCase(U8);
+        psImageOverlayCase(U16);
+        psImageOverlayCase(U32);
+        psImageOverlayCase(U64);
+        psImageOverlayCase(S8);
+        psImageOverlayCase(S16);
+        psImageOverlayCase(S32);
+        psImageOverlayCase(S64);
+        psImageOverlayCase(F32);
+        psImageOverlayCase(F64);
+        psImageOverlayCase(C32);
+        psImageOverlayCase(C64);
+
+    default:
+        psError(__func__,"Can not operate on type %d.",type);
+    }
+
+    #endif
+
+    return 0;
+}
Index: /tags/rel1_1/psLib/src/mathtypes/psImage.h
===================================================================
--- /tags/rel1_1/psLib/src/mathtypes/psImage.h	(revision 1056)
+++ /tags/rel1_1/psLib/src/mathtypes/psImage.h	(revision 1056)
@@ -0,0 +1,198 @@
+/** @file  psImage.h
+ *
+ *  @brief Contains basic image definitions and operations
+ *
+ *  This file defines the basic type for an image struct and functions useful
+ *  in manupulating images.
+ *
+ *  @ingroup Image
+ *
+ *  @author Robert DeSonia, MHPCC
+ *  @author Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.21 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-10 01:58:06 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+# ifndef PS_IMAGE_H
+# define PS_IMAGE_H
+
+#include <complex.h>
+
+#include "psType.h"
+
+/// @addtogroup Image
+/// @{
+
+/** Basic image data structure.
+ *
+ * Struct for maintaining image data of varying types. It also contains
+ * information about image size, parent images and children images.
+ *
+ */
+typedef struct psImage
+{
+    const psType type;                  ///< Image data type and dimension.
+    const unsigned int numCols;         ///< Number of columns in image
+    const unsigned int numRows;         ///< Number of rows in image.
+    const int col0;                     ///< Column position relative to parent.
+    const int row0;                     ///< Row position relative to parent.
+
+    union {
+        psU8    **U8;                   ///< Unsigned 8-bit integer data.
+        psU16   **U16;                  ///< Unsigned 16-bit integer data.
+        psU32   **U32;                  ///< Unsigned 32-bit integer data.
+        psU64   **U64;                  ///< Unsigned 64-bit integer data.
+        psS8    **S8;                   ///< Signed 8-bit integer data.
+        psS16   **S16;                  ///< Signed 16-bit integer data.
+        psS32   **S32;                  ///< Signed 32-bit integer data.
+        psS64   **S64;                  ///< Signed 64-bit integer data.
+        psF32   **F32;                  ///< Single-precision float data.
+        psF64   **F64;                  ///< Double-precision float data.
+        psC32   **C32;                  ///< Single-precision complex data.
+        psC64   **C64;                  ///< Double-precision complex data.
+        psPTR   **PTR;                  ///< Void pointers.
+        psPTR    *V;                    ///< Pointer to data.
+    } data;                             ///< Union for data types.
+    const struct psImage *parent;       ///< Parent, if a subimage.
+    int nChildren;                      ///< Number of subimages.
+    struct psImage** children;          ///< Children of this region.
+}
+psImage;
+
+/*****************************************************************************/
+/* FUNCTION PROTOTYPES                                                       */
+/*****************************************************************************/
+
+
+/** Create an image of the specified size and type.
+ *
+ * Uses psLib memory allocation functions to create an image struct of the
+ * specified size and type.
+ *
+ * @return psImage*: Pointer to psImage.
+ *
+ */
+psImage *psImageAlloc(
+    unsigned int numCols,               ///< Number of rows in image.
+    unsigned int numRows,               ///< Number of columns in image.
+    const psElemType type               ///< Type of data for image.
+);
+
+/** Resize a given image to the given size/type.
+ *
+ *  @return psImage* Resized psImage.
+ *
+ */
+psImage* psImageRecycle(
+    psImage* old,                       ///< the psImage to recycle by resizing image buffer
+    unsigned int numCols,               ///< the desired number of columns in image
+    unsigned int numRows,               ///< the desired number of rows in image
+    const psElemType type               ///< the desired datatype of the image
+);
+
+/** Create a subimage of the specified area.
+ *
+ * Uses psLib memory allocation functions to create an image based on a larger
+ * one.
+ *
+ * @return psImage*: Pointer to psImage.
+ *
+ */
+psImage *psImageSubset(
+    psImage *out,                       ///< Subimage to return, or NULL.
+    psImage *image,                     ///< Parent image.
+    unsigned int numCols,               ///< Subimage width (<= image.nCols - col0).
+    unsigned int numRows,               ///< Subimage height (<= image.nRows - row0).
+    unsigned int col0,                  ///< Subimage col-offset (0 <= col0 < nCol).
+    unsigned int row0                   ///< Subimage row-offset (0 <= row0 < nCol).
+);
+
+/** Destroy the specified image.
+ *
+ *  Uses psLib memory deallocation functions to free an image and any existing
+ *  children.
+ *
+ */
+void psImageFree(
+    psImage *restrict image             ///< Free psImage
+);
+
+/** Frees all children of a psImage.
+ *
+ *  @return int      Number of children freed.
+ *
+ */
+int psImageFreeChildren(
+    psImage* image
+    /**< psImage in which all children shall be deallocated */
+);
+
+/** Makes a copy of a psImage
+ *
+ * @return psImage*  Copy of the input psImage.  This may not be equal to the
+ * output parameter
+ *
+ */
+psImage *psImageCopy(
+    psImage* restrict output,
+    /**< if not NULL, a psImage that could be recycled.  If it can not be used,
+     *   it will be freed via psImageFree
+     */
+    const psImage *input,
+    /**< the psImage to copy */
+    psElemType type
+    /**< the desired datatype of the returned copy */
+);
+
+/** Clip image values outside of tange to given values
+ *
+ *  All pixels with values less than min are set to the value vmin.  all pixels
+ *  with values greater than max are set to the value vmax. This function is
+ *  defined for psU8, psU16, psS8, psS16, psF32, psF64, psC32, and psC64.
+ *
+ *  @return int     The number of clipped pixels
+ */
+int psImageClip(
+    psImage* input,                 ///< the image to clip
+    psF32 min,                      ///< the minimum image value allowed
+    psF32 vmin,                     ///< the value pixels < min are set to
+    psF32 max,                      ///< the maximum image value allowed
+    psF32 vmax                      ///< the value pixels > max are set to
+);
+
+/** Clip NaN image pixels to given value.
+ *
+ *  Pixels with NaN, +Inf, or -Inf values are set to the specified value. This
+ *  function is defined for psF32, psF64, psC32, and psC64.
+ *
+ *  @return int     The number of clipped pixels
+ */
+int psImageClipNaN(
+    psImage* input,                 ///< the image to clip
+    psF32 value                     ///< the value to set all NaN/Inf values to
+);
+
+/** Overlay subregion of image with another image
+ *
+ *  Replace the pixels in the image which correspond to the pixels in OVERLAY
+ *  with values derived from the IMAGE and OVERLAY based on the given operator
+ *  OP.  Valid operators are "=" (set image value to OVERLAY value), "+" (add
+ *  OVERLAY value to image value), "-" (subtract OVERLAY from image), "*"
+ *  (multiply OVERLAY times image), "/" (divide image by OVERLAY).  This
+ *  function is defined for psU8, psS8, psS16, psF32, psF64, psC32, and psC64.
+ *
+ *  @return int         0 if success, non-zero if failed.
+ */
+int psImageOverlaySection(
+    psImage* image,                 ///< target image
+    const psImage* overlay,         ///< the overlay image
+    int col0,                       ///< the column to start overlay
+    int row0,                       ///< the row to start overlay
+    const char* op                  ///< the operation to perform for overlay
+);
+
+/// @}
+
+#endif
Index: /tags/rel1_1/psLib/src/mathtypes/psVector.c
===================================================================
--- /tags/rel1_1/psLib/src/mathtypes/psVector.c	(revision 1056)
+++ /tags/rel1_1/psLib/src/mathtypes/psVector.c	(revision 1056)
@@ -0,0 +1,187 @@
+/** @file  psVector.c
+ *
+ *  @brief Contains support for basic vector types
+ *
+ *  This file defines the basic type for a vector struct and functions useful
+ *  in manupulating vectors.
+ *
+ *  @author Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.10 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-12 01:33:16 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+/******************************************************************************/
+/*  INCLUDE FILES                                                             */
+/******************************************************************************/
+#include "psMemory.h"
+#include "psError.h"
+#include "psVector.h"
+#include "psLogMsg.h"
+
+/******************************************************************************/
+/*  DEFINE STATEMENTS                                                         */
+/******************************************************************************/
+
+// None
+
+/******************************************************************************/
+/*  TYPE DEFINITIONS                                                          */
+/******************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  GLOBAL VARIABLES                                                         */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  FILE STATIC VARIABLES                                                    */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  FUNCTION IMPLEMENTATION - LOCAL                                          */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* FUNCTION IMPLEMENTATION - PUBLIC                                          */
+/*****************************************************************************/
+psVector* psVectorAlloc(unsigned int nalloc, psElemType elemType)
+{
+    psVector *psVec = NULL;
+    int elementSize = 0;
+
+    // Invalid nalloc
+    if(nalloc < 1) {
+        psError(__func__, "Invalid value for nalloc. nalloc: %d\n", nalloc);
+        return NULL;
+    }
+
+    elementSize = PSELEMTYPE_SIZEOF(elemType);
+
+    // Create vector struct
+    psVec = (psVector *)psAlloc(sizeof(psVector));
+
+    psVec->type.dimen = PS_DIMEN_VECTOR;
+    psVec->type.type = elemType;
+    psVec->nalloc = nalloc;
+    psVec->n = 0;
+
+    // Create vector data array
+    psVec->data.V = psAlloc(nalloc*elementSize);
+
+    return psVec;
+}
+
+psVector *psVectorRealloc(unsigned int nalloc, psVector *restrict in)
+{
+    int elementSize = 0;
+    psElemType elemType;
+
+    // Invalid nalloc
+    if(nalloc < 1) {
+        psError(__func__, "Invalid value for realloc (%d)\n", nalloc);
+        return NULL;
+    }
+
+    if(in == NULL) {
+        psError(__func__, "Null input vector\n");
+        return NULL;
+    } else if(in->nalloc != nalloc) {                    // No need to realloc to same size
+        elemType = in->type.type;
+        elementSize = PSELEMTYPE_SIZEOF(elemType);
+        if(nalloc < in->n) {
+            if (elemType == PS_TYPE_PTR) {
+                for (int i = nalloc; i < in->n; i++) {   // For reduction in vector size
+                    psMemDecrRefCounter(in->data.PTR[i]);
+                }
+            }
+            in->n = nalloc;
+        }
+
+        // Realloc after decrementation to avoid accessing freed array elements
+        in->data.V = psRealloc(in->data.V,nalloc*elementSize);
+        in->nalloc = nalloc;
+    }
+
+    return in;
+}
+
+psVector *psVectorRecycle(psVector *restrict in, psElemType type, unsigned int nalloc)
+{
+    psElemType elemType;
+
+    if (in == NULL) {
+        return psVectorAlloc(nalloc, type);
+    }
+
+    elemType = in->type.type;
+
+    if (in->nalloc == nalloc && elemType == type) {
+        // it is proper size/type already
+        return in;
+    }
+
+    // Invalid nalloc
+    if(nalloc < 1) {
+        psError(__func__, "Invalid value for nalloc (%d)\n", nalloc);
+        psVectorFree(in);
+        return NULL;
+    }
+
+
+    // if vector of pointers, dereference old values.
+    if (elemType == PS_TYPE_PTR) {
+        for (int i = 0; i < in->n; i++) {   // For reduction in vector size
+            psMemDecrRefCounter(in->data.PTR[i]);
+            in->data.PTR[i] = NULL;
+        }
+    }
+
+    in->data.V = psRealloc(in->data.V,nalloc*PSELEMTYPE_SIZEOF(type));
+
+    in->n = 0;
+    in->type.type = type;
+    in->nalloc = nalloc;
+
+    return in;
+}
+
+void psVectorFree(psVector *restrict psVec)
+{
+    if (psVec == NULL) {
+        return;
+    }
+
+    psFree(psVec->data.V);
+    psFree(psVec);
+}
+
+void psVectorElementFree(psVector *restrict psVec, void (*elemFree)(void *))
+{
+
+    if(psVec == NULL) {
+        return;
+    }
+
+    if (psVec->type.type != PS_TYPE_PTR) {
+        psLogMsg(__func__,PS_LOG_WARN,"psVectorElementFree only operates on void* vectors");
+        return;
+    }
+
+    for(int i = 0; i < psVec->nalloc; i++) {
+        if(elemFree == NULL) {
+            psMemDecrRefCounter(psVec->data.PTR[i]);
+        } else {
+            elemFree(psMemDecrRefCounter(psVec->data.PTR[i]));
+        }
+        psVec->data.PTR[i] = NULL;
+    }
+}
+
Index: /tags/rel1_1/psLib/src/mathtypes/psVector.h
===================================================================
--- /tags/rel1_1/psLib/src/mathtypes/psVector.h	(revision 1056)
+++ /tags/rel1_1/psLib/src/mathtypes/psVector.h	(revision 1056)
@@ -0,0 +1,130 @@
+/** @file  psVector.h
+ *
+ *  @brief Contains basic vector definitions and operations
+ *
+ *  This file defines the basic type for a vector struct and functions useful
+ *  in manupulating vectors.
+ *
+ *  @ingroup Vector
+ *
+ *  @author Robert DeSonia, MHPCC
+ *  @author Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.10 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-10 01:58:06 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PS_VECTOR_H
+#define PS_VECTOR_H
+
+#include "psType.h"
+
+/// @addtogroup Vector
+/// @{
+
+/** An vector to support primitive types.
+ *
+ * Struct for maintaining an vector of frequently used primitive types.
+ *
+ */
+typedef struct
+{
+    psType type;                        ///< Type of data.
+    unsigned int nalloc;                ///< Total number of elements available.
+    unsigned int n;                     ///< Number of elements in use.
+
+    union {
+        psU8    *U8;                    ///< Unsigned 8-bit integer data.
+        psU16   *U16;                   ///< Unsigned 16-bit integer data.
+        psU32   *U32;                   ///< Unsigned 32-bit integer data.
+        psU64   *U64;                   ///< Unsigned 64-bit integer data.
+        psS8    *S8;                    ///< Signed 8-bit integer data.
+        psS16   *S16;                   ///< Signed 16-bit integer data.
+        psS32   *S32;                   ///< Signed 32-bit integer data.
+        psS64   *S64;                   ///< Signed 64-bit integer data.
+        psF32   *F32;                   ///< Single-precision float data.
+        psF64   *F64;                   ///< Double-precision float data.
+        psC32   *C32;                   ///< Single-precision complex data.
+        psC64   *C64;                   ///< Double-precision complex data.
+        psPTR   *PTR;                   ///< Void pointers.
+        psPTR    V;                     ///< Pointer to data.
+    } data;                             ///< Union for data types.
+}
+psVector;
+
+/*****************************************************************************/
+/* FUNCTION PROTOTYPES                                                       */
+/*****************************************************************************/
+
+/** Allocate a vector.
+ *
+ * Uses psLib memory allocation functions to create a vector collection of data as defined by the psType type.
+ *
+ * @return psVector*: Pointer to psVector.
+ *
+ */
+psVector *psVectorAlloc(
+    unsigned int nalloc,                ///< Total number of elements to make available.
+    psElemType dataType                 ///< Type of data to be held by vector.
+);
+
+/** Reallocate a vector.
+ *
+ * Uses psLib memory allocation functions to reallocate a vector collection of data. The vector is reallocated
+ * according to the psType type member contained within the vector.
+ *
+ * @return psVector*: Pointer to psVector.
+ *
+ */
+psVector *psVectorRealloc(
+    unsigned int nalloc,                ///< Total number of elements to make available.
+    psVector *restrict psVec            ///< Vector to reallocate.
+);
+
+/** Recycle a vector.
+ *
+ * Uses psLib memory allocation functions to reallocate a vector collection of data. The vector is reallocated
+ * according to the psElemType type parameter.
+ *
+ * @return psVector*: Pointer to psVector.
+ *
+ */
+psVector *psVectorRecycle(
+    psVector *restrict psVec,
+    ///< Vector to recycle.  If NULL, a new vector is created.  No effort taken to preserve the values.
+
+    unsigned int nalloc,                ///< Total number of elements to make available.
+    psElemType type                     ///< the datatype of the returned vector
+);
+
+/** Deallocate a vector.
+ *
+ * Uses psLib memory allocation functions to deallocate a vector collection of data. The vector is deallocated
+ * according to the psType type member contained within the vector.
+ *
+ * @return psVector*: Pointer to psVector.
+ *
+ */
+void psVectorFree(
+    psVector *restrict psVec  ///< Vector to free.
+);
+
+
+/** Deallocate/Dereference elements of a void pointer vector.
+ *
+ * Uses psLib memory allocation functions to deallocate/dereference elements of a vector of void pointers.
+ * This function does not free the vector elements unless the user provides a elemFree function
+ * pointer. If the elemFree function pointer is NULL, the reference cound of the elements are decremented
+ * without being freed.  The vector psVec is not freed, and its elements will all be set to NULL.
+ *
+ */
+void psVectorElementFree(
+    psVector *restrict psVec,   ///< Void pointer vector to destroy.
+    void (*elemFree)(void *)    ///< Optional callback function to remove vector elements.
+);
+
+/// @}
+
+#endif
Index: /tags/rel1_1/psLib/src/pslib.h
===================================================================
--- /tags/rel1_1/psLib/src/pslib.h	(revision 1056)
+++ /tags/rel1_1/psLib/src/pslib.h	(revision 1056)
@@ -0,0 +1,107 @@
+/** @file  pslib.h
+ *
+ *  @brief Contains the complete list of header files for pslib.
+ *
+ *  This header file includes all the necessary header files for a user to
+ *  user all public functions within the pslib library.
+ *
+ *  @author Eric Van Alst, MHPCC
+ *   
+ *  @version $Revision: 1.7 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-10 01:58:06 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PS_LIB_H
+#define PS_LIB_H
+
+/******************************************************************************/
+/*  INCLUDE FILES                                                             */
+/******************************************************************************/
+
+// System Utilities
+
+/// @defgroup SysUtils System Utilities
+/// @{
+
+/** @defgroup MemoryManagement Memory Management Utilities
+ *
+ *  This is the generic memory management system put inbetween the user's high level code and the OS-level
+ *  memory allocation routines.  This system adds such features as callback routines for memory error events,
+ *  tracing capabilities, and reference counting.
+ *
+ *  @ingroup SysUtils
+ */
+
+#include "psMemory.h"
+
+/// @defgroup LogTrace Tracing and Logging
+/// @ingroup SysUtils
+#include "psLogMsg.h"
+#include "psTrace.h"
+
+/// @defgroup ErrorHandling Error Handling
+/// @ingroup SysUtils
+#include "psAbort.h"
+#include "psError.h"
+
+#include "psString.h"
+
+/// @}
+
+// Collections
+/// @defgroup DataContainer Data Containers
+/// @{
+
+#include "psType.h"
+
+/// @defgroup LinkedList Linked List
+/// @ingroup DataContainer
+#include "psList.h"
+
+/// @defgroup HashTable Hash Table
+/// @ingroup DataContainer
+#include "psHash.h"
+
+/// @defgroup Vector Vector Container
+/// @ingroup DataContainer
+#include "psVector.h"
+
+/// @defgroup Image Image Container
+/// @ingroup DataContainer
+#include "psImage.h"
+
+/// @defgroup BitSet Bit Set
+/// @ingroup DataContainer
+#include "psBitSet.h"
+
+/// @defgroup Sort Sorting Functions
+/// @ingroup DataContainer
+#include "psSort.h"
+/// @}
+
+// Data Manipulation
+/// @defgroup DataManip Data Manipulation
+/// @{
+
+/// @defgroup Stats Statistic Functions
+/// @ingroup DataManip
+#include "psStats.h"
+
+/// @defgroup Matrix Matrix Operations
+/// @ingroup DataManip
+#include "psMatrix.h"
+
+/// @defgroup Transform Fourier Transform
+/// @ingroup DataManip
+#include "psFFT.h"
+
+/// @defgroup ImageIO Image File I/O
+/// @ingroup DataManip
+#include "psImageIO.h"
+
+/// @}
+
+#endif
+
Index: /tags/rel1_1/psLib/src/sys/psAbort.c
===================================================================
--- /tags/rel1_1/psLib/src/sys/psAbort.c	(revision 1056)
+++ /tags/rel1_1/psLib/src/sys/psAbort.c	(revision 1056)
@@ -0,0 +1,75 @@
+/** @file  psAbort.c
+ *
+ *  @brief Contains the definition for abort function
+ *
+ *  The abort logging and handling shall be performed by psAbort function.
+ *  This will allow for consistent handling of other software units
+ *  needing to abort from program execution.
+ *
+ *  @author Eric Van Alst, MHPCC
+ *   
+ *  @version $Revision: 1.4 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-04-27 02:17:53 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+/******************************************************************************/
+/*  INCLUDE FILES                                                             */
+/******************************************************************************/
+#include <stdarg.h>
+#include <stdlib.h>
+#include "psAbort.h"
+#include "psLogMsg.h"
+
+/******************************************************************************/
+/*  DEFINE STATEMENTS                                                         */
+/******************************************************************************/
+
+// None
+
+/******************************************************************************/
+/*  TYPE DEFINITIONS                                                          */
+/******************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  GLOBAL VARIABLES                                                         */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  FILE STATIC VARIABLES                                                    */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  FUNCTION IMPLEMENTATION - LOCAL                                          */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/* FUNCTION IMPLEMENTATION - PUBLIC                                          */
+/*****************************************************************************/
+
+void psAbort(const char *name, const char *fmt,... )
+{
+    va_list    argPtr;     // variable list arguement pointer
+
+    // Get the variable list parameters to pass to logging function
+    va_start(argPtr, fmt);
+
+    // Call logging function with PS_LOG_ABORT level
+    psVLogMsg(name, PS_LOG_ABORT, fmt, argPtr);
+
+    // Clean up stack after variable arguement has been used
+    va_end(argPtr);
+
+    // Call system abort function to terminate program execution
+    abort();
+}
+
Index: /tags/rel1_1/psLib/src/sys/psAbort.h
===================================================================
--- /tags/rel1_1/psLib/src/sys/psAbort.h	(revision 1056)
+++ /tags/rel1_1/psLib/src/sys/psAbort.h	(revision 1056)
@@ -0,0 +1,47 @@
+/** @file  psAbort.h
+ *
+ *  @brief Contains the declarations for the abort function
+ *
+ *  The abort logging and handling shall be performed by psAbort function.
+ *  This will allow for consistent handling of other software units
+ *  needing to abort from program execution.
+ *
+ *  @ingroup ErrorHandling
+ *
+ *  @author Eric Van Alst, MHPCC
+ *
+ *  @version $Revision: 1.4 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-10 01:58:06 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PS_ABORT_H
+#define PS_ABORT_H
+
+
+// Doxygen grouping tags
+/** @addtogroup ErrorHandling
+ *  @{
+ */
+
+/** Reports an abort message to logging facility
+ *
+ *  This function will invoke the psLogMsg function with a level of 
+ *  PS_LOG_ABORT and pass the parameters name and fmt to generate a proper
+ *  log message.  After logging, this function will call system abort 
+ *  function to abnormally terminate the program.
+ *
+ *  @return  void No return value
+ *
+ */
+void psAbort(
+    const char* name,                   ///< Source of abort such as file or function detected
+    const char* fmt,                    ///< A printf style formatting statement defining msg
+    ...
+);
+
+/* @} */  // Doxygen - End of SystemGroup Functions
+
+#endif
+
Index: /tags/rel1_1/psLib/src/sys/psError.c
===================================================================
--- /tags/rel1_1/psLib/src/sys/psError.c	(revision 1056)
+++ /tags/rel1_1/psLib/src/sys/psError.c	(revision 1056)
@@ -0,0 +1,72 @@
+/** @file  psError.c
+ *
+ *  @brief Contains the definitions for the error reporting functions
+ *
+ *  Error reporting functions shall be used to create log entries in the
+ *  event errors are detected.  The messages shall give enough information
+ *  to allow the user to know where the error has occurred and the type
+ *  of error detected.
+ *
+ *  @author Eric Van Alst, MHPCC
+ *   
+ *  @version $Revision: 1.6 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-04-21 21:14:41 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+/******************************************************************************/
+/*  INCLUDE FILES                                                             */
+/******************************************************************************/
+#include <stdarg.h>
+#include "psLogMsg.h"
+#include "psError.h"
+
+/******************************************************************************/
+/*  DEFINE STATEMENTS                                                         */
+/******************************************************************************/
+
+// None
+
+/******************************************************************************/
+/*  TYPE DEFINITIONS                                                          */
+/******************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  GLOBAL VARIABLES                                                         */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  FILE STATIC VARIABLES                                                    */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  FUNCTION IMPLEMENTATIONS - LOCAL                                         */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/* FUNCTION IMPLEMENTATIONS - PUBLIC                                         */
+/*****************************************************************************/
+
+void psError(const char *name,const char *fmt, ...)
+{
+    va_list    argPtr;        // variable list arguement pointer
+
+    // Get the variable list parameters  to pass to logging function
+    va_start(argPtr, fmt);
+
+    // Call logging function with PS_LOG_ERROR level
+    psVLogMsg(name, PS_LOG_ERROR, fmt, argPtr);
+
+    // Clean up stack after variable argument has been used
+    va_end(argPtr);
+}
+
Index: /tags/rel1_1/psLib/src/sys/psError.h
===================================================================
--- /tags/rel1_1/psLib/src/sys/psError.h	(revision 1056)
+++ /tags/rel1_1/psLib/src/sys/psError.h	(revision 1056)
@@ -0,0 +1,45 @@
+/** @file  psError.h
+ *
+ *  @brief Contains the declarations for the error reporting functions
+ *
+ *  Error reporting functions shall be used to create log entries in the
+ *  event errors are detected.  The messages shall give enough information
+ *  to allow the user to know where the error has occurred and the type
+ *  of error detected.
+ *
+ *  @ingroup ErrorHandling
+ *
+ *  @author Eric Van Alst, MHPCC
+ *
+ *  @version $Revision: 1.4 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-10 01:58:06 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PS_ERROR_H
+#define PS_ERROR_H
+
+/** @addtogroup ErrorHandling
+ *  @{
+ */
+
+/** Reports an error message to the logging facility
+ *
+ *  This function will invoke the psLogMsg function with a level of
+ *  PS_LOG_ERROR and pass the parameters name and fmt to generate a proper
+ *  log message.
+ *
+ *  @return  void No return value
+ *
+ */
+void psError(
+    const char *name,                   ///< Source of error such as file or function detected
+    const char *fmt,                    ///< A printf style formatting statement defining msg
+    ...
+);
+
+/* @} */  // End of SysUtils Functions
+
+#endif
+
Index: /tags/rel1_1/psLib/src/sys/psErrorCodes.h
===================================================================
--- /tags/rel1_1/psLib/src/sys/psErrorCodes.h	(revision 1056)
+++ /tags/rel1_1/psLib/src/sys/psErrorCodes.h	(revision 1056)
@@ -0,0 +1,19 @@
+#if !defined(PS_ERROR_CODES_H)
+#define PS_ERROR_CODES_H
+/*
+ * This file was machine generated from ../../src/Utils/psErrorCodes.dat;
+ * please do not modify it
+ */
+typedef enum {
+    PS_ERR_NONE = 0,
+    PS_ERR_BASE = 256,
+    PS_ERR_UNKNOWN,
+    PS_ERR_IO,
+    PS_ERR_BADFREE,
+    PS_ERR_MEMORY_CORRUPTION,
+    PS_ERR_MEMORY_EXHAUSTED,
+    PS_ERR_BAD_INDEX,
+    PS_ERR_N_ERR_CLASSES,
+} psErrorCode;
+
+#endif
Index: /tags/rel1_1/psLib/src/sys/psLogMsg.c
===================================================================
--- /tags/rel1_1/psLib/src/sys/psLogMsg.c	(revision 1056)
+++ /tags/rel1_1/psLib/src/sys/psLogMsg.c	(revision 1056)
@@ -0,0 +1,345 @@
+/** @file  psLogMsg.c
+ *  @brief Procedures for logging messages.
+ *  \ingroup LogTrace
+ *
+ *  This file will hold the prototypes for defining procedure which set
+ *  message log levels, messahe log formats, message log destinations, and
+ *  for generating the messages themselves.
+ *  @ingroup LogTrace
+ *
+ *  @author Robert Lupton, Princeton University
+ *  @author George Gusciora, MHPCC
+ *
+ *  @version $Revision: 1.16 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-14 19:40:15 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+/*****************************************************************************
+NOTES: currently, the prototype code has the following global variables:
+    static int p_psGlobalLogDest;
+    static int p_psGlobalLogLevel;
+    static int p_psLogTime;
+    static int p_psLogHost;
+    static int p_psLogLevel;
+    static int p_psLogName;
+    static int p_psLogMsg;
+ *****************************************************************************/
+#include <limits.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <time.h>
+#include <unistd.h>
+#include "psLogMsg.h"
+#include "psError.h"
+#include "psErrorCodes.h"
+#include "psTrace.h"
+
+#define MIN_LOG_LEVEL 0
+#define MAX_LOG_LEVEL 9
+static int p_psGlobalLogDest = PS_LOG_TO_STDERR; // where to log messages
+static int p_psGlobalLogLevel = PS_LOG_INFO;     // log all messages at this or above
+//static FILE *p_logFP = NULL;
+// The following variables control
+// which information is displayed in
+// log messages.
+static int p_psLogTime = 1;                // Flag to include time info
+static int p_psLogHost = 1;                // Flag to include host info
+static int p_psLogLevel = 1;               // Flag to include level info
+static int p_psLogName = 1;                // Flag to include name info
+static int p_psLogMsg = 1;                 // Flag to include message info
+/*****************************************************************************
+psLogSetLevel(): Set the current log level and return old level.
+Input:
+ level (int): the new log level.
+Output:
+ none
+Return:
+ The old log level.
+ *****************************************************************************/
+int psLogSetLevel(int level)
+{
+    // Save old global log level for changing it.
+    int oldLevel = p_psGlobalLogLevel;
+
+    if ((level < MIN_LOG_LEVEL) || (level > MAX_LOG_LEVEL)) {
+        psLogMsg("logmsg", PS_LOG_WARN,
+                 "Attempt to set invalid logMsg level: %d", level);
+        level = (level < MIN_LOG_LEVEL) ? MIN_LOG_LEVEL : MAX_LOG_LEVEL;
+    }
+
+    // Set new global log level
+    p_psGlobalLogLevel = level;
+
+    // Return old global log level
+    return oldLevel;
+}
+
+
+/*****************************************************************************
+psLogSetDestination(): sets the destination where log messages will be
+sent to.
+ 
+Input:
+ dest (int): the new log destination
+Output:
+ None.
+Return:
+ An integer specifying the old log destination.
+ *****************************************************************************/
+int psLogSetDestination(int dest)
+{
+    // Save old global log destination before changing it.
+    int old = p_psGlobalLogDest;
+
+    switch (dest) {
+    case PS_LOG_NONE:
+    case PS_LOG_TO_STDOUT:
+    case PS_LOG_TO_STDERR:
+        // Set new global log destination
+        p_psGlobalLogDest = dest;
+        break;
+
+    default:
+        // NOTE: Should you log this error properly?
+        fprintf(stderr,"Unknown p_psGlobalLogDest: %d (ignored)\n", dest);
+        break;
+    }
+
+    // Return old global log destination
+    return old;
+}
+
+
+
+/*****************************************************************************
+psLogSetFormat(): Set the format of psLogMsg output.  More precisely,
+    provide a string consisting of the letters {H (host), L (level), M
+    (message), N (name), T (time)}.  The default is "HLMNT".  This string
+    determines whether or not they associated type of information will be
+    included in message logs.  It does not determine the order in which that
+    information will appear (that order is fixed).
+ 
+Input:
+    fmt: a string specifying the format.
+Output:
+    none.
+Return:
+    NULL.
+ *****************************************************************************/
+void psLogSetFormat(const char *fmt)
+{
+
+    // Step through each character in the format string.  For each letter
+    // in that string, set/unset the appropriate logging.
+
+    for (const char *ptr = fmt; *ptr != '\0'; ptr++) {
+        switch (*ptr) {
+        case 'H':
+        case 'h':
+            p_psLogHost = 1;
+            break;
+        case 'L':
+        case 'l':
+            p_psLogLevel = 1;
+            break;
+        case 'M':
+        case 'm':
+            p_psLogMsg = 1;
+            break;
+        case 'N':
+        case 'n':
+            p_psLogName = 1;
+            break;
+        case 'T':
+        case 't':
+            p_psLogTime = 1;
+            break;
+        default:
+            psError(__func__, "Unknown logging keyword %c", *ptr);
+            break;
+        }
+    }
+
+    if (!p_psLogMsg) {
+        psTrace("utils.logMsg", 1,
+                "You must at least log error messages (You chose \"%s\")",
+                fmt);
+    }
+}
+
+
+
+#if !defined(HOST_NAME_MAX)  // should be in limits.h
+#  define HOST_NAME_MAX 256
+#endif
+/*****************************************************************************
+    psVLogMsg(): This routine sends the message, which is a printf style
+ string specified in the "..." argument, to the current message log
+ destination with the severity specified by the "level" argument.
+    Input:
+ name
+ level
+ fmt
+ ap
+    Output:
+ none
+    Return:
+ NULL.
+ *****************************************************************************/
+void psVLogMsg(const char *name,
+               int level,
+               const char *fmt,
+               va_list ap)
+{
+    static int first = 1;               // Flag for calling gethostname()
+    static char hostname[HOST_NAME_MAX + 1];
+    // Buffer for hostname.
+    char clevel=0;                      // letter-name for level
+    char head[HOST_NAME_MAX + 40];      // yes, this is long enough
+    char *head_ptr = head;              // where we've got to in head
+    time_t clock = time(NULL);          // The current time.
+    struct tm *utc = gmtime(&clock);    // The current gm time.
+
+    // If logging is off, or if the level is too high, return immediately.
+    if ((level > p_psGlobalLogLevel) || (p_psGlobalLogDest == PS_LOG_NONE)) {
+        return;
+    }
+
+    // If I have not been here yet, determine my hostname and save it.
+    if (first) {
+        first = 0;
+        gethostname(hostname, HOST_NAME_MAX);
+    }
+
+    switch (level) {
+    case PS_LOG_ABORT:
+        clevel = 'A';
+        break;
+
+    case PS_LOG_ERROR:
+        clevel = 'E';
+        break;
+
+    case PS_LOG_WARN:
+        clevel = 'W';
+        break;
+
+    case PS_LOG_INFO:
+        clevel = 'I';
+        break;
+
+    case 4:
+    case 5:
+    case 6:
+    case 7:
+    case 8:
+    case 9:
+        clevel = level + '0';
+        break;
+
+    default:
+        psTrace("utils.logMsg", 2, "Invalid logMsg level: %d (%s)\n",
+                level, fmt);
+        level = (level < 0) ? 0 : 9;
+        break;
+    }
+
+    // Create the various log fields...
+    if (p_psLogTime) {
+        sprintf(head_ptr, "%4d:%02d:%02d %02d:%02d:%02dZ",
+                utc->tm_year + 1900, utc->tm_mon + 1, utc->tm_mday,
+                utc->tm_hour, utc->tm_min, utc->tm_sec);
+        head_ptr += strlen(head_ptr);
+    }
+    // Hostname should be 20 characters.
+    if (p_psLogHost) {
+        if (head_ptr > head) {
+            *head_ptr++ = '|';
+        }
+        sprintf(head_ptr, "%-20s", hostname);
+        head_ptr += strlen(head_ptr);
+    }
+    if (p_psLogLevel) {
+        if (head_ptr > head) {
+            *head_ptr++ = '|';
+        }
+        sprintf(head_ptr, "%c", clevel);
+        head_ptr += strlen(head_ptr);
+    }
+    // The name field must be 15 characters.
+    if (p_psLogName) {
+        if (head_ptr > head) {
+            *head_ptr++ = '|';
+        }
+        sprintf(head_ptr, "%15.15s", name);
+        head_ptr += strlen(head_ptr);
+    }
+
+    if (head_ptr > head) {
+        *head_ptr++ = '|';
+    }
+    *head_ptr = '\0';
+
+    switch (p_psGlobalLogDest) {
+    case PS_LOG_TO_STDOUT:
+        puts(head);
+        if (p_psLogMsg) {
+            vprintf(fmt, ap);
+            if (fmt[strlen(fmt) - 1] != '\n') {
+                putc('\n', stdout);
+            }
+        } else {
+            putc('\n', stdout);
+        }
+        break;
+
+    case PS_LOG_TO_STDERR:
+        fputs(head, stderr);
+        if (p_psLogMsg) {
+            vfprintf(stderr, fmt, ap);
+            if (fmt[strlen(fmt) - 1] != '\n') {
+                putc('\n', stderr);
+            }
+        } else {
+            putc('\n', stderr);
+        }
+        break;
+
+    default:
+        fprintf(stderr, "psLogMsg: You cannot get here (%s:%d)\n",
+                __FILE__, __LINE__);
+        abort();
+    }
+}
+
+
+/*****************************************************************************
+    psLogMsg(): This routine sends the message, which is a printf style
+ string specified in the "..." argument, to the current message log
+ destination with the severity specified by the "level" argument.
+    Input:
+ name: Indicates the source of this log message.
+ level: The severity of this log message.
+ fmt: The printf-stype formatted string, followed by the arguments
+  to that string.
+ ... The arguments to the above printf-style string.
+    Output:
+ none
+    Return:
+ NULL
+ *****************************************************************************/
+void psLogMsg(const char *name,
+              int level,
+              const char *fmt,
+              ...)
+{
+    va_list ap;
+
+    va_start(ap, fmt);
+    psVLogMsg(name, level, fmt, ap);
+    va_end(ap);
+}
Index: /tags/rel1_1/psLib/src/sys/psLogMsg.h
===================================================================
--- /tags/rel1_1/psLib/src/sys/psLogMsg.h	(revision 1056)
+++ /tags/rel1_1/psLib/src/sys/psLogMsg.h	(revision 1056)
@@ -0,0 +1,86 @@
+/** @file  psLogMsg.h
+ *  @brief Procedures for logging messages.
+ *  \ingroup LogTrace
+ *
+ *  This file will hold the prototypes for defining procedure which set
+ *  message log levels, messahe log formats, message log destinations, and
+ *  for generating the messages themselves.
+ *  @ingroup LogTrace
+ *
+ *  @author Robert Lupton, Princeton University
+ *  @author George Gusciora, MHPCC
+ *
+ *  @version $Revision: 1.8 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-12 05:50:01 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+#if !defined(PS_LOG_MSG_H)
+#define PS_LOG_MSG_H
+#include <stdarg.h>
+
+/** @addtogroup LogTrace
+ *  @{
+ */
+
+/// This procedure sets the destination for future log messages.  Currently
+/// the destination is specified by an integer which can have the following
+/// pre-defined values: PS_LOG_NONE, PS_LOG_TO_STDOUT, and PS_LOG_TO_STDERR.
+/// In future versions, this procedure will take a character string as an
+/// argument which can specify more general log destinations.
+int psLogSetDestination(int dest     ///< Specifies where to send messages.
+                       );
+
+
+/// This procedure sets the message level for future log messages.  Subsequent
+/// log messages, with a log level of "mylevel", will only be logged if
+/// "mylevel" is less than the current log level set by this procedure.
+/// Ie. higher values set by this procedure will cause more log messages to
+/// be displayed.
+int psLogSetLevel(int level          ///< Specifies the system log level
+                 );
+
+
+/// This procedure sets the log format for future log messages.  The argument
+/// must be a character string consistsing of the letters H (host), L
+/// (level), M (message), N (name), and T (time).  The default is "THLNM".
+/// Deleting a letter from the string will cause the associated information
+/// to not be logged.
+void psLogSetFormat(const char *fmt ///< Specifies the system log format
+                   );
+
+
+/// This procedure logs a message to the destination set by a prior
+/// call to psLogSetDestination(), if myLevel is less than the level
+/// specified by a prior call to psLogSetLevel().  The message is specified
+/// with a printf-stype string an arguments.
+void psLogMsg(const char *name,     ///< name of the log source
+              int myLevel,          ///< severity level of this log message
+              const char *fmt, ...  ///< printf-style format command
+             );
+
+
+/// This procedure is functionally equivalent to psLogMsg(), except that
+/// it takes a va_list as the message parameter, not a printf-style string.
+void psVLogMsg(const char *name, ///< name of the log source
+               int myLevel,      ///< severity level of this log message
+               const char *fmt,  ///< printf-style format command
+               va_list ap        ///< varargs argument list
+              );
+
+///< Status codes for log messages
+enum {
+    PS_LOG_ABORT = 0,
+    PS_LOG_ERROR,
+    PS_LOG_WARN,
+    PS_LOG_INFO };
+
+///< Destinations for log messages
+enum {
+    PS_LOG_NONE,
+    PS_LOG_TO_STDERR,
+    PS_LOG_TO_STDOUT };
+
+/// @}
+
+#endif
Index: /tags/rel1_1/psLib/src/sys/psMemory.c
===================================================================
--- /tags/rel1_1/psLib/src/sys/psMemory.c	(revision 1056)
+++ /tags/rel1_1/psLib/src/sys/psMemory.c	(revision 1056)
@@ -0,0 +1,521 @@
+/** @file  psMemory.c
+ *
+ *  @brief Contains the definitions for the memory management system
+ *
+ *  psMemory.h has additional information and documentation of the routines found in this file.
+ *
+ *  @author Robert DeSonia, MHPCC
+ *  @author Robert Lupton, Princeton University
+ *
+ *  @version $Revision: 1.24 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-04 23:46:48 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#define PS_ALLOW_MALLOC                 // we're allowed to call malloc()
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "psMemory.h"
+#include "psError.h"
+#include "psAbort.h"
+#include "psLogMsg.h"
+
+#define P_PS_MEMMAGIC (void *)0xdeadbeef // Magic number in psMemBlock header
+
+static int checkMemBlock(const psMemBlock *m, const char* funcName);
+static psMemBlock *lastMemBlockAllocated = NULL;
+pthread_mutex_t   memBlockListMutex = PTHREAD_MUTEX_INITIALIZER;
+pthread_mutex_t   memIdMutex = PTHREAD_MUTEX_INITIALIZER;
+
+/**
+ * Unique ID for allocated blocks
+ */
+static psMemoryId memid = 0;
+
+/**
+ *  Default memExhausted callback.
+ */
+static void *memExhaustedCallbackDefault(size_t size)
+{
+    return NULL;
+}
+
+static psMemExhaustedCallback memExhaustedCallback = memExhaustedCallbackDefault;
+
+psMemExhaustedCallback psMemExhaustedCallbackSet(psMemExhaustedCallback func)
+{
+    psMemExhaustedCallback old = memExhaustedCallback;
+
+    if (func != NULL) {
+        memExhaustedCallback = func;
+    } else {
+        memExhaustedCallback = memExhaustedCallbackDefault;
+    }
+
+    return old;
+}
+
+static void memProblemCallbackDefault(const psMemBlock *ptr,
+                                      const char *file, int lineno)
+{
+    if (ptr->refCounter < 1) {
+        psError(__func__,
+                "Block %ld allocated at %s:%d freed more than once at %s:%d\n",
+                ptr->id, ptr->file, ptr->lineno, file, lineno);
+    }
+
+    if (lineno > 0) {
+        psAbort(__func__, "Detected a problem in the memory system at %s:%d", file, lineno);
+    }
+}
+static psMemProblemCallback memProblemCallback = memProblemCallbackDefault;
+
+psMemProblemCallback psMemProblemCallbackSet(psMemProblemCallback func)
+{
+    psMemProblemCallback old = memProblemCallback;
+
+    if (func != NULL) {
+        memProblemCallback = func;
+    } else {
+        memProblemCallback = memProblemCallbackDefault;
+    }
+
+    return old;
+}
+/*
+ * And now the I-want-to-be-informed callbacks
+ *
+ * Call the callbacks when these IDs are allocated/freed
+ */
+psMemoryId p_psMemAllocateID = 0;  // notify user this block is allocated
+psMemoryId p_psMemFreeID = 0;   // notify user this block is freed
+
+psMemoryId psMemAllocateCallbackSetID(psMemoryId id) // set p_psMemAllocateID to id
+{
+    psMemoryId old = p_psMemAllocateID;
+    p_psMemAllocateID = id;
+
+    return old;
+}
+
+psMemoryId psMemFreeCallbackSetID(psMemoryId id)  // set p_psMemFreeID to id
+{
+    psMemoryId old = p_psMemFreeID;
+    p_psMemFreeID = id;
+
+    return old;
+}
+
+/*
+ * Default callback for both allocate and free. Note that the
+ * value of p_psMemAllocateID/p_psMemFreeID is incremented
+ * by the return value (so returning 0 means that the callback
+ * isn't resignalled)
+ */
+static psMemoryId memAllocateCallbackDefault(const psMemBlock *ptr)
+{
+    static psMemoryId incr = 0;  // "p_psMemAllocateID += incr"
+
+    return incr;
+}
+
+static psMemoryId memFreeCallbackDefault(const psMemBlock *ptr)
+{
+    static psMemoryId incr = 0;  // "p_psMemFreeID += incr"
+
+    return incr;
+}
+
+/*
+ * The default callbacks, and the routines to change them
+ */
+static psMemAllocateCallback memAllocateCallback = memAllocateCallbackDefault;
+static psMemFreeCallback memFreeCallback = memFreeCallbackDefault;
+
+psMemAllocateCallback psMemAllocateCallbackSet(psMemAllocateCallback func)
+{
+    psMemFreeCallback old = memAllocateCallback;
+
+    if (func != NULL) {
+        memAllocateCallback =  func;
+    } else {
+        memAllocateCallback = memAllocateCallbackDefault;
+    }
+
+    return old;
+}
+
+psMemFreeCallback psMemFreeCallbackSet(psMemFreeCallback func)
+{
+    psMemFreeCallback old = memFreeCallback;
+
+    if (func != NULL) {
+        memFreeCallback = func;
+    } else {
+        memFreeCallback = memFreeCallbackDefault;
+    }
+
+    return old;
+}
+
+/*
+ * Return memory ID counter for next block to be allocated
+ */
+psMemoryId psMemGetId(void)
+{
+    psMemoryId id;
+    pthread_mutex_lock(&memIdMutex);
+    id = memid + 1;
+    pthread_mutex_unlock(&memIdMutex);
+
+    return id;
+}
+
+/*
+ * Routines to check the consistency of the allocated and/or free memory arena
+ *
+ * N.b. If the block wasn't allocated by psAlloc, it will appear corrupted
+ */
+#define ALIGNED(P) ((void *)((long)(P) & ~03) == (P))
+
+static int
+checkMemBlock(const psMemBlock *m,
+              const char* funcName)
+{
+    // n.b. since this is called by psMemCheckCorruption while the memblock list is mutex locked,
+    // we shouldn't call such things as p_psAlloc/p_psFree here.
+
+    if (m == NULL) {
+        psError(funcName,"Memory Corruption: NULL memory block found.");
+        return(1);
+    }
+
+    if (!ALIGNED(m)) {
+        psError(funcName, "psMemCheckCorruption: non-aligned memory block");
+        return(1);
+    }
+
+    if (m->startblock != P_PS_MEMMAGIC || m->endblock != P_PS_MEMMAGIC) {
+        psError(funcName, "psMemCheckCorruption: memory block %ld is corrupted (buffer underflow)",
+                m->id);
+        return(1);
+    }
+    if (*(void**)((int8_t*)(m+1)+m->userMemorySize) != P_PS_MEMMAGIC) {
+        psError(funcName, "psMemCheckCorruption: memory block %ld is corrupted (buffer overflow)",
+                m->id);
+        return(1);
+    }
+
+    return(0);
+}
+
+int psMemCheckCorruption(int abort_on_error)
+{
+    int nbad = 0;                       // number of bad blocks
+
+    // get exclusive access to the memBlock list to avoid it changing on us while we use it.
+    pthread_mutex_lock(&memBlockListMutex);
+
+    for (psMemBlock* iter=lastMemBlockAllocated; iter != NULL; iter=iter->nextBlock) {
+        if (checkMemBlock(iter, __func__)) {
+            nbad++;
+
+            memProblemCallback(iter, __func__, __LINE__);
+
+            if (abort_on_error) {
+                // release the lock on the memblock list
+                pthread_mutex_unlock(&memBlockListMutex);
+                psAbort(__func__, "Detected memory corruption");
+                return nbad;
+            }
+        }
+    }
+
+    // release the lock on the memblock list
+    pthread_mutex_unlock(&memBlockListMutex);
+    return nbad;
+}
+
+void *p_psAlloc(size_t size, const char *file, int lineno)
+{
+    psMemBlock *ptr = malloc(sizeof(psMemBlock) + size + sizeof(void*));
+
+    if (ptr == NULL) {
+        ptr = memExhaustedCallback(size);
+        if (ptr == NULL) {
+            psAbort(__func__, "Failed to allocate %u bytes at %s:%d",
+                    size, file, lineno);
+        }
+    }
+
+    // increment the memory id safely.
+    pthread_mutex_lock(&memBlockListMutex);
+    *(psMemoryId*)&ptr->id = ++memid;
+    pthread_mutex_unlock(&memBlockListMutex);
+
+    ptr->file = file;
+    *(unsigned int*)&ptr->lineno = lineno;
+    ptr->startblock = P_PS_MEMMAGIC;
+    ptr->endblock = P_PS_MEMMAGIC;
+    ptr->userMemorySize = size;
+    *(void**)((int8_t*)(ptr+1)+size) = P_PS_MEMMAGIC;
+    ptr->previousBlock = NULL;
+
+    pthread_mutex_init(&ptr->refCounterMutex, NULL);
+    ptr->refCounter = 1;                // one user so far
+
+    // need exclusive access of the memory block list now...
+    pthread_mutex_lock(&memBlockListMutex);
+
+    // insert the new block to the front of the memBlock linked-list
+    ptr->nextBlock = lastMemBlockAllocated;
+    if (ptr->nextBlock != NULL) {
+        ptr->nextBlock->previousBlock = ptr;
+    }
+    lastMemBlockAllocated = ptr;
+
+    pthread_mutex_unlock(&memBlockListMutex);
+
+    //  Did the user ask to be informed about this allocation?
+    if (ptr->id == p_psMemAllocateID) {
+        p_psMemAllocateID += memAllocateCallback(ptr);
+    }
+
+    // And return the user the memory that they allocated
+    return ptr + 1;   // user memory
+}
+
+void *p_psRealloc(void *vptr, size_t size, const char *file, int lineno)
+{
+    if (vptr == NULL) {
+        return p_psAlloc(size, file, lineno);
+    } else {
+        psMemBlock *ptr = ((psMemBlock *)vptr) - 1;
+        bool isBlockLast = false;
+
+        pthread_mutex_lock(&memBlockListMutex);
+
+        isBlockLast = (ptr == lastMemBlockAllocated);
+
+        ptr = (psMemBlock*)realloc(ptr, sizeof(psMemBlock) + size + sizeof(void*));
+
+        if (ptr == NULL) {
+            psAbort(__func__, "Failed to reallocate %ld bytes at %s:%d",
+                    size, file, lineno);
+        }
+
+        ptr->userMemorySize = size;
+        *(void**)((int8_t*)(ptr+1)+size) = P_PS_MEMMAGIC;
+
+        if (isBlockLast) {
+            lastMemBlockAllocated = ptr;
+        }
+
+        // the block location may have changed, so fix the linked list addresses.
+        if (ptr->nextBlock != NULL) {
+            ptr->nextBlock->previousBlock = ptr;
+        }
+        if (ptr->previousBlock != NULL) {
+            ptr->previousBlock->nextBlock = ptr;
+        }
+
+        pthread_mutex_unlock(&memBlockListMutex);
+
+        //  Did the user ask to be informed about this allocation?
+        if (ptr->id == p_psMemAllocateID) {
+            p_psMemAllocateID += memAllocateCallback(ptr);
+        }
+
+        return ptr + 1;   // usr memory
+    }
+}
+
+void p_psFree(void *vptr, const char *file, int lineno)
+{
+    if (vptr == NULL) {
+        return;
+    }
+
+    psMemBlock *ptr = ((psMemBlock *)vptr) - 1;
+
+    if (checkMemBlock(ptr, __func__) != 0) {
+        memProblemCallback(ptr, file, lineno); // we may not own this block; don't free it
+    }
+
+    psMemDecrRefCounter(vptr);          // this handles the free, if required.
+}
+
+/*
+ * Check for memory leaks. Not production quality code
+ */
+int psMemCheckLeaks(
+    psMemoryId id0,                     // don't list blocks with id < id0
+    psMemBlock ***arr,                  // pointer to array of pointers to leaked blocks, or NULL
+    FILE *fd)                           // print list of leaks to fd (or NULL)
+{
+    int nleak = 0;
+    int j = 0;
+    psMemBlock* topBlock = lastMemBlockAllocated;
+
+    pthread_mutex_lock(&memBlockListMutex);
+
+    for (psMemBlock* iter = topBlock; iter != NULL; iter=iter->nextBlock)
+    {
+        if ( (psMemGetRefCounter(iter+1) > 0) && (iter->id >= id0) ) {
+            nleak++;
+
+            if (fd != NULL) {
+                if (nleak == 1) {
+                    fprintf(fd, "   %20s:line ID\n", "file");
+                }
+
+                fprintf(fd, "   %20s:%-4d %ld\n", iter->file, iter->lineno, iter->id);
+            }
+        }
+    }
+
+    pthread_mutex_unlock(&memBlockListMutex);
+
+    if (nleak == 0 || arr == NULL)
+    {
+        return nleak;
+    }
+
+    *arr = p_psAlloc(nleak*sizeof(psMemBlock), __FILE__, __LINE__);
+    pthread_mutex_lock(&memBlockListMutex);
+
+    for (psMemBlock* iter = topBlock; iter != NULL; iter=iter->nextBlock)
+    {
+        if ( (psMemGetRefCounter(iter+1) > 0) && (iter->id >= id0) ) {
+            (*arr)[j++] = iter;
+            if (j == nleak) { // found them all
+                break;
+            }
+        }
+    }
+
+    pthread_mutex_unlock(&memBlockListMutex);
+
+    return nleak;
+}
+
+/*
+ * Reference counting APIs
+ */
+psReferenceCount psMemGetRefCounter(void *vptr) // return refCounter
+{
+    psMemBlock *ptr;
+    unsigned int refCount;
+
+    if (vptr == NULL)
+    {
+        return 0;
+    }
+
+    ptr = ((psMemBlock *)vptr) - 1;
+
+    if (checkMemBlock(ptr, __func__) != 0)
+    {
+        memProblemCallback(ptr, __func__, __LINE__);
+    }
+
+    pthread_mutex_lock(&ptr->refCounterMutex);
+    refCount = ptr->refCounter;
+    pthread_mutex_unlock(&ptr->refCounterMutex);
+
+    return refCount;
+}
+
+void *psMemIncrRefCounter(void *vptr) // increment and return refCounter
+{
+    psMemBlock *ptr;
+
+    if (vptr == NULL)
+    {
+        return vptr;
+    }
+
+    ptr = ((psMemBlock *)vptr) - 1;
+
+    if (checkMemBlock(ptr, __func__))
+    {
+        memProblemCallback(ptr, __func__, __LINE__);
+    }
+
+    pthread_mutex_lock(&ptr->refCounterMutex);
+    ptr->refCounter++;
+    pthread_mutex_unlock(&ptr->refCounterMutex);
+
+    return vptr;
+}
+
+void *psMemDecrRefCounter(void *vptr) // decrement and return refCounter
+{
+    if (vptr == NULL)
+    {
+        return NULL;
+    }
+
+    psMemBlock *ptr = ((psMemBlock *)vptr) - 1;
+
+
+    pthread_mutex_lock(&ptr->refCounterMutex);
+
+    if (ptr->refCounter > 1)
+    {
+        /// XXX - Probably should have another mutex here.
+        ptr->refCounter--;          // multiple references, just decrement the count.
+        pthread_mutex_unlock(&ptr->refCounterMutex);
+
+    } else
+    {
+        pthread_mutex_unlock(&ptr->refCounterMutex);
+
+        // Did the user ask to be informed about this deallocation?
+        if (ptr->id == p_psMemFreeID) {
+            p_psMemFreeID += memFreeCallback(ptr);
+        }
+
+        pthread_mutex_lock(&memBlockListMutex);
+
+        // cut the memBlock out of the memBlock list
+        if (ptr->nextBlock != NULL) {
+            ptr->nextBlock->previousBlock = ptr->previousBlock;
+        }
+        if (ptr->previousBlock != NULL) {
+            ptr->previousBlock->nextBlock = ptr->nextBlock;
+        }
+        if (lastMemBlockAllocated == ptr) {
+            lastMemBlockAllocated = ptr->nextBlock;
+        }
+
+        pthread_mutex_unlock(&memBlockListMutex);
+
+        pthread_mutex_destroy(&ptr->refCounterMutex);
+
+        free(ptr);
+
+        vptr = NULL;    // since we freed it, make sure we return NULL.
+    }
+
+    return vptr;
+}
+
+void p_psCustomFree(psFreeFcn fcn, void* ptr)
+{
+
+    if (fcn == NULL) {
+        return;
+    } else {
+        if (fcn == PS_FREE) {
+            psFree(ptr);
+        } else {
+            fcn(ptr);
+        }
+    }
+}
Index: /tags/rel1_1/psLib/src/sys/psMemory.h
===================================================================
--- /tags/rel1_1/psLib/src/sys/psMemory.h	(revision 1056)
+++ /tags/rel1_1/psLib/src/sys/psMemory.h	(revision 1056)
@@ -0,0 +1,309 @@
+#if !defined(PS_MEMORY_H)
+#define PS_MEMORY_H
+/** @file  psMemory.h
+ *
+ *  @brief Contains the definitions for the memory management system
+ *
+ *  This is the generic memory management system put inbetween the user's high level code and the OS-level
+ *  memory allocation routines.  This system adds such features as callback routines for memory error events,
+ *  tracing capabilities, and reference counting.
+ *
+ *  @author Robert DeSonia, MHPCC
+ *  @author Robert Lupton, Princeton University
+ *
+ *  @ingroup MemoryManagement
+ *
+ *  @version $Revision: 1.18 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-10 02:09:57 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include <stdio.h>                      // needed for FILE
+#include <pthread.h>                    // we need a mutex to make this stuff thread safe.
+
+/** @addtogroup MemoryManagement
+ *  @{
+ */
+
+/**
+ *  @addtogroup memCallback Memory Callbacks
+ *
+ *  Routines dealing with the creating and setting of memory management callback functions.
+ */
+
+/**
+ *  @addtogroup memTracing Memory Tracing
+ *
+ *  Routines dealing with memory tracing and corruption checking.
+ */
+
+/**
+ *  @addtogroup memRefCount Reference Count
+ *
+ *  Routines dealing with the reference counting of allocated buffers.
+ */
+
+/// typedef for memory identification numbers.  Guaranteed to be some variety of integer.
+typedef unsigned long psMemoryId;
+
+/// typedef for a memory block's reference count. Guaranteed to be some variety of integer.
+typedef unsigned long psReferenceCount;
+
+/** Book-keeping data for storage allocator.
+ *  N.b. sizeof(psMemBlock) must be chosen such that if ptr is a pointer
+ *  returned by malloc, then ((char *)ptr + sizeof(psMemBlock)) is properly
+ *  aligned for all storage types.
+ */
+typedef struct psMemBlock
+{
+    const void* startblock;             ///< initialised to p_psMEMMAGIC
+    struct psMemBlock* previousBlock;   ///< previous block in allocation list
+    struct psMemBlock* nextBlock;       ///< next block allocation list
+    size_t  userMemorySize;             ///< the size of the user-portion of the memory block
+    const psMemoryId id;                ///< a unique ID for this allocation
+    const char* file;                   ///< set from __FILE__ in e.g. p_psAlloc
+    const int lineno;                   ///< set from __LINE__ in e.g. p_psAlloc
+    pthread_mutex_t   refCounterMutex;  ///< mutex to ensure exclusive access to reference counter
+    psReferenceCount refCounter;        ///< how many times pointer is referenced
+    const void* endblock;               ///< initialised to p_psMEMMAGIC
+}
+psMemBlock;
+
+/** prototype of a basic callback used by memory functions
+ *
+ *  @see psMemAllocateCallbackSet
+ *  @ingroup memCallback
+ */
+typedef psMemoryId (*psMemAllocateCallback)(
+    const psMemBlock *ptr           ///< the psMemBlock just allocated
+);
+
+/** prototype of memory free callback used by memory functions
+ *
+ *  @see psMemFreeCallbackSet
+ *  @ingroup memCallback
+ */
+typedef psMemoryId (*psMemFreeCallback)(
+    const psMemBlock *ptr           ///< the psMemBlock being freed
+);
+
+/** prototype of a callback used in error conditions
+ *
+ *  This callback should not try to call psAlloc or psFree.
+ *
+ *  @see psMemProblemCallbackSet
+ *  @ingroup memCallback
+ */
+typedef void (*psMemProblemCallback)(
+    const psMemBlock *ptr,          ///< the pointer to the problematic memory block.
+    const char *file,               ///< the file in which the problem originated
+    int lineno                      ///< the line number in which the problem originated
+);
+
+/** prototype of a callback function used when memory runs out
+ *
+ *  @return void* pointer to requested buffer of the size size_t, or NULL if memory could not
+ *          be found.
+ *
+ *  @see psMemExhaustedCallbackSet
+ *  @ingroup memCallback
+ */
+typedef void *(*psMemExhaustedCallback)(
+    size_t size                     //< the size of buffer required
+);
+
+typedef void (*psFreeFcn)(void* ptr);
+
+/** Memory allocation.  This operates much like malloc(), but is guaranteed to return a non-NULL value.
+ *
+ *  @return void* pointer to the allocated buffer. This will not be NULL.
+ *  @see psFree
+ */
+#ifdef DOXYGEN
+void* psAlloc(
+    size_t size                     ///< Size required
+);
+#else
+void* p_psAlloc(
+    size_t size,                    ///< Size required
+    const char *file,               ///< File of call
+    int lineno                      ///< Line number of call
+);
+/// Memory allocation. psAlloc sends file and line number to p_psAlloc.
+#define psAlloc(size) p_psAlloc(size, __FILE__, __LINE__)
+#endif
+
+
+/** Memory re-allocation.  This operates much like realloc(), but is guaranteed to return a non-NULL value.
+ *
+ *  @return void* pointer to resized buffer. This will not be NULL.
+ *  @see psAlloc, psFree
+ */
+#ifdef DOXYGEN
+void* psRealloc(void *ptr               ///< Pointer to re-allocate
+                size_t size,            ///< Size required
+               );
+#else
+void* p_psRealloc(void *ptr,            ///< Pointer to re-allocate
+                  size_t size,          ///< Size required
+                  const char *file,     ///< File of call
+                  int lineno            ///< Line number of call
+                 );
+
+/// Memory re-allocation.  psRealloc sends file and line number to p_psRealloc.
+#define psRealloc(ptr, size) p_psRealloc(ptr, size, __FILE__, __LINE__)
+
+#endif
+
+
+/** Free memory.  This operates much like free().
+ *
+ *  @see psAlloc, psRealloc
+ */
+#ifdef DOXYGEN
+void psFree(void *ptr,                  ///< Pointer to free, if NULL, function returns immediately.
+           );
+#else
+void p_psFree(void *ptr,                ///< Pointer to free
+              const char *file,         ///< File of call
+              int lineno                ///< Line number of call
+             );
+
+/// Free memory.  psFree sends file and line number to p_psFree.
+#define psFree(size) p_psFree(size, __FILE__, __LINE__)
+
+#endif
+
+/** Check for memory leaks.  This scans for allocated memory buffers not freed with an ID not less than id0.
+ *  This is used to check for memory leaks by:
+ *      -# before a block of code to be checked, store the current ID count via psGetMemId
+ *      -# after the block of code to be checked, call this function using the ID stored above.  If all
+ *         memory in the block that was allocated has been freed, this call should output nothing and
+ *         return 0.
+ *
+ *  If memory leaks are found, the Memory Problem callback will be called as well.
+ *
+ *  return int  number of memory blocks found as 'leaks', i.e., the number of currently allocated memory
+ *              blocks above id0 that have not been freed.
+ *  @see psAlloc, psFree, psgetMemId, psMemProblemCallbackSet
+ *  @ingroup memTracing
+ */
+int psMemCheckLeaks(
+    psMemoryId id0,              ///< don't list blocks with id < id0
+    psMemBlock ***arr,              ///< pointer to array of pointers to leaked blocks, or NULL
+    FILE *fd                        ///< print list of leaks to fd (or NULL)
+);
+
+/** Check for memory corruption.  Scans all currently allocated memory buffers and checks for corruptions,
+ *  i.e., invalid markers that signify a buffer under/overflow.
+ *
+ *  @ingroup memTracing
+ */
+int psMemCheckCorruption(
+    int abort_on_error              ///< Abort on detecting corruption?
+);
+
+/** Return reference counter
+ *
+ *  @ingroup memRefCount
+ */
+psReferenceCount psMemGetRefCounter(
+    void *vptr                      ///< Pointer to get refCounter for
+);
+
+/** Increment reference counter and return the pointer
+ *
+ *  @ingroup memRefCount
+ */
+void *psMemIncrRefCounter(
+    void *vptr                      ///< Pointer to increment refCounter, and return
+);
+
+/** Decrement reference counter and return the pointer
+ *
+ *  @ingroup memRefCount
+ */
+void *psMemDecrRefCounter(
+    void *vptr                      ///< Pointer to decrement refCounter, and return
+);
+
+/** Set callback for problems
+ *  @ingroup memCallback
+ */
+psMemProblemCallback psMemProblemCallbackSet(
+    psMemProblemCallback func       ///< Function to run
+);
+
+/** Set callback for out-of-memory
+ *
+ *  @ingroup memCallback
+ */
+psMemExhaustedCallback psMemExhaustedCallbackSet(
+    psMemExhaustedCallback func     ///< Function to run
+);
+
+/** Set call back for when a particular memory block is allocated
+ *
+ *  @ingroup memCallback
+ */
+psMemAllocateCallback psMemAllocateCallbackSet(
+    psMemAllocateCallback func          ///< Function to run
+);
+
+/** Set call back for when a particular memory block is freed
+ *
+ *  @ingroup memCallback
+ */
+psMemFreeCallback psMemFreeCallbackSet(
+    psMemFreeCallback func              ///< Function to run
+);
+
+/** get next memory ID
+ *
+ *  @ingroup memCallback
+ */
+psMemoryId psMemGetId(void);
+
+/** set p_psMemAllocateID to id
+ *
+ *  @ingroup memCallback
+ */
+psMemoryId psMemAllocateCallbackSetID(
+    psMemoryId id                       ///< ID to set
+);
+
+/** set p_psMemFreeID to id
+ *
+ *  @ingroup memCallback
+ */
+psMemoryId psMemFreeCallbackSetID(
+    psMemoryId id                       ///< ID to set
+);
+
+#define PS_FREE     (void*)1
+
+//@} End of Memory Management Functions
+
+
+#ifndef DOXYGEN
+
+void p_psCustomFree(psFreeFcn fcn,void* ptr);
+
+/*
+ * Ensure that any program using malloc/realloc/free will fail to compile
+ */
+#ifndef PS_ALLOW_MALLOC
+#ifdef __GNUC__
+#pragma GCC poison malloc realloc calloc free
+#else
+#define malloc(S)       _Pragma("error Use of malloc is not allowed.  Use psAlloc instead.")
+#define realloc(P,S)    _Pragma("error Use of realloc is not allowed.  Use psRealloc instead.")
+#define calloc(S)       _Pragma("error Use of calloc is not allowed.  Use psAlloc instead.")
+#define free(P)         _Pragma("error Use of free is not allowed.  Use psFree instead.")
+#endif
+#endif
+
+#endif // doxygen skip
+
+#endif // end of header file
Index: /tags/rel1_1/psLib/src/sys/psString.c
===================================================================
--- /tags/rel1_1/psLib/src/sys/psString.c	(revision 1056)
+++ /tags/rel1_1/psLib/src/sys/psString.c	(revision 1056)
@@ -0,0 +1,97 @@
+/** @file  psString.c
+ *
+ *  @brief Contains the definition of string utility functions
+ *
+ *  String utility functions defined shall provide basic string copying
+ *  capabilities while using the preferred memory management utilities.
+ *
+ *  @author Eric Van Alst, MHPCC
+ *   
+ *  @version $Revision: 1.5 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-05-10 23:37:36 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+/******************************************************************************/
+/*  INCLUDE FILES                                                             */
+/******************************************************************************/
+#include <stdlib.h>
+#include <string.h>
+#include "psString.h"
+#include "psMemory.h"
+#include "psError.h"
+
+/******************************************************************************/
+/*  DEFINE STATEMENTS                                                         */
+/******************************************************************************/
+
+// None
+
+/******************************************************************************/
+/*  TYPE DEFINITIONS                                                          */
+/******************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  GLOBAL VARIABLES                                                         */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  FILE STATIC VARIABLES                                                    */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  FUNCTION IMPLEMENTATION - LOCAL                                          */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/* FUNCTION IMPLEMENTATION - PUBLIC                                          */
+/*****************************************************************************/
+
+char *psStringCopy(
+    const char*  str
+)
+{
+    // Allocate memory using psAlloc function
+    // Copy input string to memory just allocated
+    // Return the copy
+    return strcpy(psAlloc(strlen(str) + 1), str);
+}
+
+char *psStringNCopy(
+    const char*  str,
+    int          nChar
+)
+{
+    char *returnValue = NULL;
+
+    // Check the number of characters to copy is non-negative
+    if ( nChar < 0 ) {
+        // Log error message and return NULL
+        psError(__FILE__,"psStringNCopy with negative count specified %d",
+                nChar);
+        return NULL;
+    }
+    // Allocate memory using psAlloc function - nChar bytes
+    // Copy input string to memory allocated up to nChar characters
+    // Return the copy
+    returnValue = strncpy(psAlloc((size_t)nChar + 1), str, (size_t)nChar);
+
+    // Ensure the last byte is NULL character
+    if ( nChar > 0 ) {
+        returnValue[nChar-1] = '\0';
+    }
+
+    // Return the string pointer
+    return returnValue;
+}
+
+
Index: /tags/rel1_1/psLib/src/sys/psString.h
===================================================================
--- /tags/rel1_1/psLib/src/sys/psString.h	(revision 1056)
+++ /tags/rel1_1/psLib/src/sys/psString.h	(revision 1056)
@@ -0,0 +1,78 @@
+/** @file  psString.h
+ *
+ *  @brief Contains the declarations of string utility functions
+ *
+ *  @ingroup SysUtils
+ *
+ *  String utility functions defined shall provide basic string copying
+ *  capabilities.
+ *
+ *  @author Eric Van Alst, MHPCC
+ *
+ *  @version $Revision: 1.5 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-10 01:58:06 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PS_STRING_H
+#define PS_STRING_H
+
+/******************************************************************************/
+/*  DEFINE STATEMENTS                                                         */
+/******************************************************************************/
+
+/** This macro will convert the arguement to a quoted string */
+#define PS_STRING(S)  #S
+
+/******************************************************************************/
+/*  TYPE DEFINITIONS                                                          */
+/******************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/* FUNCTION PROTOTYPES                                                       */
+/*****************************************************************************/
+
+// Doxygen group tags
+/** @addtogroup SysUtils
+ *  @{
+ */
+
+/** Copies the input string
+ *
+ *  This function shall allocate memory to the length of the input string
+ *  plus one and copy the input string to the newly allocated memory.
+ *
+ *  @return  char* Copy of input string
+ *
+ */
+char *psStringCopy(
+    const char *str      /**< Input string of characters to copy */
+);
+
+
+/** Copies the input string up to the specified number of characters
+ *
+ *  This function shall allocate memory to the length specified by nChar
+ *  plus one and copy the input string to the newly allocated memory.
+ *  This function will only copy nChar bytes from the input to new string,
+ *  so if the input string is larger than nChar characters the copied
+ *  string will be a substring of the input string.  If the input string
+ *  is smaller than nChar bytes then the remaining bytes allocated will
+ *  be set to NULL.
+ *
+ *  @return  char* Copy of input string
+ *
+ */
+/*@null@*/
+char *psStringNCopy(
+    const char *str,    /**< Input string of characters to copy */
+    int        nChar    /**< Number of bytes to allocate for string copy */
+);
+
+/* @} */  // Doxygen - End of SystemGroup Functions
+
+#endif
+
Index: /tags/rel1_1/psLib/src/sys/psTrace.c
===================================================================
--- /tags/rel1_1/psLib/src/sys/psTrace.c	(revision 1056)
+++ /tags/rel1_1/psLib/src/sys/psTrace.c	(revision 1056)
@@ -0,0 +1,415 @@
+/** @file psTrace.c
+ *  \brief basic run-time trace facilities
+ *  \ingroup LogTrace
+ *
+ *  This file will hold the code for procedures to insert
+ *  trace messages into the code.
+ *
+ *  @author Robert Lupton, Princeton University
+ *  @author George Gusciora, MHPCC
+ *
+ *  @version $Revision: 1.9 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-12 05:50:01 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+/*****************************************************************************
+    NOTES:
+ In the SRD, higher trace levels correspond to a numerically lower trace
+ value in the code.  This is a bit confusing.  For example, a high-level
+ message might be something like "Begin Processing".  The module programmer
+ might give that a numerically low trace level, such as 1, so then any
+ non-zero trace level in that code component will display thatmessage.
+ 
+ We build a tree of trace components.  Every node in the tree has a
+ depth, which is it's distance from the root.  However, this is not
+ not the same thing as a node's "level", which corresponds to the
+ trace level of that node.
+ 
+ I added a function psTraceFree() which frees all nodes in the trace component
+ tree.  Previously, there had been no function in the API which accomplished
+ this purpose.
+ *****************************************************************************/
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include "psMemory.h"
+#include "psTrace.h"
+#include "psString.h"
+#include "psError.h"
+
+static Component *p_psCroot = NULL;       // The root of the trace component
+static FILE *p_psTraceFP = NULL;          // File destination for messages.
+/*****************************************************************************
+componentAlloc(): allocate memory for a new node, and initialize members.
+ *****************************************************************************/
+Component *componentAlloc(const char *name,
+                          int level)
+{
+    Component *comp = psAlloc(sizeof(Component));
+    comp->name = psStringCopy(name);
+    comp->level = level;
+    comp->n = 0;
+    comp->subcomp = NULL;
+    return comp;
+}
+
+
+/*****************************************************************************
+componentFree(): free the current node in the root tree, and all children
+nodes as well.
+ *****************************************************************************/
+static void componentFree(Component *comp)
+{
+    if (comp == NULL) {
+        return;
+    }
+
+    if (comp->subcomp != NULL) {
+        for (int i = 0; i < comp->n; i++) {
+            componentFree(comp->subcomp[i]);
+        }
+        psFree(comp->subcomp);
+    }
+
+    psFree((char *)comp->name);
+    psFree(comp);
+}
+
+
+/*****************************************************************************
+initTrace(): simply initialize the component root tree.
+*****************************************************************************/
+static void initTrace(void)
+{
+    if (p_psCroot == NULL) {
+        p_psCroot = componentAlloc(".", DEFAULT_TRACE_LEVEL);
+    }
+}
+
+
+/*****************************************************************************
+Set all trace levels to zero.
+ *****************************************************************************/
+void p_psTraceReset(Component *currentNode)
+{
+    int i = 0;
+
+    if (NULL == currentNode) {
+        return;
+    }
+
+    currentNode->level = 0;
+    for (i=0;i<currentNode->n;i++) {
+        if (NULL == currentNode->subcomp[i]) {
+            psError(__func__,
+                    "Sub-component %d of node %s in the trace tree is NULL.\n",
+                    i, currentNode->name);
+        } else {
+            p_psTraceReset(currentNode->subcomp[i]);
+        }
+    }
+    return;
+}
+
+/*****************************************************************************
+Set all trace levels to zero.
+ *****************************************************************************/
+void psTraceReset()
+{
+    p_psTraceReset(p_psCroot);
+}
+
+
+/*****************************************************************************
+Free all nodes in the component tree.
+ *****************************************************************************/
+void psTraceFree()
+{
+    componentFree(p_psCroot);
+}
+
+
+/*****************************************************************************
+componentAdd(): Adds the component named "addNodeName" to the root tree.
+ 
+NOTE: replace the call to strsep() with a call to strtok(), which conforms
+to ANSI-C.
+ *****************************************************************************/
+static void componentAdd(const char *addNodeName,
+                         int         level)
+{
+    int        i = 0;                         // Loop index variable.
+    char       name[strlen(addNodeName) + 1]; // buffer for writeable copy.
+    char      *pname=name;
+    char      *firstComponent = NULL;       // first component of name
+    Component *currentNode = p_psCroot;
+    int        nodeExists = 0;
+
+    // Is this the root node?  If so, simply set level and return.
+    if (strcmp(".", addNodeName) == 0) {
+        p_psCroot->level = level;
+        return;
+    }
+
+    if (addNodeName[0] != '.') {
+        printf("ERROR: failed to add %s to the root component tree.\n",
+               addNodeName);
+        exit(1);
+    }
+
+    strcpy(name, addNodeName);
+    pname = &name[1];
+    // Iterate through the components of addNodeName.  Strip off the first
+    // component of the name, find that in the root tree, or add it if it
+    // does not exist, then move to the next component in the name.
+
+    while (pname != NULL) {
+        firstComponent = strsep(&pname, ".");
+        nodeExists = 0;
+        for (i = 0; i < currentNode->n; i++) {
+            if (strcmp(currentNode->subcomp[i]->name, firstComponent) == 0) {
+                currentNode = currentNode->subcomp[i];
+                nodeExists = 1;
+                if (pname == NULL) {
+                    currentNode->level = level;
+                }
+            }
+        }
+
+        if (nodeExists == 0) {
+            currentNode->subcomp = psRealloc(currentNode->subcomp,
+                                             (currentNode->n + 1) * sizeof(Component *));
+            currentNode->n = (currentNode->n)+1;
+
+            currentNode->subcomp[(currentNode->n)-1] =
+                componentAlloc(firstComponent, level);
+        }
+    }
+}
+
+
+/*****************************************************************************
+    psSetTraceLevel(): add the component named "comp" to the component tree,
+ if it is not already there, and set it's trace level to "level".
+    Input:
+ comp
+ level
+    Output:
+ none
+    Returns:
+ zero
+*****************************************************************************/
+int psTraceSetLevel(const char *comp,   // component of interest
+                    int level)          // desired trace level
+{
+    // If the root component tree does not exist, then initialize it.
+    if (p_psCroot == NULL) {
+        initTrace();
+    }
+
+    // Add the new component to the component tree.
+    componentAdd(comp, level);
+
+    // return 0 on success.
+    return 0;
+}
+
+
+/*****************************************************************************
+    doGetTraceLevel()
+ This function recursively searches the root component tree for the
+ component named "name", which is supplied by a parameter.  If it
+ finds that component, it returns the level of that component.
+ Otherwise, it returns ???.
+ 
+    Inputs:
+ name:
+    Outputs:
+ none
+    Returns:
+ The trace level of the "name" component.
+ *****************************************************************************/
+static int doGetTraceLevel(const char *aname)
+{
+    char       name[strlen(aname) + 1]; // need a writeable copy: for strsep()
+    char      *pname=name;
+    char      *firstComponent = NULL;   // first component of name
+    Component *currentNode = p_psCroot;
+    int        i = 0;
+
+    if (NULL == currentNode) {
+        return(UNKNOWN_TRACE_LEVEL);
+    }
+
+    if (strcmp(".", aname) == 0) {
+        return(p_psCroot->level);
+    }
+
+    if (aname[0] != '.') {
+        return(UNKNOWN_TRACE_LEVEL);
+    }
+
+    strcpy(name, aname);
+    pname = &name[1];
+    while (pname != NULL) {
+        firstComponent = strsep(&pname, ".");
+        for (i = 0; i < currentNode->n; i++) {
+            if (NULL == currentNode->subcomp[i]) {
+                psError(__func__,
+                        "Sub-component %d of node %s in trace tree is NULL.\n",
+                        i, currentNode->name);
+            }
+
+            if (strcmp(currentNode->subcomp[i]->name, firstComponent) == 0) {
+                currentNode = currentNode->subcomp[i];
+                if (pname == NULL) {
+                    return(currentNode->level);
+                }
+            }
+        }
+    }
+    return(UNKNOWN_TRACE_LEVEL);
+}
+
+
+/*****************************************************************************
+    psGetTraceLevel()
+ Return a trace level of "name" in the root component tree.  If the
+ exact string of components in "name" does not exist in the root
+ tree, we return the deepest level of the match.
+    Input:
+ name
+    Output:
+ none
+    Return:
+ The level of "name" in the root component tree.
+ *****************************************************************************/
+int psTraceGetLevel(const char *name)
+{
+    if (p_psCroot == NULL) {
+        return(UNKNOWN_TRACE_LEVEL);
+    }
+
+    // Search the component root tree, determine the trace level.
+    return(doGetTraceLevel(name));
+}
+
+
+/*****************************************************************************
+    doPrintTraceLevels()
+ This function recursively searches the component tree supplied by the
+ parameter "comp" and prints the name and level of each component.
+    Inputs:
+ comp: a node in the component tree.
+ level: the level of that node
+    Outputs:
+ none
+    Returns:
+ null
+ *****************************************************************************/
+static void doPrintTraceLevels(const Component *comp,
+                               int depth)
+{
+    int i = 0;
+
+    if (comp->name[0] == '\0') {
+        printf("%*s%-*s %d\n", depth, "", 20 - depth,
+               "(root)", (comp->level == UNKNOWN_TRACE_LEVEL) ? 0 : comp->level);
+    } else {
+        if (comp->level == UNKNOWN_TRACE_LEVEL) {
+            printf("%*s%-*s %s\n", depth, "", 20 - depth,
+                   comp->name, ".");
+        } else {
+            printf("%*s%-*s %d\n", depth, "", 20 - depth,
+                   comp->name, comp->level);
+        }
+    }
+
+    for (i = 0; i < comp->n; i++) {
+        doPrintTraceLevels(comp->subcomp[i], depth+1);
+    }
+}
+
+
+/*****************************************************************************
+psPrintTraceLevels(): Simply print all the trace levels in the trace level
+component tree.
+Inputs:
+ none
+Outputs:
+ none
+Returns:
+ null
+*****************************************************************************/
+void psTracePrintLevels(void)
+{
+    if (p_psCroot == NULL) {
+        return;
+    }
+
+    doPrintTraceLevels(p_psCroot, 0);
+}
+
+
+/*****************************************************************************
+p_psTrace(): we display the trace message to standard output if the trace
+level of that message, supplied by the parameter "level" is higher than the
+trace level that is currently associated with the component named by the
+parameter "comp".
+Input:
+ comp
+ level
+ ...  a printf-style output string.
+Output:
+ none
+Return:
+ null
+ *****************************************************************************/
+void p_psTrace(const char *comp,        // component being traced
+               int level,               // desired trace level
+               ...)                     // arguments
+{
+    char *fmt = NULL;
+    va_list ap;
+    int i = 0;
+
+    if (NULL == comp) {
+        psError(__func__,
+                "p_psTrace() called on a NULL trace level tree\n");
+    }
+
+    // Only display this message if it's trace level is less than the level
+    // of it's associatedcomponent.
+    if (level <= psTraceGetLevel(comp)) {
+        va_start(ap, level);
+
+        // The following functions get the variable list of parameters with
+        // which this function was called, and print them to the standard
+        // output.
+        fmt = va_arg(ap, char *);
+
+        if (p_psTraceFP != NULL) {
+            // We indent each message one space for each level of the message.
+            for (i = 0; i < level; i++) {
+                fprintf(p_psTraceFP, " ");
+            }
+            vfprintf(p_psTraceFP, fmt, ap);
+        } else {
+            // We indent each message one space for each level of the message.
+            for (i = 0; i < level; i++) {
+                putchar(' ');
+            }
+            vprintf(fmt, ap);
+        }
+        va_end(ap);
+    }
+
+    // NOTE: should we free *fmt as well?  Read the man page.
+}
+
+void psTraceSetDestination(FILE *fp)
+{
+    p_psTraceFP = fp;
+}
Index: /tags/rel1_1/psLib/src/sys/psTrace.h
===================================================================
--- /tags/rel1_1/psLib/src/sys/psTrace.h	(revision 1056)
+++ /tags/rel1_1/psLib/src/sys/psTrace.h	(revision 1056)
@@ -0,0 +1,85 @@
+/** @file psTrace.h
+ *  \brief basic run-time trace facilities
+ *  \ingroup LogTrace
+ *
+ *  This file will hold the prototypes for defining procedures to insert
+ *  trace messages into the code.
+ *
+ *  @author Robert Lupton, Princeton University
+ *  @author George Gusciora, MHPCC
+ *
+ *  @version $Revision: 1.8 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-12 05:50:01 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+#if !defined(PS_TRACE_H)
+#define PS_TRACE_H 1
+#define UNKNOWN_TRACE_LEVEL -9999         // we don't know this name's level
+#define DEFAULT_TRACE_LEVEL 0
+
+/** Basic structure for the component tree.  A component is a string of the
+    form aaa.bbb.ccc, and may itself contain further subcomponents.  The
+    Component structure doesn't in fact contain it's full name, but only the
+    last part. */
+typedef struct Component
+{
+    const char *name;                     // last part of name of component
+    int level;                            // trace level for this component
+    int n;                                // number of subcomponents
+    struct Component **subcomp;           // next level of subcomponents
+}
+Component;
+
+/** \addtogroup LogTrace
+ *  \{
+ */
+
+/** Functions **************************************************************/
+
+#ifndef DOXYGEN
+/// Send a trace message
+void p_psTrace(const char *facil,  ///< facilty of interest
+               int myLevel,  ///< desired trace level
+               ...)   ///< trace message arguments
+;
+#endif
+
+/// Set trace level
+int psTraceSetLevel(const char *facil, ///< facilty of interest
+                    int level)  ///< desired trace level
+;
+
+/// Get the trace level
+int psTraceGetLevel(const char *facil) ///< facilty of interest
+;
+
+/// Set all trace levels to zero (do not free nodes in the component tree).
+void psTraceReset()
+;
+
+/// Free all nodes in the component tree.
+void psTraceFree()
+;
+
+/// print trace levels
+void psTracePrintLevels(void)
+;
+
+/// Set the destination of future trace messages.
+void psTraceSetDestination(FILE *fp);
+
+
+/* \} */ // End of SystemGroup Functions
+
+//#define PS_NO_TRACE 1   ///< to turn off all tracing
+
+#if defined(PS_NO_TRACE)
+#  define psTrace(facil, level, ...) /* do nothing */
+#else
+#  define psTrace(facil, level, ...) \
+p_psTrace(facil, level, __VA_ARGS__)
+#endif
+
+#endif
+
Index: /tags/rel1_1/psLib/src/sys/psType.h
===================================================================
--- /tags/rel1_1/psLib/src/sys/psType.h	(revision 1056)
+++ /tags/rel1_1/psLib/src/sys/psType.h	(revision 1056)
@@ -0,0 +1,123 @@
+/** @file  psType.h
+ *
+ *  @brief Contains support for basic types
+ *
+ *  This file defines common datatypes used throughout psLib.
+ *
+ *  @ingroup DataContainer
+ *
+ *  @author Robert DeSonia, MHPCC
+ *  @author Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.11 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-10 01:58:06 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PS_TYPE_H
+#define PS_TYPE_H
+
+#include <complex.h>
+#include <stdint.h>
+
+/// @addtogroup DataContainer
+/// @{
+
+/******************************************************************************/
+/*  TYPE DEFINITIONS                                                          */
+/******************************************************************************/
+
+/** Basic data types used by the containers.
+ *
+ * The basic types of the primitives used by psLib are defined within this enum. This enum is in turn used by
+ * the psType struct.
+ *
+ */
+
+typedef uint8_t         psU8;           ///< 8-bit unsigned int
+typedef uint16_t        psU16;          ///< 16-bit unsigned int
+typedef uint32_t        psU32;          ///< 32-bit unsigned int
+typedef uint64_t        psU64;          ///< 64-bit unsigned int
+typedef int8_t          psS8;           ///< 8-bit signed int
+typedef int16_t         psS16;          ///< 16-bit signed int
+typedef int32_t         psS32;          ///< 32-bit signed int
+typedef int64_t         psS64;          ///< 64-bit signed int
+typedef float           psF32;          ///< 32-bit floating point
+typedef double          psF64;          ///< 64-bit floating point
+typedef complex float   psC32;          ///< complex with 32-bit floating point Real and Imagary numbers
+typedef complex double  psC64;          ///< complex with 64-bit floating point Real and Imagary numbers
+typedef void*           psPTR;           ///< void pointer
+
+
+typedef enum {
+    PS_TYPE_S8               = 0x0101,  ///< Character.
+    PS_TYPE_S16              = 0x0102,  ///< Short integer.
+    PS_TYPE_S32              = 0x0104,  ///< Integer.
+    PS_TYPE_S64              = 0x0108,  ///< Long integer.
+    PS_TYPE_U8               = 0x0301,  ///< Unsigned character.
+    PS_TYPE_U16              = 0x0302,  ///< Unsigned short integer.
+    PS_TYPE_U32              = 0x0304,  ///< Unsigned integer.
+    PS_TYPE_U64              = 0x0308,  ///< Unsigned long integer.
+    PS_TYPE_F32              = 0x0404,  ///< Single-precision Floating point.
+    PS_TYPE_F64              = 0x0408,  ///< Double-precision floating point.
+    PS_TYPE_C32              = 0x0808,  ///< Complex numbers consisting of single-precision floating point.
+    PS_TYPE_C64              = 0x0810,  ///< Complex numbers consisting of double-precision floating point.
+    PS_TYPE_PTR              = 0x0000   ///< Something else that's not supported for arithmetic.
+} psElemType;
+
+#define PS_TYPE_MASK PS_TYPE_U8         ///< the psElemType to use for mask image
+typedef psU8 psMaskType;                ///< the C datatype for a mask image
+
+/// Macro to get the bad pixel reason code (stored as part of mask value)
+#define PS_BADPIXEL_BITMASK 0x0f
+#define PS_GET_BADPIXEL(maskValue) (maskValue & PS_BADPIXEL_BITMASK)
+
+#define PS_IS_BADPIXEL(maskValue) (PS_GET_BADPIXEL(maskValue) != 0)
+
+/// Macro to apply a bad pixel reason code to mask image
+#define PS_SET_BADPIXEL(maskValue, reasonCode) \
+{ \
+    maskValue = (psMaskType)((reasonCode & PS_BADPIXEL_BITMASK) | (maskValue & ~PS_BADPIXEL_BITMASK)); \
+}
+
+/// Macro to determine if the psElemType is an integer.
+#define PS_IS_PSELEMTYPE_INT(x) ((x & 0x100) == 0x100)
+/// Macro to determine if the psElemType is unsigned.
+#define PS_IS_PSELEMTYPE_UNSIGNED(x) ((x & 0x200) == 0x200)
+/// Macro to determine if the psElemType is a real (non-complex) floating-point type.
+#define PS_IS_PSELEMTYPE_REAL(x) ((x & 0x400) == 0x400)
+/// Macro to determine if the psElemType is complex number type.
+#define PS_IS_PSELEMTYPE_COMPLEX(x) ((x & 0x800) == 0x800)
+/// Macro to determine the storage size, in bytes, of the psElemType.
+#define PSELEMTYPE_SIZEOF(x) ( (x==PS_TYPE_PTR) ? sizeof(void*) :(x & 0xFF) )
+
+/** Dimensions of a data type.
+ *
+ * The dimensions of containers used by psLib are defined within this enum. This enum is used by the psType
+struct. *
+ */
+typedef enum {
+    PS_DIMEN_SCALAR,    ///< Scalar.
+    PS_DIMEN_VECTOR,    ///< Vector.
+    PS_DIMEN_TRANSV,    ///< Transposed vector.
+    PS_DIMEN_IMAGE,     ///< Image.
+    PS_DIMEN_OTHER      ///< Something else that's not supported for arithmetic.
+} psDimen;
+
+/** The type of a data type.
+ *
+ * All psLib complex types consist of primitive components. This struct provides the description of those
+ * primitives.
+ *
+ */
+typedef struct
+{
+    psElemType type;    ///< Primitive type.
+    psDimen dimen;      ///< Dimensionality.
+}
+psType;
+
+/// @}
+
+#endif
Index: /tags/rel1_1/psLib/src/sysUtils/.cvsignore
===================================================================
--- /tags/rel1_1/psLib/src/sysUtils/.cvsignore	(revision 1056)
+++ /tags/rel1_1/psLib/src/sysUtils/.cvsignore	(revision 1056)
@@ -0,0 +1,1 @@
+*.i
Index: /tags/rel1_1/psLib/src/sysUtils/Makefile
===================================================================
--- /tags/rel1_1/psLib/src/sysUtils/Makefile	(revision 1056)
+++ /tags/rel1_1/psLib/src/sysUtils/Makefile	(revision 1056)
@@ -0,0 +1,75 @@
+###############################################################################
+##
+##  Makefile:   sysUtils
+##
+##  $Revision: 1.16 $  $Name: not supported by cvs2svn $
+##  $Date: 2004-06-10 20:40:26 $
+##
+##  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+###############################################################################
+
+# Define variable prefix to the top level project - psLib
+# This is necessary for definition is Makefile.Globals uses prefix
+
+ifndef prefix
+    export prefix=$(shell cd ../..;pwd)
+endif
+
+# Define the two targets to be built
+
+TARGET_STATIC  = libpslib.a
+
+# Include the make global definitions for the project
+
+include ../Makefile.Globals
+
+# Set CFLAGS used by the implicit rule to compile .c
+
+CFLAGS := $(CFLAGS_RELOC) -I../collections -I../dataManip -I../sysUtils -I../include
+
+# Define the source objects
+ 
+SRC_OBJS = psMemory.o    \
+           psError.o     \
+           psTrace.o     \
+           psLogMsg.o    \
+           psHash.o      \
+           psAbort.o     \
+           psString.o    
+
+# Define PHONY target "all" which will make all the necessary items
+
+all: $(TARGET_STATIC)
+
+# Rule to make static library
+
+libpslib.a: $(SRC_OBJS)
+# The ar option -r is to add/replace object and -s is to create
+# a symbol table in the archive
+	$(AR) rcs ../$@ $(SRC_OBJS)
+
+# Define PHONY target "install" which will install necessary files
+
+install: $(TARGET_STATIC) 
+	install *.h $(includedir)
+
+# Define PHONY target "distclean" which will cleanup the distribution
+
+distclean:	clean
+	$(RM) ../$(TARGET_STATIC)
+
+# Define PHONY target "clean" which will cleanup the development area
+
+clean:
+	@echo "    Deleting intermediate files for 'sysUtils'"
+	$(RM) $(SRC_OBJS) *.lint
+
+%.lint: %.c
+	splint +posixlib -exportlocal -realcompare $(INCLUDE_GLOBAL) $? > $@; cat $@
+
+%.d: %.c
+	$(CC) -MM $(CFLAGS) $< > $@.tmp
+	sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' $@.tmp > $@
+	$(RM) -f $@.tmp
+
+include $(SRC_OBJS:.o=.d)
Index: /tags/rel1_1/psLib/src/sysUtils/README
===================================================================
--- /tags/rel1_1/psLib/src/sysUtils/README	(revision 1056)
+++ /tags/rel1_1/psLib/src/sysUtils/README	(revision 1056)
@@ -0,0 +1,2 @@
+This directory includes code related to the 'system utilities' section of the
+IfA supplied SDR.
Index: /tags/rel1_1/psLib/src/sysUtils/psAbort.c
===================================================================
--- /tags/rel1_1/psLib/src/sysUtils/psAbort.c	(revision 1056)
+++ /tags/rel1_1/psLib/src/sysUtils/psAbort.c	(revision 1056)
@@ -0,0 +1,75 @@
+/** @file  psAbort.c
+ *
+ *  @brief Contains the definition for abort function
+ *
+ *  The abort logging and handling shall be performed by psAbort function.
+ *  This will allow for consistent handling of other software units
+ *  needing to abort from program execution.
+ *
+ *  @author Eric Van Alst, MHPCC
+ *   
+ *  @version $Revision: 1.4 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-04-27 02:17:53 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+/******************************************************************************/
+/*  INCLUDE FILES                                                             */
+/******************************************************************************/
+#include <stdarg.h>
+#include <stdlib.h>
+#include "psAbort.h"
+#include "psLogMsg.h"
+
+/******************************************************************************/
+/*  DEFINE STATEMENTS                                                         */
+/******************************************************************************/
+
+// None
+
+/******************************************************************************/
+/*  TYPE DEFINITIONS                                                          */
+/******************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  GLOBAL VARIABLES                                                         */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  FILE STATIC VARIABLES                                                    */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  FUNCTION IMPLEMENTATION - LOCAL                                          */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/* FUNCTION IMPLEMENTATION - PUBLIC                                          */
+/*****************************************************************************/
+
+void psAbort(const char *name, const char *fmt,... )
+{
+    va_list    argPtr;     // variable list arguement pointer
+
+    // Get the variable list parameters to pass to logging function
+    va_start(argPtr, fmt);
+
+    // Call logging function with PS_LOG_ABORT level
+    psVLogMsg(name, PS_LOG_ABORT, fmt, argPtr);
+
+    // Clean up stack after variable arguement has been used
+    va_end(argPtr);
+
+    // Call system abort function to terminate program execution
+    abort();
+}
+
Index: /tags/rel1_1/psLib/src/sysUtils/psAbort.d
===================================================================
--- /tags/rel1_1/psLib/src/sysUtils/psAbort.d	(revision 1056)
+++ /tags/rel1_1/psLib/src/sysUtils/psAbort.d	(revision 1056)
@@ -0,0 +1,1 @@
+psAbort.o psAbort.d : psAbort.c psAbort.h psLogMsg.h
Index: /tags/rel1_1/psLib/src/sysUtils/psAbort.h
===================================================================
--- /tags/rel1_1/psLib/src/sysUtils/psAbort.h	(revision 1056)
+++ /tags/rel1_1/psLib/src/sysUtils/psAbort.h	(revision 1056)
@@ -0,0 +1,47 @@
+/** @file  psAbort.h
+ *
+ *  @brief Contains the declarations for the abort function
+ *
+ *  The abort logging and handling shall be performed by psAbort function.
+ *  This will allow for consistent handling of other software units
+ *  needing to abort from program execution.
+ *
+ *  @ingroup ErrorHandling
+ *
+ *  @author Eric Van Alst, MHPCC
+ *
+ *  @version $Revision: 1.4 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-10 01:58:06 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PS_ABORT_H
+#define PS_ABORT_H
+
+
+// Doxygen grouping tags
+/** @addtogroup ErrorHandling
+ *  @{
+ */
+
+/** Reports an abort message to logging facility
+ *
+ *  This function will invoke the psLogMsg function with a level of 
+ *  PS_LOG_ABORT and pass the parameters name and fmt to generate a proper
+ *  log message.  After logging, this function will call system abort 
+ *  function to abnormally terminate the program.
+ *
+ *  @return  void No return value
+ *
+ */
+void psAbort(
+    const char* name,                   ///< Source of abort such as file or function detected
+    const char* fmt,                    ///< A printf style formatting statement defining msg
+    ...
+);
+
+/* @} */  // Doxygen - End of SystemGroup Functions
+
+#endif
+
Index: /tags/rel1_1/psLib/src/sysUtils/psError.c
===================================================================
--- /tags/rel1_1/psLib/src/sysUtils/psError.c	(revision 1056)
+++ /tags/rel1_1/psLib/src/sysUtils/psError.c	(revision 1056)
@@ -0,0 +1,72 @@
+/** @file  psError.c
+ *
+ *  @brief Contains the definitions for the error reporting functions
+ *
+ *  Error reporting functions shall be used to create log entries in the
+ *  event errors are detected.  The messages shall give enough information
+ *  to allow the user to know where the error has occurred and the type
+ *  of error detected.
+ *
+ *  @author Eric Van Alst, MHPCC
+ *   
+ *  @version $Revision: 1.6 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-04-21 21:14:41 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+/******************************************************************************/
+/*  INCLUDE FILES                                                             */
+/******************************************************************************/
+#include <stdarg.h>
+#include "psLogMsg.h"
+#include "psError.h"
+
+/******************************************************************************/
+/*  DEFINE STATEMENTS                                                         */
+/******************************************************************************/
+
+// None
+
+/******************************************************************************/
+/*  TYPE DEFINITIONS                                                          */
+/******************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  GLOBAL VARIABLES                                                         */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  FILE STATIC VARIABLES                                                    */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  FUNCTION IMPLEMENTATIONS - LOCAL                                         */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/* FUNCTION IMPLEMENTATIONS - PUBLIC                                         */
+/*****************************************************************************/
+
+void psError(const char *name,const char *fmt, ...)
+{
+    va_list    argPtr;        // variable list arguement pointer
+
+    // Get the variable list parameters  to pass to logging function
+    va_start(argPtr, fmt);
+
+    // Call logging function with PS_LOG_ERROR level
+    psVLogMsg(name, PS_LOG_ERROR, fmt, argPtr);
+
+    // Clean up stack after variable argument has been used
+    va_end(argPtr);
+}
+
Index: /tags/rel1_1/psLib/src/sysUtils/psError.d
===================================================================
--- /tags/rel1_1/psLib/src/sysUtils/psError.d	(revision 1056)
+++ /tags/rel1_1/psLib/src/sysUtils/psError.d	(revision 1056)
@@ -0,0 +1,1 @@
+psError.o psError.d : psError.c psLogMsg.h psError.h
Index: /tags/rel1_1/psLib/src/sysUtils/psError.h
===================================================================
--- /tags/rel1_1/psLib/src/sysUtils/psError.h	(revision 1056)
+++ /tags/rel1_1/psLib/src/sysUtils/psError.h	(revision 1056)
@@ -0,0 +1,45 @@
+/** @file  psError.h
+ *
+ *  @brief Contains the declarations for the error reporting functions
+ *
+ *  Error reporting functions shall be used to create log entries in the
+ *  event errors are detected.  The messages shall give enough information
+ *  to allow the user to know where the error has occurred and the type
+ *  of error detected.
+ *
+ *  @ingroup ErrorHandling
+ *
+ *  @author Eric Van Alst, MHPCC
+ *
+ *  @version $Revision: 1.4 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-10 01:58:06 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PS_ERROR_H
+#define PS_ERROR_H
+
+/** @addtogroup ErrorHandling
+ *  @{
+ */
+
+/** Reports an error message to the logging facility
+ *
+ *  This function will invoke the psLogMsg function with a level of
+ *  PS_LOG_ERROR and pass the parameters name and fmt to generate a proper
+ *  log message.
+ *
+ *  @return  void No return value
+ *
+ */
+void psError(
+    const char *name,                   ///< Source of error such as file or function detected
+    const char *fmt,                    ///< A printf style formatting statement defining msg
+    ...
+);
+
+/* @} */  // End of SysUtils Functions
+
+#endif
+
Index: /tags/rel1_1/psLib/src/sysUtils/psErrorCodes.h
===================================================================
--- /tags/rel1_1/psLib/src/sysUtils/psErrorCodes.h	(revision 1056)
+++ /tags/rel1_1/psLib/src/sysUtils/psErrorCodes.h	(revision 1056)
@@ -0,0 +1,19 @@
+#if !defined(PS_ERROR_CODES_H)
+#define PS_ERROR_CODES_H
+/*
+ * This file was machine generated from ../../src/Utils/psErrorCodes.dat;
+ * please do not modify it
+ */
+typedef enum {
+    PS_ERR_NONE = 0,
+    PS_ERR_BASE = 256,
+    PS_ERR_UNKNOWN,
+    PS_ERR_IO,
+    PS_ERR_BADFREE,
+    PS_ERR_MEMORY_CORRUPTION,
+    PS_ERR_MEMORY_EXHAUSTED,
+    PS_ERR_BAD_INDEX,
+    PS_ERR_N_ERR_CLASSES,
+} psErrorCode;
+
+#endif
Index: /tags/rel1_1/psLib/src/sysUtils/psHash.c
===================================================================
--- /tags/rel1_1/psLib/src/sysUtils/psHash.c	(revision 1056)
+++ /tags/rel1_1/psLib/src/sysUtils/psHash.c	(revision 1056)
@@ -0,0 +1,452 @@
+/** @file  psHash.c
+ *
+ *  @brief Contains support for basic hashing functions.
+ *
+ *  This file will hold the functions for defining a hash table with arbitrary
+ *  data types, allocating/deallocating that hash table, adding and removing
+ *  data from that hash table, and listing all keys defined in the hash table.
+ *
+ *  @author Robert Lupton, Princeton University
+ *  @author George Gusciora, MHPCC
+ *   
+ *  @version $Revision: 1.8 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-10 00:09:55 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "psHash.h"
+#include "psMemory.h"
+#include "psString.h"
+#include "psTrace.h"
+#include "psAbort.h"
+
+
+/******************************************************************************
+psHashKeyList(table): this function creates a linked list with an entry in
+that list for every key in the hash table.
+Inputs:
+    table: a hash table
+Return;
+    The linked list 
+ *****************************************************************************/
+psList *psHashKeyList(psHash *table)
+{
+    int i = 0;                          // Loop index variable
+    psList *myLinkList = NULL;  // The output data structure
+    psHashBucket *ptr = NULL;           // Used to step thru linked list.
+
+    if (table == NULL) {
+        return NULL;
+    }
+
+    // Create the linked list
+    myLinkList = psListAlloc(NULL);
+
+    // Loop through every bucket in the hash table.  If that bucket is not
+    // NULL, then add the bucket's key to the linked list.
+    for (i=0;i<table->nbucket;i++) {
+        if (table->buckets[i] != NULL) {
+            // Since a bucket contains a linked list of keys/data, we must
+            // step trough each key in that linked list:
+
+            ptr = table->buckets[i];
+            while (ptr != NULL) {
+                psListAdd(myLinkList, ptr->key, PS_LIST_HEAD);
+                ptr = ptr->next;
+            }
+        }
+    }
+
+    // Return the linked list
+    return(myLinkList);
+}
+
+
+
+/******************************************************************************
+hashBucketAlloc(key, data, next): This procedure creates a new hash bucket
+with the specified key, data, and next.
+Inputs:
+    key:  the new bucket's key pointer
+    data: the new bucket's data pointer
+    next: the new bucket's key pointer
+Return:
+    the new hash bucket.
+ *****************************************************************************/
+static psHashBucket *hashBucketAlloc(const char *key,
+                                     void *data,
+                                     psHashBucket *next)
+{
+    if (key == NULL) {
+        psAbort(__func__, "psHashBucket() called with NULL key.");
+    }
+
+    // Allocate memory for the new hash bucket.
+    psHashBucket *bucket = psAlloc(sizeof(psHashBucket));
+
+    // Initialize the bucket.
+    bucket->key = psStringCopy(key);
+
+    if (data == NULL) {
+        // NOTE: Should we flag a warning message?
+        bucket->data = NULL;
+    } else {
+        bucket->data = psMemIncrRefCounter(data);
+    }
+
+    bucket->next = next;
+
+    return bucket;
+}
+
+
+/******************************************************************************
+hashBucketFree(bucket, itemFree): This procedure deallocates the specified
+hash bucket.  If "itemFree" is NULL, then we simply free the data with the
+standard psFree() function.  If "itemFree" is not NULL, then it must be a
+function pointer which takes the hash bucket as a parameter, and frees the
+data in that hash bucket.
+Inputs:
+    bucket: the hash bucket to be freed.
+    itemFree: a function pointer, possibly NULL.
+Return:
+    NONE
+ *****************************************************************************/
+static void hashBucketFree(psHashBucket *bucket,   // bucket to free
+                           void (*itemFree)(void *item)) // how to free data;
+{
+    if (bucket == NULL)
+    {
+        return;
+    }
+
+    // A bucket is actually a linked list of buckets.  We recursively step
+    // through that linked list, free each bucket.
+    if (bucket->next != NULL)
+    {
+        hashBucketFree(bucket, itemFree);
+    }
+
+    psFree(bucket->key);
+    psMemDecrRefCounter(bucket->data);
+
+    if (itemFree != NULL)
+    {
+        itemFree(bucket->data);
+    } else
+    {
+        psFree(bucket->data);
+    }
+
+    psFree(bucket);
+}
+
+
+/******************************************************************************
+psHashAlloc(nbucket): this procedure creates a new hash table with the
+specified number of buckets.
+Inputs:
+    nbucket: initial number of buckets
+Return:
+    The new hash table.
+ *****************************************************************************/
+psHash *psHashAlloc(int nbucket) // initial number of buckets
+{
+    int i = 0;   // loop index variable
+    // Create the new hash table.
+    psHash *table = psAlloc(sizeof(psHash));
+
+    // Allocate memory for the buckets.
+    table->buckets = psAlloc(nbucket*sizeof(psHashBucket *));
+    table->nbucket = nbucket;
+
+    psTrace("utils.hash", 1, "Creating %d-element hash table\n", nbucket);
+
+    // Initialize all buckets to NULL.
+    for (i = 0; i < nbucket; i++)
+    {
+        table->buckets[i] = NULL;
+    }
+
+    // Return the new hash table.
+    return table;
+}
+
+
+
+/******************************************************************************
+psHashFree(table, itemFree): This procedure deallocates the specified hash
+table.  It loops through each bucket, and calls hashBucketFree() on that
+bucket.
+ 
+Inputs:
+    table: a hash table
+    itemFree: a function pointer, possibly NULL.
+Return:
+    NONE
+ *****************************************************************************/
+void psHashFree(psHash *table,  // hash table to be freed
+                void (*itemFree)(void *item)) // how to free hashed data; or NULL
+{
+    psHashBucket *tmp = NULL;           // Used to step through linked list.
+    psHashBucket *ptr = NULL;           // Used to step through linked list.
+    int i = 0;                          // Loop index variable.
+
+    if (table == NULL)
+    {
+        return;
+    }
+
+    // Loop through each bucket in the hash table.  If that bucket is not
+    // NULL, then free the bucket via a function call to hashBucketFree();
+
+    for (i = 0; i < table->nbucket; i++)
+    {
+        // A bucket is composed of a linked list of buckets.  We use the
+        // "tmp" and "ptr" pointers to step through that list and free each
+        // non-NULL bucket.
+
+        if (table->buckets[i] != NULL) {
+            ptr = table->buckets[i];
+            while (ptr != NULL) {
+                tmp = ptr->next;
+                hashBucketFree(ptr, itemFree);
+                ptr = tmp;
+            }
+        }
+    }
+
+    // Free the bucket structure, then the hash table.
+    psFree(table->buckets);
+    psFree(table);
+}
+
+/******************************************************************************
+doHashWork(table, key, data, remove, itemFree): This is an internal
+procedure which does the bulk of the work in using the hash table.  Depending
+upon the input parameters, it will either insert a new key/data into the hash
+table, retrieve the data for a specified key, or remove a key/data item.  If
+we try to insert a key that already exists in the hash table, then we call
+the user-supplied function itemfree (or psFree if that is NULL), to free the
+existing data/key item.
+Inputs:
+    table: a hash table
+    key: the key to insert, retrieve, or remove.  Must not be NULL.
+    data: the data to insert, if not NULL
+    remove: set to non-zero if the key/data should be removed from the table.
+    itemFree: function pointer
+Return:
+    NONE
+ 
+NOTE: consider removing this private function and simply putting the code
+into the psHashInsert(), psHashLookup(), and psHashRemove().  Why?  Because
+there is little common code between those functions.
+  *****************************************************************************/
+static void *doHashWork(psHash     *table,   // table to insert in
+                        const char *key,     // key to use
+                        void       *data,    // data to insert, or (if NULL) retrieve/remove
+                        int remove
+                            ,          // remove the item from the list?
+                            void (*itemFree)(void *item)) // how to free hashed data
+{
+    long int hash = 1;                  // This will contain an integer value
+    // "hashed" from the key.
+    char *tmpchar = NULL;               // Used in computing the hash function.
+    psHashBucket *ptr = NULL;           // Used to retrieve the hash bucket.
+    psHashBucket *optr = NULL;          // "original pointer": used to step
+    // thru the linked list for a bucket.
+
+    // The following condition should never be true, since this is a private
+    // function, but I'm checking it anyway since future coders might change
+    // the way this procedure is called.
+    if ((table == NULL) || (key == NULL)) {
+
+        psAbort(__func__, "psHashRemove() called with NULL key or table.");
+    }
+
+    // NOTE: This is the originally supplied hash function.
+    //    for (int i = 0, len = strlen(key); i < len; i++) {
+    //        hash = (hash << 1) ^ key[i];
+    //    }
+    //    hash &= (table->nbucket - 1);
+
+    // This hash algorithm is from Sedgewick.  NOTE: must reread to ensure that
+    // the size of the hash table is not required to be a prime number.
+    tmpchar = (char *) key;
+    for (hash = 0; *tmpchar != '\0'; tmpchar++) {
+        hash = (64 * hash + *tmpchar) % (table->nbucket);
+    }
+
+    // NOTE: This should not be necessary, but for now, I'm checking bounds
+    // anyway.
+    if ((hash < 0) || (hash >= table->nbucket)) {
+        psAbort(__func__,"Internal hash function out of range (%d)", hash);
+    }
+
+    // ptr will have the correct hash bucket.
+    ptr = table->buckets[hash];
+
+    // We know the correct hash bucket, now we need to know what to do.
+    // If the data parameter is NULL, then, by definition, this is a retrieve
+    // or a remove operation on the hash table.
+
+    if (data == NULL) {
+        if (remove
+           ) {
+            // We search through the linked list for this bucket in
+            // the hash table and look for an entry for this key.
+
+            optr = ptr;
+            while (ptr != NULL) {
+                // Dtermine if this entry holds the correct key.
+                if (strcmp(key, ptr->key) == 0) {
+                    // The following lines of code are fairly standard ways
+                    // of removing an item from a single-linked list.
+
+                    void *data = ptr->data;
+                    optr->next = ptr->next;
+                    if (ptr == table->buckets[hash]) {
+                        table->buckets[hash] = ptr->next;
+                    }
+
+                    psFree(ptr->key);
+                    psFree(ptr);
+
+                    // By definition, the data associated with that key
+                    // must be returned, not freed.
+                    return psMemDecrRefCounter(data);
+                }
+                optr = ptr;
+                ptr = ptr->next;
+            }
+            return NULL;   // not in hash
+        }
+        else {
+            // If we get here, then a retrieve operation is requested.  So,
+            // we step trough the linked list at this bucket, and return the
+            // data once we find it, or return NULL if we don't.
+            while (ptr != NULL) {
+                if (strcmp(key, ptr->key) == 0) {
+                    return ptr->data;
+                }
+                ptr = ptr->next;
+            }
+            return NULL;   // not in hash
+        }
+    } else {
+        // We get here if this procedure was called with non-NULL data.
+        // Therefore, we should insert that data into the hash table.
+        // First, we search through the linked list for this bucket in
+        // the hash table and look for a duplicate entry for this key.
+
+        while (ptr != NULL) {
+            if (strcmp(key, ptr->key) == 0) {
+                // We have found this key in the hash table.
+
+                psTrace("utils.hash.insert", 3, "Replacing data for %s\n",
+                        key);
+
+                // NOTE: I have changed this behavior from the originally
+                // supplied code.  Formerly, if itemFree was NULL, then
+                // the new data was not inserted into the hash table.
+
+                if (itemFree == NULL) {
+                    psFree(psMemDecrRefCounter(ptr->data));
+                } else {
+                    itemFree(psMemDecrRefCounter(ptr->data));
+                }
+
+                ptr->data = psMemIncrRefCounter(data);
+                return data;
+            }
+        }
+        // We did not found key in the linked list for this bucket of the hash
+        // table.  So, we insert this data at the head of that linked list.
+
+        table->buckets[hash] = hashBucketAlloc(key,
+                                               data,
+                                               table->buckets[hash]);
+        return data;
+    }
+}
+
+/******************************************************************************
+psHashInsert(table, key, data, itemFree): this procedure, which is part of
+the public API, inserts a new key/data pair into the hash table.
+Inputs:
+    table: a hash table
+    key: the key to use
+    data: the data to insert.
+    itemFree: a function pointer
+Return:
+    NONE
+ *****************************************************************************/
+void *psHashInsert(psHash *table,   // table to insert in
+                   const char *key, // key to use
+                   void *data,      // data to insert
+                   void (*itemFree)(void *item)) // how to free hashed data;
+{
+    if (table == NULL) {
+        psAbort(__func__, "psHashInsert() called with NULL hash table.");
+    }
+    if (key == NULL) {
+        psAbort(__func__, "psHashInsert() called with NULL key.");
+    }
+    if (data == NULL) {
+        psAbort(__func__, "psHashLookup() called with NULL data.");
+    }
+
+    return doHashWork(table, key, data, 0, itemFree);
+}
+
+/******************************************************************************
+psHashLookup(table, key): this procedure, which is part of the public API,
+looks up the specified key in the hash table and returns the data associated
+with that key.
+ 
+Inputs:
+    table: a hash table
+    key: the key to use
+Return:
+    The data associated with that key.
+ *****************************************************************************/
+void *psHashLookup(psHash *table,   // table to lookup key in
+                   const char *key) // key to lookup
+{
+    if (table == NULL) {
+        psAbort(__func__, "psHashLookup() called with NULL hash table.");
+    }
+    if (key == NULL) {
+        psAbort(__func__, "psHashLookup() called with NULL key.");
+    }
+
+
+    return doHashWork(table, key, NULL, 0, NULL);
+}
+
+/******************************************************************************
+psHashRemove(table, key, itemFree): this procedure, which is part of the
+public API, removes the specified key from the hash table.
+Inputs:
+    table: a hash table
+    key: the key to remove
+    itemFree: a function pointer
+Return:
+    The data that was associated with that key.
+ *****************************************************************************/
+void *psHashRemove(psHash *table,   // table to lookup key in
+                   const char *key, // key to lookup
+                   void (*itemFree)(void *item)) // how to free hashed data;
+{
+    if (table == NULL) {
+        psAbort(__func__, "psHashRemove() called with NULL hash table.");
+    }
+    if (key == NULL) {
+        psAbort(__func__, "psHashRemove() called with NULL key.");
+    }
+
+    return doHashWork(table, key, NULL, 1, itemFree);
+}
Index: /tags/rel1_1/psLib/src/sysUtils/psHash.d
===================================================================
--- /tags/rel1_1/psLib/src/sysUtils/psHash.d	(revision 1056)
+++ /tags/rel1_1/psLib/src/sysUtils/psHash.d	(revision 1056)
@@ -0,0 +1,3 @@
+psHash.o psHash.d : psHash.c psHash.h ../collections/psList.h \
+  ../collections/psVector.h ../collections/psType.h \
+  ../sysUtils/psMemory.h psString.h psTrace.h psAbort.h
Index: /tags/rel1_1/psLib/src/sysUtils/psHash.h
===================================================================
--- /tags/rel1_1/psLib/src/sysUtils/psHash.h	(revision 1056)
+++ /tags/rel1_1/psLib/src/sysUtils/psHash.h	(revision 1056)
@@ -0,0 +1,76 @@
+/** @file  psHash.h
+ *  @brief Contains support for basic hashing functions.
+ *  @ingroup HashTable
+ *
+ *  This file will hold the prototypes for defining a hash table with arbitrary
+ *  data types, allocating/deallocating that has table, adding and removing
+ *  data from that hash table, and listing all keys defined in the hash table.
+ *
+ *  @author Robert Lupton, Princeton University
+ *  @author George Gusciora, MHPCC
+ *   
+ *  @version $Revision: 1.13 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-12 05:50:01 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+#if !defined(PS_HASH_H)
+#define PS_HASH_H
+
+/** \addtogroup HashTable
+ *  \{
+ */
+#include "psList.h"
+
+/** A bucket that holds an item of data. */
+typedef struct psHashBucket
+{
+    char *key;                          ///< key for this item of data
+    void *data;                         ///< the data itself
+    struct psHashBucket *next;          ///< list of other possible keys
+}
+psHashBucket;
+
+//typedef struct HashTable psHash; ///< Opaque type for a hash table
+/** The hash-table itself. */
+typedef struct psHash
+{
+    int nbucket;                        ///< Number of buckets in hash table.
+    psHashBucket **buckets;             ///< The bucket data.
+}
+psHash;
+
+/// Allocate hash buckets in table.
+psHash *psHashAlloc(int nbucket       ///< The number of buckets to allocate.
+                   );
+
+/// Free hash buckets from table.
+void psHashFree(psHash *table,               ///< hash table to be freed
+                void (*itemFree)(void *item) ///< how to free hashed data; or NULL
+               );
+
+/// Insert entry into table.
+void *psHashInsert(psHash *table,               ///< table to insert in
+                   const char *key,             ///< key to use
+                   void *data,                  ///< data to insert
+                   void (*itemFree)(void *item) ///< how to free hashed data; or NULL
+                  );
+
+/// Lookup key in table.
+void *psHashLookup(psHash *table, ///< table to lookup key in
+                   const char *key ///< key to lookup
+                  );
+
+/// Remove key from table.
+void *psHashRemove(psHash *table, ///< table to lookup key in
+                   const char *key, ///< key to lookup
+                   void (*itemFree)(void *item) ///< how to free hashed data; or NULL
+                  );
+
+/// List all keys in table.
+psList *psHashKeyList(psHash *table  ///< table to list keys from.
+                     );
+
+/* \} */ // End of DataGroup Functions
+
+#endif
Index: /tags/rel1_1/psLib/src/sysUtils/psLogMsg.c
===================================================================
--- /tags/rel1_1/psLib/src/sysUtils/psLogMsg.c	(revision 1056)
+++ /tags/rel1_1/psLib/src/sysUtils/psLogMsg.c	(revision 1056)
@@ -0,0 +1,345 @@
+/** @file  psLogMsg.c
+ *  @brief Procedures for logging messages.
+ *  \ingroup LogTrace
+ *
+ *  This file will hold the prototypes for defining procedure which set
+ *  message log levels, messahe log formats, message log destinations, and
+ *  for generating the messages themselves.
+ *  @ingroup LogTrace
+ *
+ *  @author Robert Lupton, Princeton University
+ *  @author George Gusciora, MHPCC
+ *
+ *  @version $Revision: 1.16 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-14 19:40:15 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+/*****************************************************************************
+NOTES: currently, the prototype code has the following global variables:
+    static int p_psGlobalLogDest;
+    static int p_psGlobalLogLevel;
+    static int p_psLogTime;
+    static int p_psLogHost;
+    static int p_psLogLevel;
+    static int p_psLogName;
+    static int p_psLogMsg;
+ *****************************************************************************/
+#include <limits.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <time.h>
+#include <unistd.h>
+#include "psLogMsg.h"
+#include "psError.h"
+#include "psErrorCodes.h"
+#include "psTrace.h"
+
+#define MIN_LOG_LEVEL 0
+#define MAX_LOG_LEVEL 9
+static int p_psGlobalLogDest = PS_LOG_TO_STDERR; // where to log messages
+static int p_psGlobalLogLevel = PS_LOG_INFO;     // log all messages at this or above
+//static FILE *p_logFP = NULL;
+// The following variables control
+// which information is displayed in
+// log messages.
+static int p_psLogTime = 1;                // Flag to include time info
+static int p_psLogHost = 1;                // Flag to include host info
+static int p_psLogLevel = 1;               // Flag to include level info
+static int p_psLogName = 1;                // Flag to include name info
+static int p_psLogMsg = 1;                 // Flag to include message info
+/*****************************************************************************
+psLogSetLevel(): Set the current log level and return old level.
+Input:
+ level (int): the new log level.
+Output:
+ none
+Return:
+ The old log level.
+ *****************************************************************************/
+int psLogSetLevel(int level)
+{
+    // Save old global log level for changing it.
+    int oldLevel = p_psGlobalLogLevel;
+
+    if ((level < MIN_LOG_LEVEL) || (level > MAX_LOG_LEVEL)) {
+        psLogMsg("logmsg", PS_LOG_WARN,
+                 "Attempt to set invalid logMsg level: %d", level);
+        level = (level < MIN_LOG_LEVEL) ? MIN_LOG_LEVEL : MAX_LOG_LEVEL;
+    }
+
+    // Set new global log level
+    p_psGlobalLogLevel = level;
+
+    // Return old global log level
+    return oldLevel;
+}
+
+
+/*****************************************************************************
+psLogSetDestination(): sets the destination where log messages will be
+sent to.
+ 
+Input:
+ dest (int): the new log destination
+Output:
+ None.
+Return:
+ An integer specifying the old log destination.
+ *****************************************************************************/
+int psLogSetDestination(int dest)
+{
+    // Save old global log destination before changing it.
+    int old = p_psGlobalLogDest;
+
+    switch (dest) {
+    case PS_LOG_NONE:
+    case PS_LOG_TO_STDOUT:
+    case PS_LOG_TO_STDERR:
+        // Set new global log destination
+        p_psGlobalLogDest = dest;
+        break;
+
+    default:
+        // NOTE: Should you log this error properly?
+        fprintf(stderr,"Unknown p_psGlobalLogDest: %d (ignored)\n", dest);
+        break;
+    }
+
+    // Return old global log destination
+    return old;
+}
+
+
+
+/*****************************************************************************
+psLogSetFormat(): Set the format of psLogMsg output.  More precisely,
+    provide a string consisting of the letters {H (host), L (level), M
+    (message), N (name), T (time)}.  The default is "HLMNT".  This string
+    determines whether or not they associated type of information will be
+    included in message logs.  It does not determine the order in which that
+    information will appear (that order is fixed).
+ 
+Input:
+    fmt: a string specifying the format.
+Output:
+    none.
+Return:
+    NULL.
+ *****************************************************************************/
+void psLogSetFormat(const char *fmt)
+{
+
+    // Step through each character in the format string.  For each letter
+    // in that string, set/unset the appropriate logging.
+
+    for (const char *ptr = fmt; *ptr != '\0'; ptr++) {
+        switch (*ptr) {
+        case 'H':
+        case 'h':
+            p_psLogHost = 1;
+            break;
+        case 'L':
+        case 'l':
+            p_psLogLevel = 1;
+            break;
+        case 'M':
+        case 'm':
+            p_psLogMsg = 1;
+            break;
+        case 'N':
+        case 'n':
+            p_psLogName = 1;
+            break;
+        case 'T':
+        case 't':
+            p_psLogTime = 1;
+            break;
+        default:
+            psError(__func__, "Unknown logging keyword %c", *ptr);
+            break;
+        }
+    }
+
+    if (!p_psLogMsg) {
+        psTrace("utils.logMsg", 1,
+                "You must at least log error messages (You chose \"%s\")",
+                fmt);
+    }
+}
+
+
+
+#if !defined(HOST_NAME_MAX)  // should be in limits.h
+#  define HOST_NAME_MAX 256
+#endif
+/*****************************************************************************
+    psVLogMsg(): This routine sends the message, which is a printf style
+ string specified in the "..." argument, to the current message log
+ destination with the severity specified by the "level" argument.
+    Input:
+ name
+ level
+ fmt
+ ap
+    Output:
+ none
+    Return:
+ NULL.
+ *****************************************************************************/
+void psVLogMsg(const char *name,
+               int level,
+               const char *fmt,
+               va_list ap)
+{
+    static int first = 1;               // Flag for calling gethostname()
+    static char hostname[HOST_NAME_MAX + 1];
+    // Buffer for hostname.
+    char clevel=0;                      // letter-name for level
+    char head[HOST_NAME_MAX + 40];      // yes, this is long enough
+    char *head_ptr = head;              // where we've got to in head
+    time_t clock = time(NULL);          // The current time.
+    struct tm *utc = gmtime(&clock);    // The current gm time.
+
+    // If logging is off, or if the level is too high, return immediately.
+    if ((level > p_psGlobalLogLevel) || (p_psGlobalLogDest == PS_LOG_NONE)) {
+        return;
+    }
+
+    // If I have not been here yet, determine my hostname and save it.
+    if (first) {
+        first = 0;
+        gethostname(hostname, HOST_NAME_MAX);
+    }
+
+    switch (level) {
+    case PS_LOG_ABORT:
+        clevel = 'A';
+        break;
+
+    case PS_LOG_ERROR:
+        clevel = 'E';
+        break;
+
+    case PS_LOG_WARN:
+        clevel = 'W';
+        break;
+
+    case PS_LOG_INFO:
+        clevel = 'I';
+        break;
+
+    case 4:
+    case 5:
+    case 6:
+    case 7:
+    case 8:
+    case 9:
+        clevel = level + '0';
+        break;
+
+    default:
+        psTrace("utils.logMsg", 2, "Invalid logMsg level: %d (%s)\n",
+                level, fmt);
+        level = (level < 0) ? 0 : 9;
+        break;
+    }
+
+    // Create the various log fields...
+    if (p_psLogTime) {
+        sprintf(head_ptr, "%4d:%02d:%02d %02d:%02d:%02dZ",
+                utc->tm_year + 1900, utc->tm_mon + 1, utc->tm_mday,
+                utc->tm_hour, utc->tm_min, utc->tm_sec);
+        head_ptr += strlen(head_ptr);
+    }
+    // Hostname should be 20 characters.
+    if (p_psLogHost) {
+        if (head_ptr > head) {
+            *head_ptr++ = '|';
+        }
+        sprintf(head_ptr, "%-20s", hostname);
+        head_ptr += strlen(head_ptr);
+    }
+    if (p_psLogLevel) {
+        if (head_ptr > head) {
+            *head_ptr++ = '|';
+        }
+        sprintf(head_ptr, "%c", clevel);
+        head_ptr += strlen(head_ptr);
+    }
+    // The name field must be 15 characters.
+    if (p_psLogName) {
+        if (head_ptr > head) {
+            *head_ptr++ = '|';
+        }
+        sprintf(head_ptr, "%15.15s", name);
+        head_ptr += strlen(head_ptr);
+    }
+
+    if (head_ptr > head) {
+        *head_ptr++ = '|';
+    }
+    *head_ptr = '\0';
+
+    switch (p_psGlobalLogDest) {
+    case PS_LOG_TO_STDOUT:
+        puts(head);
+        if (p_psLogMsg) {
+            vprintf(fmt, ap);
+            if (fmt[strlen(fmt) - 1] != '\n') {
+                putc('\n', stdout);
+            }
+        } else {
+            putc('\n', stdout);
+        }
+        break;
+
+    case PS_LOG_TO_STDERR:
+        fputs(head, stderr);
+        if (p_psLogMsg) {
+            vfprintf(stderr, fmt, ap);
+            if (fmt[strlen(fmt) - 1] != '\n') {
+                putc('\n', stderr);
+            }
+        } else {
+            putc('\n', stderr);
+        }
+        break;
+
+    default:
+        fprintf(stderr, "psLogMsg: You cannot get here (%s:%d)\n",
+                __FILE__, __LINE__);
+        abort();
+    }
+}
+
+
+/*****************************************************************************
+    psLogMsg(): This routine sends the message, which is a printf style
+ string specified in the "..." argument, to the current message log
+ destination with the severity specified by the "level" argument.
+    Input:
+ name: Indicates the source of this log message.
+ level: The severity of this log message.
+ fmt: The printf-stype formatted string, followed by the arguments
+  to that string.
+ ... The arguments to the above printf-style string.
+    Output:
+ none
+    Return:
+ NULL
+ *****************************************************************************/
+void psLogMsg(const char *name,
+              int level,
+              const char *fmt,
+              ...)
+{
+    va_list ap;
+
+    va_start(ap, fmt);
+    psVLogMsg(name, level, fmt, ap);
+    va_end(ap);
+}
Index: /tags/rel1_1/psLib/src/sysUtils/psLogMsg.d
===================================================================
--- /tags/rel1_1/psLib/src/sysUtils/psLogMsg.d	(revision 1056)
+++ /tags/rel1_1/psLib/src/sysUtils/psLogMsg.d	(revision 1056)
@@ -0,0 +1,1 @@
+psLogMsg.o psLogMsg.d : psLogMsg.c psLogMsg.h psError.h psErrorCodes.h psTrace.h
Index: /tags/rel1_1/psLib/src/sysUtils/psLogMsg.h
===================================================================
--- /tags/rel1_1/psLib/src/sysUtils/psLogMsg.h	(revision 1056)
+++ /tags/rel1_1/psLib/src/sysUtils/psLogMsg.h	(revision 1056)
@@ -0,0 +1,86 @@
+/** @file  psLogMsg.h
+ *  @brief Procedures for logging messages.
+ *  \ingroup LogTrace
+ *
+ *  This file will hold the prototypes for defining procedure which set
+ *  message log levels, messahe log formats, message log destinations, and
+ *  for generating the messages themselves.
+ *  @ingroup LogTrace
+ *
+ *  @author Robert Lupton, Princeton University
+ *  @author George Gusciora, MHPCC
+ *
+ *  @version $Revision: 1.8 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-12 05:50:01 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+#if !defined(PS_LOG_MSG_H)
+#define PS_LOG_MSG_H
+#include <stdarg.h>
+
+/** @addtogroup LogTrace
+ *  @{
+ */
+
+/// This procedure sets the destination for future log messages.  Currently
+/// the destination is specified by an integer which can have the following
+/// pre-defined values: PS_LOG_NONE, PS_LOG_TO_STDOUT, and PS_LOG_TO_STDERR.
+/// In future versions, this procedure will take a character string as an
+/// argument which can specify more general log destinations.
+int psLogSetDestination(int dest     ///< Specifies where to send messages.
+                       );
+
+
+/// This procedure sets the message level for future log messages.  Subsequent
+/// log messages, with a log level of "mylevel", will only be logged if
+/// "mylevel" is less than the current log level set by this procedure.
+/// Ie. higher values set by this procedure will cause more log messages to
+/// be displayed.
+int psLogSetLevel(int level          ///< Specifies the system log level
+                 );
+
+
+/// This procedure sets the log format for future log messages.  The argument
+/// must be a character string consistsing of the letters H (host), L
+/// (level), M (message), N (name), and T (time).  The default is "THLNM".
+/// Deleting a letter from the string will cause the associated information
+/// to not be logged.
+void psLogSetFormat(const char *fmt ///< Specifies the system log format
+                   );
+
+
+/// This procedure logs a message to the destination set by a prior
+/// call to psLogSetDestination(), if myLevel is less than the level
+/// specified by a prior call to psLogSetLevel().  The message is specified
+/// with a printf-stype string an arguments.
+void psLogMsg(const char *name,     ///< name of the log source
+              int myLevel,          ///< severity level of this log message
+              const char *fmt, ...  ///< printf-style format command
+             );
+
+
+/// This procedure is functionally equivalent to psLogMsg(), except that
+/// it takes a va_list as the message parameter, not a printf-style string.
+void psVLogMsg(const char *name, ///< name of the log source
+               int myLevel,      ///< severity level of this log message
+               const char *fmt,  ///< printf-style format command
+               va_list ap        ///< varargs argument list
+              );
+
+///< Status codes for log messages
+enum {
+    PS_LOG_ABORT = 0,
+    PS_LOG_ERROR,
+    PS_LOG_WARN,
+    PS_LOG_INFO };
+
+///< Destinations for log messages
+enum {
+    PS_LOG_NONE,
+    PS_LOG_TO_STDERR,
+    PS_LOG_TO_STDOUT };
+
+/// @}
+
+#endif
Index: /tags/rel1_1/psLib/src/sysUtils/psMemory.c
===================================================================
--- /tags/rel1_1/psLib/src/sysUtils/psMemory.c	(revision 1056)
+++ /tags/rel1_1/psLib/src/sysUtils/psMemory.c	(revision 1056)
@@ -0,0 +1,521 @@
+/** @file  psMemory.c
+ *
+ *  @brief Contains the definitions for the memory management system
+ *
+ *  psMemory.h has additional information and documentation of the routines found in this file.
+ *
+ *  @author Robert DeSonia, MHPCC
+ *  @author Robert Lupton, Princeton University
+ *
+ *  @version $Revision: 1.24 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-04 23:46:48 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#define PS_ALLOW_MALLOC                 // we're allowed to call malloc()
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "psMemory.h"
+#include "psError.h"
+#include "psAbort.h"
+#include "psLogMsg.h"
+
+#define P_PS_MEMMAGIC (void *)0xdeadbeef // Magic number in psMemBlock header
+
+static int checkMemBlock(const psMemBlock *m, const char* funcName);
+static psMemBlock *lastMemBlockAllocated = NULL;
+pthread_mutex_t   memBlockListMutex = PTHREAD_MUTEX_INITIALIZER;
+pthread_mutex_t   memIdMutex = PTHREAD_MUTEX_INITIALIZER;
+
+/**
+ * Unique ID for allocated blocks
+ */
+static psMemoryId memid = 0;
+
+/**
+ *  Default memExhausted callback.
+ */
+static void *memExhaustedCallbackDefault(size_t size)
+{
+    return NULL;
+}
+
+static psMemExhaustedCallback memExhaustedCallback = memExhaustedCallbackDefault;
+
+psMemExhaustedCallback psMemExhaustedCallbackSet(psMemExhaustedCallback func)
+{
+    psMemExhaustedCallback old = memExhaustedCallback;
+
+    if (func != NULL) {
+        memExhaustedCallback = func;
+    } else {
+        memExhaustedCallback = memExhaustedCallbackDefault;
+    }
+
+    return old;
+}
+
+static void memProblemCallbackDefault(const psMemBlock *ptr,
+                                      const char *file, int lineno)
+{
+    if (ptr->refCounter < 1) {
+        psError(__func__,
+                "Block %ld allocated at %s:%d freed more than once at %s:%d\n",
+                ptr->id, ptr->file, ptr->lineno, file, lineno);
+    }
+
+    if (lineno > 0) {
+        psAbort(__func__, "Detected a problem in the memory system at %s:%d", file, lineno);
+    }
+}
+static psMemProblemCallback memProblemCallback = memProblemCallbackDefault;
+
+psMemProblemCallback psMemProblemCallbackSet(psMemProblemCallback func)
+{
+    psMemProblemCallback old = memProblemCallback;
+
+    if (func != NULL) {
+        memProblemCallback = func;
+    } else {
+        memProblemCallback = memProblemCallbackDefault;
+    }
+
+    return old;
+}
+/*
+ * And now the I-want-to-be-informed callbacks
+ *
+ * Call the callbacks when these IDs are allocated/freed
+ */
+psMemoryId p_psMemAllocateID = 0;  // notify user this block is allocated
+psMemoryId p_psMemFreeID = 0;   // notify user this block is freed
+
+psMemoryId psMemAllocateCallbackSetID(psMemoryId id) // set p_psMemAllocateID to id
+{
+    psMemoryId old = p_psMemAllocateID;
+    p_psMemAllocateID = id;
+
+    return old;
+}
+
+psMemoryId psMemFreeCallbackSetID(psMemoryId id)  // set p_psMemFreeID to id
+{
+    psMemoryId old = p_psMemFreeID;
+    p_psMemFreeID = id;
+
+    return old;
+}
+
+/*
+ * Default callback for both allocate and free. Note that the
+ * value of p_psMemAllocateID/p_psMemFreeID is incremented
+ * by the return value (so returning 0 means that the callback
+ * isn't resignalled)
+ */
+static psMemoryId memAllocateCallbackDefault(const psMemBlock *ptr)
+{
+    static psMemoryId incr = 0;  // "p_psMemAllocateID += incr"
+
+    return incr;
+}
+
+static psMemoryId memFreeCallbackDefault(const psMemBlock *ptr)
+{
+    static psMemoryId incr = 0;  // "p_psMemFreeID += incr"
+
+    return incr;
+}
+
+/*
+ * The default callbacks, and the routines to change them
+ */
+static psMemAllocateCallback memAllocateCallback = memAllocateCallbackDefault;
+static psMemFreeCallback memFreeCallback = memFreeCallbackDefault;
+
+psMemAllocateCallback psMemAllocateCallbackSet(psMemAllocateCallback func)
+{
+    psMemFreeCallback old = memAllocateCallback;
+
+    if (func != NULL) {
+        memAllocateCallback =  func;
+    } else {
+        memAllocateCallback = memAllocateCallbackDefault;
+    }
+
+    return old;
+}
+
+psMemFreeCallback psMemFreeCallbackSet(psMemFreeCallback func)
+{
+    psMemFreeCallback old = memFreeCallback;
+
+    if (func != NULL) {
+        memFreeCallback = func;
+    } else {
+        memFreeCallback = memFreeCallbackDefault;
+    }
+
+    return old;
+}
+
+/*
+ * Return memory ID counter for next block to be allocated
+ */
+psMemoryId psMemGetId(void)
+{
+    psMemoryId id;
+    pthread_mutex_lock(&memIdMutex);
+    id = memid + 1;
+    pthread_mutex_unlock(&memIdMutex);
+
+    return id;
+}
+
+/*
+ * Routines to check the consistency of the allocated and/or free memory arena
+ *
+ * N.b. If the block wasn't allocated by psAlloc, it will appear corrupted
+ */
+#define ALIGNED(P) ((void *)((long)(P) & ~03) == (P))
+
+static int
+checkMemBlock(const psMemBlock *m,
+              const char* funcName)
+{
+    // n.b. since this is called by psMemCheckCorruption while the memblock list is mutex locked,
+    // we shouldn't call such things as p_psAlloc/p_psFree here.
+
+    if (m == NULL) {
+        psError(funcName,"Memory Corruption: NULL memory block found.");
+        return(1);
+    }
+
+    if (!ALIGNED(m)) {
+        psError(funcName, "psMemCheckCorruption: non-aligned memory block");
+        return(1);
+    }
+
+    if (m->startblock != P_PS_MEMMAGIC || m->endblock != P_PS_MEMMAGIC) {
+        psError(funcName, "psMemCheckCorruption: memory block %ld is corrupted (buffer underflow)",
+                m->id);
+        return(1);
+    }
+    if (*(void**)((int8_t*)(m+1)+m->userMemorySize) != P_PS_MEMMAGIC) {
+        psError(funcName, "psMemCheckCorruption: memory block %ld is corrupted (buffer overflow)",
+                m->id);
+        return(1);
+    }
+
+    return(0);
+}
+
+int psMemCheckCorruption(int abort_on_error)
+{
+    int nbad = 0;                       // number of bad blocks
+
+    // get exclusive access to the memBlock list to avoid it changing on us while we use it.
+    pthread_mutex_lock(&memBlockListMutex);
+
+    for (psMemBlock* iter=lastMemBlockAllocated; iter != NULL; iter=iter->nextBlock) {
+        if (checkMemBlock(iter, __func__)) {
+            nbad++;
+
+            memProblemCallback(iter, __func__, __LINE__);
+
+            if (abort_on_error) {
+                // release the lock on the memblock list
+                pthread_mutex_unlock(&memBlockListMutex);
+                psAbort(__func__, "Detected memory corruption");
+                return nbad;
+            }
+        }
+    }
+
+    // release the lock on the memblock list
+    pthread_mutex_unlock(&memBlockListMutex);
+    return nbad;
+}
+
+void *p_psAlloc(size_t size, const char *file, int lineno)
+{
+    psMemBlock *ptr = malloc(sizeof(psMemBlock) + size + sizeof(void*));
+
+    if (ptr == NULL) {
+        ptr = memExhaustedCallback(size);
+        if (ptr == NULL) {
+            psAbort(__func__, "Failed to allocate %u bytes at %s:%d",
+                    size, file, lineno);
+        }
+    }
+
+    // increment the memory id safely.
+    pthread_mutex_lock(&memBlockListMutex);
+    *(psMemoryId*)&ptr->id = ++memid;
+    pthread_mutex_unlock(&memBlockListMutex);
+
+    ptr->file = file;
+    *(unsigned int*)&ptr->lineno = lineno;
+    ptr->startblock = P_PS_MEMMAGIC;
+    ptr->endblock = P_PS_MEMMAGIC;
+    ptr->userMemorySize = size;
+    *(void**)((int8_t*)(ptr+1)+size) = P_PS_MEMMAGIC;
+    ptr->previousBlock = NULL;
+
+    pthread_mutex_init(&ptr->refCounterMutex, NULL);
+    ptr->refCounter = 1;                // one user so far
+
+    // need exclusive access of the memory block list now...
+    pthread_mutex_lock(&memBlockListMutex);
+
+    // insert the new block to the front of the memBlock linked-list
+    ptr->nextBlock = lastMemBlockAllocated;
+    if (ptr->nextBlock != NULL) {
+        ptr->nextBlock->previousBlock = ptr;
+    }
+    lastMemBlockAllocated = ptr;
+
+    pthread_mutex_unlock(&memBlockListMutex);
+
+    //  Did the user ask to be informed about this allocation?
+    if (ptr->id == p_psMemAllocateID) {
+        p_psMemAllocateID += memAllocateCallback(ptr);
+    }
+
+    // And return the user the memory that they allocated
+    return ptr + 1;   // user memory
+}
+
+void *p_psRealloc(void *vptr, size_t size, const char *file, int lineno)
+{
+    if (vptr == NULL) {
+        return p_psAlloc(size, file, lineno);
+    } else {
+        psMemBlock *ptr = ((psMemBlock *)vptr) - 1;
+        bool isBlockLast = false;
+
+        pthread_mutex_lock(&memBlockListMutex);
+
+        isBlockLast = (ptr == lastMemBlockAllocated);
+
+        ptr = (psMemBlock*)realloc(ptr, sizeof(psMemBlock) + size + sizeof(void*));
+
+        if (ptr == NULL) {
+            psAbort(__func__, "Failed to reallocate %ld bytes at %s:%d",
+                    size, file, lineno);
+        }
+
+        ptr->userMemorySize = size;
+        *(void**)((int8_t*)(ptr+1)+size) = P_PS_MEMMAGIC;
+
+        if (isBlockLast) {
+            lastMemBlockAllocated = ptr;
+        }
+
+        // the block location may have changed, so fix the linked list addresses.
+        if (ptr->nextBlock != NULL) {
+            ptr->nextBlock->previousBlock = ptr;
+        }
+        if (ptr->previousBlock != NULL) {
+            ptr->previousBlock->nextBlock = ptr;
+        }
+
+        pthread_mutex_unlock(&memBlockListMutex);
+
+        //  Did the user ask to be informed about this allocation?
+        if (ptr->id == p_psMemAllocateID) {
+            p_psMemAllocateID += memAllocateCallback(ptr);
+        }
+
+        return ptr + 1;   // usr memory
+    }
+}
+
+void p_psFree(void *vptr, const char *file, int lineno)
+{
+    if (vptr == NULL) {
+        return;
+    }
+
+    psMemBlock *ptr = ((psMemBlock *)vptr) - 1;
+
+    if (checkMemBlock(ptr, __func__) != 0) {
+        memProblemCallback(ptr, file, lineno); // we may not own this block; don't free it
+    }
+
+    psMemDecrRefCounter(vptr);          // this handles the free, if required.
+}
+
+/*
+ * Check for memory leaks. Not production quality code
+ */
+int psMemCheckLeaks(
+    psMemoryId id0,                     // don't list blocks with id < id0
+    psMemBlock ***arr,                  // pointer to array of pointers to leaked blocks, or NULL
+    FILE *fd)                           // print list of leaks to fd (or NULL)
+{
+    int nleak = 0;
+    int j = 0;
+    psMemBlock* topBlock = lastMemBlockAllocated;
+
+    pthread_mutex_lock(&memBlockListMutex);
+
+    for (psMemBlock* iter = topBlock; iter != NULL; iter=iter->nextBlock)
+    {
+        if ( (psMemGetRefCounter(iter+1) > 0) && (iter->id >= id0) ) {
+            nleak++;
+
+            if (fd != NULL) {
+                if (nleak == 1) {
+                    fprintf(fd, "   %20s:line ID\n", "file");
+                }
+
+                fprintf(fd, "   %20s:%-4d %ld\n", iter->file, iter->lineno, iter->id);
+            }
+        }
+    }
+
+    pthread_mutex_unlock(&memBlockListMutex);
+
+    if (nleak == 0 || arr == NULL)
+    {
+        return nleak;
+    }
+
+    *arr = p_psAlloc(nleak*sizeof(psMemBlock), __FILE__, __LINE__);
+    pthread_mutex_lock(&memBlockListMutex);
+
+    for (psMemBlock* iter = topBlock; iter != NULL; iter=iter->nextBlock)
+    {
+        if ( (psMemGetRefCounter(iter+1) > 0) && (iter->id >= id0) ) {
+            (*arr)[j++] = iter;
+            if (j == nleak) { // found them all
+                break;
+            }
+        }
+    }
+
+    pthread_mutex_unlock(&memBlockListMutex);
+
+    return nleak;
+}
+
+/*
+ * Reference counting APIs
+ */
+psReferenceCount psMemGetRefCounter(void *vptr) // return refCounter
+{
+    psMemBlock *ptr;
+    unsigned int refCount;
+
+    if (vptr == NULL)
+    {
+        return 0;
+    }
+
+    ptr = ((psMemBlock *)vptr) - 1;
+
+    if (checkMemBlock(ptr, __func__) != 0)
+    {
+        memProblemCallback(ptr, __func__, __LINE__);
+    }
+
+    pthread_mutex_lock(&ptr->refCounterMutex);
+    refCount = ptr->refCounter;
+    pthread_mutex_unlock(&ptr->refCounterMutex);
+
+    return refCount;
+}
+
+void *psMemIncrRefCounter(void *vptr) // increment and return refCounter
+{
+    psMemBlock *ptr;
+
+    if (vptr == NULL)
+    {
+        return vptr;
+    }
+
+    ptr = ((psMemBlock *)vptr) - 1;
+
+    if (checkMemBlock(ptr, __func__))
+    {
+        memProblemCallback(ptr, __func__, __LINE__);
+    }
+
+    pthread_mutex_lock(&ptr->refCounterMutex);
+    ptr->refCounter++;
+    pthread_mutex_unlock(&ptr->refCounterMutex);
+
+    return vptr;
+}
+
+void *psMemDecrRefCounter(void *vptr) // decrement and return refCounter
+{
+    if (vptr == NULL)
+    {
+        return NULL;
+    }
+
+    psMemBlock *ptr = ((psMemBlock *)vptr) - 1;
+
+
+    pthread_mutex_lock(&ptr->refCounterMutex);
+
+    if (ptr->refCounter > 1)
+    {
+        /// XXX - Probably should have another mutex here.
+        ptr->refCounter--;          // multiple references, just decrement the count.
+        pthread_mutex_unlock(&ptr->refCounterMutex);
+
+    } else
+    {
+        pthread_mutex_unlock(&ptr->refCounterMutex);
+
+        // Did the user ask to be informed about this deallocation?
+        if (ptr->id == p_psMemFreeID) {
+            p_psMemFreeID += memFreeCallback(ptr);
+        }
+
+        pthread_mutex_lock(&memBlockListMutex);
+
+        // cut the memBlock out of the memBlock list
+        if (ptr->nextBlock != NULL) {
+            ptr->nextBlock->previousBlock = ptr->previousBlock;
+        }
+        if (ptr->previousBlock != NULL) {
+            ptr->previousBlock->nextBlock = ptr->nextBlock;
+        }
+        if (lastMemBlockAllocated == ptr) {
+            lastMemBlockAllocated = ptr->nextBlock;
+        }
+
+        pthread_mutex_unlock(&memBlockListMutex);
+
+        pthread_mutex_destroy(&ptr->refCounterMutex);
+
+        free(ptr);
+
+        vptr = NULL;    // since we freed it, make sure we return NULL.
+    }
+
+    return vptr;
+}
+
+void p_psCustomFree(psFreeFcn fcn, void* ptr)
+{
+
+    if (fcn == NULL) {
+        return;
+    } else {
+        if (fcn == PS_FREE) {
+            psFree(ptr);
+        } else {
+            fcn(ptr);
+        }
+    }
+}
Index: /tags/rel1_1/psLib/src/sysUtils/psMemory.d
===================================================================
--- /tags/rel1_1/psLib/src/sysUtils/psMemory.d	(revision 1056)
+++ /tags/rel1_1/psLib/src/sysUtils/psMemory.d	(revision 1056)
@@ -0,0 +1,1 @@
+psMemory.o psMemory.d : psMemory.c psMemory.h psError.h psAbort.h psLogMsg.h
Index: /tags/rel1_1/psLib/src/sysUtils/psMemory.h
===================================================================
--- /tags/rel1_1/psLib/src/sysUtils/psMemory.h	(revision 1056)
+++ /tags/rel1_1/psLib/src/sysUtils/psMemory.h	(revision 1056)
@@ -0,0 +1,309 @@
+#if !defined(PS_MEMORY_H)
+#define PS_MEMORY_H
+/** @file  psMemory.h
+ *
+ *  @brief Contains the definitions for the memory management system
+ *
+ *  This is the generic memory management system put inbetween the user's high level code and the OS-level
+ *  memory allocation routines.  This system adds such features as callback routines for memory error events,
+ *  tracing capabilities, and reference counting.
+ *
+ *  @author Robert DeSonia, MHPCC
+ *  @author Robert Lupton, Princeton University
+ *
+ *  @ingroup MemoryManagement
+ *
+ *  @version $Revision: 1.18 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-10 02:09:57 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include <stdio.h>                      // needed for FILE
+#include <pthread.h>                    // we need a mutex to make this stuff thread safe.
+
+/** @addtogroup MemoryManagement
+ *  @{
+ */
+
+/**
+ *  @addtogroup memCallback Memory Callbacks
+ *
+ *  Routines dealing with the creating and setting of memory management callback functions.
+ */
+
+/**
+ *  @addtogroup memTracing Memory Tracing
+ *
+ *  Routines dealing with memory tracing and corruption checking.
+ */
+
+/**
+ *  @addtogroup memRefCount Reference Count
+ *
+ *  Routines dealing with the reference counting of allocated buffers.
+ */
+
+/// typedef for memory identification numbers.  Guaranteed to be some variety of integer.
+typedef unsigned long psMemoryId;
+
+/// typedef for a memory block's reference count. Guaranteed to be some variety of integer.
+typedef unsigned long psReferenceCount;
+
+/** Book-keeping data for storage allocator.
+ *  N.b. sizeof(psMemBlock) must be chosen such that if ptr is a pointer
+ *  returned by malloc, then ((char *)ptr + sizeof(psMemBlock)) is properly
+ *  aligned for all storage types.
+ */
+typedef struct psMemBlock
+{
+    const void* startblock;             ///< initialised to p_psMEMMAGIC
+    struct psMemBlock* previousBlock;   ///< previous block in allocation list
+    struct psMemBlock* nextBlock;       ///< next block allocation list
+    size_t  userMemorySize;             ///< the size of the user-portion of the memory block
+    const psMemoryId id;                ///< a unique ID for this allocation
+    const char* file;                   ///< set from __FILE__ in e.g. p_psAlloc
+    const int lineno;                   ///< set from __LINE__ in e.g. p_psAlloc
+    pthread_mutex_t   refCounterMutex;  ///< mutex to ensure exclusive access to reference counter
+    psReferenceCount refCounter;        ///< how many times pointer is referenced
+    const void* endblock;               ///< initialised to p_psMEMMAGIC
+}
+psMemBlock;
+
+/** prototype of a basic callback used by memory functions
+ *
+ *  @see psMemAllocateCallbackSet
+ *  @ingroup memCallback
+ */
+typedef psMemoryId (*psMemAllocateCallback)(
+    const psMemBlock *ptr           ///< the psMemBlock just allocated
+);
+
+/** prototype of memory free callback used by memory functions
+ *
+ *  @see psMemFreeCallbackSet
+ *  @ingroup memCallback
+ */
+typedef psMemoryId (*psMemFreeCallback)(
+    const psMemBlock *ptr           ///< the psMemBlock being freed
+);
+
+/** prototype of a callback used in error conditions
+ *
+ *  This callback should not try to call psAlloc or psFree.
+ *
+ *  @see psMemProblemCallbackSet
+ *  @ingroup memCallback
+ */
+typedef void (*psMemProblemCallback)(
+    const psMemBlock *ptr,          ///< the pointer to the problematic memory block.
+    const char *file,               ///< the file in which the problem originated
+    int lineno                      ///< the line number in which the problem originated
+);
+
+/** prototype of a callback function used when memory runs out
+ *
+ *  @return void* pointer to requested buffer of the size size_t, or NULL if memory could not
+ *          be found.
+ *
+ *  @see psMemExhaustedCallbackSet
+ *  @ingroup memCallback
+ */
+typedef void *(*psMemExhaustedCallback)(
+    size_t size                     //< the size of buffer required
+);
+
+typedef void (*psFreeFcn)(void* ptr);
+
+/** Memory allocation.  This operates much like malloc(), but is guaranteed to return a non-NULL value.
+ *
+ *  @return void* pointer to the allocated buffer. This will not be NULL.
+ *  @see psFree
+ */
+#ifdef DOXYGEN
+void* psAlloc(
+    size_t size                     ///< Size required
+);
+#else
+void* p_psAlloc(
+    size_t size,                    ///< Size required
+    const char *file,               ///< File of call
+    int lineno                      ///< Line number of call
+);
+/// Memory allocation. psAlloc sends file and line number to p_psAlloc.
+#define psAlloc(size) p_psAlloc(size, __FILE__, __LINE__)
+#endif
+
+
+/** Memory re-allocation.  This operates much like realloc(), but is guaranteed to return a non-NULL value.
+ *
+ *  @return void* pointer to resized buffer. This will not be NULL.
+ *  @see psAlloc, psFree
+ */
+#ifdef DOXYGEN
+void* psRealloc(void *ptr               ///< Pointer to re-allocate
+                size_t size,            ///< Size required
+               );
+#else
+void* p_psRealloc(void *ptr,            ///< Pointer to re-allocate
+                  size_t size,          ///< Size required
+                  const char *file,     ///< File of call
+                  int lineno            ///< Line number of call
+                 );
+
+/// Memory re-allocation.  psRealloc sends file and line number to p_psRealloc.
+#define psRealloc(ptr, size) p_psRealloc(ptr, size, __FILE__, __LINE__)
+
+#endif
+
+
+/** Free memory.  This operates much like free().
+ *
+ *  @see psAlloc, psRealloc
+ */
+#ifdef DOXYGEN
+void psFree(void *ptr,                  ///< Pointer to free, if NULL, function returns immediately.
+           );
+#else
+void p_psFree(void *ptr,                ///< Pointer to free
+              const char *file,         ///< File of call
+              int lineno                ///< Line number of call
+             );
+
+/// Free memory.  psFree sends file and line number to p_psFree.
+#define psFree(size) p_psFree(size, __FILE__, __LINE__)
+
+#endif
+
+/** Check for memory leaks.  This scans for allocated memory buffers not freed with an ID not less than id0.
+ *  This is used to check for memory leaks by:
+ *      -# before a block of code to be checked, store the current ID count via psGetMemId
+ *      -# after the block of code to be checked, call this function using the ID stored above.  If all
+ *         memory in the block that was allocated has been freed, this call should output nothing and
+ *         return 0.
+ *
+ *  If memory leaks are found, the Memory Problem callback will be called as well.
+ *
+ *  return int  number of memory blocks found as 'leaks', i.e., the number of currently allocated memory
+ *              blocks above id0 that have not been freed.
+ *  @see psAlloc, psFree, psgetMemId, psMemProblemCallbackSet
+ *  @ingroup memTracing
+ */
+int psMemCheckLeaks(
+    psMemoryId id0,              ///< don't list blocks with id < id0
+    psMemBlock ***arr,              ///< pointer to array of pointers to leaked blocks, or NULL
+    FILE *fd                        ///< print list of leaks to fd (or NULL)
+);
+
+/** Check for memory corruption.  Scans all currently allocated memory buffers and checks for corruptions,
+ *  i.e., invalid markers that signify a buffer under/overflow.
+ *
+ *  @ingroup memTracing
+ */
+int psMemCheckCorruption(
+    int abort_on_error              ///< Abort on detecting corruption?
+);
+
+/** Return reference counter
+ *
+ *  @ingroup memRefCount
+ */
+psReferenceCount psMemGetRefCounter(
+    void *vptr                      ///< Pointer to get refCounter for
+);
+
+/** Increment reference counter and return the pointer
+ *
+ *  @ingroup memRefCount
+ */
+void *psMemIncrRefCounter(
+    void *vptr                      ///< Pointer to increment refCounter, and return
+);
+
+/** Decrement reference counter and return the pointer
+ *
+ *  @ingroup memRefCount
+ */
+void *psMemDecrRefCounter(
+    void *vptr                      ///< Pointer to decrement refCounter, and return
+);
+
+/** Set callback for problems
+ *  @ingroup memCallback
+ */
+psMemProblemCallback psMemProblemCallbackSet(
+    psMemProblemCallback func       ///< Function to run
+);
+
+/** Set callback for out-of-memory
+ *
+ *  @ingroup memCallback
+ */
+psMemExhaustedCallback psMemExhaustedCallbackSet(
+    psMemExhaustedCallback func     ///< Function to run
+);
+
+/** Set call back for when a particular memory block is allocated
+ *
+ *  @ingroup memCallback
+ */
+psMemAllocateCallback psMemAllocateCallbackSet(
+    psMemAllocateCallback func          ///< Function to run
+);
+
+/** Set call back for when a particular memory block is freed
+ *
+ *  @ingroup memCallback
+ */
+psMemFreeCallback psMemFreeCallbackSet(
+    psMemFreeCallback func              ///< Function to run
+);
+
+/** get next memory ID
+ *
+ *  @ingroup memCallback
+ */
+psMemoryId psMemGetId(void);
+
+/** set p_psMemAllocateID to id
+ *
+ *  @ingroup memCallback
+ */
+psMemoryId psMemAllocateCallbackSetID(
+    psMemoryId id                       ///< ID to set
+);
+
+/** set p_psMemFreeID to id
+ *
+ *  @ingroup memCallback
+ */
+psMemoryId psMemFreeCallbackSetID(
+    psMemoryId id                       ///< ID to set
+);
+
+#define PS_FREE     (void*)1
+
+//@} End of Memory Management Functions
+
+
+#ifndef DOXYGEN
+
+void p_psCustomFree(psFreeFcn fcn,void* ptr);
+
+/*
+ * Ensure that any program using malloc/realloc/free will fail to compile
+ */
+#ifndef PS_ALLOW_MALLOC
+#ifdef __GNUC__
+#pragma GCC poison malloc realloc calloc free
+#else
+#define malloc(S)       _Pragma("error Use of malloc is not allowed.  Use psAlloc instead.")
+#define realloc(P,S)    _Pragma("error Use of realloc is not allowed.  Use psRealloc instead.")
+#define calloc(S)       _Pragma("error Use of calloc is not allowed.  Use psAlloc instead.")
+#define free(P)         _Pragma("error Use of free is not allowed.  Use psFree instead.")
+#endif
+#endif
+
+#endif // doxygen skip
+
+#endif // end of header file
Index: /tags/rel1_1/psLib/src/sysUtils/psString.c
===================================================================
--- /tags/rel1_1/psLib/src/sysUtils/psString.c	(revision 1056)
+++ /tags/rel1_1/psLib/src/sysUtils/psString.c	(revision 1056)
@@ -0,0 +1,97 @@
+/** @file  psString.c
+ *
+ *  @brief Contains the definition of string utility functions
+ *
+ *  String utility functions defined shall provide basic string copying
+ *  capabilities while using the preferred memory management utilities.
+ *
+ *  @author Eric Van Alst, MHPCC
+ *   
+ *  @version $Revision: 1.5 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-05-10 23:37:36 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+/******************************************************************************/
+/*  INCLUDE FILES                                                             */
+/******************************************************************************/
+#include <stdlib.h>
+#include <string.h>
+#include "psString.h"
+#include "psMemory.h"
+#include "psError.h"
+
+/******************************************************************************/
+/*  DEFINE STATEMENTS                                                         */
+/******************************************************************************/
+
+// None
+
+/******************************************************************************/
+/*  TYPE DEFINITIONS                                                          */
+/******************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  GLOBAL VARIABLES                                                         */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  FILE STATIC VARIABLES                                                    */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  FUNCTION IMPLEMENTATION - LOCAL                                          */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/* FUNCTION IMPLEMENTATION - PUBLIC                                          */
+/*****************************************************************************/
+
+char *psStringCopy(
+    const char*  str
+)
+{
+    // Allocate memory using psAlloc function
+    // Copy input string to memory just allocated
+    // Return the copy
+    return strcpy(psAlloc(strlen(str) + 1), str);
+}
+
+char *psStringNCopy(
+    const char*  str,
+    int          nChar
+)
+{
+    char *returnValue = NULL;
+
+    // Check the number of characters to copy is non-negative
+    if ( nChar < 0 ) {
+        // Log error message and return NULL
+        psError(__FILE__,"psStringNCopy with negative count specified %d",
+                nChar);
+        return NULL;
+    }
+    // Allocate memory using psAlloc function - nChar bytes
+    // Copy input string to memory allocated up to nChar characters
+    // Return the copy
+    returnValue = strncpy(psAlloc((size_t)nChar + 1), str, (size_t)nChar);
+
+    // Ensure the last byte is NULL character
+    if ( nChar > 0 ) {
+        returnValue[nChar-1] = '\0';
+    }
+
+    // Return the string pointer
+    return returnValue;
+}
+
+
Index: /tags/rel1_1/psLib/src/sysUtils/psString.d
===================================================================
--- /tags/rel1_1/psLib/src/sysUtils/psString.d	(revision 1056)
+++ /tags/rel1_1/psLib/src/sysUtils/psString.d	(revision 1056)
@@ -0,0 +1,1 @@
+psString.o psString.d : psString.c psString.h psMemory.h psError.h
Index: /tags/rel1_1/psLib/src/sysUtils/psString.h
===================================================================
--- /tags/rel1_1/psLib/src/sysUtils/psString.h	(revision 1056)
+++ /tags/rel1_1/psLib/src/sysUtils/psString.h	(revision 1056)
@@ -0,0 +1,78 @@
+/** @file  psString.h
+ *
+ *  @brief Contains the declarations of string utility functions
+ *
+ *  @ingroup SysUtils
+ *
+ *  String utility functions defined shall provide basic string copying
+ *  capabilities.
+ *
+ *  @author Eric Van Alst, MHPCC
+ *
+ *  @version $Revision: 1.5 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-10 01:58:06 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PS_STRING_H
+#define PS_STRING_H
+
+/******************************************************************************/
+/*  DEFINE STATEMENTS                                                         */
+/******************************************************************************/
+
+/** This macro will convert the arguement to a quoted string */
+#define PS_STRING(S)  #S
+
+/******************************************************************************/
+/*  TYPE DEFINITIONS                                                          */
+/******************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/* FUNCTION PROTOTYPES                                                       */
+/*****************************************************************************/
+
+// Doxygen group tags
+/** @addtogroup SysUtils
+ *  @{
+ */
+
+/** Copies the input string
+ *
+ *  This function shall allocate memory to the length of the input string
+ *  plus one and copy the input string to the newly allocated memory.
+ *
+ *  @return  char* Copy of input string
+ *
+ */
+char *psStringCopy(
+    const char *str      /**< Input string of characters to copy */
+);
+
+
+/** Copies the input string up to the specified number of characters
+ *
+ *  This function shall allocate memory to the length specified by nChar
+ *  plus one and copy the input string to the newly allocated memory.
+ *  This function will only copy nChar bytes from the input to new string,
+ *  so if the input string is larger than nChar characters the copied
+ *  string will be a substring of the input string.  If the input string
+ *  is smaller than nChar bytes then the remaining bytes allocated will
+ *  be set to NULL.
+ *
+ *  @return  char* Copy of input string
+ *
+ */
+/*@null@*/
+char *psStringNCopy(
+    const char *str,    /**< Input string of characters to copy */
+    int        nChar    /**< Number of bytes to allocate for string copy */
+);
+
+/* @} */  // Doxygen - End of SystemGroup Functions
+
+#endif
+
Index: /tags/rel1_1/psLib/src/sysUtils/psTrace.c
===================================================================
--- /tags/rel1_1/psLib/src/sysUtils/psTrace.c	(revision 1056)
+++ /tags/rel1_1/psLib/src/sysUtils/psTrace.c	(revision 1056)
@@ -0,0 +1,415 @@
+/** @file psTrace.c
+ *  \brief basic run-time trace facilities
+ *  \ingroup LogTrace
+ *
+ *  This file will hold the code for procedures to insert
+ *  trace messages into the code.
+ *
+ *  @author Robert Lupton, Princeton University
+ *  @author George Gusciora, MHPCC
+ *
+ *  @version $Revision: 1.9 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-12 05:50:01 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+/*****************************************************************************
+    NOTES:
+ In the SRD, higher trace levels correspond to a numerically lower trace
+ value in the code.  This is a bit confusing.  For example, a high-level
+ message might be something like "Begin Processing".  The module programmer
+ might give that a numerically low trace level, such as 1, so then any
+ non-zero trace level in that code component will display thatmessage.
+ 
+ We build a tree of trace components.  Every node in the tree has a
+ depth, which is it's distance from the root.  However, this is not
+ not the same thing as a node's "level", which corresponds to the
+ trace level of that node.
+ 
+ I added a function psTraceFree() which frees all nodes in the trace component
+ tree.  Previously, there had been no function in the API which accomplished
+ this purpose.
+ *****************************************************************************/
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include "psMemory.h"
+#include "psTrace.h"
+#include "psString.h"
+#include "psError.h"
+
+static Component *p_psCroot = NULL;       // The root of the trace component
+static FILE *p_psTraceFP = NULL;          // File destination for messages.
+/*****************************************************************************
+componentAlloc(): allocate memory for a new node, and initialize members.
+ *****************************************************************************/
+Component *componentAlloc(const char *name,
+                          int level)
+{
+    Component *comp = psAlloc(sizeof(Component));
+    comp->name = psStringCopy(name);
+    comp->level = level;
+    comp->n = 0;
+    comp->subcomp = NULL;
+    return comp;
+}
+
+
+/*****************************************************************************
+componentFree(): free the current node in the root tree, and all children
+nodes as well.
+ *****************************************************************************/
+static void componentFree(Component *comp)
+{
+    if (comp == NULL) {
+        return;
+    }
+
+    if (comp->subcomp != NULL) {
+        for (int i = 0; i < comp->n; i++) {
+            componentFree(comp->subcomp[i]);
+        }
+        psFree(comp->subcomp);
+    }
+
+    psFree((char *)comp->name);
+    psFree(comp);
+}
+
+
+/*****************************************************************************
+initTrace(): simply initialize the component root tree.
+*****************************************************************************/
+static void initTrace(void)
+{
+    if (p_psCroot == NULL) {
+        p_psCroot = componentAlloc(".", DEFAULT_TRACE_LEVEL);
+    }
+}
+
+
+/*****************************************************************************
+Set all trace levels to zero.
+ *****************************************************************************/
+void p_psTraceReset(Component *currentNode)
+{
+    int i = 0;
+
+    if (NULL == currentNode) {
+        return;
+    }
+
+    currentNode->level = 0;
+    for (i=0;i<currentNode->n;i++) {
+        if (NULL == currentNode->subcomp[i]) {
+            psError(__func__,
+                    "Sub-component %d of node %s in the trace tree is NULL.\n",
+                    i, currentNode->name);
+        } else {
+            p_psTraceReset(currentNode->subcomp[i]);
+        }
+    }
+    return;
+}
+
+/*****************************************************************************
+Set all trace levels to zero.
+ *****************************************************************************/
+void psTraceReset()
+{
+    p_psTraceReset(p_psCroot);
+}
+
+
+/*****************************************************************************
+Free all nodes in the component tree.
+ *****************************************************************************/
+void psTraceFree()
+{
+    componentFree(p_psCroot);
+}
+
+
+/*****************************************************************************
+componentAdd(): Adds the component named "addNodeName" to the root tree.
+ 
+NOTE: replace the call to strsep() with a call to strtok(), which conforms
+to ANSI-C.
+ *****************************************************************************/
+static void componentAdd(const char *addNodeName,
+                         int         level)
+{
+    int        i = 0;                         // Loop index variable.
+    char       name[strlen(addNodeName) + 1]; // buffer for writeable copy.
+    char      *pname=name;
+    char      *firstComponent = NULL;       // first component of name
+    Component *currentNode = p_psCroot;
+    int        nodeExists = 0;
+
+    // Is this the root node?  If so, simply set level and return.
+    if (strcmp(".", addNodeName) == 0) {
+        p_psCroot->level = level;
+        return;
+    }
+
+    if (addNodeName[0] != '.') {
+        printf("ERROR: failed to add %s to the root component tree.\n",
+               addNodeName);
+        exit(1);
+    }
+
+    strcpy(name, addNodeName);
+    pname = &name[1];
+    // Iterate through the components of addNodeName.  Strip off the first
+    // component of the name, find that in the root tree, or add it if it
+    // does not exist, then move to the next component in the name.
+
+    while (pname != NULL) {
+        firstComponent = strsep(&pname, ".");
+        nodeExists = 0;
+        for (i = 0; i < currentNode->n; i++) {
+            if (strcmp(currentNode->subcomp[i]->name, firstComponent) == 0) {
+                currentNode = currentNode->subcomp[i];
+                nodeExists = 1;
+                if (pname == NULL) {
+                    currentNode->level = level;
+                }
+            }
+        }
+
+        if (nodeExists == 0) {
+            currentNode->subcomp = psRealloc(currentNode->subcomp,
+                                             (currentNode->n + 1) * sizeof(Component *));
+            currentNode->n = (currentNode->n)+1;
+
+            currentNode->subcomp[(currentNode->n)-1] =
+                componentAlloc(firstComponent, level);
+        }
+    }
+}
+
+
+/*****************************************************************************
+    psSetTraceLevel(): add the component named "comp" to the component tree,
+ if it is not already there, and set it's trace level to "level".
+    Input:
+ comp
+ level
+    Output:
+ none
+    Returns:
+ zero
+*****************************************************************************/
+int psTraceSetLevel(const char *comp,   // component of interest
+                    int level)          // desired trace level
+{
+    // If the root component tree does not exist, then initialize it.
+    if (p_psCroot == NULL) {
+        initTrace();
+    }
+
+    // Add the new component to the component tree.
+    componentAdd(comp, level);
+
+    // return 0 on success.
+    return 0;
+}
+
+
+/*****************************************************************************
+    doGetTraceLevel()
+ This function recursively searches the root component tree for the
+ component named "name", which is supplied by a parameter.  If it
+ finds that component, it returns the level of that component.
+ Otherwise, it returns ???.
+ 
+    Inputs:
+ name:
+    Outputs:
+ none
+    Returns:
+ The trace level of the "name" component.
+ *****************************************************************************/
+static int doGetTraceLevel(const char *aname)
+{
+    char       name[strlen(aname) + 1]; // need a writeable copy: for strsep()
+    char      *pname=name;
+    char      *firstComponent = NULL;   // first component of name
+    Component *currentNode = p_psCroot;
+    int        i = 0;
+
+    if (NULL == currentNode) {
+        return(UNKNOWN_TRACE_LEVEL);
+    }
+
+    if (strcmp(".", aname) == 0) {
+        return(p_psCroot->level);
+    }
+
+    if (aname[0] != '.') {
+        return(UNKNOWN_TRACE_LEVEL);
+    }
+
+    strcpy(name, aname);
+    pname = &name[1];
+    while (pname != NULL) {
+        firstComponent = strsep(&pname, ".");
+        for (i = 0; i < currentNode->n; i++) {
+            if (NULL == currentNode->subcomp[i]) {
+                psError(__func__,
+                        "Sub-component %d of node %s in trace tree is NULL.\n",
+                        i, currentNode->name);
+            }
+
+            if (strcmp(currentNode->subcomp[i]->name, firstComponent) == 0) {
+                currentNode = currentNode->subcomp[i];
+                if (pname == NULL) {
+                    return(currentNode->level);
+                }
+            }
+        }
+    }
+    return(UNKNOWN_TRACE_LEVEL);
+}
+
+
+/*****************************************************************************
+    psGetTraceLevel()
+ Return a trace level of "name" in the root component tree.  If the
+ exact string of components in "name" does not exist in the root
+ tree, we return the deepest level of the match.
+    Input:
+ name
+    Output:
+ none
+    Return:
+ The level of "name" in the root component tree.
+ *****************************************************************************/
+int psTraceGetLevel(const char *name)
+{
+    if (p_psCroot == NULL) {
+        return(UNKNOWN_TRACE_LEVEL);
+    }
+
+    // Search the component root tree, determine the trace level.
+    return(doGetTraceLevel(name));
+}
+
+
+/*****************************************************************************
+    doPrintTraceLevels()
+ This function recursively searches the component tree supplied by the
+ parameter "comp" and prints the name and level of each component.
+    Inputs:
+ comp: a node in the component tree.
+ level: the level of that node
+    Outputs:
+ none
+    Returns:
+ null
+ *****************************************************************************/
+static void doPrintTraceLevels(const Component *comp,
+                               int depth)
+{
+    int i = 0;
+
+    if (comp->name[0] == '\0') {
+        printf("%*s%-*s %d\n", depth, "", 20 - depth,
+               "(root)", (comp->level == UNKNOWN_TRACE_LEVEL) ? 0 : comp->level);
+    } else {
+        if (comp->level == UNKNOWN_TRACE_LEVEL) {
+            printf("%*s%-*s %s\n", depth, "", 20 - depth,
+                   comp->name, ".");
+        } else {
+            printf("%*s%-*s %d\n", depth, "", 20 - depth,
+                   comp->name, comp->level);
+        }
+    }
+
+    for (i = 0; i < comp->n; i++) {
+        doPrintTraceLevels(comp->subcomp[i], depth+1);
+    }
+}
+
+
+/*****************************************************************************
+psPrintTraceLevels(): Simply print all the trace levels in the trace level
+component tree.
+Inputs:
+ none
+Outputs:
+ none
+Returns:
+ null
+*****************************************************************************/
+void psTracePrintLevels(void)
+{
+    if (p_psCroot == NULL) {
+        return;
+    }
+
+    doPrintTraceLevels(p_psCroot, 0);
+}
+
+
+/*****************************************************************************
+p_psTrace(): we display the trace message to standard output if the trace
+level of that message, supplied by the parameter "level" is higher than the
+trace level that is currently associated with the component named by the
+parameter "comp".
+Input:
+ comp
+ level
+ ...  a printf-style output string.
+Output:
+ none
+Return:
+ null
+ *****************************************************************************/
+void p_psTrace(const char *comp,        // component being traced
+               int level,               // desired trace level
+               ...)                     // arguments
+{
+    char *fmt = NULL;
+    va_list ap;
+    int i = 0;
+
+    if (NULL == comp) {
+        psError(__func__,
+                "p_psTrace() called on a NULL trace level tree\n");
+    }
+
+    // Only display this message if it's trace level is less than the level
+    // of it's associatedcomponent.
+    if (level <= psTraceGetLevel(comp)) {
+        va_start(ap, level);
+
+        // The following functions get the variable list of parameters with
+        // which this function was called, and print them to the standard
+        // output.
+        fmt = va_arg(ap, char *);
+
+        if (p_psTraceFP != NULL) {
+            // We indent each message one space for each level of the message.
+            for (i = 0; i < level; i++) {
+                fprintf(p_psTraceFP, " ");
+            }
+            vfprintf(p_psTraceFP, fmt, ap);
+        } else {
+            // We indent each message one space for each level of the message.
+            for (i = 0; i < level; i++) {
+                putchar(' ');
+            }
+            vprintf(fmt, ap);
+        }
+        va_end(ap);
+    }
+
+    // NOTE: should we free *fmt as well?  Read the man page.
+}
+
+void psTraceSetDestination(FILE *fp)
+{
+    p_psTraceFP = fp;
+}
Index: /tags/rel1_1/psLib/src/sysUtils/psTrace.d
===================================================================
--- /tags/rel1_1/psLib/src/sysUtils/psTrace.d	(revision 1056)
+++ /tags/rel1_1/psLib/src/sysUtils/psTrace.d	(revision 1056)
@@ -0,0 +1,1 @@
+psTrace.o psTrace.d : psTrace.c psMemory.h psTrace.h psString.h psError.h
Index: /tags/rel1_1/psLib/src/sysUtils/psTrace.h
===================================================================
--- /tags/rel1_1/psLib/src/sysUtils/psTrace.h	(revision 1056)
+++ /tags/rel1_1/psLib/src/sysUtils/psTrace.h	(revision 1056)
@@ -0,0 +1,85 @@
+/** @file psTrace.h
+ *  \brief basic run-time trace facilities
+ *  \ingroup LogTrace
+ *
+ *  This file will hold the prototypes for defining procedures to insert
+ *  trace messages into the code.
+ *
+ *  @author Robert Lupton, Princeton University
+ *  @author George Gusciora, MHPCC
+ *
+ *  @version $Revision: 1.8 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-12 05:50:01 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+#if !defined(PS_TRACE_H)
+#define PS_TRACE_H 1
+#define UNKNOWN_TRACE_LEVEL -9999         // we don't know this name's level
+#define DEFAULT_TRACE_LEVEL 0
+
+/** Basic structure for the component tree.  A component is a string of the
+    form aaa.bbb.ccc, and may itself contain further subcomponents.  The
+    Component structure doesn't in fact contain it's full name, but only the
+    last part. */
+typedef struct Component
+{
+    const char *name;                     // last part of name of component
+    int level;                            // trace level for this component
+    int n;                                // number of subcomponents
+    struct Component **subcomp;           // next level of subcomponents
+}
+Component;
+
+/** \addtogroup LogTrace
+ *  \{
+ */
+
+/** Functions **************************************************************/
+
+#ifndef DOXYGEN
+/// Send a trace message
+void p_psTrace(const char *facil,  ///< facilty of interest
+               int myLevel,  ///< desired trace level
+               ...)   ///< trace message arguments
+;
+#endif
+
+/// Set trace level
+int psTraceSetLevel(const char *facil, ///< facilty of interest
+                    int level)  ///< desired trace level
+;
+
+/// Get the trace level
+int psTraceGetLevel(const char *facil) ///< facilty of interest
+;
+
+/// Set all trace levels to zero (do not free nodes in the component tree).
+void psTraceReset()
+;
+
+/// Free all nodes in the component tree.
+void psTraceFree()
+;
+
+/// print trace levels
+void psTracePrintLevels(void)
+;
+
+/// Set the destination of future trace messages.
+void psTraceSetDestination(FILE *fp);
+
+
+/* \} */ // End of SystemGroup Functions
+
+//#define PS_NO_TRACE 1   ///< to turn off all tracing
+
+#if defined(PS_NO_TRACE)
+#  define psTrace(facil, level, ...) /* do nothing */
+#else
+#  define psTrace(facil, level, ...) \
+p_psTrace(facil, level, __VA_ARGS__)
+#endif
+
+#endif
+
Index: /tags/rel1_1/psLib/src/sysUtils/psType.h
===================================================================
--- /tags/rel1_1/psLib/src/sysUtils/psType.h	(revision 1056)
+++ /tags/rel1_1/psLib/src/sysUtils/psType.h	(revision 1056)
@@ -0,0 +1,123 @@
+/** @file  psType.h
+ *
+ *  @brief Contains support for basic types
+ *
+ *  This file defines common datatypes used throughout psLib.
+ *
+ *  @ingroup DataContainer
+ *
+ *  @author Robert DeSonia, MHPCC
+ *  @author Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.11 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-10 01:58:06 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PS_TYPE_H
+#define PS_TYPE_H
+
+#include <complex.h>
+#include <stdint.h>
+
+/// @addtogroup DataContainer
+/// @{
+
+/******************************************************************************/
+/*  TYPE DEFINITIONS                                                          */
+/******************************************************************************/
+
+/** Basic data types used by the containers.
+ *
+ * The basic types of the primitives used by psLib are defined within this enum. This enum is in turn used by
+ * the psType struct.
+ *
+ */
+
+typedef uint8_t         psU8;           ///< 8-bit unsigned int
+typedef uint16_t        psU16;          ///< 16-bit unsigned int
+typedef uint32_t        psU32;          ///< 32-bit unsigned int
+typedef uint64_t        psU64;          ///< 64-bit unsigned int
+typedef int8_t          psS8;           ///< 8-bit signed int
+typedef int16_t         psS16;          ///< 16-bit signed int
+typedef int32_t         psS32;          ///< 32-bit signed int
+typedef int64_t         psS64;          ///< 64-bit signed int
+typedef float           psF32;          ///< 32-bit floating point
+typedef double          psF64;          ///< 64-bit floating point
+typedef complex float   psC32;          ///< complex with 32-bit floating point Real and Imagary numbers
+typedef complex double  psC64;          ///< complex with 64-bit floating point Real and Imagary numbers
+typedef void*           psPTR;           ///< void pointer
+
+
+typedef enum {
+    PS_TYPE_S8               = 0x0101,  ///< Character.
+    PS_TYPE_S16              = 0x0102,  ///< Short integer.
+    PS_TYPE_S32              = 0x0104,  ///< Integer.
+    PS_TYPE_S64              = 0x0108,  ///< Long integer.
+    PS_TYPE_U8               = 0x0301,  ///< Unsigned character.
+    PS_TYPE_U16              = 0x0302,  ///< Unsigned short integer.
+    PS_TYPE_U32              = 0x0304,  ///< Unsigned integer.
+    PS_TYPE_U64              = 0x0308,  ///< Unsigned long integer.
+    PS_TYPE_F32              = 0x0404,  ///< Single-precision Floating point.
+    PS_TYPE_F64              = 0x0408,  ///< Double-precision floating point.
+    PS_TYPE_C32              = 0x0808,  ///< Complex numbers consisting of single-precision floating point.
+    PS_TYPE_C64              = 0x0810,  ///< Complex numbers consisting of double-precision floating point.
+    PS_TYPE_PTR              = 0x0000   ///< Something else that's not supported for arithmetic.
+} psElemType;
+
+#define PS_TYPE_MASK PS_TYPE_U8         ///< the psElemType to use for mask image
+typedef psU8 psMaskType;                ///< the C datatype for a mask image
+
+/// Macro to get the bad pixel reason code (stored as part of mask value)
+#define PS_BADPIXEL_BITMASK 0x0f
+#define PS_GET_BADPIXEL(maskValue) (maskValue & PS_BADPIXEL_BITMASK)
+
+#define PS_IS_BADPIXEL(maskValue) (PS_GET_BADPIXEL(maskValue) != 0)
+
+/// Macro to apply a bad pixel reason code to mask image
+#define PS_SET_BADPIXEL(maskValue, reasonCode) \
+{ \
+    maskValue = (psMaskType)((reasonCode & PS_BADPIXEL_BITMASK) | (maskValue & ~PS_BADPIXEL_BITMASK)); \
+}
+
+/// Macro to determine if the psElemType is an integer.
+#define PS_IS_PSELEMTYPE_INT(x) ((x & 0x100) == 0x100)
+/// Macro to determine if the psElemType is unsigned.
+#define PS_IS_PSELEMTYPE_UNSIGNED(x) ((x & 0x200) == 0x200)
+/// Macro to determine if the psElemType is a real (non-complex) floating-point type.
+#define PS_IS_PSELEMTYPE_REAL(x) ((x & 0x400) == 0x400)
+/// Macro to determine if the psElemType is complex number type.
+#define PS_IS_PSELEMTYPE_COMPLEX(x) ((x & 0x800) == 0x800)
+/// Macro to determine the storage size, in bytes, of the psElemType.
+#define PSELEMTYPE_SIZEOF(x) ( (x==PS_TYPE_PTR) ? sizeof(void*) :(x & 0xFF) )
+
+/** Dimensions of a data type.
+ *
+ * The dimensions of containers used by psLib are defined within this enum. This enum is used by the psType
+struct. *
+ */
+typedef enum {
+    PS_DIMEN_SCALAR,    ///< Scalar.
+    PS_DIMEN_VECTOR,    ///< Vector.
+    PS_DIMEN_TRANSV,    ///< Transposed vector.
+    PS_DIMEN_IMAGE,     ///< Image.
+    PS_DIMEN_OTHER      ///< Something else that's not supported for arithmetic.
+} psDimen;
+
+/** The type of a data type.
+ *
+ * All psLib complex types consist of primitive components. This struct provides the description of those
+ * primitives.
+ *
+ */
+typedef struct
+{
+    psElemType type;    ///< Primitive type.
+    psDimen dimen;      ///< Dimensionality.
+}
+psType;
+
+/// @}
+
+#endif
Index: /tags/rel1_1/psLib/src/types/psBitSet.c
===================================================================
--- /tags/rel1_1/psLib/src/types/psBitSet.c	(revision 1056)
+++ /tags/rel1_1/psLib/src/types/psBitSet.c	(revision 1056)
@@ -0,0 +1,232 @@
+/** @file  psBitSet.c
+ *
+ *  @brief Creates an array of bytes of arbitrary length for storing individual bits.
+ *
+ *  Bit masks are useful tools for toggling various flags and options. This set of functions module provides
+ *  a mechanism to create an array of bits of arbitrary length and manipulate them with basic binary
+ *  operations. A print function is also provided to display the entire set of bits in binary format as a
+ *  string.
+ *
+ *  @author Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.6.2.1 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-15 03:09:18 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+/******************************************************************************/
+/*  INCLUDE FILES                                                             */
+/******************************************************************************/
+#include <string.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <math.h>
+
+#include "psBitSet.h"
+#include "psMemory.h"
+#include "psError.h"
+
+/******************************************************************************/
+/*  DEFINE STATEMENTS                                                         */
+/******************************************************************************/
+
+// None
+
+/******************************************************************************/
+/*  TYPE DEFINITIONS                                                          */
+/******************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  GLOBAL VARIABLES                                                         */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  FILE STATIC VARIABLES                                                    */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  FUNCTION IMPLEMENTATION - LOCAL                                          */
+/*****************************************************************************/
+
+/** Private function to create a mask.
+ *
+ *  Creates an eight bit mask with the given bit set. All other bits in the byte are zero. The input bit uses
+ *  zero-based indexing, and is the cumulitive index within the array, not the localized byte's bit position.
+ *
+ *  @return  char*: Pointer to byte in which bit is contained.
+ */
+static char mask(int bit)
+{
+    char mask = (char)0x01;
+    // Ignore splint warning about negative bit shifts
+    /*@i@*/
+    mask = mask << (bit%8);
+
+    return mask;
+}
+
+/*****************************************************************************/
+/* FUNCTION IMPLEMENTATION - PUBLIC                                          */
+/*****************************************************************************/
+psBitSet* psBitSetAlloc(int n)
+{
+    int numBytes = 0;
+    psBitSet *newObj = NULL;
+
+    if(n <= 0) {
+        psError(__func__, " : Line %d - Allocation size must be > 0: size = %d\n", __LINE__, n);
+        return 0;
+    }
+
+    numBytes = ceil(n/8.0);
+    newObj = psAlloc(sizeof(psBitSet));
+    newObj->n = numBytes;
+
+    // Ignore splint warning about releasing pointer members, since they've not been allocated yet
+    /*@i@*/
+    newObj->bits = psAlloc(sizeof(char)*numBytes);
+    memset(newObj->bits, numBytes, 0);
+
+    return newObj;
+}
+
+void psBitSetFree(psBitSet *restrict inBitSet)
+{
+    if(inBitSet == NULL) {
+        psError(__func__, " : Line %d - Null psBitSet for inBitSet argument\n", __LINE__);
+        return;
+    }
+    psFree(inBitSet->bits);
+    psFree(inBitSet);
+}
+
+psBitSet* psBitSetSet(psBitSet *inBitSet, int bit)
+{
+    char* byte = NULL;
+
+    if(inBitSet == NULL) {
+        psError(__func__, " : Line %d - Null psBitSet for inBitSet argument\n", __LINE__);
+        return inBitSet;
+    } else if(bit < 0) {
+        psError(__func__, " : Line %d - Bit position too small: %d\n", __LINE__, bit);
+        return inBitSet;
+    } else if(bit > inBitSet->n*8-1) {
+        psError(__func__, " : Line %d - Bit position too large: %d\n", __LINE__, bit);
+        return inBitSet;
+    }
+
+    // Variable byte is the byte in the array that contains the bit to be set
+    byte = inBitSet->bits+bit/8;
+    *byte |= mask(bit);
+
+    return inBitSet;
+}
+
+int psBitSetTest(const psBitSet *inBitSet, int bit)
+{
+    char* byte = NULL;
+
+    if(inBitSet == NULL) {
+        psError(__func__, " : Line %d - Null psBitSet for inBitSet argument\n", __LINE__);
+        return 0;
+    } else if(bit < 0) {
+        psError(__func__, " : Line %d - Bit position too small: %d\n", __LINE__, bit);
+        return 0;
+    } else if(bit > inBitSet->n*8-1) {
+        psError(__func__, " : Line %d - Bit position too large: %d\n", __LINE__, bit);
+        return 0;
+    }
+
+    // Variable byte is the byte in the array that contains the bit to be tested
+    byte = inBitSet->bits+bit/8;
+    if((int)(*byte&mask(bit)) == 0) {
+        return 0;
+    }
+
+    return 1;
+}
+
+psBitSet* psBitSetOp(psBitSet *outBitSet, const psBitSet *restrict inBitSet1, char *operator,
+                     const psBitSet *restrict inBitSet2)
+{
+    int i = 0;
+    int n = 0;
+    char tempChar = '0';
+    char *outBits = NULL;
+    char *inBits1 = NULL;
+    char *inBits2 = NULL;
+
+    if(outBitSet == NULL) {
+        psError(__func__, " : Line %d - Null psBitSet for outBitSet argument\n", __LINE__);
+        return outBitSet;
+    }
+
+    if(inBitSet1 == NULL) {
+        psError(__func__, " : Line %d - Null psBitSet for inBitSet1 argument\n", __LINE__);
+        return outBitSet;
+    }
+
+    if(operator == NULL) {
+        psError(__func__, " : Line %d - Null input operator\n", __LINE__);
+        return outBitSet;
+    }
+
+    if(inBitSet2 == NULL) {
+        psError(__func__, " : Line %d - Null psBitSet for inBitSet2 argument\n", __LINE__);
+        return outBitSet;
+    }
+
+    if(inBitSet1->n != inBitSet2->n || outBitSet->n != inBitSet1->n) {
+        psError(__func__, " : Line %d - psBitSet sizes not the same\n", __LINE__);
+        return outBitSet;
+    }
+
+    n = outBitSet->n;
+    outBits = outBitSet->bits;
+    inBits1 = inBitSet1->bits;
+    inBits2 = inBitSet2->bits;
+
+    tempChar = toupper(operator[0]);
+    switch(tempChar) {
+    case 'A':
+        for(i=0; i<n; i++) {
+            outBits[i] = inBits1[i] & inBits2[i];
+        }
+        break;
+    case 'O':
+        for(i=0; i<n; i++) {
+            outBits[i] = inBits1[i] | inBits2[i];
+        }
+        break;
+    case 'X':
+        for(i=0; i<n; i++) {
+            outBits[i] = inBits1[i] ^ inBits2[i];
+        }
+        break;
+    default:
+        psError(__func__, " : Line %d - Invalid psBitMask binary operation: %s\n", __LINE__, operator);
+    }
+
+    return outBitSet;
+}
+
+char *psBitSetToString(const psBitSet *restrict inBitSet)
+{
+    int i = 0;
+    int numBits = inBitSet->n*8;
+    char* outString = psAlloc((size_t)numBits+1);
+    for(i=0; i<numBits; i++) {
+        outString[numBits-i-1] = (psBitSetTest(inBitSet, i) == 1)?'1':'0';
+    }
+
+    outString[numBits] = 0;
+
+    return outString;
+}
Index: /tags/rel1_1/psLib/src/types/psBitSet.h
===================================================================
--- /tags/rel1_1/psLib/src/types/psBitSet.h	(revision 1056)
+++ /tags/rel1_1/psLib/src/types/psBitSet.h	(revision 1056)
@@ -0,0 +1,120 @@
+/** @file  psBitSet.h
+ *
+ *  @brief Creates an array of bytes of arbitrary length for storing individual bits.
+ *
+ *  Bit masks are useful tools for toggling various flags and options. This set of functions module provides
+ *  a mechanism to create an array of bits of arbitrary length and manipulate them with basic binary
+ *  operations. A print function is also provided to display the entire set of bits in binary format as a
+ *  string.
+ *
+ *  @ingroup BitSet
+ *
+ *  @author Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.6 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-10 01:58:06 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PSBITSET_H
+#define PSBITSET_H
+
+/// @addtogroup BitSet
+/// @{
+
+/******************************************************************************/
+/*  TYPE DEFINITIONS                                                          */
+/******************************************************************************/
+
+/** Struct containing array of bytes to hold bit data and corresponding array length.
+ *
+ *  The bits in the struct are assembled in as an array of bytes with eight bits per byte. The bits are
+ *  arranged with the LSB in first (right most) position of the first array element.
+ */
+typedef struct
+{
+    int n;      /**< Number of bytes in the array */
+    char *bits; /**< Aray of bytes holding bits */
+}
+psBitSet;
+
+/*****************************************************************************/
+/* FUNCTION PROTOTYPES                                                       */
+/*****************************************************************************/
+
+/** Allocate a psBitSet.
+ *
+ *  Create a psBitSet with the number of bits specified by the user. All bits are set to zero upon
+ *  allocation.
+ *
+ *  @return  psBitSet*: Pointer to struct containing array of bits and size of array.
+ */
+/*@null@*/
+psBitSet* psBitSetAlloc(
+    int n   /**< Number of bits in psBitSet array */
+);
+
+/** Free a psBitSet
+ *
+ *  Deletes a psBitSet array.
+ */
+void psBitSetFree(
+    psBitSet *restrict inMask  /**< Pointer to psBitSet to be deleted. */
+);
+
+/** Set a bit.
+ *
+ *  Sets a bit at a given bit location, either one or zero. The bit is set based on a zero index with the
+ *  first bit set in the zero bit slot of the zero element of the byte array. As an example, setting bit 3 in
+ *  an array with two elements would result in an psBitSet that looks like 00000000 00001000.
+ *
+ *  @return  psBitSet*: Pointer to struct containing psBitSet.
+ */
+psBitSet* psBitSetSet(
+    /*@returned@*/psBitSet *restrict inMask,  /**< Pointer to psBitSet to be set. */
+    int bit                     /**< Bit to be set. */
+);
+
+/** Test the value of a bit.
+ *
+ *  Prints the value of a bit at a given bit location, either one or zero. The resulting bit is based on a
+ *  zero index format with the first bit set in the zero bit slot of the zero element of the byte array
+ *  As an example, testing bit 3 in a psBitSet with two bytes that looks like 00000000 00001000 would return a
+ *  value of one, since that is the value that was set.
+ *
+ *  @return  int: Value of bit, either one or zero.
+ */
+int psBitSetTest(
+    const psBitSet *restrict inMask,    /**< Pointer psBitSet to be tested. */
+    int bit                             /**< Bit to be tested. */
+);
+
+/** Perform a binary operation on two psBitSets
+ *
+ *  Perform an AND, OR, or XOR on two psBitSets. If the BitMasks are not the same size, the operation will not
+ *  be performed and an error message will be logged.
+ *
+ *  @return  psBitSet*: Pointer to struct containing result of binary operation.
+ */
+psBitSet* psBitSetOp(
+    /*@returned@*/psBitSet *restrict outMask,   /**< Resulting psBitSet from binary operation */
+    const psBitSet *restrict inMask1,           /**< First psBitSet on which to operate */
+    char *operator,                             /**< Bit operation */
+    const psBitSet *restrict inMask2            /**< First psBitSet on which to operate */
+);
+
+/** Convert the psBitSet to a string of ones and zeros.
+ *
+ *  Converts the contents of a psBitSet to a string representation of its binary form of ones and zeros. The
+ *  LSB is the right-most chracter. Each set of eight characters represents one byte.
+ *
+ *  @return  char*: Pointer to character array containing string data.
+ */
+char *psBitSetToString(
+    const psBitSet *restrict inMask /**< psBitSet to convert */
+);
+
+/// @}
+
+#endif
Index: /tags/rel1_1/psLib/src/types/psList.c
===================================================================
--- /tags/rel1_1/psLib/src/types/psList.c	(revision 1056)
+++ /tags/rel1_1/psLib/src/types/psList.c	(revision 1056)
@@ -0,0 +1,458 @@
+/** @file psList.c
+ *  @brief Support for doubly linked lists
+ *  @ingroup DataContainers
+ *
+ *  @author Robert Lupton, Princeton University
+ *  @author Robert Daniel DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.6 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-14 19:45:46 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include <stdlib.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <pthread.h>                   // we need a mutex to make this stuff thread safe.
+
+#include "psError.h"
+#include "psAbort.h"
+#include "psMemory.h"
+#include "psList.h"
+#include "psTrace.h"
+#include "psLogMsg.h"
+
+#define ITER_INIT_HEAD ((void *)1) // next iteration should return head
+#define ITER_INIT_TAIL ((void *)2) // next iteration should return tail
+
+// private functions.
+psListElem* listGetIterator(psList* list);
+int listGetIteratorIndex(psList* list);
+void listSetIterator(psList *list, int where, bool lockList);
+
+
+psList *psListAlloc(void *data)
+{
+    psList *list = psAlloc(sizeof(psList));
+
+    list->size = 0;
+    list->head = list->tail = NULL;
+    list->iter = ITER_INIT_HEAD;
+    list->iterIndex = PS_LIST_HEAD;
+    pthread_mutex_init(&(list->lock),NULL)
+    ;
+
+    if (data != NULL) {
+        psListAdd(list, data, PS_LIST_TAIL);
+    }
+
+    return list;
+}
+
+void psListFree(psList *list, psFreeFcn elemFree)
+{
+    if (list == NULL) {
+        return;
+    }
+
+    pthread_mutex_lock(&list->lock)
+    ;
+
+    for(psListElem *ptr = list->head; ptr != NULL; ) {
+        psListElem *next = ptr->next;
+
+        p_psCustomFree(elemFree, psMemDecrRefCounter(ptr->data));
+        psFree(ptr);
+
+        ptr = next;
+    }
+
+    pthread_mutex_unlock(&list->lock)
+    ;
+
+    pthread_mutex_destroy(&list->lock)
+    ;
+
+    psFree(list);
+}
+
+psList* psListAdd(psList *list, void *data, int where)
+{
+    psListElem* position;
+    psListElem* elem;
+    int cursorIndex = 0;
+
+    if (list == NULL) {
+        return NULL;
+    }
+
+    if (data == NULL) {
+        return list;
+    }
+    elem = psAlloc(sizeof(psListElem));
+
+    pthread_mutex_lock(&list->lock)
+    ;
+
+    if (where <= PS_LIST_UNKNOWN) {
+        /// XXX What is the better way to communicate this failure to the caller?
+        psLogMsg(__func__,PS_LOG_WARN,
+                 "The given insert location (%i) for psListAdd is invalid. Adding to head instead.",
+                 where);
+        where = PS_LIST_HEAD; // given I can't tell caller about this, should just add it somewhere???
+    }
+
+    if (where > 0 && where > list->size) {
+        psLogMsg(__func__,PS_LOG_WARN,
+                 "Invalid index %d (only %d elements in psList); assuming tail.",
+                 where, list->size);
+        where = PS_LIST_TAIL;
+    }
+
+    if (where == PS_LIST_TAIL || list->size == 0) {
+        // insert the element at the end of the list
+        elem->prev = list->tail;
+        elem->next = NULL;
+
+        if (list->tail != NULL) {
+            list->tail->next = elem;
+        }
+
+        if (list->head == NULL) {
+            list->head = elem;
+        }
+        list->tail = elem;
+
+        list->size++;
+        list->iter = elem;
+        list->iterIndex = list->size - 1;
+    } else {
+        // move ourselves to the given position
+        listSetIterator(list, where, false);
+        position = listGetIterator(list);
+        cursorIndex = listGetIteratorIndex(list);
+
+        if (position == NULL) {
+            psError(__func__,"%s failed to move cursor to specified location (%d)",__func__,where);
+            position = list->head; // since we no list->size != 0, this must be non-NULL
+        }
+
+        // insert our new element in front of the given position
+        elem->prev = position->prev;
+        elem->next = position;
+        position->prev = elem;
+
+        if (elem->prev == NULL) { // must be front of list
+            list->head = elem;
+        } else {
+            elem->prev->next = elem;
+        }
+
+        list->size++;
+        list->iter = elem;
+        list->iterIndex = cursorIndex;
+    }
+
+    elem->data = psMemIncrRefCounter(data);
+
+    pthread_mutex_unlock(&list->lock)
+    ;
+
+    return list;
+}
+
+/*****************************************************************************/
+
+psList *psListAppend(psList *list, void *data)
+{
+    return psListAdd(list, data, PS_LIST_TAIL);
+}
+
+/*****************************************************************************/
+/*
+ * Remove an element from a list
+ */
+void *psListRemove(psList *list, void *data,  int which)
+{
+    psListElem *elem = NULL;  // element to remove
+    int cursorIndex = 0;
+
+    if (list == NULL) {
+        psError(__func__,"list parameter found to be NULL in %s",__func__);
+        return NULL;
+    }
+
+    // get exclusive access to list so that other threads will not get in the way.
+    pthread_mutex_lock(&list->lock)
+    ;
+
+    if (which == PS_LIST_UNKNOWN) {
+        // search list for the data item.
+
+        int i = 0;   // index
+        for (psListElem *ptr = list->head; ptr != NULL; ptr = ptr->next) {
+            if (ptr->data == data) {
+                which = i;
+                break;
+            }
+            i++;
+        }
+
+        if (which == PS_LIST_UNKNOWN) {
+            psError(__func__, "Failed to find item in given psList.");
+            return NULL;
+        }
+    }
+
+    // position the list's cursor to the desired location
+    listSetIterator(list,which,false);
+    elem = listGetIterator(list);
+    cursorIndex = listGetIteratorIndex(list);
+
+    if (elem == NULL) {
+        psError(__func__, "Couldn't position to given index (%d) to remove element from list.",which);
+        return NULL;
+    }
+
+    list->size--;
+
+    if (elem->prev == NULL) { // head of list?
+        list->head = elem->next;
+    } else {
+        elem->prev->next = elem->next;
+    }
+
+    if (elem->next == NULL) { // tail of list?
+        list->tail = elem->prev;
+
+        // removed tail, so iter should be the last element of list to keep it valid
+        if (list->size > 0) {
+            list->iter = list->tail;
+            list->iterIndex = list->size - 1;
+        } else {
+            list->iter = ITER_INIT_TAIL;
+        }
+    } else {
+        elem->next->prev = elem->prev;
+        list->iter = elem->next;
+        list->iterIndex = cursorIndex;
+    }
+
+    pthread_mutex_unlock(&list->lock)
+    ;
+
+    /*
+     * OK, delete list element and return the data
+     */
+    data = elem->data;
+    psFree(elem);
+    return data;
+}
+
+void psListSetIterator(psList *list, int where)
+{
+    listSetIterator(list,where,true);
+}
+
+void listSetIterator(psList* list, int where, bool lockList)
+{
+    psListElem* cursor;
+    int position;
+
+    if (list == NULL) {
+        psError(__func__,"Unexpected null pointer for psList parameter (%s:%d).",__FILE__,__LINE__);
+        return;
+    }
+
+    if (where == PS_LIST_CURRENT) {
+        return;
+    }
+
+    if (lockList) {
+        pthread_mutex_lock(&list->lock)
+        ;
+        // don't want the list changing on us while we move about
+    }
+
+    if (where >= (int)list->size) {
+        list->iter = NULL;
+        return;
+    }
+
+    switch (where) {
+    case PS_LIST_HEAD:
+        list->iter = ITER_INIT_HEAD;
+        break;
+
+    case PS_LIST_TAIL:
+        list->iter = ITER_INIT_TAIL;
+        break;
+
+    case PS_LIST_PREVIOUS:
+        cursor = listGetIterator(list);
+        position = listGetIteratorIndex(list);
+
+        if (cursor != NULL) {
+            list->iter = cursor->prev;
+            list->iterIndex = position-1;
+        }
+        break;
+
+    case PS_LIST_NEXT:
+        cursor = listGetIterator(list);
+        position = listGetIteratorIndex(list);
+
+        if (cursor != NULL) {
+            list->iter = cursor->next;
+            list->iterIndex = position+1;
+        }
+        break;
+
+    case PS_LIST_CURRENT:
+        break;
+
+    default:
+        if (where <= PS_LIST_HEAD) { // bascially same as PS_LIST_UNKNOWN above
+            psError(__func__,"Can't move to an unknown position.  Not moving the iterator position.");
+        } else {
+            cursor = listGetIterator(list);
+            if (cursor == NULL) { // reset the iterator if it is invalid
+                list->iter = ITER_INIT_HEAD;
+                list->iterIndex = 0;
+            }
+
+            int position = listGetIteratorIndex(list);
+
+            if (where < position) {
+                int diff = position-where;
+                for (int count=0;count < diff; count++) {
+                    listSetIterator(list,PS_LIST_PREVIOUS,false);
+                }
+            } else {
+                int diff = where-position;
+                for (int count=0;count < diff; count++) {
+                    listSetIterator(list,PS_LIST_NEXT,false);
+                }
+            }
+        }
+        break;
+    }
+
+    if (lockList) {
+        pthread_mutex_unlock(&list->lock)
+        ;
+    }
+}
+
+psListElem* listGetIterator(psList* list)
+{
+    if (list == NULL) {
+        return NULL;
+    }
+
+    if (list->iter == ITER_INIT_HEAD) {
+        return list->head;
+    } else if (list->iter == ITER_INIT_TAIL) {
+        return list->tail;
+    } else {
+        return list->iter;
+    }
+}
+
+int listGetIteratorIndex(psList* list)
+{
+    if (list->iter == ITER_INIT_HEAD) {
+        return 0;
+    } else if (list->iter == ITER_INIT_TAIL) {
+        return list->size-1;
+    } else {
+        return list->iterIndex;
+    }
+}
+
+void* psListGet(psList* list,int which)
+{
+    psListElem* element;
+
+    psListSetIterator(list,which);
+    element = listGetIterator(list);
+
+    if (element == NULL) {
+        return NULL;
+    } else {
+        return element->data;
+    }
+}
+/*
+ * and now return the previous/next element of the list
+ */
+void *psListGetNext(psList *list)
+{
+    return psListGet(list, PS_LIST_NEXT);
+}
+
+void *psListGetPrevious(psList *list)
+{
+    return psListGet(list, PS_LIST_PREVIOUS);
+}
+
+void *psListGetCurrent(psList *list)
+{
+    return psListGet(list, PS_LIST_CURRENT);
+}
+
+/*
+ * Convert a psList to/from a psVoidPtrArray
+ */
+psVector* psListToVector(psList* restrict list)
+{
+    psListElem* ptr;
+    unsigned int n;
+    psVector* restrict arr;
+
+    if (list == NULL) {
+        return NULL;
+    }
+
+    if (list->size > 0) {
+        arr = psVectorAlloc(list->size, PS_TYPE_PTR);
+    } else {
+        arr = psVectorAlloc(1, PS_TYPE_PTR);
+    }
+
+    arr->n = list->size;
+
+
+    ptr = list->head;
+    n = list->size;
+    for (int i = 0; i < n; i++) {
+        arr->data.PTR[i] = psMemIncrRefCounter(ptr->data);
+        ptr = ptr->next;
+    }
+
+    return arr;
+}
+
+psList* psVectorToList(psVector* arr)
+{
+    unsigned int n;
+    psList* list; // list of elements
+
+    if (arr == NULL) {
+        return NULL;
+    }
+
+    if (arr->type.type != PS_TYPE_PTR) {
+        psError(__func__,"Can not convert a non pointer-vector to a linked list.");
+        return NULL;
+    }
+
+    list = psListAlloc(NULL);
+    n = arr->n;
+    for (int i = 0; i < n; i++) {
+        psListAppend(list,arr->data.PTR[i]);
+    }
+
+    return list;
+}
Index: /tags/rel1_1/psLib/src/types/psList.h
===================================================================
--- /tags/rel1_1/psLib/src/types/psList.h	(revision 1056)
+++ /tags/rel1_1/psLib/src/types/psList.h	(revision 1056)
@@ -0,0 +1,196 @@
+#if !defined(PS_LIST_H)
+#define PS_LIST_H
+
+/** @file psList.h
+ *  @brief Support for doubly linked lists
+ *
+ *  @author Robert Lupton, Princeton University
+ *  @author Robert Daniel DeSonia, MHPCC
+ *
+ *  @ingroup LinkedList
+ *
+ *  @version $Revision: 1.4 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-12 22:15:39 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include <pthread.h>                   // we need a mutex to make this stuff thread safe.
+
+#include "psVector.h"
+
+/** @addtogroup LinkedList
+ *  @{
+ */
+
+/** Special values of index into list
+ *
+ *  This list of possible list position values should be contiguous non-positive values ending with
+ *  PS_LIST_UNKNOWN.  Any value less-than-or-equal-to PS_LIST_UNKNOWN is considered a undefined position.
+ *
+ */
+enum {
+    PS_LIST_HEAD = 0,                  ///< at head
+    PS_LIST_TAIL = -1,                 ///< at tail
+    PS_LIST_PREVIOUS = -2,             ///< previous element
+    PS_LIST_CURRENT = -3,              ///< current element
+    PS_LIST_NEXT = -4,                 ///< next element
+    PS_LIST_UNKNOWN = -5               ///< unknown position (should be last in enum list)
+};
+
+/** Doubly-linked list element */
+typedef struct psListElem
+{
+    struct psListElem *prev;            ///< previous link in list
+    struct psListElem *next;            ///< next link in list
+    void *data;                         ///< real data item
+}
+psListElem;
+
+/** The psList Linked list structure.  User should not allocate this struct
+ *  directly; rather the psListAlloc should be used.
+ *
+ *  @see psListAlloc, psListFree
+ */
+typedef struct
+{
+    unsigned int size;                  ///< number of elements on list
+    psListElem* head;                   ///< first element on list (may be NULL)
+    psListElem* tail;                   ///< last element on list (may be NULL)
+    psListElem* iter;                   ///< iteration cursor
+    unsigned int iterIndex;             ///< the numeric position of the iteration cursor in the list
+    pthread_mutex_t lock;               ///< mutex to lock a node during changes
+}
+psList;
+
+/** Creates a psList linked list object.
+ *
+ *  @return psList*     A new psList object.
+ */
+psList* psListAlloc(
+    void *data
+    ///< initial data item; may be NULL if no an empty psList is desired
+)
+;
+
+#include "psMemory.h"
+/** Destroys a psList linked list object.  This also frees the elements of the
+ *  list using the psFreeFcn given, if any.  If no psFreeFcn is specified,
+ *  the elements are just dereferenced via psMemDecrRefCounter(...).
+ *
+ */
+void psListFree(
+    psList* restrict list,              ///< list to destroy
+    psFreeFcn elemFree                  ///< destructor for data on list
+);
+
+/** Adds an element to a psList at position given.
+ *
+ *  @return psList*     The psList with added data item.  If list parameter is
+ *                      NULL, the return value will also be NULL.
+ */
+psList* psListAdd(
+    psList* restrict list,              ///< list to add to (if NULL, nothing is done)
+    void* data,                         ///< data item to add.  If NULL, list is not modified.
+    int where                           ///< index, PS_LIST_HEAD, PS_LIST_TAIL, or numbered location.
+);
+
+/** Appends an item to a psList.
+ *
+ *  @return psList*     The psList with added data item.  If list parameter is
+ *                      NULL, the return value will also be NULL.
+ */
+psList* psListAppend(
+    psList* restrict list,              ///< list to append to (if NULL, nothing is done)
+    void *data                          ///< data item to add. If NULL, list is not modified.
+);
+
+/** Remove an item from a list.  If which parameter is PS_LIST_UNKNOWN,
+ *
+ *  @return void*       The data item that was removed.  If NULL, no item was
+ *                      removed.
+ */
+void* psListRemove(
+    psList* restrict list,
+    ///< list to remove element from
+    void *data,
+    ///< if which is PS_LIST_UNKNOWN, data item to find and remove, otherwise this is ignored.
+    int which
+    ///< index of item, or PS_LIST_UNKNOWN, PS_LIST_NEXT, PS_LIST_PREV, or numbered location.
+);
+
+/** Retrieve an item from a list.
+ *
+ *  @return void*       the item corresponding to the which parameter.  If
+ *                      which is invalid (e.g., a numbered index greater
+ *                      than the list size or if the list is empty), a
+ *                      NULL is returned.
+ */
+void* psListGet(
+    psList* restrict list,             ///< list to retrieve element from
+    int which                          ///< index number, or PS_LIST_NEXT, PS_LIST_PREV, PS_LIST_UNKNOWN
+);
+
+/** Set the iterator of the list to a given position.  If where is invalid the
+ *  iterator position is not changed.
+ *
+ */
+void psListSetIterator(
+    psList* restrict list,             ///< list to retrieve element from
+    int where                           ///< index number, PS_LIST_HEAD, or PS_LIST_TAIL
+);
+
+/** Get next element relative to the iterator.  This also moves the iterator to
+ *  the next list position.
+ *
+ *  @return void*       the data item next on the list or NULL if the iterator
+ *                      is already pointing to the last element or the list
+ *                      parameter was NULL.
+ */
+void* psListGetNext(
+    psList* restrict list              ///< list to retrieve element from
+);
+
+/** Get current element according to the psList's iterator cursor.  This does
+ *  not move the iterator location.
+ *
+ *  @return void*       the data item cooresponding to current iterator
+ *                      cursor position of the list, or NULL if either the
+ *                      iterator is not valid or list parameter was NULL.
+ */
+void* psListGetCurrent(
+    psList* restrict list              ///< list to retrieve element from
+);
+
+/** Get previous element relative to list's iterator. This also moves the
+ *  iterator to the previous list position.
+ *
+ *  @return void*       the data item previous on the list or NULL if the iterator
+ *                      is already pointing to the first element or the list
+ *                      parameter was NULL.
+ */
+void* psListGetPrevious(
+    psList* restrict list              ///< list to retrieve element from
+);
+
+/** Convert a linked list to an array
+ *
+ *  @return psVector*   A new psVector populated with elements from the list,
+ *                      or NULL if the given dlist parameter is NULL.
+ */
+psVector* psListToVector(
+    psList *dlist                      ///< List to convert
+);
+
+/** Convert array to a doubly-linked list
+ *
+ *  @return psList*     A new psList populated with elements formt the psVector,
+ *                      or NULL is the given arr parameter is NULL.
+ */
+psList* psVectorToList(
+    psVector* arr                      ///< vector to convert
+);
+
+/// @} End of DataGroup Functions
+
+#endif
Index: /tags/rel1_1/psLib/test/FullUnitTest
===================================================================
--- /tags/rel1_1/psLib/test/FullUnitTest	(revision 1056)
+++ /tags/rel1_1/psLib/test/FullUnitTest	(revision 1056)
@@ -0,0 +1,588 @@
+#!/usr/bin/perl
+#
+#  This is a perl script test harness which will recursively search the
+#  directory tree looking for files named UnitTest and then execute
+#  the script
+#
+#  SYNOSIS :  FullUnitTest options arguements
+#
+#       where  options =
+#             --verbose     Display extra information to user
+#             --noverbose   Don't display extra information to user
+#             --recursiv e  Recursively run tests in directory tree
+#             --norecursive Test only the specified or current directory
+#             --silent      Don't display any information to user
+#             --nosilent    Display progress of script to user
+#
+#              arguements = directory(ies) to perform tests
+#
+#  RETURN : integer number of tests which failed
+#
+#  $Revision: 1.7.2.1 $  $Name: not supported by cvs2svn $
+#  $Date: 2004-06-15 21:44:22 $
+#
+#  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+#
+##############################################################################
+
+# Provide functions for determining the pathname of current working directory
+use Cwd;
+
+# Provides functions for handling long command line options
+use Getopt::Long;
+
+# Assign variables based on the presence of command line options to the script
+# The ! option allows for --nooption to be set to zero
+# (e.g. --noverbose --recursive causes $verbose=0 and $recursive=1)
+GetOptions("verbose!"=>\$verbose,
+           "recursive!"=>\$recursive,
+           "silent!"=>\$silent,
+           "clean!"=>\$clean);
+
+# Check if both silent and verbose options are set and if so stop the script
+die "Can't specify both verbose and silent options." if ($verbose && $silent);
+
+# Set up the PSLIB_ROOT environment variable if the user doesn't have
+if (! $ENV{'PSLIB_ROOT'})  {
+    # Use the directory directly above where FullUnitTest script resides
+    $PSLIB_ROOT = `cd ..;pwd`;
+    # Remove newline for the end of path returned
+    chomp($PSLIB_ROOT);
+    # Set the environment variable
+    $ENV{'PSLIB_ROOT'} = $PSLIB_ROOT;
+    print("PSLIB_ROOT not found: set to $PSLIB_ROOT.\n") if $verbose;
+}
+
+# add PSLIB_ROOT/lib to LD_LIBRARY_PATH and DYLD_LIBRARY_PATH environment
+# variables
+$ENV{'LD_LIBRARY_PATH'} = "$ENV{'PSLIB_ROOT'}/lib:$ENV{'LD_LIBRARY_PATH'}";
+$ENV{'DYLD_LIBRARY_PATH'} = "$ENV{'PSLIB_ROOT'}/lib:$ENV{'DYLD_LIBRARY_PATH'}";
+
+# Initialize variables for counting the makes and test failures and the
+# total makes and tests performed
+$makeFailCount = 0;
+$testpointFailCount = 0;
+$testDriverFailCount = 0;
+$totalTestpoints = 0;
+$totalTestDrivers = 0;
+$totalMakes = 0;
+
+# Initialize variable indicating how many arguements were passed
+$args = 0;
+
+# Loop through all the arguements passed to the script
+foreach (@ARGV) {
+    # Remove newline if there is one
+    chomp;
+    # Increment number of arguements found
+    $args++;
+    # Set variable to current working directory
+    $cwd = cwd;
+    # Change directory to the directory of the arguement
+    chdir($_);
+    # Check for the recursive option
+    if ($recursive) {
+        # Invoke subroutine to go to the lowest directory in tree
+        # starting at the specified directory
+        &worm($_);
+    } else {
+        # Invoke subroutines to run the test at the specified directory
+        &makeTestDrivers($_);
+        &executeTestDrivers($_);
+    }
+    # Change directory back to the directory where FullUnitTest was invoked
+    chdir($cwd);
+}
+
+# Check if there were no arguements specified
+if ($args == 0){
+    # Display message to user that all directories under the current will be
+    # tested
+    print("Recursively testing current directory tree.\n") if $verbose;
+    # Invoke subroutine to go to recursively test each directory in tree
+    &worm($ENV{"PWD"});
+}
+
+# Check if there were any failures during make or testing
+if ($makeFailCount>0 || $testDriverFailCount>0) {
+    # Display summary of failures
+    print("\nMake Failures = $makeFailCount out of $totalMakes");
+    print("\nTest Driver Failures = $testDriverFailCount out of $totalTestDrivers\n");
+    print("\nMakes that failed:\n  ".join("\n  ",@makesFailed) . "\n") if $makeFailCount;
+    print("\nTests that failed:\n  ".join("\n  ",@testsFailed) . "\n") if $testDriverFailCount;
+} else {
+    # Display message of all makes and tests pass to user if silent option
+    # not specified
+    print("\nAll $totalTestDrivers Test Drivers Passed with $totalTestpoints Testpoints.\n") if (! $silent);
+}
+
+# Exit with the number of tests that failed
+exit($testDriverFailCount);
+
+
+################################################################################
+#
+# SUBROUTINE: worm
+#
+#     Description:  This subroutine will perform the necessary unit tests be
+#                   calling makeTestDrivers and executeTestDrivers  subroutines
+#                   and then check each subdirectory below the base directory 
+#                   recursively.
+#
+#     Parameter(s):  base directory to start testing
+#
+#     Return:  None
+#
+################################################################################
+
+sub worm {
+    # Assign local variable to input parameter
+    local($base_dir) = @_;
+    local(@files, $i);
+
+    # Invoke subroutine to make test driver in the base directory
+    &makeTestDrivers($base_dir);
+
+    # Invoke subroutine to execute tests in the base directory
+    &executeTestDrivers($base_dir);
+
+    # Create array of entries found in directory
+    @files = <*>;
+
+    # Loop through the file list looking for another directory that is not
+    # labelled CVS and recursively invoke subroutine worm
+    $i = 0;
+    while ($files[$i]) {
+        # Check for directory and directory not labelled CVS
+        if (-d $files[$i] && ($files[$i] ne "CVS") && ($files[$i] ne "temp")
+                          && ($files[$i] ne "verified")) {
+            # Change current directory to directory found
+            chdir($files[$i]);
+            # Invoke subroutine worm again
+            &worm($files[$i]);
+            # Change current directory back to parent
+            chdir("..");
+        }
+        # Increment file list index
+        $i++;
+    }
+}
+
+################################################################################
+#
+#  SUBROUTINE: makeTestDrivers
+#
+#      Description:  This subroutine will perform a make for all the necessary
+#                    test drivers.    This will occur in the specified
+#                    base directory which is passed as the only parameter.
+#
+#      Parameter(s):  base directory where make and test drivers are located
+#
+#      Return:  None
+#
+################################################################################
+
+sub makeTestDrivers{
+    local($base_dir) = @_;
+    local($pwd);
+
+    # Set variable pwd to current working directory
+    $pwd = cwd;
+
+    # Display message to user in which directory testing is taken place only
+    # if the silent command option was not specified
+    print("---- Entering $pwd ----\n") if ( ! $silent);
+
+    # Check for the existence of a file name Makefile in current directory
+    if (-e "Makefile") {
+
+        # Increment the total number of makes executed
+        $totalMakes++;
+
+        if ($clean) { 
+            # Execute the make clean
+            `make clean`;
+
+            # Execute the make distclean
+            `make distclean`;
+        }
+
+        # Execute the make and save results
+        $_ = join("\n|| ",split("\n", "\n" . `make`) );
+
+        # Check the output of make for return value != 0 or any of the
+        # following words: FAILED, FAULT, ERROR, Not found, SIGNAL
+        if (($? != 0) || m/FAILED/i || m/FAULT/i || m/\bERROR/i
+                      || m/Not found/i || m/SIGNAL/i) {
+            # Display the errored output of make if silent option not enabled
+            print("$_\n") if ( ! $silent );
+            # Display the make failed in the current directory
+            print("\nMake for $pwd Failed\n");
+            # Increment the number of makes that have failed
+            $makeFailCount++;
+            # Push the current working directory onto the list of failed
+            # make directories list
+            push(@makesFailed, $pwd);
+        } else {
+            # Display the results of the successful make if verbose option set
+            print("$_\n") if $verbose;
+            # Display the make was successful if silent option not set
+            print("\nMake successful.\n") if ( ! $silent);
+            if ($clean) {
+                `make install`;
+            }
+        }
+    }
+}
+
+################################################################################
+#
+#  SUBROUTINE: executeTestDrivers
+#
+#      Description:  This subroutine will execute all the necessary
+#                    test drivers.    This will occur in the specified
+#                    base directory which is passed as the only parameter.
+#
+#      Parameter(s):  base directory where make and test drivers are located
+#
+################################################################################
+
+sub executeTestDrivers{
+    local($base_dir) = @_;
+    local(@files,$j);
+    local($pwd);
+    local($exitValue) = 0;
+
+    # Set variable to pwd to current test directory
+    $pwd = cwd;
+
+    # Create a list of all elements in base directory
+    @files = <*>;
+
+    # Loop through all the items in the files array
+    $initialTest = 0;
+    $j = 0;
+    while ( $files[$j]) {
+        # Check that the item is not a directory and is executable and
+        # conforms to the test driver naming convention TST
+        if ( ! (-d $files[$j]) && (-x $files[$j]) && 
+             ( $files[$j] =~ /^TST/i || $files[$j] =~ /^ATST/i ) ) {
+
+            # Increment total number of test drivers executed
+            $totalTestDrivers++;
+
+            # Perform subdirectory checks only the first time a test
+            # file is found with the list of enteries
+            if ( $initialTest == 0 ) {
+                $initialTest++;
+
+                # Check for a temp subdirectory already exists and if not
+                # then create one
+                &checkForTempDirectory();
+
+                # Check for the presence of verified directory
+                if ( &checkForVerifiedDirectory() ) {
+            
+                    # Display message to user that verified directories do not 
+                    # exist eventhough TST files have been found
+#                    print("Unable to execute test drivers in $base_dir\n");
+                    print("No verified subdirectory present.\n") if ($verbose);
+                    # Increment test fail count
+ #                   $testDriverFailCount++;
+                    # Save the file failed
+#                    push(@testsFailed, $pwd . "/" . $files[$j]);
+#                    return;
+                }
+            }
+
+            # Display message to user of which test driver is being executed
+            print("--- Executing test driver $files[$j]\n") if ( ! $silent );
+            # Execute the test driver
+            system("./$files[$j] 1> temp/$files[$j].stdout 2> temp/$files[$j].stderr");
+            $retVal = $?;
+            # Count testpoints
+	    $testPattern = "\"\\*\\*\\*\\* TESTPOINT \\*\\*\\*\\*\"";
+            $totalPoints = `grep -c $testPattern temp/$files[$j].stdout`;
+            $totalPoints += `grep -c $testPattern temp/$files[$j].stderr`;
+            $failPoints = `grep "> TESTPOINT FAILED" temp/$files[$j].stdout | wc -l`;
+            $failPoints += `grep "> TESTPOINT FAILED" temp/$files[$j].stderr | wc -l`;
+            $testpointFailCount += $failPoints;
+            $totalTestpoints += $totalPoints;
+            # Check result of test driver
+            if ( ( ($retVal != 0) && ($files[$j] =~ /^TST/i) ) ||
+                 ( ($retVal == 0) && ($files[$j] =~ /^ATST/i ) ) ) {
+                # Display test driver failed
+                $failPoints++;
+                print("Test driver: $files[$j] Failed (Return value $retVal).\n");
+                # Increment the total number of test failed
+                $testDriverFailCount++;
+                # Push the current working directory on the list of failed
+                push(@testsFailed, $pwd . "/" . $files[$j]);
+            } else {
+                # Create filter versions of STDOUT and STDERR to replace variable
+                # items such as date, time and host
+                &filterStdFiles($files[$j]);
+                # Perform difference on STDOUT file collected
+                # with verified files
+                $exitValue = &compareStream("verified/$files[$j].stdout");
+                if ( $exitValue & 2 ) {
+                    # STDOUT verified doesn't exist. Search STDOUT capture
+                    # for strings indicating error or failure
+                    $exitValue |= &errorStrSearch("$files[$j].stdout");
+                }
+                if ( ($exitValue & 8) || ($exitValue & 64) ) {
+                    # Increment the total number of test failed
+                    $testDriverFailCount++;
+                    # Push test on failed list
+                    print("Test failed ($failPoints out of $totalPoints testpoints failed)\n") if ( ! $silent);
+                    push(@testsFailed, $pwd . "/" . $files[$j]);
+                } else {
+                    # Perform difference on STDERR file collection with verified
+                    $exitValue = &compareStream("verified/$files[$j].stderr");
+                    if ( $exitValue & 4 ) {
+                        # STDERR verified doesn't exist. Search STDERR capture
+                        # for strings indicating error or failure
+                        $exitValue |= &errorStrSearch("$files[$j].stderr");
+                    }
+                    if ( ($exitValue & 16) || ($exitValue & 128) ) {
+                        # Increment the total number of tests failed
+                        $testDriverFailCount++;
+                        # Push test on failed list
+                        print("Test failed ($failPoints out of $totalPoints testpoints failed)\n") if ( ! $silent);
+                        push(@testsFailed, $pwd . "/" . $files[$j]);
+                    } else {
+                       print("Test successful ($totalPoints testpoints)\n") if ( ! $silent);
+                    }
+                }
+            }
+        }
+        $j++;
+    }
+}
+
+################################################################################
+#
+#  SUBROUTINE: errorStrSearch
+#
+#      Description:  This subroutine will search the file specified in its
+#                    parameter for error strings and if they do exists
+#                    the appropriate value will be returned.
+#
+#      Parameter(s): fileName - input file to search for strings
+#
+#      Return:   0  -  No error strings found
+#               64  -  Error strings found in STDOUT
+#              128  -  Error strings found in STDERR
+#
+###############################################################################
+
+sub errorStrSearch {
+    local($fileName) = @_;
+    local($returnVal) = 0;
+
+    # Open the captured file
+    open(CAPT_FILE, "<temp/$fileName");
+
+    # Scan through all the lines of the file searching for error strings
+    while ( <CAPT_FILE> ) {
+        if ( m/FAIL/i || m/FAULT/i || m/ERROR/i || m/Not Found/i
+                      || m/SIGNAL/i || m/NO SUCH FILE/i || m/|E|/i
+                      || m/|A|/i ) {
+            if ( $fileName =~ m/out/ ) {
+                print("        Failed - File $fileName contains error strings.\n");
+                $returnVal = 64;
+            } elsif ( $fileName =~ m/err/ ) {
+                print("        Failed - File $fileName contains error strings.\n");
+                $returnVal = 128;
+            }
+            last;
+        }
+    }
+    # Close the capture file
+    close(CAPT_FILE);
+    # Return the return value
+    return($returnVal);
+}
+
+################################################################################
+#
+#  SUBROUTINE: compareStream
+#
+#      Description:  This subroutine will compare the captured stream file with
+#                    a file in the verified directory if one exists.
+#
+#      Parameter(s): streamFile - input file to compare
+#
+#      Return:   0  -  Compare successful
+#                2  -  STDOUT verified file doesn't exist
+#                4  -  STDERR verified file doesn't exist
+#                8  -  STDOUT verified file doesn't compare
+#               16  -  STDERR verified file doesn't compare
+#
+###############################################################################
+
+sub compareStream {
+    local($streamFile) = @_;
+    local($returnVal) = 0;
+    local($tempFile) = "";
+
+    # Check for existence of verified STD stream files
+    if ( !( -e $streamFile) ) {
+
+        # Display message to user that verified STDOUT file doesn't exist
+        print("        File $streamFile doesn't exist.\n") if ($verbose);
+
+        # Set exit value bit 1 to indicate proper failure
+        if ( $streamFile =~ /out$/ ) {
+            $returnVal |= 2;
+        } elsif ( $streamFile =~ /err$/ ) {
+            $returnVal |= 4;
+        }
+    } else {
+
+        # Verified STD stream file exists
+
+        # Create name of the temp file to compare
+        $tempFile = $streamFile;
+        $tempFile =~ s/verified/temp/;
+        $tempFile = $tempFile . ".mod";
+
+        # Perform difference on the STD stream files
+        $diffstdout = `diff $streamFile $tempFile`;
+
+        # Check the return value of the difference
+        if ( $? != 0 ) {
+
+            # Difference of STD stream files failed
+
+            # Check for STDOUT in file name to convey appropirate return value
+            if ( $streamFile =~ /out$/ ) {
+               # Display message of the failure of difference to user
+               print("        Failed - STDOUT difference\n$diffstdout\n");
+
+               # Exit value to indicate STDOUT did not compare
+               $returnVal |= 8;
+            } elsif ( $streamFile =~ /err$/ ) {
+               # Display message of the failure of difference to user
+               print("        Failed - STDERR difference\n$diffstdout\n");
+
+               # Exit value to indicate STDERR did not compare
+               $returnVal |= 16;
+            }
+        }
+    }
+
+    # Return the result of the compare
+    return($returnVal);
+}
+
+
+################################################################################
+#
+#  SUBROUTINE: checkForTempDirectory
+#
+#      Description:  This subroutine will check for the existence of a temp
+#                    directory to store STDOUT, STDERR files during test.  If
+#                    the subdirectory doesn't exist, it will be created.
+#
+#      Parameter(s):  None
+#
+#      Return: None
+#
+################################################################################
+
+sub checkForTempDirectory{
+
+    # Check if a temp directory already exists in the current work directory
+    if ( !( -e "temp" )) {
+        # Create temp directory to store STDOUT, STDERR files during test
+        `mkdir temp`;
+        # Display message of new directory created
+        print("Creating temp directory\n") if ( $verbose );
+    }
+}
+
+################################################################################
+#
+#  SUBROUTINE: checkForVerifiedDirectory
+#
+#      Description:  This subroutine will check for the existence of a verified
+#                    directory which stores verified STDOUT, STDERR files for
+#                    comparison during the test.
+#
+#      Parameter(s):  None
+#
+#      Return: 0 - subdirectory present
+#              1 - subdirectory not present
+#
+################################################################################
+
+sub checkForVerifiedDirectory{
+    $returnValue = 0;
+    # Check if verified subdirectory exists in the current working directory
+    if ( !( -e "verified")) {
+       # Set return value to 1
+       $returnValue = 1;
+    }
+    return($returnValue);
+}
+
+################################################################################
+#
+#  SUBROUTINE: filterStdFiles
+#
+#      Description:  This subroutine will filter variable items in the STDOUT
+#                    and STDERR files captured.  Date, time and host names
+#                    are variable items in the log messages captured.
+#
+#      Parameter(s):  test file name
+#
+#      Return: None
+#
+################################################################################
+
+sub filterStdFiles{
+
+   local($fileName) = @_;
+
+   # Open the STDOUT file for reading
+   open(OUTFILE, "< temp/$fileName.stdout");
+   # Open mod file to place filtered STDOUT
+   open(MODFILE, "> temp/$fileName.stdout.mod");
+   # Replace the variable data, time and host information with constants
+   while( <OUTFILE> ) {
+       s/\d+:\d+:\d+/ <DATE> /;
+       s/\s+\d+:\d+:\d+\w/ <TIME> /;
+       s/\|\s*[\w\.\-\_]+\s*\|/<HOST> |/;
+       # Filter lines with *** malloc.  This is an artifact of Mac testing of
+       # memory functions
+       if ( ! m/\*\*\*\smalloc/ ) {
+          print MODFILE ($_);
+       }
+   }
+   # Close mod file
+   close(MODFILE);
+   # Close STDERR file
+   close(OUTFILE);
+
+   # Open the STDERR file for reading
+   open(OUTFILE, "< temp/$fileName.stderr");
+   # Open mod file to place filtered STDERR
+   open(MODFILE, "> temp/$fileName.stderr.mod");
+   # Replace the variable date, time and host information with constants
+   while( <OUTFILE> ) {
+       s/\d+:\d+:\d+/ <DATE> /;
+       s/\s+\d+:\d+:\d+\w/ <TIME> /;
+       s/\|\s*[\w\.\-\_]+\s*\|/<HOST> |/;
+       # Filter lines with *** malloc.  This is an artifact of Mac testing of
+       # memory functions
+       if ( ! m/\*\*\*\smalloc/ ) {
+          print MODFILE ($_);
+       }
+   }
+   # Close mod file
+   close(MODFILE);
+   # Close STDERR file
+   close(OUTFILE);
+}
+
Index: /tags/rel1_1/psLib/test/Makefile
===================================================================
--- /tags/rel1_1/psLib/test/Makefile	(revision 1056)
+++ /tags/rel1_1/psLib/test/Makefile	(revision 1056)
@@ -0,0 +1,99 @@
+##############################################################################
+##
+##  Makefile:   test
+##
+##  $Revision: 1.5.2.1 $  $Name: not supported by cvs2svn $
+##  $Date: 2004-06-15 03:09:20 $
+##
+##  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+###############################################################################
+
+# Define variable prefix to the top level project - psLib
+# This is necessary for definition is Makefile.Globals uses prefix
+
+ifndef prefix
+    export prefix=$(shell cd ..;pwd)
+endif
+
+# Define the two targets to be built
+
+TARGET_STATIC  = libpstest.a
+TARGET_DYNAMIC = libpstest.$(DLL)
+
+# Include the make global definitions for the project
+
+include ../src/Makefile.Globals
+
+# Set CFLAGS used by the implicit rule to compile .c
+
+CFLAGS := $(CFLAGS_RELOC) -I../include
+
+# Define the source objects
+ 
+SRC_OBJS = psTest.o
+
+# Define PHONY target "all" which will make all the necessary items
+
+all: $(TARGET_STATIC) $(TARGET_DYNAMIC)
+
+# Rule to make static library
+
+libpstest.a: $(SRC_OBJS)
+# The ar option -r is to add/replace object and -s is to create
+# a symbol table in the archive
+	$(AR) rcs $@ $(SRC_OBJS)
+
+# Rule to make dynamic library
+
+libpstest.$(DLL): $(SRC_OBJS)
+	$(CC) $(LDFLAGS_DLL) -L../lib -lpslib $(SRC_OBJS) -o $@  
+
+# Define PHONY target "install" which will install necessary files
+
+install: $(TARGET_STATIC) $(TARGET_DYNAMIC) $(includedir) $(libexecdir) 
+	install *.h $(includedir)
+	install $(TARGET_STATIC) $(libexecdir)
+	install $(TARGET_DYNAMIC) $(libexecdir)
+
+installtests: install $(testbindir)
+	install FullUnitTest runTest $(testbindir)
+	$(MAKE) --directory=collections install
+	$(MAKE) --directory=dataManip install
+	$(MAKE) --directory=sysUtils install
+
+# Define PHONY target "distclean" which will cleanup the distribution
+
+distclean:	clean
+	$(MAKE) --directory=collections distclean
+	$(MAKE) --directory=dataManip distclean
+	$(MAKE) --directory=sysUtils distclean
+	$(RM) $(TARGET_STATIC)
+	$(RM) $(TARGET_DYNAMIC)
+	$(RM) $(libexecdir)/$(TARGET_STATIC)
+	$(RM) $(libexecdir)/$(TARGET_DYNAMIC)
+
+# Define PHONY target "clean" which will cleanup the development area
+
+clean:
+	$(MAKE) --directory=collections clean
+	$(MAKE) --directory=dataManip clean
+	$(MAKE) --directory=sysUtils clean
+	@echo "    Deleting intermediate files for 'test'"
+	$(RM) $(SRC_OBJS) *.lint
+
+%.lint: %.c
+	splint +posixlib -exportlocal -realcompare $(INCLUDE_GLOBAL) $? > $@; cat $@
+
+# Rule to make include directory if needed
+
+$(includedir):
+	mkdir -p $(includedir)
+
+# Rule to make lib directory if needed
+
+$(libexecdir):
+	mkdir -p $(libexecdir)
+
+$(testbindir):
+	mkdir -p $(testbindir)
+
Index: /tags/rel1_1/psLib/test/collections/.cvsignore
===================================================================
--- /tags/rel1_1/psLib/test/collections/.cvsignore	(revision 1056)
+++ /tags/rel1_1/psLib/test/collections/.cvsignore	(revision 1056)
@@ -0,0 +1,18 @@
+CVS
+temp
+Makefile
+tst_psBitSet_01
+tst_psBitSet_02
+tst_psBitSet_03
+tst_psBitSet_04
+tst_psBitSet_05
+tst_psBitSet_06
+tst_psImage
+tst_psSort_01
+tst_psSort_02
+tst_psSort_03
+tst_psSort_04
+tst_psVector_01
+tst_psVector_02
+tst_psVector_03
+tst_psList
Index: /tags/rel1_1/psLib/test/collections/Makefile
===================================================================
--- /tags/rel1_1/psLib/test/collections/Makefile	(revision 1056)
+++ /tags/rel1_1/psLib/test/collections/Makefile	(revision 1056)
@@ -0,0 +1,85 @@
+################################################################################
+##
+##  Makefile:   test/collections
+##
+##  $Revision: 1.14 $  $Name: not supported by cvs2svn $
+##  $Date: 2004-06-11 20:36:04 $
+##
+##  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+##
+###############################################################################
+
+ifndef prefix
+    export prefix=$(shell cd ../..;pwd)
+endif
+
+include ../../src/Makefile.Globals
+
+PSLIB_INCL_DIR = ../../include
+
+PSLIB_LIB_DIR = ../../lib
+
+TARGET = tst_psVector_01 \
+         tst_psVector_02 \
+         tst_psVector_03 \
+         tst_psBitSet_01 \
+         tst_psBitSet_02 \
+         tst_psBitSet_03 \
+         tst_psBitSet_04 \
+         tst_psBitSet_05 \
+         tst_psBitSet_06 \
+         tst_psSort_01   \
+         tst_psSort_02   \
+         tst_psSort_03   \
+         tst_psSort_04   \
+         tst_psImage     \
+         tst_psList
+
+DEPENDENCIES = $(addprefix builddir/,$(addsuffix .d,$(TARGET)))
+OBJS = $(addprefix builddir/,$(addsuffix .o,$(TARGET)))
+
+all: builddir $(TARGET)
+
+builddir:
+	mkdir builddir
+
+include $(DEPENDENCIES)
+
+clean:
+	@echo "    Deleting executable and binary files for 'test/collections'"
+	$(RM) $(OBJS) *.lint builddir/*.i
+
+distclean: clean
+	$(RM) $(TARGET)
+
+builddir/%.o : builddir/%.i
+	$(CC) $(CFLAGS) -I$(PSLIB_INCL_DIR) -c -o $@ $<
+
+builddir/%.o : %.c
+	$(CC) $(CFLAGS) -I$(PSLIB_INCL_DIR) -c -o $@ $<
+
+%   : builddir/%.o
+	$(CC) -o $@ $< -L$(PSLIB_LIB_DIR) -lpslib -lpstest $(LDFLAGS)
+
+%.lint: %.c
+	splint +posixlib -exportlocal -realcompare $(INCLUDE_GLOBAL) $? > $@; cat $@
+
+builddir/%.i: %.c
+	$(CC) -E $(CFLAGS) $(CPPFLAGS) -I$(PSLIB_INCL_DIR) -o $@ $<
+
+builddir/%.d: %.c
+	$(CC) -MM $(CFLAGS) -I$(PSLIB_INCL_DIR) $< > $@.tmp
+	sed 's|\($*\)\.o[ :]*|builddir\/\1.o $@ : |g' $@.tmp > $@
+	$(RM) -f $@.tmp
+
+install: $(testbindir) $(testbindir)/verified $(TARGET)
+	install $(TARGET) $(testbindir)
+	install verified/*.stderr verified/*.stdout $(testbindir)/verified
+
+$(testbindir):
+	mkdir -p $(testbindir)
+
+$(testbindir)/verified:
+	mkdir -p $(testbindir)/verified
+
+
Index: /tags/rel1_1/psLib/test/collections/builddir/tst_psBitSet_01.d
===================================================================
--- /tags/rel1_1/psLib/test/collections/builddir/tst_psBitSet_01.d	(revision 1056)
+++ /tags/rel1_1/psLib/test/collections/builddir/tst_psBitSet_01.d	(revision 1056)
@@ -0,0 +1,8 @@
+builddir/tst_psBitSet_01.o builddir/tst_psBitSet_01.d : tst_psBitSet_01.c ../../include/pslib.h \
+  ../../include/psMemory.h ../../include/psLogMsg.h \
+  ../../include/psTrace.h ../../include/psAbort.h ../../include/psError.h \
+  ../../include/psString.h ../../include/psType.h ../../include/psList.h \
+  ../../include/psVector.h ../../include/psHash.h ../../include/psImage.h \
+  ../../include/psBitSet.h ../../include/psSort.h ../../include/psStats.h \
+  ../../include/psMatrix.h ../../include/psFFT.h \
+  ../../include/psImageIO.h ../../include/psTest.h
Index: /tags/rel1_1/psLib/test/collections/builddir/tst_psBitSet_02.d
===================================================================
--- /tags/rel1_1/psLib/test/collections/builddir/tst_psBitSet_02.d	(revision 1056)
+++ /tags/rel1_1/psLib/test/collections/builddir/tst_psBitSet_02.d	(revision 1056)
@@ -0,0 +1,8 @@
+builddir/tst_psBitSet_02.o builddir/tst_psBitSet_02.d : tst_psBitSet_02.c ../../include/pslib.h \
+  ../../include/psMemory.h ../../include/psLogMsg.h \
+  ../../include/psTrace.h ../../include/psAbort.h ../../include/psError.h \
+  ../../include/psString.h ../../include/psType.h ../../include/psList.h \
+  ../../include/psVector.h ../../include/psHash.h ../../include/psImage.h \
+  ../../include/psBitSet.h ../../include/psSort.h ../../include/psStats.h \
+  ../../include/psMatrix.h ../../include/psFFT.h \
+  ../../include/psImageIO.h ../../include/psTest.h
Index: /tags/rel1_1/psLib/test/collections/builddir/tst_psBitSet_03.d
===================================================================
--- /tags/rel1_1/psLib/test/collections/builddir/tst_psBitSet_03.d	(revision 1056)
+++ /tags/rel1_1/psLib/test/collections/builddir/tst_psBitSet_03.d	(revision 1056)
@@ -0,0 +1,8 @@
+builddir/tst_psBitSet_03.o builddir/tst_psBitSet_03.d : tst_psBitSet_03.c ../../include/pslib.h \
+  ../../include/psMemory.h ../../include/psLogMsg.h \
+  ../../include/psTrace.h ../../include/psAbort.h ../../include/psError.h \
+  ../../include/psString.h ../../include/psType.h ../../include/psList.h \
+  ../../include/psVector.h ../../include/psHash.h ../../include/psImage.h \
+  ../../include/psBitSet.h ../../include/psSort.h ../../include/psStats.h \
+  ../../include/psMatrix.h ../../include/psFFT.h \
+  ../../include/psImageIO.h ../../include/psTest.h
Index: /tags/rel1_1/psLib/test/collections/builddir/tst_psBitSet_04.d
===================================================================
--- /tags/rel1_1/psLib/test/collections/builddir/tst_psBitSet_04.d	(revision 1056)
+++ /tags/rel1_1/psLib/test/collections/builddir/tst_psBitSet_04.d	(revision 1056)
@@ -0,0 +1,8 @@
+builddir/tst_psBitSet_04.o builddir/tst_psBitSet_04.d : tst_psBitSet_04.c ../../include/pslib.h \
+  ../../include/psMemory.h ../../include/psLogMsg.h \
+  ../../include/psTrace.h ../../include/psAbort.h ../../include/psError.h \
+  ../../include/psString.h ../../include/psType.h ../../include/psList.h \
+  ../../include/psVector.h ../../include/psHash.h ../../include/psImage.h \
+  ../../include/psBitSet.h ../../include/psSort.h ../../include/psStats.h \
+  ../../include/psMatrix.h ../../include/psFFT.h \
+  ../../include/psImageIO.h ../../include/psTest.h
Index: /tags/rel1_1/psLib/test/collections/builddir/tst_psBitSet_05.d
===================================================================
--- /tags/rel1_1/psLib/test/collections/builddir/tst_psBitSet_05.d	(revision 1056)
+++ /tags/rel1_1/psLib/test/collections/builddir/tst_psBitSet_05.d	(revision 1056)
@@ -0,0 +1,8 @@
+builddir/tst_psBitSet_05.o builddir/tst_psBitSet_05.d : tst_psBitSet_05.c ../../include/pslib.h \
+  ../../include/psMemory.h ../../include/psLogMsg.h \
+  ../../include/psTrace.h ../../include/psAbort.h ../../include/psError.h \
+  ../../include/psString.h ../../include/psType.h ../../include/psList.h \
+  ../../include/psVector.h ../../include/psHash.h ../../include/psImage.h \
+  ../../include/psBitSet.h ../../include/psSort.h ../../include/psStats.h \
+  ../../include/psMatrix.h ../../include/psFFT.h \
+  ../../include/psImageIO.h ../../include/psTest.h
Index: /tags/rel1_1/psLib/test/collections/builddir/tst_psBitSet_06.d
===================================================================
--- /tags/rel1_1/psLib/test/collections/builddir/tst_psBitSet_06.d	(revision 1056)
+++ /tags/rel1_1/psLib/test/collections/builddir/tst_psBitSet_06.d	(revision 1056)
@@ -0,0 +1,8 @@
+builddir/tst_psBitSet_06.o builddir/tst_psBitSet_06.d : tst_psBitSet_06.c ../../include/pslib.h \
+  ../../include/psMemory.h ../../include/psLogMsg.h \
+  ../../include/psTrace.h ../../include/psAbort.h ../../include/psError.h \
+  ../../include/psString.h ../../include/psType.h ../../include/psList.h \
+  ../../include/psVector.h ../../include/psHash.h ../../include/psImage.h \
+  ../../include/psBitSet.h ../../include/psSort.h ../../include/psStats.h \
+  ../../include/psMatrix.h ../../include/psFFT.h \
+  ../../include/psImageIO.h ../../include/psTest.h
Index: /tags/rel1_1/psLib/test/collections/builddir/tst_psImage.d
===================================================================
--- /tags/rel1_1/psLib/test/collections/builddir/tst_psImage.d	(revision 1056)
+++ /tags/rel1_1/psLib/test/collections/builddir/tst_psImage.d	(revision 1056)
@@ -0,0 +1,8 @@
+builddir/tst_psImage.o builddir/tst_psImage.d : tst_psImage.c ../../include/psTest.h ../../include/pslib.h \
+  ../../include/psMemory.h ../../include/psLogMsg.h \
+  ../../include/psTrace.h ../../include/psAbort.h ../../include/psError.h \
+  ../../include/psString.h ../../include/psType.h ../../include/psList.h \
+  ../../include/psVector.h ../../include/psHash.h ../../include/psImage.h \
+  ../../include/psBitSet.h ../../include/psSort.h ../../include/psStats.h \
+  ../../include/psMatrix.h ../../include/psFFT.h \
+  ../../include/psImageIO.h
Index: /tags/rel1_1/psLib/test/collections/builddir/tst_psList.d
===================================================================
--- /tags/rel1_1/psLib/test/collections/builddir/tst_psList.d	(revision 1056)
+++ /tags/rel1_1/psLib/test/collections/builddir/tst_psList.d	(revision 1056)
@@ -0,0 +1,8 @@
+builddir/tst_psList.o builddir/tst_psList.d : tst_psList.c ../../include/psTest.h ../../include/pslib.h \
+  ../../include/psMemory.h ../../include/psLogMsg.h \
+  ../../include/psTrace.h ../../include/psAbort.h ../../include/psError.h \
+  ../../include/psString.h ../../include/psType.h ../../include/psList.h \
+  ../../include/psVector.h ../../include/psHash.h ../../include/psImage.h \
+  ../../include/psBitSet.h ../../include/psSort.h ../../include/psStats.h \
+  ../../include/psMatrix.h ../../include/psFFT.h \
+  ../../include/psImageIO.h
Index: /tags/rel1_1/psLib/test/collections/builddir/tst_psSort_01.d
===================================================================
--- /tags/rel1_1/psLib/test/collections/builddir/tst_psSort_01.d	(revision 1056)
+++ /tags/rel1_1/psLib/test/collections/builddir/tst_psSort_01.d	(revision 1056)
@@ -0,0 +1,8 @@
+builddir/tst_psSort_01.o builddir/tst_psSort_01.d : tst_psSort_01.c ../../include/pslib.h \
+  ../../include/psMemory.h ../../include/psLogMsg.h \
+  ../../include/psTrace.h ../../include/psAbort.h ../../include/psError.h \
+  ../../include/psString.h ../../include/psType.h ../../include/psList.h \
+  ../../include/psVector.h ../../include/psHash.h ../../include/psImage.h \
+  ../../include/psBitSet.h ../../include/psSort.h ../../include/psStats.h \
+  ../../include/psMatrix.h ../../include/psFFT.h \
+  ../../include/psImageIO.h ../../include/psTest.h
Index: /tags/rel1_1/psLib/test/collections/builddir/tst_psSort_02.d
===================================================================
--- /tags/rel1_1/psLib/test/collections/builddir/tst_psSort_02.d	(revision 1056)
+++ /tags/rel1_1/psLib/test/collections/builddir/tst_psSort_02.d	(revision 1056)
@@ -0,0 +1,8 @@
+builddir/tst_psSort_02.o builddir/tst_psSort_02.d : tst_psSort_02.c ../../include/pslib.h \
+  ../../include/psMemory.h ../../include/psLogMsg.h \
+  ../../include/psTrace.h ../../include/psAbort.h ../../include/psError.h \
+  ../../include/psString.h ../../include/psType.h ../../include/psList.h \
+  ../../include/psVector.h ../../include/psHash.h ../../include/psImage.h \
+  ../../include/psBitSet.h ../../include/psSort.h ../../include/psStats.h \
+  ../../include/psMatrix.h ../../include/psFFT.h \
+  ../../include/psImageIO.h ../../include/psTest.h
Index: /tags/rel1_1/psLib/test/collections/builddir/tst_psSort_03.d
===================================================================
--- /tags/rel1_1/psLib/test/collections/builddir/tst_psSort_03.d	(revision 1056)
+++ /tags/rel1_1/psLib/test/collections/builddir/tst_psSort_03.d	(revision 1056)
@@ -0,0 +1,8 @@
+builddir/tst_psSort_03.o builddir/tst_psSort_03.d : tst_psSort_03.c ../../include/pslib.h \
+  ../../include/psMemory.h ../../include/psLogMsg.h \
+  ../../include/psTrace.h ../../include/psAbort.h ../../include/psError.h \
+  ../../include/psString.h ../../include/psType.h ../../include/psList.h \
+  ../../include/psVector.h ../../include/psHash.h ../../include/psImage.h \
+  ../../include/psBitSet.h ../../include/psSort.h ../../include/psStats.h \
+  ../../include/psMatrix.h ../../include/psFFT.h \
+  ../../include/psImageIO.h ../../include/psTest.h
Index: /tags/rel1_1/psLib/test/collections/builddir/tst_psSort_04.d
===================================================================
--- /tags/rel1_1/psLib/test/collections/builddir/tst_psSort_04.d	(revision 1056)
+++ /tags/rel1_1/psLib/test/collections/builddir/tst_psSort_04.d	(revision 1056)
@@ -0,0 +1,8 @@
+builddir/tst_psSort_04.o builddir/tst_psSort_04.d : tst_psSort_04.c ../../include/pslib.h \
+  ../../include/psMemory.h ../../include/psLogMsg.h \
+  ../../include/psTrace.h ../../include/psAbort.h ../../include/psError.h \
+  ../../include/psString.h ../../include/psType.h ../../include/psList.h \
+  ../../include/psVector.h ../../include/psHash.h ../../include/psImage.h \
+  ../../include/psBitSet.h ../../include/psSort.h ../../include/psStats.h \
+  ../../include/psMatrix.h ../../include/psFFT.h \
+  ../../include/psImageIO.h ../../include/psTest.h
Index: /tags/rel1_1/psLib/test/collections/builddir/tst_psVector_01.d
===================================================================
--- /tags/rel1_1/psLib/test/collections/builddir/tst_psVector_01.d	(revision 1056)
+++ /tags/rel1_1/psLib/test/collections/builddir/tst_psVector_01.d	(revision 1056)
@@ -0,0 +1,8 @@
+builddir/tst_psVector_01.o builddir/tst_psVector_01.d : tst_psVector_01.c ../../include/pslib.h \
+  ../../include/psMemory.h ../../include/psLogMsg.h \
+  ../../include/psTrace.h ../../include/psAbort.h ../../include/psError.h \
+  ../../include/psString.h ../../include/psType.h ../../include/psList.h \
+  ../../include/psVector.h ../../include/psHash.h ../../include/psImage.h \
+  ../../include/psBitSet.h ../../include/psSort.h ../../include/psStats.h \
+  ../../include/psMatrix.h ../../include/psFFT.h \
+  ../../include/psImageIO.h ../../include/psTest.h
Index: /tags/rel1_1/psLib/test/collections/builddir/tst_psVector_02.d
===================================================================
--- /tags/rel1_1/psLib/test/collections/builddir/tst_psVector_02.d	(revision 1056)
+++ /tags/rel1_1/psLib/test/collections/builddir/tst_psVector_02.d	(revision 1056)
@@ -0,0 +1,8 @@
+builddir/tst_psVector_02.o builddir/tst_psVector_02.d : tst_psVector_02.c ../../include/pslib.h \
+  ../../include/psMemory.h ../../include/psLogMsg.h \
+  ../../include/psTrace.h ../../include/psAbort.h ../../include/psError.h \
+  ../../include/psString.h ../../include/psType.h ../../include/psList.h \
+  ../../include/psVector.h ../../include/psHash.h ../../include/psImage.h \
+  ../../include/psBitSet.h ../../include/psSort.h ../../include/psStats.h \
+  ../../include/psMatrix.h ../../include/psFFT.h \
+  ../../include/psImageIO.h ../../include/psTest.h
Index: /tags/rel1_1/psLib/test/collections/builddir/tst_psVector_03.d
===================================================================
--- /tags/rel1_1/psLib/test/collections/builddir/tst_psVector_03.d	(revision 1056)
+++ /tags/rel1_1/psLib/test/collections/builddir/tst_psVector_03.d	(revision 1056)
@@ -0,0 +1,8 @@
+builddir/tst_psVector_03.o builddir/tst_psVector_03.d : tst_psVector_03.c ../../include/pslib.h \
+  ../../include/psMemory.h ../../include/psLogMsg.h \
+  ../../include/psTrace.h ../../include/psAbort.h ../../include/psError.h \
+  ../../include/psString.h ../../include/psType.h ../../include/psList.h \
+  ../../include/psVector.h ../../include/psHash.h ../../include/psImage.h \
+  ../../include/psBitSet.h ../../include/psSort.h ../../include/psStats.h \
+  ../../include/psMatrix.h ../../include/psFFT.h \
+  ../../include/psImageIO.h ../../include/psTest.h
Index: /tags/rel1_1/psLib/test/collections/tst_psBitSet_01.c
===================================================================
--- /tags/rel1_1/psLib/test/collections/tst_psBitSet_01.c	(revision 1056)
+++ /tags/rel1_1/psLib/test/collections/tst_psBitSet_01.c	(revision 1056)
@@ -0,0 +1,133 @@
+/** @file  tst_psBitSet_01.c
+ *
+ *  @brief Test driver for psBitSet functions
+ *
+ *  This test driver contains the following tests for psArray test point 1:
+ *     A)  Create psBitSet
+ *     B)  Set bits
+ *     C)  Test bits
+ *     D)  Attempt to test negative bit
+ *     E)  Attempt to test bit to large
+ *     F)  Attempt to test bit in null BitSet
+ *     G)  Attempt to set negative bit
+ *     H)  Attempt to set bit to large
+ *     I)  Attempt to set bit in null BitSet
+ *     J)  Free psBitSet
+ *
+ *  @author  Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.4 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2004-06-10 00:28:23 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#include "pslib.h"
+#include "psTest.h"
+
+int main(int argc,
+         char* argv[])
+{
+    char *binOut = NULL;
+    psBitSet *tempBs = NULL;
+
+
+    // Test A - Create psBitSet
+    printPositiveTestHeader(stdout,"psBitSet", "Create psBitSet");
+    printf("Creating psBitSet with 24 bits...\n");
+    psBitSet* bs = psBitSetAlloc(24);
+    binOut = psBitSetToString(bs);
+    printf("%s\n\n", binOut);
+    psFree(binOut);
+    printFooter(stdout, "psBitSet", "Create psBitSet", true);
+
+
+    // Test B - Set bits
+    printPositiveTestHeader(stdout, "psBitSet", "Set bits");
+    tempBs = bs;
+    printf("Setting first bit...\n");
+    bs = psBitSetSet(bs, 0);
+    printf("Setting third bit...\n");
+    bs = psBitSetSet(bs, 2);
+    printf("Setting last bit...\n");
+    bs = psBitSetSet(bs, 23);
+    if(bs != tempBs) {
+        printf("Error: Return pointer not equal to output argument pointer\n");
+    }
+    binOut = psBitSetToString(bs);
+    printf("%s\n\n", binOut);
+    psFree(binOut);
+    printFooter(stdout, "psBitSet", "Set bits", true);
+
+
+    // Test C - Test bits
+    printPositiveTestHeader(stdout, "psBitSet", "Test bits");
+    printf("Testing first bit...\n");
+    printf("Result: %d\n", psBitSetTest(bs, 0));
+    printf("Testing third bit...\n");
+    printf("Result: %d\n", psBitSetTest(bs, 2));
+    printf("Testing last bit...\n");
+    printf("Result: %d\n", psBitSetTest(bs, 23));
+    printFooter(stdout, "psBitSet", "Test bits", true);
+
+
+    // Test D - Attempt to test negative bit
+    printNegativeTestHeader(stdout,"psBitSet", "Attempt to test negative bit",
+                            "Bit position too small: -4", 0);
+    if(psBitSetTest(bs, -4)) {
+        printf("Error: Return value should be zero\n");
+    }
+    printFooter(stdout, "psBitSet", "Attempt to test negative bit", true);
+
+
+    // Test E - Attempt to test bit to large
+    printNegativeTestHeader(stdout,"psBitSet", "Attempt to test bit to large",
+                            "Bit position too large: 200", 0);
+    if(psBitSetTest(bs, 200)) {
+        printf("Error: Return value should be zero\n");
+    }
+    printFooter(stdout, "psBitSet", "Attempt to test bit to large", true);
+
+
+    // Test F - Attempt to test bit in null BitSet
+    printNegativeTestHeader(stdout,"psBitSet", "Attempt to test bit in null BitSet",
+                            "Null psBitSet for inBitSet argument", 0);
+    psBitSetTest(NULL, 0);
+    printFooter(stdout, "psBitSet", "Attempt to test bit in null BitSet", true);
+
+
+    // Test G - Attempt to set negative bit
+    printNegativeTestHeader(stdout,"psBitSet", "Attempt to set negative bit",
+                            "Bit position too small: -4", 0);
+    bs = psBitSetSet(bs, -4);
+    printFooter(stdout, "psBitSet", "Attempt to set negative bit", true);
+
+
+    // Test H - Attempt to set bit to large
+    printNegativeTestHeader(stdout,"psBitSet", "Attempt to set bit to large",
+                            "Bit position too large: 200", 0);
+    bs = psBitSetSet(bs, 200);
+    printFooter(stdout, "psBitSet", "Attempt to set bit to large", true);
+
+
+    // Test I - Attempt to set bit in null BitSet
+    printNegativeTestHeader(stdout,"psBitSet", "Attempt to set bit in null BitSet",
+                            "Null psBitSet for inBitSet argument", 0);
+    psBitSetSet(NULL, 0);
+    printFooter(stdout, "psBitSet", "Attempt to set bit in null BitSet", true);
+
+
+    // Test J - Free psBitSet
+    printPositiveTestHeader(stdout, "psBitSet", "Free psBitSet");
+    psBitSetFree(bs);
+    psMemCheckLeaks(0, NULL, stdout);
+    psMemCheckCorruption(0);
+    int nBad = psMemCheckCorruption(0);
+    if(nBad) {
+        printf("ERROR: Found %d bad memory blocks\n", nBad);
+    }
+    printFooter(stdout, "psBitSet", "Free psBitSet", true);
+
+    return 0;
+}
Index: /tags/rel1_1/psLib/test/collections/tst_psBitSet_02.c
===================================================================
--- /tags/rel1_1/psLib/test/collections/tst_psBitSet_02.c	(revision 1056)
+++ /tags/rel1_1/psLib/test/collections/tst_psBitSet_02.c	(revision 1056)
@@ -0,0 +1,76 @@
+/** @file  tst_psBitSet_02.c
+ *
+ *  @brief Test driver for psBitSet functions
+ *
+ *  This test driver contains the following tests for psArray test point 2:
+ *     A)  Create two psBitSets
+ *     B)  Perform binary AND with psBitSets
+ *     C)  Free psBitSets
+ *
+ *  @author  Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.4 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2004-06-11 01:39:30 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#include "pslib.h"
+#include "psTest.h"
+
+int main(int argc,
+         char* argv[])
+{
+    char *binOut = NULL;
+
+
+    // Test A - Create two psBitSets
+    printPositiveTestHeader(stdout,"psBitSet", "Create two psBitSets");
+    psBitSet* bs1 = psBitSetAlloc(24);
+    psBitSet* bs2 = psBitSetAlloc(24);
+    binOut = psBitSetToString(bs1);
+    printf("%s\n", binOut);
+    psFree(binOut);
+    binOut = psBitSetToString(bs2);
+    printf("%s\n\n", binOut);
+    psFree(binOut);
+    printf("Setting all bits true...\n");
+    for(int i=0; i<24; i++) {
+        bs1 = psBitSetSet(bs1, i);
+        bs2 = psBitSetSet(bs2, i);
+    }
+    binOut = psBitSetToString(bs1);
+    printf("%s\n", binOut);
+    psFree(binOut);
+    binOut = psBitSetToString(bs2);
+    printf("%s\n\n", binOut);
+    psFree(binOut);
+    printFooter(stdout, "psBitSet", "Create two psBitSets", true);
+
+
+    // Test B - Perform binary AND with psBitSets
+    printPositiveTestHeader(stdout,"psBitSet", "Perform binary AND with psBitSets");
+    psBitSet* outbs = psBitSetAlloc(24);
+    outbs = psBitSetOp(outbs, bs1, "AND", bs2);
+    binOut = psBitSetToString(outbs);
+    printf("Result:\n");
+    printf("%s\n", binOut);
+    psFree(binOut);
+    printFooter(stdout, "psBitSet", "Perform binary AND with psBitSets", true);
+
+
+    // Test C - Free psBitSets
+    printPositiveTestHeader(stdout, "psBitSet", "Free psBitSets");
+    psBitSetFree(bs1);
+    psBitSetFree(bs2);
+    psBitSetFree(outbs);
+    psMemCheckLeaks(0, NULL, stdout);
+    int nBad = psMemCheckCorruption(0);
+    if(nBad) {
+        printf("ERROR: Found %d bad memory blocks\n", nBad);
+    }
+    printFooter(stdout, "psBitSet", "Free psBitSets", true);
+
+    return 0;
+}
Index: /tags/rel1_1/psLib/test/collections/tst_psBitSet_03.c
===================================================================
--- /tags/rel1_1/psLib/test/collections/tst_psBitSet_03.c	(revision 1056)
+++ /tags/rel1_1/psLib/test/collections/tst_psBitSet_03.c	(revision 1056)
@@ -0,0 +1,76 @@
+/** @file  tst_psBitSet_03.c
+ *
+ *  @brief Test driver for psBitSet functions
+ *
+ *  This test driver contains the following tests for psArray test point 3:
+ *     A)  Create two psBitSets
+ *     B)  Perform binary OR with psBitSets
+ *     C)  Free psBitSets
+ *
+ *  @author  Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.5 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2004-06-11 01:40:45 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#include "pslib.h"
+#include "psTest.h"
+
+int main(int argc,
+         char* argv[])
+{
+    char *binOut = NULL;
+
+
+    // Test A - Create two psBitSets
+    printPositiveTestHeader(stdout,"psBitSet", "Create two psBitSets");
+    psBitSet* bs1 = psBitSetAlloc(24);
+    psBitSet* bs2 = psBitSetAlloc(24);
+    binOut = psBitSetToString(bs1);
+    printf("%s\n", binOut);
+    psFree(binOut);
+    binOut = psBitSetToString(bs2);
+    printf("%s\n\n", binOut);
+    psFree(binOut);
+    printf("Setting all bits true...\n");
+    for(int i=0; i<24; i++) {
+        bs1 = psBitSetSet(bs1, i);
+        bs2 = psBitSetSet(bs2, i);
+    }
+    binOut = psBitSetToString(bs1);
+    printf("%s\n", binOut);
+    psFree(binOut);
+    binOut = psBitSetToString(bs2);
+    printf("%s\n\n", binOut);
+    psFree(binOut);
+    printFooter(stdout, "psBitSet", "Create two psBitSets", true);
+
+
+    // Test B - Perform binary OR with psBitSets
+    printPositiveTestHeader(stdout,"psBitSet", "Perform binary OR with psBitSets");
+    psBitSet* outbs = psBitSetAlloc(24);
+    outbs = psBitSetOp(outbs, bs1, "OR", bs2);
+    binOut = psBitSetToString(outbs);
+    printf("Result:\n");
+    printf("%s\n", binOut);
+    psFree(binOut);
+    printFooter(stdout, "psBitSet", "Perform binary OR with psBitSets", true);
+
+
+    // Test C - Free psBitSets
+    printPositiveTestHeader(stdout, "psBitSet", "Free psBitSets");
+    psBitSetFree(bs1);
+    psBitSetFree(bs2);
+    psBitSetFree(outbs);
+    psMemCheckLeaks(0, NULL, stdout);
+    int nBad = psMemCheckCorruption(0);
+    if(nBad) {
+        printf("ERROR: Found %d bad memory blocks\n", nBad);
+    }
+    printFooter(stdout, "psBitSet", "Free psBitSets", true);
+
+    return 0;
+}
Index: /tags/rel1_1/psLib/test/collections/tst_psBitSet_04.c
===================================================================
--- /tags/rel1_1/psLib/test/collections/tst_psBitSet_04.c	(revision 1056)
+++ /tags/rel1_1/psLib/test/collections/tst_psBitSet_04.c	(revision 1056)
@@ -0,0 +1,76 @@
+/** @file  tst_psBitSet_04.c
+ *
+ *  @brief Test driver for psBitSet functions
+ *
+ *  This test driver contains the following tests for psArray test point 4:
+ *     A)  Create two psBitSets
+ *     B)  Perform binary XOR with psBitSets
+ *     C)  Free psBitSets
+ *
+ *  @author  Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.4 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2004-06-11 01:46:02 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#include "pslib.h"
+#include "psTest.h"
+
+int main(int argc,
+         char* argv[])
+{
+    char *binOut = NULL;
+
+
+    // Test A - Create two psBitSets
+    printPositiveTestHeader(stdout,"psBitSet", "Create two psBitSets");
+    psBitSet* bs1 = psBitSetAlloc(24);
+    psBitSet* bs2 = psBitSetAlloc(24);
+    binOut = psBitSetToString(bs1);
+    printf("%s\n", binOut);
+    psFree(binOut);
+    binOut = psBitSetToString(bs2);
+    printf("%s\n\n", binOut);
+    psFree(binOut);
+    printf("Setting all bits true...\n");
+    for(int i=0; i<24; i++) {
+        bs1 = psBitSetSet(bs1, i);
+        bs2 = psBitSetSet(bs2, i);
+    }
+    binOut = psBitSetToString(bs1);
+    printf("%s\n", binOut);
+    psFree(binOut);
+    binOut = psBitSetToString(bs2);
+    printf("%s\n\n", binOut);
+    psFree(binOut);
+    printFooter(stdout, "psBitSet", "Create two psBitSets", true);
+
+
+    // Test B - Perform binary XOR with psBitSets
+    printPositiveTestHeader(stdout,"psBitSet", "Perform binary XOR with psBitSets");
+    psBitSet* outbs = psBitSetAlloc(24);
+    outbs = psBitSetOp(outbs, bs1, "XOR", bs2);
+    binOut = psBitSetToString(outbs);
+    printf("Result:\n");
+    printf("%s\n", binOut);
+    psFree(binOut);
+    printFooter(stdout, "psBitSet", "Perform binary XOR with psBitSets", true);
+
+
+    // Test C - Free psBitSets
+    printPositiveTestHeader(stdout, "psBitSet", "Free psBitSets");
+    psBitSetFree(bs1);
+    psBitSetFree(bs2);
+    psBitSetFree(outbs);
+    psMemCheckLeaks(0, NULL, stdout);
+    int nBad = psMemCheckCorruption(0);
+    if(nBad) {
+        printf("ERROR: Found %d bad memory blocks\n", nBad);
+    }
+    printFooter(stdout, "psBitSet", "Free psBitSets", true);
+
+    return 0;
+}
Index: /tags/rel1_1/psLib/test/collections/tst_psBitSet_05.c
===================================================================
--- /tags/rel1_1/psLib/test/collections/tst_psBitSet_05.c	(revision 1056)
+++ /tags/rel1_1/psLib/test/collections/tst_psBitSet_05.c	(revision 1056)
@@ -0,0 +1,61 @@
+/** @file  tst_psBitSet_05.c
+ *
+ *  @brief Test driver for psBitSet functions
+ *
+ *  This test driver contains the following tests for psArray test point 5:
+ *     A)  Create two psBitSets of different size
+ *     B)  Attempt OR with psBitsets, should get error
+ *     C)  Free psBitSets
+ *
+ *  @author  Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.4 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2004-06-10 00:28:36 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#include "pslib.h"
+#include "psTest.h"
+
+int main(int argc,
+         char* argv[])
+{
+    char *binOut = NULL;
+
+
+    // Test A - Create two psBitSets
+    printPositiveTestHeader(stdout,"psBitSet", "Create two psBitSets of different size");
+    psBitSet* bs1 = psBitSetAlloc(24);
+    psBitSet* bs2 = psBitSetAlloc(40);
+    binOut = psBitSetToString(bs1);
+    printf("%s\n", binOut);
+    psFree(binOut);
+    binOut = psBitSetToString(bs2);
+    printf("%s\n\n", binOut);
+    psFree(binOut);
+    printFooter(stdout, "psBitSet", "Create two psBitSets of different size", true);
+
+
+    // Test B - Attempt OR with psBitsets, should get error
+    printNegativeTestHeader(stdout, "psBitSet", "Attempt OR with psBitsets", "psBitSet sizes not the same", 0);
+    psBitSet* outbs = psBitSetAlloc(24);
+    outbs = psBitSetOp(outbs, bs1, "OR", bs2);
+    printFooter(stdout, "psBitSet", "Attempt OR with psBitsets", true);
+
+
+    // Test C - Free psBitSets
+    printPositiveTestHeader(stdout, "psBitSet", "Free psBitSets");
+    psBitSetFree(bs1);
+    psBitSetFree(bs2);
+    psBitSetFree(outbs);
+    psMemCheckLeaks(0, NULL, stdout);
+    int nBad = psMemCheckCorruption(0);
+    if(nBad) {
+        printf("ERROR: Found %d bad memory blocks\n", nBad);
+    }
+    printFooter(stdout, "psBitSet", "Free psBitSets", true);
+
+    return 0;
+}
Index: /tags/rel1_1/psLib/test/collections/tst_psBitSet_06.c
===================================================================
--- /tags/rel1_1/psLib/test/collections/tst_psBitSet_06.c	(revision 1056)
+++ /tags/rel1_1/psLib/test/collections/tst_psBitSet_06.c	(revision 1056)
@@ -0,0 +1,78 @@
+/** @file  tst_psBitSet_06.c
+ *
+ *  @brief Test driver for psBitSet functions
+ *
+ *  This test driver contains the following tests for psArray test point 6:
+ *     A)  Create two psBitSets
+ *     B)  Perform invalid binary operation with psBitSets
+ *     C)  Attempt to create negative size bitset
+ *     D   Attempt to free null BitSet
+ *     E)  Free psBitSets
+ *
+ *  @author  Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.6 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2004-06-10 00:28:43 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#include "pslib.h"
+#include "psTest.h"
+
+int main(int argc,
+         char* argv[])
+{
+    char *binOut = NULL;
+
+
+    // Test A - Create two psBitSets
+    printPositiveTestHeader(stdout,"psBitSet", "Create two psBitSets");
+    psBitSet* bs1 = psBitSetAlloc(24);
+    psBitSet* bs2 = psBitSetAlloc(24);
+    binOut = psBitSetToString(bs1);
+    printf("%s\n", binOut);
+    psFree(binOut);
+    binOut = psBitSetToString(bs2);
+    printf("%s\n\n", binOut);
+    psFree(binOut);
+    printFooter(stdout, "psBitSet", "Create two psBitSets", true);
+
+
+    // Test B - Perform invalid binary operation with psBitSets
+    printNegativeTestHeader(stdout,"psBitSet", "Perform invalid binary operation",
+                            "Invalid psBitMask binary operation", 0);
+    psBitSet* outbs = psBitSetAlloc(24);
+    outbs = psBitSetOp(outbs, bs1, "ZZXOR", bs2);
+    printFooter(stdout, "psBitSet", "Perform binary XOR with psBitSets", true);
+
+
+    // Test C - Attempt to create negative size bitset
+    printNegativeTestHeader(stdout,"psBitSet", "Create negative size bitset",
+                            "Allocation size must be >= 0: size = -4", 0);
+    psBitSetAlloc(-4);
+    printFooter(stdout, "psBitSet", "Create negative size bitset", true);
+
+
+    // Test D - Attempt to free null BitSet
+    printNegativeTestHeader(stdout,"psBitSet", "Attempt to free null BitSet",
+                            "Null psBitSet for inBitSet argument", 0);
+    psBitSetFree(NULL);
+    printFooter(stdout, "psBitSet", "Attempt to free null BitSet", true);
+
+
+    // Test E - Free psBitSets
+    printPositiveTestHeader(stdout, "psBitSet", "Free psBitSets");
+    psBitSetFree(bs1);
+    psBitSetFree(bs2);
+    psBitSetFree(outbs);
+    psMemCheckLeaks(0, NULL, stdout);
+    int nBad = psMemCheckCorruption(0);
+    if(nBad) {
+        printf("ERROR: Found %d bad memory blocks\n", nBad);
+    }
+    printFooter(stdout, "psBitSet", "Free psBitSetFree psBitSets", true);
+
+    return 0;
+}
Index: /tags/rel1_1/psLib/test/collections/tst_psList.c
===================================================================
--- /tags/rel1_1/psLib/test/collections/tst_psList.c	(revision 1056)
+++ /tags/rel1_1/psLib/test/collections/tst_psList.c	(revision 1056)
@@ -0,0 +1,959 @@
+/** @file  tst_psList.c
+ *
+ *  @brief Contains the tests for psList.[ch]
+ *
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.10 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-14 23:03:43 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include "psTest.h"
+#include "pslib.h"
+
+void printListInt(psList* list);
+
+
+static int testListAlloc(void);
+static int testListAdd(void);
+static int testListGet(void);
+static int testListRemove(void);
+static int testListConvert(void);
+static int testListIterator(void);
+static int testListFree(void);
+
+testDescription tests[] = {
+                              {testListAlloc,"487-testListAlloc",0},
+                              {testListAdd,"488-testListAdd",0},
+                              {testListGet,"489-testListGet",0},
+                              {testListRemove,"490-testListRemove",0},
+                              {testListConvert,"491-testListConvert",0},
+                              {testListIterator,"494-testListIterator",0},
+                              {testListFree,"627-testListFree",0},
+                              {NULL}
+                          };
+
+int main()
+{
+    psLogSetLevel(PS_LOG_INFO);
+
+    if (! runTestSuite(stderr,"psList",tests)) {
+        psError(__FILE__,"One or more tests failed");
+        return 1;
+    }
+    return 0;
+}
+
+int testListAlloc(void)
+{
+    psList* list;
+    int ref;
+    float* data;
+
+    psLogMsg(__func__,PS_LOG_INFO,"psListAlloc shall create a psList with either 0 or 1 element.");
+
+    data = psAlloc(sizeof(float));
+
+    // if psListAlloc is invoked with a NULL parameter, it shall return an
+    // empty psList struct with head=tail=NULL and n=0. Otherwise, it shall
+    // return a psList of one element (head=tail=data, n=1).
+
+    list = psListAlloc(NULL);
+    if (list == NULL) {
+        psError(__func__,"psListAlloc failed to return a list.");
+        return 1;
+    }
+
+    if (list->head != NULL || list->tail != NULL) {
+        psError(__func__,"head and/or tail was not NULL for empty list.");
+        return 2;
+    }
+
+    if (list->size != 0) {
+        psError(__func__,"size of list wasn't zero for empty list.");
+        return 3;
+    }
+
+    psListFree(list,NULL);
+
+    list = psListAlloc(data);
+    if (list == NULL) {
+        psError(__func__,"psListAlloc failed to return a list.");
+        return 4;
+    }
+
+    if (list->head == NULL || list->tail == NULL) {
+        psError(__func__,"head and/or tail was NULL for one-element new list.");
+        return 5;
+    }
+
+    if (list->head->data != data || list->tail->data != data) {
+        psError(__func__,"head and/or tail didn't point to data's node for one-element new list.");
+        return 6;
+    }
+
+    if (list->size != 1) {
+        psError(__func__,"size of list wasn't correctly set for new, one-element list.");
+        return 7;
+    }
+
+    ref = psMemGetRefCounter(data);
+    if (ref != 2) {
+        psError(__func__,"psList didn't increment reference count of data (%d.",ref);
+        return 8;
+    }
+
+
+    psListFree(list,PS_FREE);
+
+    return 0;
+}
+
+int testListAdd(void)
+{
+    psList* list = NULL;
+    int* data = NULL;
+
+    psLogMsg(__func__,PS_LOG_INFO,"psListAdd shall add an element to list");
+
+    /*
+        psListAdd(list,data,where) should be tested in the instance where:
+
+        1. list is NULL (error)
+        2. data is NULL (error, list should not grow)
+        3. where is PS_LIST_HEAD or PS_LIST_TAIL
+        4. where is not PS_LIST_* but <0
+        5. where is >0
+    */
+
+    data = psAlloc(sizeof(int));
+    *data = 1;
+
+    //  1. list is NULL (error)
+    list = psListAdd(NULL,data,PS_LIST_HEAD);
+
+    if (list != NULL) {
+        psError(__func__,"psListAdd was given a NULL list, but returned a non-NULL list.");
+        return 1;
+    }
+
+    //  2. data is NULL (error, list should not grow)
+    list = psListAlloc(data);
+    psFree(data);
+    if (list->size != 1) {
+        psError(__func__,"psListAlloc didn't create a list properly.");
+        return 2;
+    }
+
+    list = psListAdd(list, NULL,PS_LIST_HEAD);
+
+    if (list->size != 1) {
+        psError(__func__,"psListAdd with a NULL data element changed the list size.");
+        return 3;
+    }
+
+    //  3. where is PS_LIST_HEAD or PS_LIST_TAIL
+    data = psAlloc(sizeof(int));
+    *data = 2;
+    list = psListAdd(list,data,PS_LIST_HEAD);
+    if (psMemGetRefCounter(data) != 2) {
+        psError(__func__,"psListAdd didn't increment the data reference count.");
+        return 20;
+    }
+    psFree(data);
+    // verify that the size incremented
+    if (list->size != 2) {
+        psError(__func__,"psListAdd didn't increment the size by one");
+        return 4;
+    }
+
+    // verify that the head is the inserted data item
+    if (*(int*)list->head->data != 2) {
+        psError(__func__,"psListAdd with PS_LIST_HEAD didn't insert at the head.");
+        return 5;
+    }
+
+    data = psAlloc(sizeof(int));
+    *data = 3;
+    list = psListAdd(list,data,PS_LIST_TAIL);
+    if (psMemGetRefCounter(data) != 2) {
+        psError(__func__,"psListAdd didn't increment the data reference count.");
+        return 20;
+    }
+    psFree(data);
+    // verify that the size incremented
+    if (list->size != 3) {
+        psError(__func__,"psListAdd didn't increment the size by 1");
+        return 6;
+    }
+
+    // verify that the head is still the same
+    if (*(int*)list->head->data != 2) {
+        psError(__func__,"psListAdd with PS_LIST_TAIL modified the head.");
+        return 7;
+    }
+
+    // verify that the tail is the data item inserted
+    if (*(int*)list->tail->data != 3) {
+        psError(__func__,"psListAdd with PS_LIST_TAIL didn't insert at the tail.");
+        return 8;
+    }
+
+    // 4. where is not PS_LIST_* but <0
+
+    data = psAlloc(sizeof(int));
+    *data = 4;
+    psLogMsg(__func__,PS_LOG_INFO,"Following should warn with invalid insert location");
+    list = psListAdd(list,data,-10);
+    if (psMemGetRefCounter(data) != 2) {
+        psError(__func__,"psListAdd didn't increment the data reference count.");
+        return 20;
+    }
+    psFree(data);
+    // verify that the size incremented
+    if (list->size != 4 || *(int*)list->head->data != 4) {
+        printListInt(list);
+        psError(__func__,"psListAdd didn't insert to head when where was invalid.");
+        return 9;
+    }
+
+    // 5. where is >0
+    data = psAlloc(sizeof(int));
+    *data = 5;
+    list = psListAdd(list,data,1);
+    if (psMemGetRefCounter(data) != 2) {
+        psError(__func__,"psListAdd didn't increment the data reference count.");
+        return 20;
+    }
+    psFree(data);
+    // verify that the size incremented
+    if (list->size != 5 || *(int*)list->head->next->data != 5) {
+        printListInt(list);
+        psError(__func__,"psListAdd didn't insert to position #1.");
+        return 9;
+    }
+
+    data = psAlloc(sizeof(int));
+    *data = 6;
+    list = psListAdd(list,data,4);
+    if (psMemGetRefCounter(data) != 2) {
+        psError(__func__,"psListAdd didn't increment the data reference count.");
+        return 20;
+    }
+    psFree(data);
+    // verify that the size incremented
+    if (list->size != 6  || *(int *)list->head->next->next->next->next->data != 6) {
+        printListInt(list);
+        psError(__func__,"psListAdd didn't insert to position #4.");
+        return 9;
+    }
+
+    data = psAlloc(sizeof(int));
+    *data = 7;
+    list = psListAdd(list,data,2);
+    if (psMemGetRefCounter(data) != 2) {
+        psError(__func__,"psListAdd didn't increment the data reference count.");
+        return 20;
+    }
+    psFree(data);
+    // verify that the size incremented
+    if (list->size != 7  || *(int *)list->head->next->next->data != 7) {
+        printListInt(list);
+        psError(__func__,"psListAdd didn't insert to position #2.");
+        return 9;
+    }
+
+    data = psAlloc(sizeof(int));
+    *data = 7;
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be a warning.");
+    list = psListAdd(list,data,9);
+    if (psMemGetRefCounter(data) != 2) {
+        psError(__func__,"psListAdd didn't increment the data reference count.");
+        return 20;
+    }
+    psFree(data);
+    // verify that the size incremented
+    if (list->size != 8) {
+        printListInt(list);
+        psError(__func__,"psListAdd didn't insert to position #9.");
+        return 9;
+    }
+
+    psListFree(list, PS_FREE);
+
+    return 0;
+}
+
+void printListInt(psList* list)
+{
+    int* data = NULL;
+    bool first = true;
+
+    psListSetIterator(list,PS_LIST_HEAD);
+    data = psListGetCurrent(list);
+
+    while ( data != NULL ) {
+        if (!first) {
+            printf(", %d",*(int*)data);
+        } else {
+            printf("%d",*(int*)data);
+            first = false;
+        }
+        data = psListGetNext(list);
+    }
+
+    printf(".\n");
+}
+
+
+int testListGet(void)
+{
+    psList* list = NULL;
+    int* data;
+
+    /*
+     psListGet(list,which) shall be tested with the following instances
+
+        1. list is NULL.
+        2. which>0 and which<list.n.
+        3. which>list.n.
+        4. which=PS_LIST_HEAD
+        5. which=PS_LIST_NEXT
+        6. which=PS_LIST_TAIL
+        7. which=PS_LIST_PREV
+        8. which<0 and not any PS_LIST_* values
+    */
+
+    //  1. list is NULL.
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error");
+    if (psListGet(list,PS_LIST_HEAD) != NULL) {
+        psError(__func__,"psListGet didn't return NULL given a NULL list.");
+        return 1;
+    };
+
+    // create a list
+    data = psAlloc(sizeof(int));
+    *data = 0;
+    list = psListAlloc(data);
+
+    data = psAlloc(sizeof(int));
+    *data = 1;
+    list = psListAdd(list,data,PS_LIST_TAIL);
+
+    data = psAlloc(sizeof(int));
+    *data = 2;
+    list = psListAdd(list,data,PS_LIST_TAIL);
+
+    data = psAlloc(sizeof(int));
+    *data = 3;
+    list = psListAdd(list,data,PS_LIST_TAIL);
+
+    //  2. which>0 and which<list.n.
+    data = (int*)psListGet(list,3);
+    if (data == NULL || *data != 3) {
+        psError(__func__,"psListGet failed with which=3");
+        return 2;
+    }
+    data = (int*)psListGet(list,1);
+    if (data == NULL || *data != 1) {
+        psError(__func__,"psListGet failed with which=1");
+        return 3;
+    }
+
+    //  3. which>=list.n.
+    data = (int*)psListGet(list,5);
+    if (data != NULL) {
+        psError(__func__,"psListGet failed with which=5");
+        return 4;
+    }
+    data = (int*)psListGet(list,4);
+    if (data != NULL) {
+        psError(__func__,"psListGet failed with which=4");
+        return 5;
+    }
+
+    //  4. which=PS_LIST_HEAD
+    data = (int*)psListGet(list,PS_LIST_HEAD);
+    if (data == NULL || *data != 0) {
+        psError(__func__,"psListGet failed with which=PS_LIST_HEAD");
+        return 6;
+    }
+
+    //  5. which=PS_LIST_NEXT
+    data = (int*)psListGet(list,PS_LIST_NEXT);
+    if (data == NULL || *data != 1) {
+        psError(__func__,"psListGet failed with which=PS_LIST_NEXT");
+        return 7;
+    }
+
+    //  6. which=PS_LIST_TAIL
+    data = (int*)psListGet(list,PS_LIST_TAIL);
+    if (data == NULL || *data != 3) {
+        psError(__func__,"psListGet failed with which=PS_LIST_TAIL");
+        return 8;
+    }
+
+    //  7. which=PS_LIST_PREV
+    data = (int*)psListGet(list,PS_LIST_PREVIOUS);
+    if (data == NULL || *data != 2) {
+        psError(__func__,"psListGet failed with which=PS_LIST_PREV");
+        return 9;
+    }
+
+    psListFree(list,PS_FREE);
+
+    return 0;
+}
+
+int testListRemove(void)
+{
+    psList* list = NULL;
+    int* data;
+
+    /*
+        psListRemove(list,data,which) should be tested under the following conditions:
+
+        1. list is NULL
+        2. which is PS_LIST_HEAD (remove first element of list)
+        3. which is PS_LIST_TAIL (remove last element of list)
+        4. which is PS_LIST_NEXT (element right of cursor [which should be head,tail, and neither])
+        5. which is PS_LIST_PREV (element left of cursor [which should be head,tail, and neither])
+        6. which is PS_LIST_UNKNOWN and data=NULL (error)
+        7. which is PS_LIST_UNKNOWN and data=[head,tail,other list items]
+        8. which is PS_LIST_UNKNOWN and data!=NULL and data!=any element in list
+
+        In all conditions that are not an error, list.n shall be decremented and only the specified element
+        shall be removed. After each step, list.n should be checked to verify that it is the true
+        number of elements in list.
+    */
+
+    //  1. list is NULL.
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error");
+    if (psListRemove(list,NULL,PS_LIST_HEAD) != NULL) {
+        psError(__func__,"psListGet didn't return NULL given a NULL list.");
+        return 1;
+    };
+
+    // create a list
+    list = psListAlloc(NULL);
+
+    for (int lcv=0;lcv<15;lcv++) {
+        data = psAlloc(sizeof(int));
+        *data = lcv;
+        list = psListAdd(list,data,PS_LIST_TAIL);
+        psMemDecrRefCounter(data);
+    }
+
+
+    // 2. which is PS_LIST_HEAD (remove first element of list)
+    data = psListRemove(list,NULL,PS_LIST_HEAD);
+    if (data == NULL || *data != 0) {
+        printListInt(list);
+        psError(__func__,"Failed to remove PS_LIST_HEAD (%p)",data);
+        return 1;
+    }
+    psFree(data);
+    if (list->size != 14) {
+        printListInt(list);
+        psError(__func__,"Didn't decrement size properly to 14.");
+        return 1;
+    }
+
+    // 3. which is PS_LIST_TAIL (remove last element of list)
+    data = psListRemove(list,NULL,PS_LIST_TAIL);
+    if (data == NULL || *data != 14) {
+        printListInt(list);
+        psError(__func__,"Failed to remove PS_LIST_TAIL");
+        return 1;
+    }
+    psFree(data);
+    if (list->size != 13) {
+        printListInt(list);
+        psError(__func__,"Didn't decrement size properly to 13.");
+        return 1;
+    }
+
+    // 4. which is PS_LIST_NEXT (element right of cursor [which should be head,tail, and neither])
+    psListSetIterator(list,PS_LIST_HEAD);
+    data = psListRemove(list,NULL,PS_LIST_NEXT);
+    if (data == NULL || *data != 2) {
+        printListInt(list);
+        psError(__func__,"Failed to remove PS_LIST_NEXT @ PS_LIST_HEAD");
+        return 1;
+    }
+    psFree(data);
+    if (list->size != 12) {
+        printListInt(list);
+        psError(__func__,"Didn't decrement size properly to 12.");
+        return 1;
+    }
+
+    psListSetIterator(list,PS_LIST_TAIL);
+    psLogMsg(__func__,PS_LOG_INFO,"Next message should be an error");
+    data = psListRemove(list,NULL,PS_LIST_NEXT);
+    if (data != NULL) {
+        printListInt(list);
+        psError(__func__,"Removed something with PS_LIST_NEXT @ PS_LIST_TAIL");
+        return 1;
+    }
+
+    psListSetIterator(list,2);
+    data = psListRemove(list,NULL,PS_LIST_NEXT);
+    if (data == NULL || *data != 5) {
+        printListInt(list);
+        psError(__func__,"Failed to remove PS_LIST_NEXT @ which=2");
+        return 1;
+    }
+    psFree(data);
+    if (list->size != 11) {
+        printListInt(list);
+        psError(__func__,"Didn't decrement size properly to 11.");
+        return 1;
+    }
+
+    // 5. which is PS_LIST_PREV (element left of cursor [which should be head,tail, and neither])
+    psListSetIterator(list,PS_LIST_HEAD);
+    psLogMsg(__func__,PS_LOG_INFO,"Next message should be an error");
+    data = psListRemove(list,NULL,PS_LIST_PREVIOUS);
+    if (data != NULL) {
+        printListInt(list);
+        psError(__func__,"removed something for PS_LIST_PREVIOUS @ PS_LIST_HEAD");
+        return 1;
+    }
+
+    psListSetIterator(list,PS_LIST_TAIL);
+    data = psListRemove(list,NULL,PS_LIST_PREVIOUS);
+    if (data == NULL || *data != 12) {
+        printListInt(list);
+        psError(__func__,"Failed to remove PS_LIST_PREVIOUS @ PS_LIST_TAIL");
+        return 1;
+    }
+    psFree(data);
+    if (list->size != 10) {
+        printListInt(list);
+        psError(__func__,"Didn't decrement size properly to 10.");
+        return 1;
+    }
+
+    psListSetIterator(list,2);
+    data = psListRemove(list,NULL,PS_LIST_PREVIOUS);
+    if (data == NULL || *data != 3) {
+        printListInt(list);
+        psError(__func__,"Failed to remove PS_LIST_PREVIOUS @ which=2");
+        return 1;
+    }
+    psFree(data);
+    if (list->size != 9) {
+        printListInt(list);
+        psError(__func__,"Didn't decrement size properly to 9.");
+        return 1;
+    }
+
+    // 6. which is PS_LIST_UNKNOWN and data=NULL (error)
+    psLogMsg(__func__,PS_LOG_INFO,"Next message should be an error");
+    data = psListRemove(list,NULL,PS_LIST_UNKNOWN);
+    if (data != NULL) {
+        printListInt(list);
+        psError(__func__,"removed something for PS_LIST_UNKNOWN with data=NULL");
+        return 1;
+    }
+
+    // 7. which is PS_LIST_UNKNOWN and data=[head,tail,other list items]
+    data = psListGet(list,PS_LIST_HEAD);
+    data = psListRemove(list,data,PS_LIST_UNKNOWN);
+    if (data == NULL || *data != 1) {
+        printListInt(list);
+        psError(__func__,"Failed to remove PS_LIST_UNKNOWN @ PS_LIST_HEAD");
+        return 1;
+    }
+    psFree(data);
+    if (list->size != 8) {
+        printListInt(list);
+        psError(__func__,"Didn't decrement size properly to 8.");
+        return 1;
+    }
+
+    data = psListGet(list,PS_LIST_TAIL);
+    data = psListRemove(list,data,PS_LIST_UNKNOWN);
+    if (data == NULL || *data != 13) {
+        printListInt(list);
+        psError(__func__,"Failed to remove PS_LIST_UNKNOWN @ PS_LIST_TAIL");
+        return 1;
+    }
+    psFree(data);
+    if (list->size != 7) {
+        printListInt(list);
+        psError(__func__,"Didn't decrement size properly to 7.");
+        return 1;
+    }
+
+    psListSetIterator(list,PS_LIST_HEAD);
+    data = psListGet(list,PS_LIST_NEXT);
+
+    data = psListRemove(list,data,PS_LIST_UNKNOWN);
+    if (data == NULL || *data != 6) {
+        printListInt(list);
+        psError(__func__,"Failed to remove PS_LIST_UNKNOWN @ which=1");
+        return 1;
+    }
+    psFree(data);
+    if (list->size != 6) {
+        printListInt(list);
+        psError(__func__,"Didn't decrement size properly to 6.");
+        return 1;
+    }
+
+    // 8. which is PS_LIST_UNKNOWN and data!=NULL and data!=any element in list
+    psLogMsg(__func__,PS_LOG_INFO,"Next message should be an error");
+    data = psListRemove(list,data,PS_LIST_UNKNOWN);
+    if (data != NULL) {
+        printListInt(list);
+        psError(__func__,"removed something for PS_LIST_UNKNOWN with previously removed item");
+        return 1;
+    }
+
+    // clear out the list
+    psFree(psListRemove(list,NULL,PS_LIST_HEAD));
+    psFree(psListRemove(list,NULL,PS_LIST_HEAD));
+    psFree(psListRemove(list,NULL,PS_LIST_HEAD));
+    psFree(psListRemove(list,NULL,PS_LIST_HEAD));
+    psFree(psListRemove(list,NULL,PS_LIST_HEAD));
+
+    data = psListRemove(list,data,PS_LIST_HEAD);
+    if (data == NULL || *data != 11) {
+        printListInt(list);
+        psError(__func__,"Failed to remove last element");
+        return 1;
+    }
+    psFree(data);
+
+    if (list->size != 0) {
+        printListInt(list);
+        psError(__func__,"Didn't remove all the elements.");
+        return 1;
+    }
+
+    psListFree(list,PS_FREE);
+
+    return 0;
+
+}
+
+int testListConvert(void)
+{
+
+    psList* list = NULL;
+    psVector* vec = NULL;
+    int* data;
+
+    /*
+        array=psListToArray(list) shall take each element of the list, increment
+        their reference, and insert them into the returned fresh void* array.
+        The list shall not be changed, except for the element reference increment.
+    */
+
+    // test dlist -> vector
+
+    // create a list
+    list = psListAlloc(NULL);
+    for (int lcv=0;lcv<15;lcv++) {
+        data = psAlloc(sizeof(int));
+        *data = lcv;
+        list = psListAdd(list,data,PS_LIST_TAIL);
+        psMemDecrRefCounter(data);
+    }
+
+    vec = psListToVector(list);
+
+    if (vec->n != 15 || list->size != 15) {
+        psError(__func__,"The created vector didn't have the proper size");
+        return 1;
+    }
+    for (int i=0;i<vec->n;i++) {
+        if (i != *(int*)vec->data.PTR[i]) {
+            psError(__func__,"Element %d of vector is incorrect (%d).",
+                    i,*(int*)vec->data.PTR[i]);
+            return 1;
+        }
+        if (i != *(int*)psListGet(list,i)) {
+            psError(__func__,"Element %d of list is incorrect (%d).",
+                    i,*(int*)vec->data.PTR[i]);
+            return 1;
+        }
+        if (psMemGetRefCounter(vec->data.PTR[i]) != 2) {
+            psError(__func__,"Element %d had wrong reference count (%d).",
+                    i,psMemGetRefCounter(vec->data.PTR[i]));
+            return 1;
+        }
+    }
+
+    psVectorFree(vec);
+    psListFree(list,PS_FREE);
+
+    // test vector -> dlist
+
+    // create a vector
+    vec = psVectorAlloc(15,PS_TYPE_PTR);
+    vec->n = vec->nalloc;
+    for (int lcv=0;lcv<15;lcv++) {
+        data = psAlloc(sizeof(int));
+        *data = lcv;
+        vec->data.PTR[lcv] = data;
+    }
+
+    list = psVectorToList(vec);
+
+    if (vec->n != 15 || list->size != 15) {
+        psError(__func__,"The created vector didn't have the proper size");
+        return 1;
+    }
+    for (int i=0;i<vec->n;i++) {
+        if (i != *(int*)vec->data.PTR[i]) {
+            psError(__func__,"Element %d of vector is incorrect (%d).",
+                    i,*(int*)vec->data.PTR[i]);
+            return 1;
+        }
+        if (i != *(int*)psListGet(list,i)) {
+            psError(__func__,"Element %d of list is incorrect (%d).",
+                    i,*(int*)vec->data.PTR[i]);
+            return 1;
+        }
+        if (psMemGetRefCounter(vec->data.PTR[i]) != 2) {
+            psError(__func__,"Element %d had wrong reference count (%d).",
+                    i,psMemGetRefCounter(vec->data.PTR[i]));
+            return 1;
+        }
+    }
+
+    psVectorFree(vec);
+    psListFree(list,PS_FREE);
+
+    // now, make sure if input vector/list is NULL, output is NULL
+
+    vec = psListToVector(NULL);
+    if (vec != NULL) {
+        psError(__func__,"psListToVector didn't return NULL when given NULL");
+        return 1;
+    }
+
+    list = psVectorToList(NULL);
+    if (list != NULL) {
+        psError(__func__,"psVectorToList didn't return NULL when given NULL");
+        return 1;
+    }
+
+    // now, see what happens with a zero-size vector/list
+    vec = psVectorAlloc(1,PS_TYPE_PTR);
+    vec->n = 0;
+    list = psVectorToList(vec);
+    if (list == NULL) {
+        psError(__func__,"psVectorToList didn't create an empty list from an "
+                "empty vector.");
+        return 1;
+    }
+    psVectorFree(vec);
+    psListFree(list,PS_FREE);
+
+    list = psListAlloc(NULL);
+    vec = psListToVector(list);
+    if (vec == NULL) {
+        psError(__func__,"psVectorToList didn't create an empty vector from an "
+                "empty list.");
+        return 1;
+    }
+    psVectorFree(vec);
+    psListFree(list,PS_FREE);
+
+    return 0;
+}
+
+int testListIterator(void)
+{
+    psList* list = NULL;
+    int* data;
+
+    psLogMsg(__func__,PS_LOG_INFO," psListSetIterator/psListGetNext/psListGetPrev"
+             " shall move the list cursor to the specified location");
+
+    /*
+            psDlistSetIterator(list,where) shall:
+
+            1. output error message and do nothing if list=NULL
+            2. set list.cursor to list.head if where=PS_LIST_HEAD
+            3. set list.cursor to list.tail if where=PS_LIST_TAIL
+            4. set list.cursor to list.cursor->next if where=PS_LIST_NEXT
+            5. set list.cursor to list.cursor->prev if where=PS_LIST_PREV
+            6. leave list.cursor untouched if where=PS_LIST_UNKNOWN or PS_LIST_CURRENT
+
+            psDlistGetNext(list) shall be functionally equivalent to
+            psDlistSetIterator(list,PS_LIST_NEXT) but returns list.cursor.
+
+            psDlistGetPrev(list) shall be functionally equivalent to
+            psDlistSetIterator(list,PS_LIST_PREV) but returns list.cursor.
+    */
+
+    // create a list
+    list = psListAlloc(NULL);
+    for (int lcv=0;lcv<15;lcv++) {
+        data = psAlloc(sizeof(int));
+        *data = lcv;
+        list = psListAdd(list,data,PS_LIST_TAIL);
+        psFree(data);
+    }
+
+
+    // 1. output error message and do nothing if list=NULL
+    psLogMsg(__func__,PS_LOG_INFO,"Following should error with "
+             "'Unexpected null pointer'");
+    psListSetIterator(NULL,PS_LIST_HEAD);
+
+    // 3. set list.cursor to list.tail if where=PS_LIST_TAIL
+    psListSetIterator(list,PS_LIST_TAIL);
+    if (*(int*)psListGetCurrent(list) != 14) {
+        psError(__func__,"Didn't successfully move cursor to tail.");
+        return 1;
+    }
+
+    // 2. set list.cursor to list.head if where=PS_LIST_HEAD
+    psListSetIterator(list,PS_LIST_HEAD);
+    if (*(int*)psListGetCurrent(list) != 0) {
+        psError(__func__,"Didn't successfully move cursor to head.");
+        return 2;
+    }
+
+    // 4. set list.cursor to list.cursor->next if where=PS_LIST_NEXT
+    psListSetIterator(list,PS_LIST_NEXT);
+    if (*(int*)psListGetCurrent(list) != 1) {
+        psError(__func__,"Didn't successfully move cursor to next.");
+        return 3;
+    }
+    psListSetIterator(list,PS_LIST_NEXT);
+    if (*(int*)psListGetCurrent(list) != 2) {
+        psError(__func__,"Didn't successfully move cursor to next twice.");
+        return 4;
+    }
+
+    // 5. set list.cursor to list.cursor->prev if where=PS_LIST_PREV
+    psListSetIterator(list,PS_LIST_PREVIOUS);
+    if (*(int*)psListGetCurrent(list) != 1) {
+        psError(__func__,"Didn't successfully move cursor to previous.");
+        return 5;
+    }
+    psListSetIterator(list,PS_LIST_PREVIOUS);
+    if (*(int*)psListGetCurrent(list) != 0) {
+        psError(__func__,"Didn't successfully move cursor to previous twice.");
+        return 6;
+    }
+
+    // 6. leave list.cursor untouched if where=PS_LIST_UNKNOWN or PS_LIST_CURRENT
+    psListSetIterator(list,PS_LIST_NEXT);   // move off of head (works according to above)
+    psLogMsg(__func__,PS_LOG_INFO,"Following should error with 'Can't move to an unknown position.'");
+    psListSetIterator(list,PS_LIST_UNKNOWN);
+    if (*(int*)psListGetCurrent(list) != 1) {
+        psError(__func__,"PS_LIST_UNKNOWN moved cursor.");
+        return 7;
+    }
+    psListSetIterator(list,PS_LIST_CURRENT);
+    if (*(int*)psListGetCurrent(list) != 1) {
+        psError(__func__,"PS_LIST_CURRENT moved cursor.");
+        return 8;
+    }
+
+    // test psListGetPrevious/Next
+    if (*(int*)psListGetNext(list) != 2) {
+        psError(__func__,"psListGetNext didn't move cursor to next.");
+        return 9;
+    }
+    if (*(int*)psListGetNext(list) != 3) {
+        psError(__func__,"psListGetNext didn't move cursor to next.");
+        return 10;
+    }
+    if (*(int*)psListGetPrevious(list) != 2) {
+        psError(__func__,"psListGetPrevious didn't move cursor to previous.");
+        return 11;
+    }
+    if (*(int*)psListGetPrevious(list) != 1) {
+        psError(__func__,"psListGetPrevious didn't move cursor to previous.");
+        return 12;
+    }
+    if (*(int*)psListGetPrevious(list) != 0) {
+        psError(__func__,"psListGetPrevious didn't move cursor to previous..");
+        return 13;
+    }
+    if (psListGetPrevious(list) != NULL) {
+        psError(__func__,"psListGetPrevious moved cursor beyond head.");
+        return 14;
+    }
+
+    psListSetIterator(list,PS_LIST_TAIL); // works according to an above test
+    if (psListGetNext(list) != NULL) {
+        psError(__func__,"psListGetNext moved cursor beyond tail.");
+        return 15;
+    }
+
+    psListFree(list,PS_FREE);
+
+    return 0;
+}
+
+int testListFree(void)
+{
+    float* data[15];
+    psList* list;
+
+    /*
+    Call psDlistAlloc to create a doubly linked list.
+
+    Create several data items and add them to the list.
+
+    Verify the data item's reference counter are incremented after adding to the list.
+    (not really needed, as psListAdd is tested elsewhere)
+    */
+
+    list = psListAlloc(NULL);
+    for (int lcv=0;lcv<15;lcv++) {
+        data[lcv] = psAlloc(sizeof(int));
+        *data[lcv] = lcv;
+        list = psListAdd(list,data[lcv],PS_LIST_TAIL);
+        if (psMemGetRefCounter(data[lcv]) != 2) {
+            psError(__func__,"Reference counter for data was not incremented");
+            return 1;
+        }
+    }
+
+    /*
+    Verify items are within the list.
+    (not needed, as psListAdd is tested elsewhere, but check anyway.)
+    */
+    if (list->size != 15) {
+        psError(__func__,"List wasn't populated as expected?");
+        return 2;
+    }
+
+    /*
+    Call psDlistFree with NULL specified as the elemFree function.
+    */
+
+    psListFree(list,NULL);
+
+    /*
+    Verify the list is deallocated but not the data items.
+    (accomplished by checking for memory leaks)
+
+    Verify the data item's reference counters are decremented by one compared to when added to the list.
+    (technically, this could be accomplished by checking memory leaks too, but I checked anyway)
+    */
+
+    for (int i=0;i<15;i++) {
+        if (psMemGetRefCounter(data[i]) != 1) {
+            psError(__func__,"pslistFree didn't decrement the data item's reference counter");
+            return 3;
+        }
+        psFree(data[i]);
+    }
+
+    return 0;
+}
Index: /tags/rel1_1/psLib/test/collections/tst_psSort_01.c
===================================================================
--- /tags/rel1_1/psLib/test/collections/tst_psSort_01.c	(revision 1056)
+++ /tags/rel1_1/psLib/test/collections/tst_psSort_01.c	(revision 1056)
@@ -0,0 +1,83 @@
+/** @file  tst_psSort_01.c
+ *
+ *  @brief Test driver for psSort functions
+ *
+ *  This test driver contains the following tests for psSort test point 1:
+ *     A)  Create float vectors
+ *     B)  Sort input float vector and put results into output float vector
+ *     C)  Free float vectors
+ *
+ *  @author  Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.6 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2004-06-10 23:14:22 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#include "pslib.h"
+#include "psTest.h"
+
+int main(int argc,
+         char* argv[])
+{
+    psVector *in = NULL;
+    psVector *out = NULL;
+    psVector *tempVec = NULL;
+
+
+    // Test A - Create float vectors
+    printPositiveTestHeader(stdout,"psSort", "Create float vectors");
+    in = psVectorAlloc(7, PS_TYPE_F32);
+    in->n = 7;
+    out = psVectorAlloc(7, PS_TYPE_F32);
+    out->n = 7;
+    in->data.F32[0] = 7.0f;
+    in->data.F32[1] = 9.0f;
+    in->data.F32[2] = 3.0f;
+    in->data.F32[3] = 1.0f;
+    in->data.F32[4] = 5.0f;
+    in->data.F32[5] = 5.0f;
+    in->data.F32[6] = -20.0f;
+    for(int i=0; i<7; i++) {
+        printf("vec[%d] = %f\n", i, in->data.F32[i]);
+    }
+    printFooter(stdout, "psSort", "Create float vectors", true);
+
+
+    // Test B - Sort input float vector and put results into output float vector
+    printPositiveTestHeader(stdout,"psSort", "Sort float vector");
+    tempVec = out;
+    out = psSort(out, in);
+    for(int i=0; i<7; i++) {
+        printf("vec[%d] = %f\n", i, out->data.F32[i]);
+    }
+    if(out != tempVec) {
+        printf("Error: Return pointer not equal to output argument pointer\n");
+    }
+    printFooter(stdout, "psSort", "Sort float vector", true);
+
+
+    // Test C - Sort input float vector into itself
+    printPositiveTestHeader(stdout,"psSort", "Sort input float vector into itself");
+    in = psSort(in, in);
+    for(int i=0; i<7; i++) {
+        printf("vec[%d] = %f\n", i, out->data.F32[i]);
+    }
+    printFooter(stdout, "psSort", "Sort input float vector into itself", true);
+
+
+    // Test D - Free float vectors
+    printPositiveTestHeader(stdout,"psSort", "Free float vectors");
+    psVectorFree(in);
+    psVectorFree(out);
+    psMemCheckLeaks(0, NULL, stdout);
+    int nBad = psMemCheckCorruption(0);
+    if(nBad) {
+        printf("ERROR: Found %d bad memory blocks\n", nBad);
+    }
+    printFooter(stdout, "psSort", "Free float vectors", true);
+
+    return 0;
+}
Index: /tags/rel1_1/psLib/test/collections/tst_psSort_02.c
===================================================================
--- /tags/rel1_1/psLib/test/collections/tst_psSort_02.c	(revision 1056)
+++ /tags/rel1_1/psLib/test/collections/tst_psSort_02.c	(revision 1056)
@@ -0,0 +1,66 @@
+/** @file  tst_psSort_02.c
+ *
+ *  @brief Test driver for psSort functions
+ *
+ *  This test driver contains the following tests for psSort test point 2:
+ *     A)  Create vectors
+ *     B)  Sort integer vector of indices based on pre-sort order of floating point vector
+ *     C)  Free vectors
+ *
+ *  @author  Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.5 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2004-06-02 23:29:29 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#include "pslib.h"
+#include "psTest.h"
+
+int main(int argc,
+         char* argv[])
+{
+    psVector *in = NULL;
+    psVector *out = NULL;
+
+
+    // Test A - Create float vectors
+    printPositiveTestHeader(stdout,"psSort", "Create vectors");
+    in = psVectorAlloc(5, PS_TYPE_F32);
+    in->n = 5;
+    out = psVectorAlloc(5, PS_TYPE_F32);
+    out->n = 5;
+    in->data.F32[0] = 7.0f;
+    in->data.F32[1] = 9.0f;
+    in->data.F32[2] = 3.0f;
+    in->data.F32[3] = 1.0f;
+    in->data.F32[4] = 5.0f;
+    for(int i=0; i<5; i++) {
+        printf("arr[%d] = %f\n", i, in->data.F32[i]);
+    }
+    printFooter(stdout, "psSort", "Create vectors", true);
+
+
+    // Test B - Sort integer vector of indices based on pre-sort order of floating point vector
+    printPositiveTestHeader(stdout,"psSort", "Create sorted index vector");
+    out = psSortIndex(out, in);
+    for(int i=0; i<5; i++) {
+        printf("arr[%d] = %d\n", i, out->data.S32[i]);
+    }
+    printFooter(stdout, "psSort", "Create sorted index vector", true);
+
+
+    // Test C - Free vectors
+    printPositiveTestHeader(stdout,"psSort", "Free vectors");
+    psVectorFree(in);
+    psVectorFree(out);
+    psMemCheckLeaks(0, NULL, stdout);
+    int nBad = psMemCheckCorruption(0);
+    if(nBad) {
+        printf("ERROR: Found %d bad memory blocks\n", nBad);
+    }
+    printFooter(stdout, "psSort", "Free vectors", true);
+
+}
Index: /tags/rel1_1/psLib/test/collections/tst_psSort_03.c
===================================================================
--- /tags/rel1_1/psLib/test/collections/tst_psSort_03.c	(revision 1056)
+++ /tags/rel1_1/psLib/test/collections/tst_psSort_03.c	(revision 1056)
@@ -0,0 +1,60 @@
+/** @file  tst_psSort_03.c
+ *
+ *  @brief Test driver for psSort functions
+ *
+ *  This test driver contains the following tests for psSort test point 3:
+ *     A)  Create float vectors of different sizes
+ *     B)  Attempt to sort vectors...should get errors
+ *     C)  Free float vectors
+ *
+ *  @author  Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.5 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2004-06-02 23:29:29 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#include "pslib.h"
+#include "psTest.h"
+
+int main(int argc,
+         char* argv[])
+{
+    psVector *in = NULL;
+    psVector *out = NULL;
+
+
+    // Test A - Create float vectors
+    printPositiveTestHeader(stdout,"psSort", "Create float vectors of different sizes");
+    in = psVectorAlloc(5, PS_TYPE_F32);
+    in->n = 5;
+    out = psVectorAlloc(6, PS_TYPE_F32);
+    out->n = 6;
+    in->n = 5;
+    for(int i=0; i<5; i++) {
+        printf("arr[%d] = %f\n", i, in->data.F32[i]);
+    }
+    printFooter(stdout, "psSort", "Create float vectors of different sizes", true);
+
+
+    // Test B - Sort input float vector and put results into output float vector
+    printNegativeTestHeader(stdout,"psSort", "Sort float vector",
+                            "Input and output vector sizes are not equal", 0);
+    out = psSort(out, in);
+    printFooter(stdout, "psSort", "Sort float vector", true);
+
+
+    // Test C - Free float vectors
+    printPositiveTestHeader(stdout,"psSort", "Free float vectors");
+    psVectorFree(in);
+    psVectorFree(out);
+    psMemCheckLeaks(0, NULL, stdout);
+    int nBad = psMemCheckCorruption(0);
+    if(nBad) {
+        printf("ERROR: Found %d bad memory blocks\n", nBad);
+    }
+    printFooter(stdout, "psSort", "Free float vectors", true);
+
+}
Index: /tags/rel1_1/psLib/test/collections/tst_psSort_04.c
===================================================================
--- /tags/rel1_1/psLib/test/collections/tst_psSort_04.c	(revision 1056)
+++ /tags/rel1_1/psLib/test/collections/tst_psSort_04.c	(revision 1056)
@@ -0,0 +1,44 @@
+/** @file  tst_psSort_04.c
+ *
+ *  @brief Test driver for psSort functions
+ *
+ *  This test driver contains the following tests for psSort test point 4:
+ *     A)  Attempt to sort with null input vector
+ *     B)  Free vectors
+ *
+ *  @author  Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.6 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2004-06-10 23:14:22 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#include "pslib.h"
+#include "psTest.h"
+
+int main(int argc,
+         char* argv[])
+{
+    psVector *badIn = NULL;
+    psVector *goodOut = psVectorAlloc(5, PS_TYPE_F32);
+
+    // Test A - Attempt to sort with null input vector
+    printNegativeTestHeader(stdout,"psSort", "Attempt to sort with null input vector",
+                            "Null input vector", 0);
+    goodOut = psSort(goodOut, badIn);
+    printFooter(stdout, "psSort", "Attempt to sort with null input vector", true);
+
+    // Test B - Free vectors
+    printPositiveTestHeader(stdout, "psSort", "Free vectors");
+    psVectorFree(goodOut);
+    psMemCheckLeaks(0, NULL, stdout);
+    int nBad = psMemCheckCorruption(0);
+    if(nBad) {
+        printf("ERROR: Found %d bad memory blocks\n", nBad);
+    }
+    printFooter(stdout, "psSort", "Free arays", true);
+
+    return 0;
+}
Index: /tags/rel1_1/psLib/test/collections/tst_psVector_01.c
===================================================================
--- /tags/rel1_1/psLib/test/collections/tst_psVector_01.c	(revision 1056)
+++ /tags/rel1_1/psLib/test/collections/tst_psVector_01.c	(revision 1056)
@@ -0,0 +1,107 @@
+/** @file  tst_psVector_01.c
+ *
+ *  @brief Test driver for psVector integer functions
+ *
+ *  This test driver contains the following tests for psVector test point 1:
+ *     A)  Create S32 vector
+ *     B)  Add data to S32 vector
+ *     C)  Reallocate S32 vector bigger
+ *     D)  Reallocate S32 vector smaller
+ *     E)  Free S32 vector
+ *     F)  Attempt to create a S32 vector with zero size
+ *     G)  Attempt to realloc a null S32 vector
+ *
+ *  @author  Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.7 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2004-06-10 01:50:43 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#include "pslib.h"
+#include "psTest.h"
+
+int main(int argc,
+         char* argv[])
+{
+
+
+    // Test A - Create S32 vector
+    printPositiveTestHeader(stdout,"psVector", "Create S32 vector");
+    psVector *psVec = psVectorAlloc(5, PS_TYPE_S32);
+    printf("Vector size = %d\n", psVec->nalloc);
+    printf("Vector type = %d\n", psVec->type.type);
+    printf("Vector dimen = %d\n", psVec->type.dimen);
+    printf("Vector size = %d\n", psVec->nalloc);
+    printFooter(stdout, "psVector", "Create S32 vector", true);
+
+
+    // Test B - Add data to integer vector
+    printPositiveTestHeader(stdout, "psVector", "Add data to S32 vector");
+    for(int i = 0; i < 5; i++) {
+        psVec->data.S32[i] = i*10;
+        psVec->n++;
+        printf("Elem %d = %d\n", i, psVec->data.S32[i]);
+    }
+    printf("Vector size = %d\n", psVec->nalloc);
+    printf("Vector population = %d\n", psVec->n);
+    printFooter(stdout, "psVector", "Add data to S32 vector", true);
+
+
+    // Test C - Reallocate S32 vector bigger
+    printPositiveTestHeader(stdout,"psVector", "Reallocate S32 vector bigger");
+    psVec = psVectorRealloc(10, psVec);
+    printf("Adding more elements to S32 vector...\n");
+    for(int i = 5; i < 10; i++) {
+        psVec->data.S32[i] = i*10;
+        psVec->n++;
+        printf("Elem %d = %d\n", i, psVec->data.S32[i]);
+    }
+    printf("Vector size = %d\n", psVec->nalloc);
+    printf("Vector population = %d\n", psVec->n);
+    printFooter(stdout, "psVector", "Reallocate S32 vector bigger", true);
+
+
+    // Test D - Reallocate S32 vector smaller
+    printPositiveTestHeader(stdout,"psVector","Reallocate S32 vector smaller");
+    psVec = psVectorRealloc(3, psVec);
+    printf("Vector size = %d\n", psVec->nalloc);
+    for(int i = 0; i < 3; i++) {
+        printf("Elem %d = %d\n", i, psVec->data.S32[i]);
+    }
+    printf("Vector size = %d\n", psVec->nalloc);
+    printf("Vector population = %d\n", psVec->n);
+    printFooter(stdout, "psVector", "Reallocate integer S32 smaller", true);
+
+
+    // Test E - Free S32 vector
+    printPositiveTestHeader(stdout, "psVector", "Free S32 vector");
+    psVectorFree(psVec);
+    psMemCheckLeaks(0, NULL, stdout);
+    int nBad = psMemCheckCorruption(0);
+    if(nBad) {
+        printf("ERROR: Found %d bad memory blocks\n", nBad);
+    }
+    printFooter(stdout, "psVector" ,"Free S32 vector", true);
+
+
+    // Test F - Attempt to create a S32 vector with zero size
+    printNegativeTestHeader(stdout,"psVector", "Attempt to create a S32 vector with zero size",
+                            "Invalid value for nalloc", 0);
+    psVector *vecBad = psVectorAlloc(0, PS_TYPE_S32);
+    if(vecBad != NULL) {
+        printf("ERROR: Return is not NULL\n");
+    }
+    printFooter(stdout, "psVector", "Attempt to create a S32 vector with zero size", true);
+
+
+    // Test G - Attempt to realloc a null S32 vector
+    printNegativeTestHeader(stdout,"psVector", "Attempt to realloc a null S32 vector",
+                            "Null input vector", 0);
+    psVectorRealloc(6, NULL);
+    printFooter(stdout, "psVector", "Attempt to realloc a null S32 vector", true);
+
+    return 0;
+}
Index: /tags/rel1_1/psLib/test/collections/tst_psVector_02.c
===================================================================
--- /tags/rel1_1/psLib/test/collections/tst_psVector_02.c	(revision 1056)
+++ /tags/rel1_1/psLib/test/collections/tst_psVector_02.c	(revision 1056)
@@ -0,0 +1,117 @@
+/** @file  tst_psVector_02.c
+ *
+ *  @brief Test driver for psVector integer functions
+ *
+ *  This test driver contains the following tests for psVector test point 1:
+ *     A)  Create void pointer vector
+ *     B)  Add data to void pointer vector
+ *     C)  Reallocate void pointer vector bigger
+ *     D)  Reallocate void pointer vector smaller
+ *     E)  Free void pointer vector
+ *
+ *  @author  Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.3 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2004-06-02 23:29:29 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#include "pslib.h"
+#include "psTest.h"
+
+typedef struct
+{
+    int x;
+    float y;
+}
+testStruct;
+
+
+int main(int argc,
+         char* argv[])
+{
+    // Create array of pointers
+    testStruct *mySt[10];
+
+
+    // Test A - Create void pointer vector
+    printPositiveTestHeader(stdout,"psVector", "Create void pointer vector");
+    psVector *psVec = psVectorAlloc(5, PS_TYPE_PTR);
+    printf("Vector size = %d\n", psVec->nalloc);
+    printf("Vector population = %d\n", psVec->n);
+    printFooter(stdout, "psVector", "Create void pointer vector", true);
+
+
+    // Test B - Add data to void pointer vector
+    printPositiveTestHeader(stdout, "psVector", "Add data to void pointer vector");
+    for(int i = 0; i < 5; i++) {
+        testStruct *ts = psAlloc(sizeof(testStruct));
+        ts->x = 10*i;
+        ts->y = 10.1*i;
+        mySt[i] = ts;
+        psVec->data.PTR[i] = ts;
+        psVec->n++;
+        psMemIncrRefCounter(ts);
+    }
+
+    for(int i = 0; i < 5; i++) {
+        testStruct *ts = (testStruct*)psVec->data.PTR[i];
+        printf("ts[%d].x = %d ts[%d].y = %.2f\n", i, ts->x, i, ts->y);
+    }
+    printf("Vector size = %d\n", psVec->nalloc);
+    printf("Vector population = %d\n", psVec->n);
+    printFooter(stdout, "psVector", "Add data to void pointer vector", true);
+
+
+    // Test C - Reallocate void pointer vector bigger
+    printPositiveTestHeader(stdout,"psVector", "Reallocate void pointer vector bigger");
+    psVec = psVectorRealloc(10, psVec);
+    printf("Adding more elements to void pointer vector...\n");
+    for(int i = 5; i < 10; i++) {
+        testStruct *ts = psAlloc(sizeof(testStruct));
+        ts->x = 10*i;
+        ts->y = 10.1*i;
+        mySt[i] = ts;
+        psVec->data.PTR[i] = ts;
+        psVec->n++;
+        psMemIncrRefCounter(ts);
+    }
+    for(int i = 0; i < 10; i++) {
+        testStruct *ts = (testStruct*)psVec->data.PTR[i];
+        printf("ts[%d].x = %d ts[%d].y = %.2f\n", i, ts->x, i, ts->y);
+    }
+    printf("Vector size = %d\n", psVec->nalloc);
+    printf("Vector population = %d\n", psVec->n);
+    printFooter(stdout, "psVector", "Reallocate void pointer vector bigger", true);
+
+
+    // Test D - Reallocate void pointer vector smaller
+    printPositiveTestHeader(stdout,"psVector","Reallocate void pointer vector smaller");
+    psVec = psVectorRealloc(3, psVec);
+    for(int i = 0; i < 3; i++) {
+        testStruct *ts = (testStruct*)psVec->data.PTR[i];
+        printf("ts[%d].x = %d ts[%d].y = %.2f\n", i, ts->x, i, ts->y);
+    }
+    printf("Vector size = %d\n", psVec->nalloc);
+    printf("Vector population = %d\n", psVec->n);
+    printFooter(stdout, "psVector", "Reallocate integer void pointer smaller", true);
+
+
+    // Test E - Free void pointer vector
+    printPositiveTestHeader(stdout, "psVector", "Free void pointer vector");
+    psVectorElementFree(psVec, NULL);
+    psVectorFree(psVec);
+    for(int i = 0; i < 10; i++) {
+        psFree(mySt[i]);
+    }
+    psMemCheckLeaks(0, NULL, stdout);
+    int nBad = psMemCheckCorruption(0);
+    if(nBad) {
+        printf("ERROR: Found %d bad memory blocks\n", nBad);
+    }
+    printFooter(stdout, "psVector" ,"Free void pointer vector", true);
+
+    return 0;
+}
Index: /tags/rel1_1/psLib/test/collections/tst_psVector_03.c
===================================================================
--- /tags/rel1_1/psLib/test/collections/tst_psVector_03.c	(revision 1056)
+++ /tags/rel1_1/psLib/test/collections/tst_psVector_03.c	(revision 1056)
@@ -0,0 +1,126 @@
+/** @file  tst_psVector_03.c
+ *
+ *  @brief Test driver for psVector integer functions
+ *
+ *  This test driver contains the following tests for psVector test point 3:
+ *     A)  Create void pointer vector
+ *     B)  Add data to void pointer vector
+ *     C)  Reallocate void pointer vector bigger
+ *     D)  Reallocate void pointer vector smaller
+ *     E)  Free void pointer array with function callback
+ *
+ *  @author  Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.4 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2004-06-04 19:51:49 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#include "pslib.h"
+#include "psTest.h"
+
+typedef struct
+{
+    int x;
+    float y;
+}
+testStruct;
+
+static void freeData(void *data)
+{
+    psFree(data);
+}
+
+
+int main(int argc,
+         char* argv[])
+{
+    // Create array of pointers
+    testStruct *mySt[10];
+
+
+    // Test A - Create void pointer vector
+    printPositiveTestHeader(stdout,"psVector", "Create void pointer vector");
+    psVector *psVec = psVectorAlloc(5, PS_TYPE_PTR);
+    printf("Vector size = %d\n", psVec->nalloc);
+    printf("Vector population = %d\n", psVec->n);
+    printFooter(stdout, "psVector", "Create void pointer vector", true);
+
+
+    // Test B - Add data to void pointer vector
+    printPositiveTestHeader(stdout, "psVector", "Add data to void pointer vector");
+    for(int i = 0; i < 5; i++) {
+        testStruct *ts = psAlloc(sizeof(testStruct));
+        ts->x = 10*i;
+        ts->y = 10.1*i;
+        mySt[i] = ts;
+        psVec->data.PTR[i] = ts;
+        psVec->n++;
+        psMemIncrRefCounter(ts);
+    }
+
+    for(int i = 0; i < 5; i++) {
+        testStruct *ts = (testStruct*)psVec->data.PTR[i];
+        printf("ts[%d].x = %d ts[%d].y = %.2f\n", i, ts->x, i, ts->y);
+    }
+    printf("Vector size = %d\n", psVec->nalloc);
+    printf("Vector population = %d\n", psVec->n);
+    printFooter(stdout, "psVector", "Add data to void pointer vector", true);
+
+
+    // Test C - Reallocate void pointer vector bigger
+    printPositiveTestHeader(stdout,"psVector", "Reallocate void pointer vector bigger");
+    psVec = psVectorRealloc(10, psVec);
+    printf("Adding more elements to void pointer vector...\n");
+    for(int i = 5; i < 10; i++) {
+        testStruct *ts = psAlloc(sizeof(testStruct));
+        ts->x = 10*i;
+        ts->y = 10.1*i;
+        mySt[i] = ts;
+        psVec->data.PTR[i] = ts;
+        psVec->n++;
+        psMemIncrRefCounter(ts);
+    }
+    for(int i = 0; i < 10; i++) {
+        testStruct *ts = (testStruct*)psVec->data.PTR[i];
+        printf("ts[%d].x = %d ts[%d].y = %.2f\n", i, ts->x, i, ts->y);
+    }
+    printf("Vector size = %d\n", psVec->nalloc);
+    printf("Vector population = %d\n", psVec->n);
+    printFooter(stdout, "psVector", "Reallocate void pointer vector bigger", true);
+
+
+    // Test D - Reallocate void pointer vector smaller
+    printPositiveTestHeader(stdout,"psVector","Reallocate void pointer vector smaller");
+    psVec = psVectorRealloc(3, psVec);
+    for(int i = 0; i < 3; i++) {
+        testStruct *ts = (testStruct*)psVec->data.PTR[i];
+        printf("ts[%d].x = %d ts[%d].y = %.2f\n", i, ts->x, i, ts->y);
+    }
+    printf("Vector size = %d\n", psVec->nalloc);
+    printf("Vector population = %d\n", psVec->n);
+    printFooter(stdout, "psVector", "Reallocate integer void pointer smaller", true);
+
+
+    // Test E - Free void pointer array with function callback
+    printPositiveTestHeader(stdout, "psVector", "Free void pointer array with function callback");
+
+    // Free void pointer array struct and its 3 internal elements
+    psVectorElementFree(psVec, freeData);
+    psVectorFree(psVec);
+
+    // Free 7 elements manually that were lost after array was reallocated smaller
+    for(int i = 3; i < 10; i++) {
+        psFree(mySt[i]);
+    }
+    psMemCheckLeaks(0, NULL, stdout);
+    int nBad = psMemCheckCorruption(0);
+    if(nBad) {
+        printf("ERROR: Found %d bad memory blocks\n", nBad);
+    }
+    printFooter(stdout, "psVector" ,"Free void pointer array with function callback", true);
+
+    return 0;
+}
Index: /tags/rel1_1/psLib/test/collections/verified/tst_psBitSet_01.stderr
===================================================================
--- /tags/rel1_1/psLib/test/collections/verified/tst_psBitSet_01.stderr	(revision 1056)
+++ /tags/rel1_1/psLib/test/collections/verified/tst_psBitSet_01.stderr	(revision 1056)
@@ -0,0 +1,6 @@
+ <DATE> <TIME> <HOST> |E|   psBitSetTest| : Line 140 - Bit position too small: -4
+ <DATE> <TIME> <HOST> |E|   psBitSetTest| : Line 143 - Bit position too large: 200
+ <DATE> <TIME> <HOST> |E|   psBitSetTest| : Line 137 - Null psBitSet for inBitSet argument
+ <DATE> <TIME> <HOST> |E|    psBitSetSet| : Line 118 - Bit position too small: -4
+ <DATE> <TIME> <HOST> |E|    psBitSetSet| : Line 121 - Bit position too large: 200
+ <DATE> <TIME> <HOST> |E|    psBitSetSet| : Line 115 - Null psBitSet for inBitSet argument
Index: /tags/rel1_1/psLib/test/collections/verified/tst_psBitSet_01.stdout
===================================================================
--- /tags/rel1_1/psLib/test/collections/verified/tst_psBitSet_01.stdout	(revision 1056)
+++ /tags/rel1_1/psLib/test/collections/verified/tst_psBitSet_01.stdout	(revision 1056)
@@ -0,0 +1,116 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psBitSet_01.c                                          *
+*            TestPoint: psBitSet{Create psBitSet}                                  *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Creating psBitSet with 24 bits...
+000000000000000000000000
+
+
+---> TESTPOINT PASSED (psBitSet{Create psBitSet} | tst_psBitSet_01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psBitSet_01.c                                          *
+*            TestPoint: psBitSet{Set bits}                                         *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Setting first bit...
+Setting third bit...
+Setting last bit...
+100000000000000000000101
+
+
+---> TESTPOINT PASSED (psBitSet{Set bits} | tst_psBitSet_01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psBitSet_01.c                                          *
+*            TestPoint: psBitSet{Test bits}                                        *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Testing first bit...
+Result: 1
+Testing third bit...
+Result: 1
+Testing last bit...
+Result: 1
+
+---> TESTPOINT PASSED (psBitSet{Test bits} | tst_psBitSet_01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psBitSet_01.c                                          *
+*            TestPoint: psBitSet{Attempt to test negative bit}                     *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Bit position too small: -4                                 *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psBitSet{Attempt to test negative bit} | tst_psBitSet_01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psBitSet_01.c                                          *
+*            TestPoint: psBitSet{Attempt to test bit to large}                     *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Bit position too large: 200                                *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psBitSet{Attempt to test bit to large} | tst_psBitSet_01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psBitSet_01.c                                          *
+*            TestPoint: psBitSet{Attempt to test bit in null BitSet}               *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Null psBitSet for inBitSet argument                        *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psBitSet{Attempt to test bit in null BitSet} | tst_psBitSet_01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psBitSet_01.c                                          *
+*            TestPoint: psBitSet{Attempt to set negative bit}                      *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Bit position too small: -4                                 *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psBitSet{Attempt to set negative bit} | tst_psBitSet_01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psBitSet_01.c                                          *
+*            TestPoint: psBitSet{Attempt to set bit to large}                      *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Bit position too large: 200                                *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psBitSet{Attempt to set bit to large} | tst_psBitSet_01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psBitSet_01.c                                          *
+*            TestPoint: psBitSet{Attempt to set bit in null BitSet}                *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Null psBitSet for inBitSet argument                        *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psBitSet{Attempt to set bit in null BitSet} | tst_psBitSet_01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psBitSet_01.c                                          *
+*            TestPoint: psBitSet{Free psBitSet}                                    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psBitSet{Free psBitSet} | tst_psBitSet_01.c)
+
Index: /tags/rel1_1/psLib/test/collections/verified/tst_psBitSet_02.stdout
===================================================================
--- /tags/rel1_1/psLib/test/collections/verified/tst_psBitSet_02.stdout	(revision 1056)
+++ /tags/rel1_1/psLib/test/collections/verified/tst_psBitSet_02.stdout	(revision 1056)
@@ -0,0 +1,36 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psBitSet_02.c                                          *
+*            TestPoint: psBitSet{Create two psBitSets}                             *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+000000000000000000000000
+000000000000000000000000
+
+Setting all bits true...
+111111111111111111111111
+111111111111111111111111
+
+
+---> TESTPOINT PASSED (psBitSet{Create two psBitSets} | tst_psBitSet_02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psBitSet_02.c                                          *
+*            TestPoint: psBitSet{Perform binary AND with psBitSets}                *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Result:
+111111111111111111111111
+
+---> TESTPOINT PASSED (psBitSet{Perform binary AND with psBitSets} | tst_psBitSet_02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psBitSet_02.c                                          *
+*            TestPoint: psBitSet{Free psBitSets}                                   *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psBitSet{Free psBitSets} | tst_psBitSet_02.c)
+
Index: /tags/rel1_1/psLib/test/collections/verified/tst_psBitSet_03.stdout
===================================================================
--- /tags/rel1_1/psLib/test/collections/verified/tst_psBitSet_03.stdout	(revision 1056)
+++ /tags/rel1_1/psLib/test/collections/verified/tst_psBitSet_03.stdout	(revision 1056)
@@ -0,0 +1,36 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psBitSet_03.c                                          *
+*            TestPoint: psBitSet{Create two psBitSets}                             *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+000000000000000000000000
+000000000000000000000000
+
+Setting all bits true...
+111111111111111111111111
+111111111111111111111111
+
+
+---> TESTPOINT PASSED (psBitSet{Create two psBitSets} | tst_psBitSet_03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psBitSet_03.c                                          *
+*            TestPoint: psBitSet{Perform binary OR with psBitSets}                 *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Result:
+111111111111111111111111
+
+---> TESTPOINT PASSED (psBitSet{Perform binary OR with psBitSets} | tst_psBitSet_03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psBitSet_03.c                                          *
+*            TestPoint: psBitSet{Free psBitSets}                                   *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psBitSet{Free psBitSets} | tst_psBitSet_03.c)
+
Index: /tags/rel1_1/psLib/test/collections/verified/tst_psBitSet_04.stdout
===================================================================
--- /tags/rel1_1/psLib/test/collections/verified/tst_psBitSet_04.stdout	(revision 1056)
+++ /tags/rel1_1/psLib/test/collections/verified/tst_psBitSet_04.stdout	(revision 1056)
@@ -0,0 +1,36 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psBitSet_04.c                                          *
+*            TestPoint: psBitSet{Create two psBitSets}                             *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+000000000000000000000000
+000000000000000000000000
+
+Setting all bits true...
+111111111111111111111111
+111111111111111111111111
+
+
+---> TESTPOINT PASSED (psBitSet{Create two psBitSets} | tst_psBitSet_04.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psBitSet_04.c                                          *
+*            TestPoint: psBitSet{Perform binary XOR with psBitSets}                *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Result:
+000000000000000000000000
+
+---> TESTPOINT PASSED (psBitSet{Perform binary XOR with psBitSets} | tst_psBitSet_04.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psBitSet_04.c                                          *
+*            TestPoint: psBitSet{Free psBitSets}                                   *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psBitSet{Free psBitSets} | tst_psBitSet_04.c)
+
Index: /tags/rel1_1/psLib/test/collections/verified/tst_psBitSet_05.stderr
===================================================================
--- /tags/rel1_1/psLib/test/collections/verified/tst_psBitSet_05.stderr	(revision 1056)
+++ /tags/rel1_1/psLib/test/collections/verified/tst_psBitSet_05.stderr	(revision 1056)
@@ -0,0 +1,1 @@
+ <DATE> <TIME> <HOST> |E|     psBitSetOp| : Line 187 - psBitSet sizes not the same
Index: /tags/rel1_1/psLib/test/collections/verified/tst_psBitSet_05.stdout
===================================================================
--- /tags/rel1_1/psLib/test/collections/verified/tst_psBitSet_05.stdout	(revision 1056)
+++ /tags/rel1_1/psLib/test/collections/verified/tst_psBitSet_05.stdout	(revision 1056)
@@ -0,0 +1,32 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psBitSet_05.c                                          *
+*            TestPoint: psBitSet{Create two psBitSets of different size}           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+000000000000000000000000
+0000000000000000000000000000000000000000
+
+
+---> TESTPOINT PASSED (psBitSet{Create two psBitSets of different size} | tst_psBitSet_05.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psBitSet_05.c                                          *
+*            TestPoint: psBitSet{Attempt OR with psBitsets}                        *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: psBitSet sizes not the same                                *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psBitSet{Attempt OR with psBitsets} | tst_psBitSet_05.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psBitSet_05.c                                          *
+*            TestPoint: psBitSet{Free psBitSets}                                   *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psBitSet{Free psBitSets} | tst_psBitSet_05.c)
+
Index: /tags/rel1_1/psLib/test/collections/verified/tst_psBitSet_06.stderr
===================================================================
--- /tags/rel1_1/psLib/test/collections/verified/tst_psBitSet_06.stderr	(revision 1056)
+++ /tags/rel1_1/psLib/test/collections/verified/tst_psBitSet_06.stderr	(revision 1056)
@@ -0,0 +1,3 @@
+ <DATE> <TIME> <HOST> |E|     psBitSetOp| : Line 214 - Invalid psBitMask binary operation: ZZXOR
+ <DATE> <TIME> <HOST> |E|  psBitSetAlloc| : Line 84 - Allocation size must be > 0: size = -4
+ <DATE> <TIME> <HOST> |E|   psBitSetFree| : Line 103 - Null psBitSet for inBitSet argument
Index: /tags/rel1_1/psLib/test/collections/verified/tst_psBitSet_06.stdout
===================================================================
--- /tags/rel1_1/psLib/test/collections/verified/tst_psBitSet_06.stdout	(revision 1056)
+++ /tags/rel1_1/psLib/test/collections/verified/tst_psBitSet_06.stdout	(revision 1056)
@@ -0,0 +1,54 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psBitSet_06.c                                          *
+*            TestPoint: psBitSet{Create two psBitSets}                             *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+000000000000000000000000
+000000000000000000000000
+
+
+---> TESTPOINT PASSED (psBitSet{Create two psBitSets} | tst_psBitSet_06.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psBitSet_06.c                                          *
+*            TestPoint: psBitSet{Perform invalid binary operation}                 *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Invalid psBitMask binary operation                         *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psBitSet{Perform binary XOR with psBitSets} | tst_psBitSet_06.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psBitSet_06.c                                          *
+*            TestPoint: psBitSet{Create negative size bitset}                      *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Allocation size must be >= 0: size = -4                    *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psBitSet{Create negative size bitset} | tst_psBitSet_06.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psBitSet_06.c                                          *
+*            TestPoint: psBitSet{Attempt to free null BitSet}                      *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Null psBitSet for inBitSet argument                        *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psBitSet{Attempt to free null BitSet} | tst_psBitSet_06.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psBitSet_06.c                                          *
+*            TestPoint: psBitSet{Free psBitSets}                                   *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psBitSet{Free psBitSetFree psBitSets} | tst_psBitSet_06.c)
+
Index: /tags/rel1_1/psLib/test/collections/verified/tst_psList.stderr
===================================================================
--- /tags/rel1_1/psLib/test/collections/verified/tst_psList.stderr	(revision 1056)
+++ /tags/rel1_1/psLib/test/collections/verified/tst_psList.stderr	(revision 1056)
@@ -0,0 +1,86 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psList.c                                               *
+*            TestPoint: psList{487-testListAlloc}                                  *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+ <DATE> <TIME> <HOST> |I|  testListAlloc|psListAlloc shall create a psList with either 0 or 1 element.
+
+---> TESTPOINT PASSED (psList{487-testListAlloc} | tst_psList.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psList.c                                               *
+*            TestPoint: psList{488-testListAdd}                                    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+ <DATE> <TIME> <HOST> |I|    testListAdd|psListAdd shall add an element to list
+ <DATE> <TIME> <HOST> |I|    testListAdd|Following should warn with invalid insert location
+ <DATE> <TIME> <HOST> |W|      psListAdd|The given insert location (-10) for psListAdd is invalid. Adding to head instead.
+ <DATE> <TIME> <HOST> |I|    testListAdd|Following should be a warning.
+ <DATE> <TIME> <HOST> |W|      psListAdd|Invalid index 9 (only 7 elements in psList); assuming tail.
+
+---> TESTPOINT PASSED (psList{488-testListAdd} | tst_psList.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psList.c                                               *
+*            TestPoint: psList{489-testListGet}                                    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+ <DATE> <TIME> <HOST> |I|    testListGet|Following should be an error
+ <DATE> <TIME> <HOST> |E|listSetIterator|Unexpected null pointer for psList parameter (psList.c:264).
+
+---> TESTPOINT PASSED (psList{489-testListGet} | tst_psList.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psList.c                                               *
+*            TestPoint: psList{490-testListRemove}                                 *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+ <DATE> <TIME> <HOST> |I| testListRemove|Following should be an error
+ <DATE> <TIME> <HOST> |E|   psListRemove|list parameter found to be NULL in psListRemove
+ <DATE> <TIME> <HOST> |I| testListRemove|Next message should be an error
+ <DATE> <TIME> <HOST> |E|   psListRemove|Couldn't position to given index (-4) to remove element from list.
+ <DATE> <TIME> <HOST> |I| testListRemove|Next message should be an error
+ <DATE> <TIME> <HOST> |E|   psListRemove|Couldn't position to given index (-2) to remove element from list.
+ <DATE> <TIME> <HOST> |I| testListRemove|Next message should be an error
+ <DATE> <TIME> <HOST> |E|   psListRemove|Failed to find item in given psList.
+ <DATE> <TIME> <HOST> |I| testListRemove|Next message should be an error
+ <DATE> <TIME> <HOST> |E|   psListRemove|Failed to find item in given psList.
+
+---> TESTPOINT PASSED (psList{490-testListRemove} | tst_psList.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psList.c                                               *
+*            TestPoint: psList{491-testListConvert}                                *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psList{491-testListConvert} | tst_psList.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psList.c                                               *
+*            TestPoint: psList{494-testListIterator}                               *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+ <DATE> <TIME> <HOST> |I|testListIterato| psListSetIterator/psListGetNext/psListGetPrev shall move the list cursor to the specified location
+ <DATE> <TIME> <HOST> |I|testListIterato|Following should error with 'Unexpected null pointer'
+ <DATE> <TIME> <HOST> |E|listSetIterator|Unexpected null pointer for psList parameter (psList.c:264).
+ <DATE> <TIME> <HOST> |I|testListIterato|Following should error with 'Can't move to an unknown position.'
+ <DATE> <TIME> <HOST> |E|listSetIterator|Can't move to an unknown position.  Not moving the iterator position.
+
+---> TESTPOINT PASSED (psList{494-testListIterator} | tst_psList.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psList.c                                               *
+*            TestPoint: psList{627-testListFree}                                   *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psList{627-testListFree} | tst_psList.c)
+
Index: /tags/rel1_1/psLib/test/collections/verified/tst_psSort_01.stdout
===================================================================
--- /tags/rel1_1/psLib/test/collections/verified/tst_psSort_01.stdout	(revision 1056)
+++ /tags/rel1_1/psLib/test/collections/verified/tst_psSort_01.stdout	(revision 1056)
@@ -0,0 +1,57 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psSort_01.c                                            *
+*            TestPoint: psSort{Create float vectors}                               *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+vec[0] = 7.000000
+vec[1] = 9.000000
+vec[2] = 3.000000
+vec[3] = 1.000000
+vec[4] = 5.000000
+vec[5] = 5.000000
+vec[6] = -20.000000
+
+---> TESTPOINT PASSED (psSort{Create float vectors} | tst_psSort_01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psSort_01.c                                            *
+*            TestPoint: psSort{Sort float vector}                                  *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+vec[0] = -20.000000
+vec[1] = 1.000000
+vec[2] = 3.000000
+vec[3] = 5.000000
+vec[4] = 5.000000
+vec[5] = 7.000000
+vec[6] = 9.000000
+
+---> TESTPOINT PASSED (psSort{Sort float vector} | tst_psSort_01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psSort_01.c                                            *
+*            TestPoint: psSort{Sort input float vector into itself}                *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+vec[0] = -20.000000
+vec[1] = 1.000000
+vec[2] = 3.000000
+vec[3] = 5.000000
+vec[4] = 5.000000
+vec[5] = 7.000000
+vec[6] = 9.000000
+
+---> TESTPOINT PASSED (psSort{Sort input float vector into itself} | tst_psSort_01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psSort_01.c                                            *
+*            TestPoint: psSort{Free float vectors}                                 *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psSort{Free float vectors} | tst_psSort_01.c)
+
Index: /tags/rel1_1/psLib/test/collections/verified/tst_psSort_02.stdout
===================================================================
--- /tags/rel1_1/psLib/test/collections/verified/tst_psSort_02.stdout	(revision 1056)
+++ /tags/rel1_1/psLib/test/collections/verified/tst_psSort_02.stdout	(revision 1056)
@@ -0,0 +1,37 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psSort_02.c                                            *
+*            TestPoint: psSort{Create vectors}                                     *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+arr[0] = 7.000000
+arr[1] = 9.000000
+arr[2] = 3.000000
+arr[3] = 1.000000
+arr[4] = 5.000000
+
+---> TESTPOINT PASSED (psSort{Create vectors} | tst_psSort_02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psSort_02.c                                            *
+*            TestPoint: psSort{Create sorted index vector}                         *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+arr[0] = 3
+arr[1] = 2
+arr[2] = 4
+arr[3] = 0
+arr[4] = 1
+
+---> TESTPOINT PASSED (psSort{Create sorted index vector} | tst_psSort_02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psSort_02.c                                            *
+*            TestPoint: psSort{Free vectors}                                       *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psSort{Free vectors} | tst_psSort_02.c)
+
Index: /tags/rel1_1/psLib/test/collections/verified/tst_psSort_03.stderr
===================================================================
--- /tags/rel1_1/psLib/test/collections/verified/tst_psSort_03.stderr	(revision 1056)
+++ /tags/rel1_1/psLib/test/collections/verified/tst_psSort_03.stderr	(revision 1056)
@@ -0,0 +1,1 @@
+ <DATE> <TIME> <HOST> |E|         psSort| : Line 136 - Input and output vector sizes are not equal: in=5 out=6
Index: /tags/rel1_1/psLib/test/collections/verified/tst_psSort_03.stdout
===================================================================
--- /tags/rel1_1/psLib/test/collections/verified/tst_psSort_03.stdout	(revision 1056)
+++ /tags/rel1_1/psLib/test/collections/verified/tst_psSort_03.stdout	(revision 1056)
@@ -0,0 +1,34 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psSort_03.c                                            *
+*            TestPoint: psSort{Create float vectors of different sizes}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+arr[0] = 0.000000
+arr[1] = 0.000000
+arr[2] = 0.000000
+arr[3] = 0.000000
+arr[4] = 0.000000
+
+---> TESTPOINT PASSED (psSort{Create float vectors of different sizes} | tst_psSort_03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psSort_03.c                                            *
+*            TestPoint: psSort{Sort float vector}                                  *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Input and output vector sizes are not equal                *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psSort{Sort float vector} | tst_psSort_03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psSort_03.c                                            *
+*            TestPoint: psSort{Free float vectors}                                 *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psSort{Free float vectors} | tst_psSort_03.c)
+
Index: /tags/rel1_1/psLib/test/collections/verified/tst_psSort_04.stderr
===================================================================
--- /tags/rel1_1/psLib/test/collections/verified/tst_psSort_04.stderr	(revision 1056)
+++ /tags/rel1_1/psLib/test/collections/verified/tst_psSort_04.stderr	(revision 1056)
@@ -0,0 +1,1 @@
+ <DATE> <TIME> <HOST> |E|         psSort| : Line 118 - Null input vector
Index: /tags/rel1_1/psLib/test/collections/verified/tst_psSort_04.stdout
===================================================================
--- /tags/rel1_1/psLib/test/collections/verified/tst_psSort_04.stdout	(revision 1056)
+++ /tags/rel1_1/psLib/test/collections/verified/tst_psSort_04.stdout	(revision 1056)
@@ -0,0 +1,20 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psSort_04.c                                            *
+*            TestPoint: psSort{Attempt to sort with null input vector}             *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Null input vector                                          *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psSort{Attempt to sort with null input vector} | tst_psSort_04.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psSort_04.c                                            *
+*            TestPoint: psSort{Free vectors}                                       *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psSort{Free arays} | tst_psSort_04.c)
+
Index: /tags/rel1_1/psLib/test/collections/verified/tst_psVector_01.stderr
===================================================================
--- /tags/rel1_1/psLib/test/collections/verified/tst_psVector_01.stderr	(revision 1056)
+++ /tags/rel1_1/psLib/test/collections/verified/tst_psVector_01.stderr	(revision 1056)
@@ -0,0 +1,2 @@
+ <DATE> <TIME> <HOST> |E|  psVectorAlloc|Invalid value for nalloc. nalloc: 0
+ <DATE> <TIME> <HOST> |E|psVectorRealloc|Null input vector
Index: /tags/rel1_1/psLib/test/collections/verified/tst_psVector_01.stdout
===================================================================
--- /tags/rel1_1/psLib/test/collections/verified/tst_psVector_01.stdout	(revision 1056)
+++ /tags/rel1_1/psLib/test/collections/verified/tst_psVector_01.stdout	(revision 1056)
@@ -0,0 +1,92 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVector_01.c                                          *
+*            TestPoint: psVector{Create S32 vector}                                *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Vector size = 5
+Vector type = 260
+Vector dimen = 1
+Vector size = 5
+
+---> TESTPOINT PASSED (psVector{Create S32 vector} | tst_psVector_01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVector_01.c                                          *
+*            TestPoint: psVector{Add data to S32 vector}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Elem 0 = 0
+Elem 1 = 10
+Elem 2 = 20
+Elem 3 = 30
+Elem 4 = 40
+Vector size = 5
+Vector population = 5
+
+---> TESTPOINT PASSED (psVector{Add data to S32 vector} | tst_psVector_01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVector_01.c                                          *
+*            TestPoint: psVector{Reallocate S32 vector bigger}                     *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Adding more elements to S32 vector...
+Elem 5 = 50
+Elem 6 = 60
+Elem 7 = 70
+Elem 8 = 80
+Elem 9 = 90
+Vector size = 10
+Vector population = 10
+
+---> TESTPOINT PASSED (psVector{Reallocate S32 vector bigger} | tst_psVector_01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVector_01.c                                          *
+*            TestPoint: psVector{Reallocate S32 vector smaller}                    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Vector size = 3
+Elem 0 = 0
+Elem 1 = 10
+Elem 2 = 20
+Vector size = 3
+Vector population = 3
+
+---> TESTPOINT PASSED (psVector{Reallocate integer S32 smaller} | tst_psVector_01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVector_01.c                                          *
+*            TestPoint: psVector{Free S32 vector}                                  *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psVector{Free S32 vector} | tst_psVector_01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVector_01.c                                          *
+*            TestPoint: psVector{Attempt to create a S32 vector with zero size}    *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Invalid value for nalloc                                   *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psVector{Attempt to create a S32 vector with zero size} | tst_psVector_01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVector_01.c                                          *
+*            TestPoint: psVector{Attempt to realloc a null S32 vector}             *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Null input vector                                          *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psVector{Attempt to realloc a null S32 vector} | tst_psVector_01.c)
+
Index: /tags/rel1_1/psLib/test/collections/verified/tst_psVector_02.stdout
===================================================================
--- /tags/rel1_1/psLib/test/collections/verified/tst_psVector_02.stdout	(revision 1056)
+++ /tags/rel1_1/psLib/test/collections/verified/tst_psVector_02.stdout	(revision 1056)
@@ -0,0 +1,72 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVector_02.c                                          *
+*            TestPoint: psVector{Create void pointer vector}                       *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Vector size = 5
+Vector population = 0
+
+---> TESTPOINT PASSED (psVector{Create void pointer vector} | tst_psVector_02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVector_02.c                                          *
+*            TestPoint: psVector{Add data to void pointer vector}                  *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+ts[0].x = 0 ts[0].y = 0.00
+ts[1].x = 10 ts[1].y = 10.10
+ts[2].x = 20 ts[2].y = 20.20
+ts[3].x = 30 ts[3].y = 30.30
+ts[4].x = 40 ts[4].y = 40.40
+Vector size = 5
+Vector population = 5
+
+---> TESTPOINT PASSED (psVector{Add data to void pointer vector} | tst_psVector_02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVector_02.c                                          *
+*            TestPoint: psVector{Reallocate void pointer vector bigger}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Adding more elements to void pointer vector...
+ts[0].x = 0 ts[0].y = 0.00
+ts[1].x = 10 ts[1].y = 10.10
+ts[2].x = 20 ts[2].y = 20.20
+ts[3].x = 30 ts[3].y = 30.30
+ts[4].x = 40 ts[4].y = 40.40
+ts[5].x = 50 ts[5].y = 50.50
+ts[6].x = 60 ts[6].y = 60.60
+ts[7].x = 70 ts[7].y = 70.70
+ts[8].x = 80 ts[8].y = 80.80
+ts[9].x = 90 ts[9].y = 90.90
+Vector size = 10
+Vector population = 10
+
+---> TESTPOINT PASSED (psVector{Reallocate void pointer vector bigger} | tst_psVector_02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVector_02.c                                          *
+*            TestPoint: psVector{Reallocate void pointer vector smaller}           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+ts[0].x = 0 ts[0].y = 0.00
+ts[1].x = 10 ts[1].y = 10.10
+ts[2].x = 20 ts[2].y = 20.20
+Vector size = 3
+Vector population = 3
+
+---> TESTPOINT PASSED (psVector{Reallocate integer void pointer smaller} | tst_psVector_02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVector_02.c                                          *
+*            TestPoint: psVector{Free void pointer vector}                         *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psVector{Free void pointer vector} | tst_psVector_02.c)
+
Index: /tags/rel1_1/psLib/test/collections/verified/tst_psVector_03.stdout
===================================================================
--- /tags/rel1_1/psLib/test/collections/verified/tst_psVector_03.stdout	(revision 1056)
+++ /tags/rel1_1/psLib/test/collections/verified/tst_psVector_03.stdout	(revision 1056)
@@ -0,0 +1,72 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVector_03.c                                          *
+*            TestPoint: psVector{Create void pointer vector}                       *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Vector size = 5
+Vector population = 0
+
+---> TESTPOINT PASSED (psVector{Create void pointer vector} | tst_psVector_03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVector_03.c                                          *
+*            TestPoint: psVector{Add data to void pointer vector}                  *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+ts[0].x = 0 ts[0].y = 0.00
+ts[1].x = 10 ts[1].y = 10.10
+ts[2].x = 20 ts[2].y = 20.20
+ts[3].x = 30 ts[3].y = 30.30
+ts[4].x = 40 ts[4].y = 40.40
+Vector size = 5
+Vector population = 5
+
+---> TESTPOINT PASSED (psVector{Add data to void pointer vector} | tst_psVector_03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVector_03.c                                          *
+*            TestPoint: psVector{Reallocate void pointer vector bigger}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Adding more elements to void pointer vector...
+ts[0].x = 0 ts[0].y = 0.00
+ts[1].x = 10 ts[1].y = 10.10
+ts[2].x = 20 ts[2].y = 20.20
+ts[3].x = 30 ts[3].y = 30.30
+ts[4].x = 40 ts[4].y = 40.40
+ts[5].x = 50 ts[5].y = 50.50
+ts[6].x = 60 ts[6].y = 60.60
+ts[7].x = 70 ts[7].y = 70.70
+ts[8].x = 80 ts[8].y = 80.80
+ts[9].x = 90 ts[9].y = 90.90
+Vector size = 10
+Vector population = 10
+
+---> TESTPOINT PASSED (psVector{Reallocate void pointer vector bigger} | tst_psVector_03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVector_03.c                                          *
+*            TestPoint: psVector{Reallocate void pointer vector smaller}           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+ts[0].x = 0 ts[0].y = 0.00
+ts[1].x = 10 ts[1].y = 10.10
+ts[2].x = 20 ts[2].y = 20.20
+Vector size = 3
+Vector population = 3
+
+---> TESTPOINT PASSED (psVector{Reallocate integer void pointer smaller} | tst_psVector_03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVector_03.c                                          *
+*            TestPoint: psVector{Free void pointer array with function callback}   *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psVector{Free void pointer array with function callback} | tst_psVector_03.c)
+
Index: /tags/rel1_1/psLib/test/dataManip/.cvsignore
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/.cvsignore	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/.cvsignore	(revision 1056)
@@ -0,0 +1,30 @@
+temp
+tmpImages
+tst_psMatrix01
+tst_psStats00
+tst_psStats01
+tst_psStats02
+tst_psStats03
+tst_psStats04
+tst_psFunc00
+tst_psFunc01
+tst_psHist00
+tst_psHist01
+tst_psHist02
+tst_psImageIO
+tst_psImageStats00
+tst_psImageStats01
+tst_psImageStats02
+tst_psMatrix02
+tst_psMatrix03
+tst_psMatrix04
+tst_psMatrix05
+tst_psMatrix06
+tst_psMatrix07
+tst_psStats05
+tst_psStats06
+tst_psStats07
+tst_psStats08
+tst_psStats09
+tst_psImageFFT
+tst_psVectorFFT
Index: /tags/rel1_1/psLib/test/dataManip/Makefile
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/Makefile	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/Makefile	(revision 1056)
@@ -0,0 +1,91 @@
+################################################################################
+##
+##  Makefile:   test/sysUtils
+##
+##  $Revision: 1.14.2.2 $  $Name: not supported by cvs2svn $
+##  $Date: 2004-06-15 21:45:11 $
+##
+##  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+##
+###############################################################################
+
+ifndef prefix
+    export prefix=$(shell cd ../..;pwd)
+endif
+
+include ../../src/Makefile.Globals
+
+PSLIB_INCL_DIR = ../../include
+
+PSLIB_LIB_DIR = ../../lib
+
+TARGET = tst_psMatrix01 \
+ tst_psMatrix02 \
+ tst_psMatrix03 \
+ tst_psMatrix04 \
+ tst_psMatrix05 \
+ tst_psMatrix06 \
+ tst_psMatrix07 \
+ tst_psStats00 \
+ tst_psStats01 \
+ tst_psStats02 \
+ tst_psStats03 \
+ tst_psStats05 \
+ tst_psStats06 \
+ tst_psStats08 \
+ tst_psStats09 \
+ tst_psHist00 \
+ tst_psHist01 \
+ tst_psHist02 \
+ tst_psFunc00 \
+ tst_psFunc01 \
+ tst_psImageStats00 \
+ tst_psImageStats01 \
+ tst_psImageStats02 \
+ tst_psImageIO \
+ tst_psVectorFFT \
+ tst_psImageFFT
+# tst_psStats07 
+
+DEPENDENCIES = $(addprefix builddir/,$(addsuffix .d,$(TARGET)))
+OBJS = $(addprefix builddir/,$(addsuffix .o,$(TARGET)))
+
+all: builddir $(TARGET)
+
+builddir:
+	mkdir builddir
+
+include $(DEPENDENCIES)
+
+clean:
+	@echo "    Deleting executable and binary files for 'test/sysUtils'"
+	$(RM) $(OBJS) *.lint tmpImages/*.fits
+
+builddir/%.o : %.c
+	$(CC) $(CFLAGS) $(CPPFLAGS) -I.. -I$(PSLIB_INCL_DIR) -c -o $@ $<
+
+%   : builddir/%.o
+	$(CC) -o $@ $< -L$(PSLIB_LIB_DIR) -lpslib -lpstest $(LDFLAGS)
+
+distclean: clean
+	$(RM) $(TARGET)
+
+%.lint: %.c
+	splint +posixlib -exportlocal -realcompare $(INCLUDE_GLOBAL) $? > $@; cat $@
+
+builddir/%.d: %.c
+	$(CC) -MM $(CFLAGS) -I$(PSLIB_INCL_DIR) $< > $@.tmp
+	sed 's|\($*\)\.o[ :]*|builddir\/\1.o $@ : |g' $@.tmp > $@
+	$(RM) -f $@.tmp
+
+install: $(testbindir) $(testbindir)/verified $(TARGET)
+	install $(TARGET) $(testbindir)
+	install verified/*.stderr verified/*.stdout $(testbindir)/verified
+
+$(testbindir):
+	mkdir -p $(testbindir)
+
+$(testbindir)/verified:
+	mkdir -p $(testbindir)/verified
+
+
Index: /tags/rel1_1/psLib/test/dataManip/builddir/tst_psFunc00.d
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/builddir/tst_psFunc00.d	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/builddir/tst_psFunc00.d	(revision 1056)
@@ -0,0 +1,9 @@
+builddir/tst_psFunc00.o builddir/tst_psFunc00.d : tst_psFunc00.c ../../include/pslib.h \
+  ../../include/psMemory.h ../../include/psLogMsg.h \
+  ../../include/psTrace.h ../../include/psAbort.h ../../include/psError.h \
+  ../../include/psString.h ../../include/psType.h ../../include/psList.h \
+  ../../include/psVector.h ../../include/psHash.h ../../include/psImage.h \
+  ../../include/psBitSet.h ../../include/psSort.h ../../include/psStats.h \
+  ../../include/psMatrix.h ../../include/psFFT.h \
+  ../../include/psImageIO.h ../../include/psTest.h \
+  ../../include/psFunctions.h
Index: /tags/rel1_1/psLib/test/dataManip/builddir/tst_psFunc01.d
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/builddir/tst_psFunc01.d	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/builddir/tst_psFunc01.d	(revision 1056)
@@ -0,0 +1,9 @@
+builddir/tst_psFunc01.o builddir/tst_psFunc01.d : tst_psFunc01.c ../../include/pslib.h \
+  ../../include/psMemory.h ../../include/psLogMsg.h \
+  ../../include/psTrace.h ../../include/psAbort.h ../../include/psError.h \
+  ../../include/psString.h ../../include/psType.h ../../include/psList.h \
+  ../../include/psVector.h ../../include/psHash.h ../../include/psImage.h \
+  ../../include/psBitSet.h ../../include/psSort.h ../../include/psStats.h \
+  ../../include/psMatrix.h ../../include/psFFT.h \
+  ../../include/psImageIO.h ../../include/psTest.h \
+  ../../include/psFunctions.h
Index: /tags/rel1_1/psLib/test/dataManip/builddir/tst_psHist00.d
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/builddir/tst_psHist00.d	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/builddir/tst_psHist00.d	(revision 1056)
@@ -0,0 +1,8 @@
+builddir/tst_psHist00.o builddir/tst_psHist00.d : tst_psHist00.c ../../include/pslib.h \
+  ../../include/psMemory.h ../../include/psLogMsg.h \
+  ../../include/psTrace.h ../../include/psAbort.h ../../include/psError.h \
+  ../../include/psString.h ../../include/psType.h ../../include/psList.h \
+  ../../include/psVector.h ../../include/psHash.h ../../include/psImage.h \
+  ../../include/psBitSet.h ../../include/psSort.h ../../include/psStats.h \
+  ../../include/psMatrix.h ../../include/psFFT.h \
+  ../../include/psImageIO.h ../../include/psTest.h
Index: /tags/rel1_1/psLib/test/dataManip/builddir/tst_psHist01.d
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/builddir/tst_psHist01.d	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/builddir/tst_psHist01.d	(revision 1056)
@@ -0,0 +1,8 @@
+builddir/tst_psHist01.o builddir/tst_psHist01.d : tst_psHist01.c ../../include/pslib.h \
+  ../../include/psMemory.h ../../include/psLogMsg.h \
+  ../../include/psTrace.h ../../include/psAbort.h ../../include/psError.h \
+  ../../include/psString.h ../../include/psType.h ../../include/psList.h \
+  ../../include/psVector.h ../../include/psHash.h ../../include/psImage.h \
+  ../../include/psBitSet.h ../../include/psSort.h ../../include/psStats.h \
+  ../../include/psMatrix.h ../../include/psFFT.h \
+  ../../include/psImageIO.h ../../include/psTest.h
Index: /tags/rel1_1/psLib/test/dataManip/builddir/tst_psHist02.d
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/builddir/tst_psHist02.d	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/builddir/tst_psHist02.d	(revision 1056)
@@ -0,0 +1,8 @@
+builddir/tst_psHist02.o builddir/tst_psHist02.d : tst_psHist02.c ../../include/pslib.h \
+  ../../include/psMemory.h ../../include/psLogMsg.h \
+  ../../include/psTrace.h ../../include/psAbort.h ../../include/psError.h \
+  ../../include/psString.h ../../include/psType.h ../../include/psList.h \
+  ../../include/psVector.h ../../include/psHash.h ../../include/psImage.h \
+  ../../include/psBitSet.h ../../include/psSort.h ../../include/psStats.h \
+  ../../include/psMatrix.h ../../include/psFFT.h \
+  ../../include/psImageIO.h ../../include/psTest.h
Index: /tags/rel1_1/psLib/test/dataManip/builddir/tst_psImageFFT.d
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/builddir/tst_psImageFFT.d	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/builddir/tst_psImageFFT.d	(revision 1056)
@@ -0,0 +1,8 @@
+builddir/tst_psImageFFT.o builddir/tst_psImageFFT.d : tst_psImageFFT.c ../../include/psTest.h \
+  ../../include/pslib.h ../../include/psMemory.h ../../include/psLogMsg.h \
+  ../../include/psTrace.h ../../include/psAbort.h ../../include/psError.h \
+  ../../include/psString.h ../../include/psType.h ../../include/psList.h \
+  ../../include/psVector.h ../../include/psHash.h ../../include/psImage.h \
+  ../../include/psBitSet.h ../../include/psSort.h ../../include/psStats.h \
+  ../../include/psMatrix.h ../../include/psFFT.h \
+  ../../include/psImageIO.h
Index: /tags/rel1_1/psLib/test/dataManip/builddir/tst_psImageIO.d
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/builddir/tst_psImageIO.d	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/builddir/tst_psImageIO.d	(revision 1056)
@@ -0,0 +1,8 @@
+builddir/tst_psImageIO.o builddir/tst_psImageIO.d : tst_psImageIO.c ../../include/psTest.h \
+  ../../include/pslib.h ../../include/psMemory.h ../../include/psLogMsg.h \
+  ../../include/psTrace.h ../../include/psAbort.h ../../include/psError.h \
+  ../../include/psString.h ../../include/psType.h ../../include/psList.h \
+  ../../include/psVector.h ../../include/psHash.h ../../include/psImage.h \
+  ../../include/psBitSet.h ../../include/psSort.h ../../include/psStats.h \
+  ../../include/psMatrix.h ../../include/psFFT.h \
+  ../../include/psImageIO.h
Index: /tags/rel1_1/psLib/test/dataManip/builddir/tst_psImageStats00.d
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/builddir/tst_psImageStats00.d	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/builddir/tst_psImageStats00.d	(revision 1056)
@@ -0,0 +1,9 @@
+builddir/tst_psImageStats00.o builddir/tst_psImageStats00.d : tst_psImageStats00.c ../../include/pslib.h \
+  ../../include/psMemory.h ../../include/psLogMsg.h \
+  ../../include/psTrace.h ../../include/psAbort.h ../../include/psError.h \
+  ../../include/psString.h ../../include/psType.h ../../include/psList.h \
+  ../../include/psVector.h ../../include/psHash.h ../../include/psImage.h \
+  ../../include/psBitSet.h ../../include/psSort.h ../../include/psStats.h \
+  ../../include/psMatrix.h ../../include/psFFT.h \
+  ../../include/psImageIO.h ../../include/psTest.h \
+  ../../include/psImageStats.h ../../include/psFunctions.h
Index: /tags/rel1_1/psLib/test/dataManip/builddir/tst_psImageStats01.d
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/builddir/tst_psImageStats01.d	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/builddir/tst_psImageStats01.d	(revision 1056)
@@ -0,0 +1,9 @@
+builddir/tst_psImageStats01.o builddir/tst_psImageStats01.d : tst_psImageStats01.c ../../include/pslib.h \
+  ../../include/psMemory.h ../../include/psLogMsg.h \
+  ../../include/psTrace.h ../../include/psAbort.h ../../include/psError.h \
+  ../../include/psString.h ../../include/psType.h ../../include/psList.h \
+  ../../include/psVector.h ../../include/psHash.h ../../include/psImage.h \
+  ../../include/psBitSet.h ../../include/psSort.h ../../include/psStats.h \
+  ../../include/psMatrix.h ../../include/psFFT.h \
+  ../../include/psImageIO.h ../../include/psTest.h \
+  ../../include/psImageStats.h ../../include/psFunctions.h
Index: /tags/rel1_1/psLib/test/dataManip/builddir/tst_psImageStats02.d
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/builddir/tst_psImageStats02.d	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/builddir/tst_psImageStats02.d	(revision 1056)
@@ -0,0 +1,9 @@
+builddir/tst_psImageStats02.o builddir/tst_psImageStats02.d : tst_psImageStats02.c ../../include/pslib.h \
+  ../../include/psMemory.h ../../include/psLogMsg.h \
+  ../../include/psTrace.h ../../include/psAbort.h ../../include/psError.h \
+  ../../include/psString.h ../../include/psType.h ../../include/psList.h \
+  ../../include/psVector.h ../../include/psHash.h ../../include/psImage.h \
+  ../../include/psBitSet.h ../../include/psSort.h ../../include/psStats.h \
+  ../../include/psMatrix.h ../../include/psFFT.h \
+  ../../include/psImageIO.h ../../include/psTest.h \
+  ../../include/psImageStats.h ../../include/psFunctions.h
Index: /tags/rel1_1/psLib/test/dataManip/builddir/tst_psMatrix01.d
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/builddir/tst_psMatrix01.d	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/builddir/tst_psMatrix01.d	(revision 1056)
@@ -0,0 +1,8 @@
+builddir/tst_psMatrix01.o builddir/tst_psMatrix01.d : tst_psMatrix01.c ../../include/pslib.h \
+  ../../include/psMemory.h ../../include/psLogMsg.h \
+  ../../include/psTrace.h ../../include/psAbort.h ../../include/psError.h \
+  ../../include/psString.h ../../include/psType.h ../../include/psList.h \
+  ../../include/psVector.h ../../include/psHash.h ../../include/psImage.h \
+  ../../include/psBitSet.h ../../include/psSort.h ../../include/psStats.h \
+  ../../include/psMatrix.h ../../include/psFFT.h \
+  ../../include/psImageIO.h ../../include/psTest.h
Index: /tags/rel1_1/psLib/test/dataManip/builddir/tst_psMatrix02.d
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/builddir/tst_psMatrix02.d	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/builddir/tst_psMatrix02.d	(revision 1056)
@@ -0,0 +1,8 @@
+builddir/tst_psMatrix02.o builddir/tst_psMatrix02.d : tst_psMatrix02.c ../../include/pslib.h \
+  ../../include/psMemory.h ../../include/psLogMsg.h \
+  ../../include/psTrace.h ../../include/psAbort.h ../../include/psError.h \
+  ../../include/psString.h ../../include/psType.h ../../include/psList.h \
+  ../../include/psVector.h ../../include/psHash.h ../../include/psImage.h \
+  ../../include/psBitSet.h ../../include/psSort.h ../../include/psStats.h \
+  ../../include/psMatrix.h ../../include/psFFT.h \
+  ../../include/psImageIO.h ../../include/psTest.h
Index: /tags/rel1_1/psLib/test/dataManip/builddir/tst_psMatrix03.d
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/builddir/tst_psMatrix03.d	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/builddir/tst_psMatrix03.d	(revision 1056)
@@ -0,0 +1,8 @@
+builddir/tst_psMatrix03.o builddir/tst_psMatrix03.d : tst_psMatrix03.c ../../include/pslib.h \
+  ../../include/psMemory.h ../../include/psLogMsg.h \
+  ../../include/psTrace.h ../../include/psAbort.h ../../include/psError.h \
+  ../../include/psString.h ../../include/psType.h ../../include/psList.h \
+  ../../include/psVector.h ../../include/psHash.h ../../include/psImage.h \
+  ../../include/psBitSet.h ../../include/psSort.h ../../include/psStats.h \
+  ../../include/psMatrix.h ../../include/psFFT.h \
+  ../../include/psImageIO.h ../../include/psTest.h
Index: /tags/rel1_1/psLib/test/dataManip/builddir/tst_psMatrix04.d
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/builddir/tst_psMatrix04.d	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/builddir/tst_psMatrix04.d	(revision 1056)
@@ -0,0 +1,8 @@
+builddir/tst_psMatrix04.o builddir/tst_psMatrix04.d : tst_psMatrix04.c ../../include/pslib.h \
+  ../../include/psMemory.h ../../include/psLogMsg.h \
+  ../../include/psTrace.h ../../include/psAbort.h ../../include/psError.h \
+  ../../include/psString.h ../../include/psType.h ../../include/psList.h \
+  ../../include/psVector.h ../../include/psHash.h ../../include/psImage.h \
+  ../../include/psBitSet.h ../../include/psSort.h ../../include/psStats.h \
+  ../../include/psMatrix.h ../../include/psFFT.h \
+  ../../include/psImageIO.h ../../include/psTest.h
Index: /tags/rel1_1/psLib/test/dataManip/builddir/tst_psMatrix05.d
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/builddir/tst_psMatrix05.d	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/builddir/tst_psMatrix05.d	(revision 1056)
@@ -0,0 +1,8 @@
+builddir/tst_psMatrix05.o builddir/tst_psMatrix05.d : tst_psMatrix05.c ../../include/pslib.h \
+  ../../include/psMemory.h ../../include/psLogMsg.h \
+  ../../include/psTrace.h ../../include/psAbort.h ../../include/psError.h \
+  ../../include/psString.h ../../include/psType.h ../../include/psList.h \
+  ../../include/psVector.h ../../include/psHash.h ../../include/psImage.h \
+  ../../include/psBitSet.h ../../include/psSort.h ../../include/psStats.h \
+  ../../include/psMatrix.h ../../include/psFFT.h \
+  ../../include/psImageIO.h ../../include/psTest.h
Index: /tags/rel1_1/psLib/test/dataManip/builddir/tst_psMatrix06.d
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/builddir/tst_psMatrix06.d	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/builddir/tst_psMatrix06.d	(revision 1056)
@@ -0,0 +1,8 @@
+builddir/tst_psMatrix06.o builddir/tst_psMatrix06.d : tst_psMatrix06.c ../../include/pslib.h \
+  ../../include/psMemory.h ../../include/psLogMsg.h \
+  ../../include/psTrace.h ../../include/psAbort.h ../../include/psError.h \
+  ../../include/psString.h ../../include/psType.h ../../include/psList.h \
+  ../../include/psVector.h ../../include/psHash.h ../../include/psImage.h \
+  ../../include/psBitSet.h ../../include/psSort.h ../../include/psStats.h \
+  ../../include/psMatrix.h ../../include/psFFT.h \
+  ../../include/psImageIO.h ../../include/psTest.h
Index: /tags/rel1_1/psLib/test/dataManip/builddir/tst_psMatrix07.d
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/builddir/tst_psMatrix07.d	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/builddir/tst_psMatrix07.d	(revision 1056)
@@ -0,0 +1,8 @@
+builddir/tst_psMatrix07.o builddir/tst_psMatrix07.d : tst_psMatrix07.c ../../include/pslib.h \
+  ../../include/psMemory.h ../../include/psLogMsg.h \
+  ../../include/psTrace.h ../../include/psAbort.h ../../include/psError.h \
+  ../../include/psString.h ../../include/psType.h ../../include/psList.h \
+  ../../include/psVector.h ../../include/psHash.h ../../include/psImage.h \
+  ../../include/psBitSet.h ../../include/psSort.h ../../include/psStats.h \
+  ../../include/psMatrix.h ../../include/psFFT.h \
+  ../../include/psImageIO.h ../../include/psTest.h
Index: /tags/rel1_1/psLib/test/dataManip/builddir/tst_psStats00.d
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/builddir/tst_psStats00.d	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/builddir/tst_psStats00.d	(revision 1056)
@@ -0,0 +1,8 @@
+builddir/tst_psStats00.o builddir/tst_psStats00.d : tst_psStats00.c ../../include/pslib.h \
+  ../../include/psMemory.h ../../include/psLogMsg.h \
+  ../../include/psTrace.h ../../include/psAbort.h ../../include/psError.h \
+  ../../include/psString.h ../../include/psType.h ../../include/psList.h \
+  ../../include/psVector.h ../../include/psHash.h ../../include/psImage.h \
+  ../../include/psBitSet.h ../../include/psSort.h ../../include/psStats.h \
+  ../../include/psMatrix.h ../../include/psFFT.h \
+  ../../include/psImageIO.h ../../include/psTest.h
Index: /tags/rel1_1/psLib/test/dataManip/builddir/tst_psStats01.d
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/builddir/tst_psStats01.d	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/builddir/tst_psStats01.d	(revision 1056)
@@ -0,0 +1,8 @@
+builddir/tst_psStats01.o builddir/tst_psStats01.d : tst_psStats01.c ../../include/pslib.h \
+  ../../include/psMemory.h ../../include/psLogMsg.h \
+  ../../include/psTrace.h ../../include/psAbort.h ../../include/psError.h \
+  ../../include/psString.h ../../include/psType.h ../../include/psList.h \
+  ../../include/psVector.h ../../include/psHash.h ../../include/psImage.h \
+  ../../include/psBitSet.h ../../include/psSort.h ../../include/psStats.h \
+  ../../include/psMatrix.h ../../include/psFFT.h \
+  ../../include/psImageIO.h ../../include/psTest.h
Index: /tags/rel1_1/psLib/test/dataManip/builddir/tst_psStats02.d
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/builddir/tst_psStats02.d	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/builddir/tst_psStats02.d	(revision 1056)
@@ -0,0 +1,8 @@
+builddir/tst_psStats02.o builddir/tst_psStats02.d : tst_psStats02.c ../../include/pslib.h \
+  ../../include/psMemory.h ../../include/psLogMsg.h \
+  ../../include/psTrace.h ../../include/psAbort.h ../../include/psError.h \
+  ../../include/psString.h ../../include/psType.h ../../include/psList.h \
+  ../../include/psVector.h ../../include/psHash.h ../../include/psImage.h \
+  ../../include/psBitSet.h ../../include/psSort.h ../../include/psStats.h \
+  ../../include/psMatrix.h ../../include/psFFT.h \
+  ../../include/psImageIO.h ../../include/psTest.h
Index: /tags/rel1_1/psLib/test/dataManip/builddir/tst_psStats03.d
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/builddir/tst_psStats03.d	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/builddir/tst_psStats03.d	(revision 1056)
@@ -0,0 +1,8 @@
+builddir/tst_psStats03.o builddir/tst_psStats03.d : tst_psStats03.c ../../include/pslib.h \
+  ../../include/psMemory.h ../../include/psLogMsg.h \
+  ../../include/psTrace.h ../../include/psAbort.h ../../include/psError.h \
+  ../../include/psString.h ../../include/psType.h ../../include/psList.h \
+  ../../include/psVector.h ../../include/psHash.h ../../include/psImage.h \
+  ../../include/psBitSet.h ../../include/psSort.h ../../include/psStats.h \
+  ../../include/psMatrix.h ../../include/psFFT.h \
+  ../../include/psImageIO.h ../../include/psTest.h
Index: /tags/rel1_1/psLib/test/dataManip/builddir/tst_psStats05.d
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/builddir/tst_psStats05.d	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/builddir/tst_psStats05.d	(revision 1056)
@@ -0,0 +1,8 @@
+builddir/tst_psStats05.o builddir/tst_psStats05.d : tst_psStats05.c ../../include/pslib.h \
+  ../../include/psMemory.h ../../include/psLogMsg.h \
+  ../../include/psTrace.h ../../include/psAbort.h ../../include/psError.h \
+  ../../include/psString.h ../../include/psType.h ../../include/psList.h \
+  ../../include/psVector.h ../../include/psHash.h ../../include/psImage.h \
+  ../../include/psBitSet.h ../../include/psSort.h ../../include/psStats.h \
+  ../../include/psMatrix.h ../../include/psFFT.h \
+  ../../include/psImageIO.h ../../include/psTest.h
Index: /tags/rel1_1/psLib/test/dataManip/builddir/tst_psStats06.d
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/builddir/tst_psStats06.d	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/builddir/tst_psStats06.d	(revision 1056)
@@ -0,0 +1,8 @@
+builddir/tst_psStats06.o builddir/tst_psStats06.d : tst_psStats06.c ../../include/pslib.h \
+  ../../include/psMemory.h ../../include/psLogMsg.h \
+  ../../include/psTrace.h ../../include/psAbort.h ../../include/psError.h \
+  ../../include/psString.h ../../include/psType.h ../../include/psList.h \
+  ../../include/psVector.h ../../include/psHash.h ../../include/psImage.h \
+  ../../include/psBitSet.h ../../include/psSort.h ../../include/psStats.h \
+  ../../include/psMatrix.h ../../include/psFFT.h \
+  ../../include/psImageIO.h ../../include/psTest.h
Index: /tags/rel1_1/psLib/test/dataManip/builddir/tst_psStats07.d
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/builddir/tst_psStats07.d	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/builddir/tst_psStats07.d	(revision 1056)
@@ -0,0 +1,8 @@
+builddir/tst_psStats07.o builddir/tst_psStats07.d : tst_psStats07.c ../../include/pslib.h \
+  ../../include/psMemory.h ../../include/psLogMsg.h \
+  ../../include/psTrace.h ../../include/psAbort.h ../../include/psError.h \
+  ../../include/psString.h ../../include/psType.h ../../include/psList.h \
+  ../../include/psVector.h ../../include/psHash.h ../../include/psImage.h \
+  ../../include/psBitSet.h ../../include/psSort.h ../../include/psStats.h \
+  ../../include/psMatrix.h ../../include/psFFT.h \
+  ../../include/psImageIO.h ../../include/psTest.h
Index: /tags/rel1_1/psLib/test/dataManip/builddir/tst_psStats08.d
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/builddir/tst_psStats08.d	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/builddir/tst_psStats08.d	(revision 1056)
@@ -0,0 +1,8 @@
+builddir/tst_psStats08.o builddir/tst_psStats08.d : tst_psStats08.c ../../include/pslib.h \
+  ../../include/psMemory.h ../../include/psLogMsg.h \
+  ../../include/psTrace.h ../../include/psAbort.h ../../include/psError.h \
+  ../../include/psString.h ../../include/psType.h ../../include/psList.h \
+  ../../include/psVector.h ../../include/psHash.h ../../include/psImage.h \
+  ../../include/psBitSet.h ../../include/psSort.h ../../include/psStats.h \
+  ../../include/psMatrix.h ../../include/psFFT.h \
+  ../../include/psImageIO.h ../../include/psTest.h
Index: /tags/rel1_1/psLib/test/dataManip/builddir/tst_psStats09.d
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/builddir/tst_psStats09.d	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/builddir/tst_psStats09.d	(revision 1056)
@@ -0,0 +1,9 @@
+builddir/tst_psStats09.o builddir/tst_psStats09.d : tst_psStats09.c ../../include/pslib.h \
+  ../../include/psMemory.h ../../include/psLogMsg.h \
+  ../../include/psTrace.h ../../include/psAbort.h ../../include/psError.h \
+  ../../include/psString.h ../../include/psType.h ../../include/psList.h \
+  ../../include/psVector.h ../../include/psHash.h ../../include/psImage.h \
+  ../../include/psBitSet.h ../../include/psSort.h ../../include/psStats.h \
+  ../../include/psMatrix.h ../../include/psFFT.h \
+  ../../include/psImageIO.h ../../include/psTest.h \
+  ../../include/psImageStats.h ../../include/psFunctions.h
Index: /tags/rel1_1/psLib/test/dataManip/builddir/tst_psVectorFFT.d
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/builddir/tst_psVectorFFT.d	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/builddir/tst_psVectorFFT.d	(revision 1056)
@@ -0,0 +1,8 @@
+builddir/tst_psVectorFFT.o builddir/tst_psVectorFFT.d : tst_psVectorFFT.c ../../include/psTest.h \
+  ../../include/pslib.h ../../include/psMemory.h ../../include/psLogMsg.h \
+  ../../include/psTrace.h ../../include/psAbort.h ../../include/psError.h \
+  ../../include/psString.h ../../include/psType.h ../../include/psList.h \
+  ../../include/psVector.h ../../include/psHash.h ../../include/psImage.h \
+  ../../include/psBitSet.h ../../include/psSort.h ../../include/psStats.h \
+  ../../include/psMatrix.h ../../include/psFFT.h \
+  ../../include/psImageIO.h
Index: /tags/rel1_1/psLib/test/dataManip/tst_psFunc00.c
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/tst_psFunc00.c	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/tst_psFunc00.c	(revision 1056)
@@ -0,0 +1,286 @@
+/*****************************************************************************
+    This routine must ensure that the psPolynomial structures are
+    allocated and deallocated by the psPolynomialXXXlloc() procedures.
+ *****************************************************************************/
+#include <stdio.h>
+#include "pslib.h"
+#include "psTest.h"
+#include "psMemory.h"
+#include "psFunctions.h"
+#define MISC_FLOAT_NUMBER 345.0
+#define MISC_X_VALUE 5.0
+#define MISC_INT_NUMBER 35
+#define NUM_BINS 200
+#define AN 2
+#define BN 4
+#define CN 6
+#define DN 8
+int main()
+{
+    psPolynomial1D *my1DPoly = NULL;
+    psPolynomial2D *my2DPoly = NULL;
+    psPolynomial3D *my3DPoly = NULL;
+    psPolynomial4D *my4DPoly = NULL;
+    psDPolynomial1D *my1DPolyD = NULL;
+    psDPolynomial2D *my2DPolyD = NULL;
+    psDPolynomial3D *my3DPolyD = NULL;
+    psDPolynomial4D *my4DPolyD = NULL;
+    int testStatus      = true;
+    int memLeaks        = 0;
+    int a               = 0;
+    int b               = 0;
+    int c               = 0;
+    int d               = 0;
+    int currentId       = 0;
+
+    currentId       = psMemGetId();
+    /*************************************************************************/
+    /*  Allocate and initialize data structures                      */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psFunctions functions",
+                            "Allocate/Deallocate the psPolynomial1D structure.");
+
+    my1DPoly = psPolynomial1DAlloc(AN);
+    for (a = 0; a < AN ; a++) {
+        my1DPoly->coeff[a] = MISC_FLOAT_NUMBER;
+        my1DPoly->coeffErr[a] = MISC_FLOAT_NUMBER;
+        my1DPoly->mask[a] = MISC_INT_NUMBER;
+    }
+    psMemCheckCorruption(1);
+
+    printf("At (x) = (%f): %f\n", MISC_X_VALUE,
+           psEvalPolynomial1D(MISC_X_VALUE, my1DPoly));
+
+    psPolynomial1DFree(my1DPoly);
+    memLeaks = psMemCheckLeaks(currentId,NULL,NULL);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+    printFooter(stdout,
+                "psStats functions",
+                "Allocate/Deallocate the psPolynomial1D structure.",
+                testStatus);
+
+
+
+
+
+    printPositiveTestHeader(stdout,
+                            "psFunctions functions",
+                            "Allocate/Deallocate the psPolynomial2D structure.");
+    my2DPoly = psPolynomial2DAlloc(AN, BN);
+    for (a = 0; a < AN ; a++) {
+        for (b = 0; b < BN ; b++) {
+            my2DPoly->coeff[a][b] = MISC_FLOAT_NUMBER;
+            my2DPoly->coeffErr[a][b] = MISC_FLOAT_NUMBER;
+            my2DPoly->mask[a][b] = MISC_INT_NUMBER;
+        }
+    }
+    psMemCheckCorruption(1);
+
+    printf("At (x, y) = (%f, %f): %f\n", MISC_X_VALUE, MISC_X_VALUE,
+           psEvalPolynomial2D(MISC_X_VALUE, MISC_X_VALUE, my2DPoly));
+
+    psPolynomial2DFree(my2DPoly);
+    memLeaks = psMemCheckLeaks(currentId,NULL,NULL);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+    printFooter(stdout,
+                "psStats functions",
+                "Allocate/Deallocate the psPolynomial2D structure.",
+                testStatus);
+
+
+
+    printPositiveTestHeader(stdout,
+                            "psFunctions functions",
+                            "Allocate/Deallocate the psPolynomial3D structure.");
+    my3DPoly = psPolynomial3DAlloc(AN, BN, CN);
+    for (a = 0; a < AN ; a++) {
+        for (b = 0; b < BN ; b++) {
+            for (c = 0; c < CN ; c++) {
+                my3DPoly->coeff[a][b][c] = MISC_FLOAT_NUMBER;
+                my3DPoly->coeffErr[a][b][c] = MISC_FLOAT_NUMBER;
+                my3DPoly->mask[a][b][c] = MISC_INT_NUMBER;
+            }
+        }
+    }
+    psMemCheckCorruption(1);
+
+    printf("At (x, y, z) = (%f, %f, %f): %f\n", MISC_X_VALUE, MISC_X_VALUE,
+           MISC_X_VALUE,
+           psEvalPolynomial3D(MISC_X_VALUE, MISC_X_VALUE, MISC_X_VALUE, my3DPoly));
+
+    psPolynomial3DFree(my3DPoly);
+    memLeaks = psMemCheckLeaks(currentId,NULL,NULL);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+    printFooter(stdout,
+                "psStats functions",
+                "Allocate/Deallocate the psPolynomial3D structure.",
+                testStatus);
+
+
+
+
+    printPositiveTestHeader(stdout,
+                            "psFunctions functions",
+                            "Allocate/Deallocate the psPolynomial4D structure.");
+    my4DPoly = psPolynomial4DAlloc(AN, BN, CN, DN);
+    for (a = 0; a < AN ; a++) {
+        for (b = 0; b < BN ; b++) {
+            for (c = 0; c < CN ; c++) {
+                for (d = 0; d < DN ; d++) {
+                    my4DPoly->coeff[a][b][c][d] = MISC_FLOAT_NUMBER;
+                    my4DPoly->coeffErr[a][b][c][d] = MISC_FLOAT_NUMBER;
+                    my4DPoly->mask[a][b][c][d] = MISC_INT_NUMBER;
+                }
+            }
+        }
+    }
+    psMemCheckCorruption(1);
+
+    printf("At (w, x, y, z) = (%f, %f, %f, %f): %f\n", MISC_X_VALUE, MISC_X_VALUE,
+           MISC_X_VALUE, MISC_X_VALUE,
+           psEvalPolynomial4D(MISC_X_VALUE, MISC_X_VALUE, MISC_X_VALUE, MISC_X_VALUE, my4DPoly));
+
+    psPolynomial4DFree(my4DPoly);
+    memLeaks = psMemCheckLeaks(currentId,NULL,NULL);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+    printFooter(stdout,
+                "psStats functions",
+                "Allocate/Deallocate the psPolynomial4D structure.",
+                testStatus);
+
+
+
+    /*************************************************************************/
+    /*  Allocate and initialize data structures                      */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psFunctions functions",
+                            "Allocate/Deallocate the psDPolynomial1D structure.");
+
+    my1DPolyD = psDPolynomial1DAlloc(AN);
+    for (a = 0; a < AN ; a++) {
+        my1DPolyD->coeff[a] = MISC_FLOAT_NUMBER;
+        my1DPolyD->coeffErr[a] = MISC_FLOAT_NUMBER;
+        my1DPolyD->mask[a] = MISC_INT_NUMBER;
+    }
+    psMemCheckCorruption(1);
+
+    printf("At (x) = (%f): %f\n", MISC_X_VALUE,
+           psDEvalPolynomial1D(MISC_X_VALUE, my1DPolyD));
+
+    psDPolynomial1DFree(my1DPolyD);
+    memLeaks = psMemCheckLeaks(currentId,NULL,NULL);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+    printFooter(stdout,
+                "psStats functions",
+                "Allocate/Deallocate the psDPolynomial1D structure.",
+                testStatus);
+
+
+
+
+
+    printPositiveTestHeader(stdout,
+                            "psFunctions functions",
+                            "Allocate/Deallocate the psDPolynomial2D structure.");
+    my2DPolyD = psDPolynomial2DAlloc(AN, BN);
+    for (a = 0; a < AN ; a++) {
+        for (b = 0; b < BN ; b++) {
+            my2DPolyD->coeff[a][b] = MISC_FLOAT_NUMBER;
+            my2DPolyD->coeffErr[a][b] = MISC_FLOAT_NUMBER;
+            my2DPolyD->mask[a][b] = MISC_INT_NUMBER;
+        }
+    }
+    psMemCheckCorruption(1);
+
+    printf("At (x, y) = (%f, %f): %f\n", MISC_X_VALUE, MISC_X_VALUE,
+           psDEvalPolynomial2D(MISC_X_VALUE, MISC_X_VALUE, my2DPolyD));
+
+    psDPolynomial2DFree(my2DPolyD);
+    memLeaks = psMemCheckLeaks(currentId,NULL,NULL);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+    printFooter(stdout,
+                "psStats functions",
+                "Allocate/Deallocate the psDPolynomial2D structure.",
+                testStatus);
+
+
+
+    printPositiveTestHeader(stdout,
+                            "psFunctions functions",
+                            "Allocate/Deallocate the psDPolynomial3D structure.");
+    my3DPolyD = psDPolynomial3DAlloc(AN, BN, CN);
+    for (a = 0; a < AN ; a++) {
+        for (b = 0; b < BN ; b++) {
+            for (c = 0; c < CN ; c++) {
+                my3DPolyD->coeff[a][b][c] = MISC_FLOAT_NUMBER;
+                my3DPolyD->coeffErr[a][b][c] = MISC_FLOAT_NUMBER;
+                my3DPolyD->mask[a][b][c] = MISC_INT_NUMBER;
+            }
+        }
+    }
+    psMemCheckCorruption(1);
+
+    printf("At (x, y, z) = (%f, %f, %f): %f\n", MISC_X_VALUE, MISC_X_VALUE,
+           MISC_X_VALUE,
+           psDEvalPolynomial3D(MISC_X_VALUE, MISC_X_VALUE, MISC_X_VALUE, my3DPolyD));
+
+    psDPolynomial3DFree(my3DPolyD);
+    memLeaks = psMemCheckLeaks(currentId,NULL,NULL);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+    printFooter(stdout,
+                "psStats functions",
+                "Allocate/Deallocate the psDPolynomial3D structure.",
+                testStatus);
+
+
+
+
+    printPositiveTestHeader(stdout,
+                            "psFunctions functions",
+                            "Allocate/Deallocate the psDPolynomial4D structure.");
+    my4DPolyD = psDPolynomial4DAlloc(AN, BN, CN, DN);
+    for (a = 0; a < AN ; a++) {
+        for (b = 0; b < BN ; b++) {
+            for (c = 0; c < CN ; c++) {
+                for (d = 0; d < DN ; d++) {
+                    my4DPolyD->coeff[a][b][c][d] = MISC_FLOAT_NUMBER;
+                    my4DPolyD->coeffErr[a][b][c][d] = MISC_FLOAT_NUMBER;
+                    my4DPolyD->mask[a][b][c][d] = MISC_INT_NUMBER;
+                }
+            }
+        }
+    }
+    psMemCheckCorruption(1);
+
+    printf("At (w, x, y, z) = (%f, %f, %f, %f): %f\n", MISC_X_VALUE, MISC_X_VALUE,
+           MISC_X_VALUE, MISC_X_VALUE,
+           psDEvalPolynomial4D(MISC_X_VALUE, MISC_X_VALUE, MISC_X_VALUE, MISC_X_VALUE, my4DPolyD));
+
+    psDPolynomial4DFree(my4DPolyD);
+    memLeaks = psMemCheckLeaks(currentId,NULL,NULL);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+    printFooter(stdout,
+                "psStats functions",
+                "Allocate/Deallocate the psDPolynomial4D structure.",
+                testStatus);
+
+    return (!testStatus);
+}
Index: /tags/rel1_1/psLib/test/dataManip/tst_psFunc01.c
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/tst_psFunc01.c	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/tst_psFunc01.c	(revision 1056)
@@ -0,0 +1,72 @@
+/*****************************************************************************
+    This routine must ensure that the psGaussian() shall evaluate a
+    specified Gaussian at some X.
+ 
+    It also tests the psGaussianDev() procedure.
+ *****************************************************************************/
+#include <stdio.h>
+#include "pslib.h"
+#include "psTest.h"
+#include "psMemory.h"
+#include "psFunctions.h"
+#define MY_MEAN 30.0
+#define MY_STDEV 2.0
+#define N 30
+int main()
+{
+    int testStatus = true;
+    float x = 0.0;
+    int  memLeaks;
+    int  currentId = psMemGetId();
+    psVector *myGaussData = NULL;
+    printPositiveTestHeader(stdout,
+                            "psFunctions functions",
+                            "psGaussian()");
+
+
+    for (x = 0.0 ; x < (MY_MEAN * 2.0) ; x+= 1.0) {
+        printf("normal psGaussian(%f) is %f\n", x, psGaussian(x, MY_MEAN, MY_STDEV, 1));
+        x = x + 1.0;
+    }
+
+    for (x = 0.0 ; x < (MY_MEAN * 2.0) ; x+= 1.0) {
+        printf("NON-normal psGaussian(%f) is %f\n", x, psGaussian(x, MY_MEAN, MY_STDEV, 0));
+        x = x + 1.0;
+    }
+
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,NULL);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psFunctions functions",
+                "psGaussian()",
+                testStatus);
+
+
+    printPositiveTestHeader(stdout,
+                            "psFunctions functions",
+                            "psGaussianDev()");
+
+    myGaussData = psGaussianDev(MY_MEAN, MY_STDEV, N);
+    for (int i = 0; i < N ; i++) {
+        printf("Gaussian Deviate [%d] is %f\n", i, myGaussData->data.F32[i]);
+    }
+
+    psVectorFree(myGaussData);
+
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,NULL);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psFunctions functions",
+                "psGaussianDev()",
+                testStatus);
+
+    return (!testStatus);
+}
Index: /tags/rel1_1/psLib/test/dataManip/tst_psHist00.c
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/tst_psHist00.c	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/tst_psHist00.c	(revision 1056)
@@ -0,0 +1,124 @@
+/*****************************************************************************
+    This routine must ensure that the psHistogram structure is correctly
+    allocated and deallocated by the procedure psHistogramAlloc().
+ *****************************************************************************/
+#include <stdio.h>
+#include "pslib.h"
+#include "psTest.h"
+#include "psMemory.h"
+#define LOWER 20.0
+#define UPPER 30.0
+
+int main()
+{
+    psHistogram *myHist = NULL;
+    int testStatus      = true;
+    int memLeaks        = 0;
+    int i               = 0;
+    int nb              = 0;
+    int numBins         = 0;
+    int currentId       = 0;
+
+    currentId       = psMemGetId();
+    for (nb=0;nb<4;nb++) {
+        if (nb == 0)
+            numBins = 1;
+        if (nb == 1)
+            numBins = 2;
+        if (nb == 2)
+            numBins = 10;
+        if (nb == 3)
+            numBins = 20;
+        /*********************************************************************/
+        /*  Allocate and initialize data structures                          */
+        /*********************************************************************/
+        printPositiveTestHeader(stdout,
+                                "psStats functions",
+                                "Allocate the psHistogram structure.");
+
+        myHist = psHistogramAlloc(LOWER, UPPER, numBins);
+
+        if (myHist->nums->n != numBins) {
+            printf("ERROR: myHist->nums->n is wrong size (%d)\n", myHist->nums->n);
+            testStatus = false;
+        }
+
+        if (myHist->bounds->n != numBins+1) {
+            printf("ERROR: myHist->bounds->n is wrong size (%d)\n", myHist->bounds->n);
+            testStatus = false;
+        }
+
+        for (i=0;i<numBins;i++) {
+            if (myHist->nums->data.S32[i] != 0) {
+                printf("ERROR: myHist->nums->data.S32[%d] not initialized to 0.\n", i);
+                testStatus = false;
+            }
+            myHist->nums->data.S32[i] = 0;
+        }
+
+        if (myHist->minNum != 0) {
+            printf("ERROR: myHist->minNum is %d\n", myHist->minNum);
+            testStatus = false;
+        }
+
+        if (myHist->maxNum != 0) {
+            printf("myHist->maxNum is %d\n", myHist->maxNum);
+            testStatus = false;
+        }
+
+        if (myHist->uniform != 1) {
+            printf("ERROR: myHist->uniform is %d\n", myHist->uniform);
+            testStatus = false;
+        }
+
+        for (i=0;i<numBins;i++) {
+            printf("Bin number %d bounds: (%f - %f)\n", i,
+                   myHist->bounds->data.F32[i],
+                   myHist->bounds->data.F32[i+1]);
+        }
+
+        psMemCheckCorruption(1);
+        psHistogramFree(myHist);
+        psMemCheckCorruption(1);
+
+        printFooter(stdout,
+                    "psStats functions",
+                    "Allocate the psHistogram structure.",
+                    testStatus);
+    }
+
+
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "Allocate the psHistogram structure. (UPPER<LOWER)");
+
+    myHist = psHistogramAlloc(UPPER, LOWER, numBins);
+    if (myHist != NULL) {
+        printf("ERROR: myHist != NULL\n");
+    }
+    printFooter(stdout,
+                "psStats functions",
+                "Allocate the psHistogram structure. (UPPER<LOWER)",
+                testStatus);
+
+    /*************************************************************************/
+    /*  Deallocate data structures                                   */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "Deallocate the psHistogram structure.");
+
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,NULL);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+    psMemCheckCorruption(1);
+
+    printFooter(stdout,
+                "psStats functions",
+                "Deallocate the psHistogram structure.",
+                testStatus);
+
+    return (!testStatus);
+}
Index: /tags/rel1_1/psLib/test/dataManip/tst_psHist01.c
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/tst_psHist01.c	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/tst_psHist01.c	(revision 1056)
@@ -0,0 +1,114 @@
+/*****************************************************************************
+    This routine must ensure that the psHistogram structure is correctly
+    allocated and deallocated by the procedure psHistogramAllocGeneric().
+ *****************************************************************************/
+#include <stdio.h>
+#include "pslib.h"
+#include "psTest.h"
+#include "psMemory.h"
+#define LOWER 20.0
+#define UPPER 30.0
+
+int main()
+{
+    psHistogram *myHist = NULL;
+    psVector *myBounds  = NULL;
+    int testStatus      = true;
+    int memLeaks        = 0;
+    int i               = 0;
+    int nb              = 0;
+    int numBins         = 0;
+    int currentId       = 0;
+
+    currentId       = psMemGetId();
+    for (nb=0;nb<4;nb++) {
+        if (nb == 0)
+            numBins = 1;
+        if (nb == 1)
+            numBins = 2;
+        if (nb == 2)
+            numBins = 10;
+        if (nb == 3)
+            numBins = 20;
+        /*********************************************************************/
+        /*  Allocate and initialize data structures                          */
+        /*********************************************************************/
+        printPositiveTestHeader(stdout,
+                                "psStats functions",
+                                "Allocate the psHistogram structure.");
+        myBounds = psVectorAlloc(numBins+1, PS_TYPE_F32);
+        myBounds->n = myBounds->nalloc;
+        for (i=0;i<numBins+1;i++) {
+            myBounds->data.F32[i] = LOWER + ((UPPER - LOWER) / (float) numBins) *
+                                    (float) i;
+        }
+        myHist = psHistogramAllocGeneric(myBounds);
+
+        if (myHist->nums->n != numBins) {
+            printf("ERROR: myHist->nums->n is wrong size (%d)\n", myHist->nums->n);
+            testStatus = false;
+        }
+
+        if (myHist->bounds->n != numBins+1) {
+            printf("ERROR: myHist->bounds->n is wrong size (%d)\n", myHist->bounds->n);
+            testStatus = false;
+        }
+
+        for (i=0;i<numBins;i++) {
+            if (myHist->nums->data.S32[i] != 0) {
+                printf("ERROR: myHist->nums->data.S32[%d] not initialized to 0.\n", i);
+                testStatus = false;
+            }
+            myHist->nums->data.S32[i] = 0;
+        }
+
+        if (myHist->minNum != 0) {
+            printf("ERROR: myHist->minNum is %d\n", myHist->minNum);
+            testStatus = false;
+        }
+
+        if (myHist->maxNum != 0) {
+            printf("myHist->maxNum is %d\n", myHist->maxNum);
+            testStatus = false;
+        }
+
+        if (myHist->uniform != 0) {
+            printf("ERROR: myHist->uniform is %d\n", myHist->uniform);
+            testStatus = false;
+        }
+
+        for (i=0;i<numBins;i++) {
+            printf("Bin number %d bounds: (%f - %f)\n", i,
+                   myHist->bounds->data.F32[i],
+                   myHist->bounds->data.F32[i+1]);
+        }
+        psMemCheckCorruption(1);
+        psHistogramFree(myHist);
+        psMemCheckCorruption(1);
+        psVectorFree(myBounds);
+
+        printFooter(stdout,
+                    "psStats functions",
+                    "Allocate the psHistogram structure.",
+                    testStatus);
+    }
+    /*************************************************************************/
+    /*  Deallocate data structures                                           */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "Deallocate the psHistogram structure.");
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,NULL);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+    psMemCheckCorruption(1);
+
+    printFooter(stdout,
+                "psStats functions",
+                "Deallocate the psHistogram structure.",
+                testStatus);
+
+    return (!testStatus);
+}
Index: /tags/rel1_1/psLib/test/dataManip/tst_psHist02.c
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/tst_psHist02.c	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/tst_psHist02.c	(revision 1056)
@@ -0,0 +1,182 @@
+/*****************************************************************************
+    This routine must ensure that the psHistogram structure is correctly
+    populated by the procedure psGetArrayHistogram().
+ 
+ *****************************************************************************/
+#include <stdio.h>
+#include "pslib.h"
+#include "psTest.h"
+#include "psMemory.h"
+#define MISC_FLOAT_NUMBER 345.0
+#define MISC_INT_NUMBER 345
+#define LOWER 20.0
+#define UPPER 30.0
+#define NUM_DATA 10000
+
+int main()
+{
+    psHistogram *myHist = NULL;
+    psHistogram *myHist2= NULL;
+    psVector *myData    = NULL;
+    psVector *myMask    = NULL;
+    int testStatus      = true;
+    int memLeaks        = 0;
+    int nb              = 0;
+    int numBins         = 0;
+    int i               = 0;
+    int currentId       = 0;
+
+    currentId       = psMemGetId();
+
+    /*********************************************************************/
+    /*  Allocate and initialize data structures                          */
+    /*********************************************************************/
+    myData = psVectorAlloc(NUM_DATA, PS_TYPE_F32);
+    myData->n = myData->nalloc;
+    for (i=0;i<NUM_DATA;i++) {
+        myData->data.F32[i] = LOWER + ((UPPER - LOWER) / (float) NUM_DATA) * (float) i;
+    }
+
+    myMask = psVectorAlloc(NUM_DATA, PS_TYPE_U8);
+    myMask->n = myMask->nalloc;
+    for (i=0;i<NUM_DATA;i++) {
+        if (i >= (NUM_DATA/2)) {
+            myMask->data.U8[i] = 1;
+        } else {
+            myMask->data.U8[i] = 0;
+        }
+    }
+
+    for (nb=0;nb<4;nb++) {
+        if (nb == 0)
+            numBins = 1;
+        if (nb == 1)
+            numBins = 2;
+        if (nb == 2)
+            numBins = 10;
+        if (nb == 3)
+            numBins = 20;
+
+        /*********************************************************************/
+        /*  Allocate and Perform Histogram, no mask                          */
+        /*********************************************************************/
+        printPositiveTestHeader(stdout,
+                                "psStats functions",
+                                "Allocate and Perform Histogram, no mask");
+
+        myHist = psHistogramAlloc(LOWER, UPPER, numBins);
+        myHist = psHistogramVector(myHist, myData, NULL, 0);
+
+        for (i=0;i<numBins;i++) {
+            printf("Bin number %d bounds: (%f - %f) data (%d)\n", i,
+                   myHist->bounds->data.F32[i],
+                   myHist->bounds->data.F32[i+1],
+                   myHist->nums->data.S32[i]);
+        }
+        psMemCheckCorruption(1);
+        psHistogramFree(myHist);
+        psMemCheckCorruption(1);
+
+        printFooter(stdout,
+                    "psStats functions",
+                    "Allocate and Perform Histogram, no mask",
+                    testStatus);
+
+        /*********************************************************************/
+        /*  Allocate and Perform Histogram with mask                         */
+        /*********************************************************************/
+        printPositiveTestHeader(stdout,
+                                "psStats functions",
+                                "Allocate and Perform Histogram with mask");
+
+        myHist = psHistogramAlloc(LOWER, UPPER, numBins);
+        myHist = psHistogramVector(myHist, myData, myMask, 1);
+
+        for (i=0;i<numBins;i++) {
+            printf("Bin number %d bounds: (%f - %f) data (%d)\n", i,
+                   myHist->bounds->data.F32[i],
+                   myHist->bounds->data.F32[i+1],
+                   myHist->nums->data.S32[i]);
+        }
+        psMemCheckCorruption(1);
+        psHistogramFree(myHist);
+        psMemCheckCorruption(1);
+
+        printFooter(stdout,
+                    "psStats functions",
+                    "Allocate and Perform Histogram with mask",
+                    testStatus);
+    }
+    psVectorFree(myMask);
+
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "Calling psHistogramVector() with various NULL inputs.");
+
+    // Verify the return value is null and program execution doesn't stop,
+    // if input parameter myHist is null.
+
+    myHist2 = psHistogramVector(NULL, myData, NULL, 0);
+    if (myHist2 != NULL) {
+        printf("ERROR: myHist2!=NULL\n");
+        testStatus = false;
+    }
+    psVectorFree(myData);
+
+
+    // Verify the retrun value is the same as the input parameter myHist and
+    // program execution doesn't stop, if the input parameter myArray is
+    // null.
+
+    myHist = psHistogramAlloc(LOWER, UPPER, numBins);
+    myHist = psHistogramVector(myHist, NULL, NULL, 0);
+    if (myHist == NULL) {
+        printf("ERROR: myHist==NULL\n");
+        testStatus = false;
+    }
+    psHistogramFree(myHist);
+
+
+    // Verify the return value is the same as the input parameter myHist and
+    // program execution doesn't stop, if the input parameter myArray has no
+    // elements.
+    // NOTE: This code segment is commented out because psVectorAlloc returns
+    // NULL if called with an N element data.
+    /*
+    myData = psVectorAlloc(0, PS_TYPE_F32);
+    myData->n = myData->nalloc;
+    myHist = psHistogramAlloc(LOWER, UPPER, numBins);
+    myHist = psHistogramVector(myHist, NULL, NULL, 0);
+    if (myHist == NULL) {
+        printf("ERROR: myHist==NULL\n");
+        testStatus = false;
+    }
+    psHistogramFree(myHist);
+    psVectorFree(myData);
+    */
+    printFooter(stdout,
+                "psStats functions",
+                "Calling psHistogramVector() with various NULL inputs.",
+                testStatus);
+
+    /*************************************************************************/
+    /*  Deallocate data structures                                   */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "Deallocate the psHistogram structure.");
+
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,NULL);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+    psMemCheckCorruption(1);
+
+    printFooter(stdout,
+                "psStats functions",
+                "Deallocate the psHistogram structure.",
+                testStatus);
+
+    return (!testStatus);
+}
Index: /tags/rel1_1/psLib/test/dataManip/tst_psMatrix01.c
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/tst_psMatrix01.c	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/tst_psMatrix01.c	(revision 1056)
@@ -0,0 +1,88 @@
+/** @file  tst_psMatrix_01.c
+ *
+ *  @brief Test driver for psMatrix transpose function
+ *
+ *  This test driver contains the following tests for psMatrix test point 1:
+ *     A)  Create input and output images
+ *     B)  Transpose input image into output image
+ *     C)  Transpose input image into auto allocated NULL output image 
+ *     D)  Free images and check for leaks
+ *
+ *  @author  Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.3 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2004-06-07 20:47:52 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#include "pslib.h"
+#include "psTest.h"
+
+#define PRINT_MATRIX(IMAGE)                         \
+for(int i=IMAGE->numRows-1; i>-1; i--) {        \
+    for(int j=0; j<IMAGE->numCols; j++) {       \
+        printf("%f ", IMAGE->data.F64[i][j]);   \
+    }                                          \
+    printf("\n");                              \
+}
+
+int main(int argc,
+         char* argv[])
+{
+    psImage *tempImage = NULL;
+
+
+    // Test A - Create input and output images
+    printPositiveTestHeader(stdout, "psMatrix", "Create input and output images");
+    psImage *inImage = (psImage*)psImageAlloc(3, 3, PS_TYPE_F64);
+    psImage *outImage = (psImage*)psImageAlloc(3, 3, PS_TYPE_F64);
+    inImage->data.F64[0][0] = 1;
+    inImage->data.F64[0][1] = 2;
+    inImage->data.F64[0][2] = 3;
+    inImage->data.F64[1][0] = 4;
+    inImage->data.F64[1][1] = 5;
+    inImage->data.F64[1][2] = 6;
+    inImage->data.F64[2][0] = 7;
+    inImage->data.F64[2][1] = 8;
+    inImage->data.F64[2][2] = 9;
+    PRINT_MATRIX(inImage);
+    printFooter(stdout, "psMatrix", "Create input and output images", true);
+
+
+    // Test B - Transpose input image into output image
+    printPositiveTestHeader(stdout, "psMatrix", "Transpose input image into output image");
+    tempImage = outImage;
+    outImage = psMatrixTranspose(outImage, inImage);
+    PRINT_MATRIX(outImage);
+    if(outImage->type.dimen != PS_DIMEN_IMAGE) {
+        printf("Error: Resulting image is not PS_DIMEN_IMAGE\n");
+    } else if(outImage != tempImage) {
+        printf("Error: Return pointer not equal to output argument pointer\n");
+    }
+    printFooter(stdout, "psMatrix", "Transpose input image into output image", true);
+
+
+    // Test C -  Transpose input image into auto allocated NULL output image
+    printPositiveTestHeader(stdout, "psMatrix", "ranspose input image into auto allocated NULL output image");
+    psImage *outImageNull = NULL;
+    outImageNull = psMatrixTranspose(outImageNull, inImage);
+    PRINT_MATRIX(outImageNull);
+    printFooter(stdout, "psMatrix", "ranspose input image into auto allocated NULL output image", true);
+
+
+    // Test D - Free images and check for leaks
+    printPositiveTestHeader(stdout, "psMatrix", "Free images and check for leaks");
+    psImageFree(inImage);
+    psImageFree(outImage);
+    psImageFree(outImageNull);
+    psMemCheckLeaks(0, NULL, stdout);
+    int nBad = psMemCheckCorruption(0);
+    if(nBad) {
+        printf("ERROR: Found %d bad memory blocks\n", nBad);
+    }
+    printFooter(stdout, "psMatrix" ,"Free images and check for leaks", true);
+
+    return 0;
+}
Index: /tags/rel1_1/psLib/test/dataManip/tst_psMatrix02.c
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/tst_psMatrix02.c	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/tst_psMatrix02.c	(revision 1056)
@@ -0,0 +1,71 @@
+/** @file  tst_psMatrix_02.c
+ *
+ *  @brief Test driver for negative tests for psMatrix transpose function
+ *
+ *  This test driver contains the following tests for psMatrix test point 2:
+ *     A)  Input pointer same as output pointer
+ *     B)  Null input psImage
+ *     C)  Incorrect type for input pointer
+ *     D)  Matrix not square for input pointer
+ *     E)  Incorrect type for output pointer
+ *     F)  Matrix not square for output pointer
+ *
+ *  @author  Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.1 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2004-05-28 02:52:23 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#include "pslib.h"
+#include "psTest.h"
+
+int main(int argc,
+         char* argv[])
+{
+    psImage *nullImage = NULL;
+    psImage *inImage = (psImage*)psImageAlloc(3, 3, PS_TYPE_F64);
+    psImage *outImage = (psImage*)psImageAlloc(3, 3, PS_TYPE_F64);
+    psImage *badImage1 = (psImage*)psImageAlloc(3, 3, PS_TYPE_F32);
+    psImage *badImage2 = (psImage*)psImageAlloc(3, 2, PS_TYPE_F64);
+
+    // Test A - Input pointer same as output pointer
+    printNegativeTestHeader(stdout,"psMatrix", "Input pointer same as output pointer",
+                            "Invalid operation: Pointer to inImage is same as outImage.", 0);
+    psMatrixTranspose(inImage, inImage);
+    printFooter(stdout, "psMatrix", "Input pointer same as output pointer", true);
+
+    // Test B - Null input psImage
+    printNegativeTestHeader(stdout,"psMatrix", "Null input psImage",
+                            "Invalid operation: inImage or its data is NULL.", 0);
+    psMatrixTranspose(outImage, nullImage);
+    printFooter(stdout, "psMatrix", "Null input psImage", true);
+
+    // Test C - Incorrect type for input pointer
+    printNegativeTestHeader(stdout,"psMatrix", "Incorrect type for input pointer",
+                            "|Invalid operation: inImage not PS_TYPE_F64.", 0);
+    psMatrixTranspose(outImage, badImage1);
+    printFooter(stdout, "psMatrix", "Incorrect type for input pointer", true);
+
+    // Test D - Matrix not square for input pointer
+    printNegativeTestHeader(stdout,"psMatrix", "Matrix not square for input pointer",
+                            "Invalid operation: inImage not square array.", 0);
+    psMatrixTranspose(outImage, badImage2);
+    printFooter(stdout, "psMatrix", "Matrix not square for input pointer", true);
+
+    // Test E - Incorrect type for output pointer
+    printNegativeTestHeader(stdout,"psMatrix", "Incorrect type for output pointer",
+                            "Invalid operation: outImage not PS_TYPE_F64.", 0);
+    psMatrixTranspose(badImage1, inImage);
+    printFooter(stdout, "psMatrix", "Incorrect type for output pointer", true);
+
+    // Test F - Matrix not square for output pointer
+    printNegativeTestHeader(stdout,"psMatrix", "Matrix not square for output pointer",
+                            "Invalid operation: outImage not square array.", 0);
+    psMatrixTranspose(badImage2, inImage);
+    printFooter(stdout, "psMatrix", "Matrix not square for output pointer", true);
+
+    return 0;
+}
Index: /tags/rel1_1/psLib/test/dataManip/tst_psMatrix03.c
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/tst_psMatrix03.c	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/tst_psMatrix03.c	(revision 1056)
@@ -0,0 +1,144 @@
+/** @file  tst_psMatrix_03.c
+ *
+ *  @brief Test driver for psMatrix LU functions
+ *
+ *  This test driver contains the following tests for psMatrix test point 3:
+ *     A)  Create input and output images and vectors
+ *     B)  Calculate LU matrix
+ *     C)  Determine solution to matrix equation  
+ *     D)  Free input and output images and vectors
+ *     E)  Attempt to use null image input argument
+ *     F)  Attempt to use null input vector argument
+ *     G)  ttempt to use null LU image argument
+ * 
+ *  @author  Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.5 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2004-06-07 20:25:03 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#include "pslib.h"
+#include "psTest.h"
+
+#define PRINT_MATRIX(IMAGE)                     \
+for(int i=IMAGE->numRows-1; i>-1; i--) {        \
+    for(int j=0; j<IMAGE->numCols; j++) {       \
+        printf("%f ", IMAGE->data.F64[i][j]);   \
+    }                                           \
+    printf("\n");                               \
+}
+\
+#define PRINT_VECTOR(VECTOR)                    \
+for(int i=0; i<VECTOR->n; i++) {                \
+    printf("%f\n", VECTOR->data.F64[i]);        \
+}
+
+
+int main(int argc,
+         char* argv[])
+{
+    psImage *luImage = NULL;
+    psImage *inImage = NULL;
+    psImage *tempImage = NULL;
+    psVector *tempVector = NULL;
+    psVector *perm = NULL;
+    psVector *outVector = NULL;
+    psVector *inVector = NULL;
+
+
+    // Test A - Create input and output images and vectors
+    printPositiveTestHeader(stdout, "psMatrix", "Create input and output images and vectors");
+    luImage = (psImage*)psImageAlloc(3, 3, PS_TYPE_F64);
+    perm = (psVector*)psVectorAlloc(3, PS_TYPE_F64);
+    outVector = (psVector*)psVectorAlloc(3, PS_TYPE_F64);
+    inVector = (psVector*)psVectorAlloc(3, PS_TYPE_F64);
+    inImage = (psImage*)psImageAlloc(3, 3, PS_TYPE_F64);
+    inImage->data.F64[0][0] =  2;
+    inImage->data.F64[0][1] =  4;
+    inImage->data.F64[0][2] =  6;
+    inImage->data.F64[1][0] =  4;
+    inImage->data.F64[1][1] =  5;
+    inImage->data.F64[1][2] =  6;
+    inImage->data.F64[2][0] =  3;
+    inImage->data.F64[2][1] =  1;
+    inImage->data.F64[2][2] = -2;
+    inVector->data.F64[0] = 18.0;
+    inVector->data.F64[1] = 24.0;
+    inVector->data.F64[2] =  4.0;
+    inVector->n = 3;
+    PRINT_MATRIX(inImage);
+    printf("\n");
+    PRINT_VECTOR(inVector);
+    printFooter(stdout, "psMatrix", "Create input and output images and vectors", true);
+
+
+    // Test B - Calculate LU matrix
+    printPositiveTestHeader(stdout, "psMatrix", "Calculate LU matrix");
+    tempImage = luImage;
+    luImage = psMatrixLUD(luImage, perm, inImage);
+    PRINT_MATRIX(luImage);
+    if(luImage->type.dimen != PS_DIMEN_IMAGE) {
+        printf("Error: Resulting image is not PS_DIMEN_IMAGE\n");
+    } else if(luImage != tempImage) {
+        printf("Error: Return pointer not equal to output argument pointer\n");
+    }
+    printFooter(stdout, "psMatrix", "Calculate LU matrix", true);
+
+
+    // Test C - Determine solution to matrix equation
+    printPositiveTestHeader(stdout, "psMatrix", "Determine solution to matrix equation");
+    tempVector = outVector;
+    outVector = psMatrixLUSolve(outVector, luImage, inVector, perm);
+    PRINT_VECTOR(outVector);
+    if(outVector->type.type != PS_DIMEN_VECTOR) {
+        printf("Error: Resulting image is not PS_DIMEN_VECTOR\n");
+    } else if(outVector != tempVector) {
+        printf("Error: Return pointer not equal to output argument pointer\n");
+    }
+    printFooter(stdout, "psMatrix", "Determine solution to matrix equation", true);
+
+
+    // Test D - Free input and output images and vectors
+    printPositiveTestHeader(stdout, "psMatrix", "Free input and output images and vectors");
+    psImageFree(inImage);
+    psImageFree(luImage);
+    psVectorFree(perm);
+    psVectorFree(outVector);
+    psVectorFree(inVector);
+    psMemCheckLeaks(0, NULL, stdout);
+    int nBad = psMemCheckCorruption(0);
+    if(nBad) {
+        printf("ERROR: Found %d bad memory blocks\n", nBad);
+    }
+    printFooter(stdout, "psMatrix" ,"Free input and output images and vectors", true);
+
+
+    // Test E - Attempt to use null image input argument
+    printNegativeTestHeader(stdout,"psMatrix", "Attempt to use null image input argument",
+                            "Invalid operation: inImage or its data is NULL.", 0);
+    psImage *imageTest = (psImage*)psImageAlloc(3, 3, PS_TYPE_F64);
+    psMatrixLUD(imageTest, NULL, NULL);
+    printFooter(stdout, "psMatrix", "Attempt to use null image input argument", true);
+
+
+    // Test F - Attempt to use null input vector argument
+    printNegativeTestHeader(stdout,"psMatrix", "Attempt to use null input vector argument",
+                            "Invalid operation: inVector or its data is NULL.", 0);
+    psVector *vectorBad = NULL;
+    psVector *vectorBadOut = (psVector*)psVectorAlloc(3, PS_TYPE_F64);
+    psVector *permBad = (psVector*)psVectorAlloc(3, PS_TYPE_F64);
+    psMatrixLUSolve(vectorBadOut, imageTest, vectorBad, permBad);
+    printFooter(stdout, "psMatrix", "Attempt to use null input vector argument", true);
+
+
+    // Test G - Attempt to use null LU image argument
+    printNegativeTestHeader(stdout,"psMatrix", "Attempt to use null LU image argument",
+                            "Invalid operation: inImage or its data is NULL.", 0);
+    psMatrixLUSolve(vectorBadOut, NULL, vectorBad, permBad);
+    printFooter(stdout, "psMatrix", "Attempt to use null LU image argument", true);
+
+    return 0;
+}
Index: /tags/rel1_1/psLib/test/dataManip/tst_psMatrix04.c
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/tst_psMatrix04.c	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/tst_psMatrix04.c	(revision 1056)
@@ -0,0 +1,111 @@
+/** @file  tst_psMatrix_04.c
+ *
+ *  @brief Test driver for psMatrix invert function
+ *
+ *  This test driver contains the following tests for psMatrix test point 4:
+ *     A)  Create input and output images
+ *     B)  Invert matrix and calculate determinant
+ *     C)  Calculate determinant only
+ *     D)  Free input and output images
+ *     E)  Attempt to use null input image argument
+ *     F)  Attempt to use null input float argument
+ *  
+ *  @author  Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.2 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2004-06-07 20:25:03 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#include "pslib.h"
+#include "psTest.h"
+
+#define PRINT_MATRIX(IMAGE)                         \
+for(int i=IMAGE->numRows-1; i>-1; i--) {            \
+    for(int j=0; j<IMAGE->numCols; j++) {           \
+        printf("%f ", IMAGE->data.F64[i][j]);       \
+    }                                               \
+    printf("\n");                                   \
+}
+
+
+int main(int argc,
+         char* argv[])
+{
+    float det = 0.0f;
+    float *det2 = NULL;
+    psImage *outImage = NULL;
+    psImage *inImage = NULL;
+    psImage *tempImage = NULL;
+
+
+    // Test A - Create input and output images
+    printPositiveTestHeader(stdout, "psMatrix", "Create input and output images");
+    outImage = (psImage*)psImageAlloc(3, 3, PS_TYPE_F64);
+    inImage = (psImage*)psImageAlloc(3, 3, PS_TYPE_F64);
+    inImage->data.F64[0][0] =  2;
+    inImage->data.F64[0][1] =  4;
+    inImage->data.F64[0][2] =  3;
+    inImage->data.F64[1][0] =  0;
+    inImage->data.F64[1][1] =  1;
+    inImage->data.F64[1][2] = -1;
+    inImage->data.F64[2][0] =  3;
+    inImage->data.F64[2][1] =  5;
+    inImage->data.F64[2][2] =  7;
+    PRINT_MATRIX(inImage);
+    printFooter(stdout, "psMatrix", "Create input and output images", true);
+
+
+    // Test B - Invert matrix and calculate determinant
+    printPositiveTestHeader(stdout, "psMatrix", "Invert matrix and calculate determinant");
+    tempImage = outImage;
+    outImage = psMatrixInvert(outImage, inImage, &det);
+    PRINT_MATRIX(outImage);
+    printf("\ndet = %f\n", det);
+    if(outImage->type.dimen != PS_DIMEN_IMAGE) {
+        printf("Error: Resulting image is not PS_DIMEN_IMAGE\n");
+    } else if(outImage != tempImage) {
+        printf("Error: Return pointer not equal to output argument pointer\n");
+    }
+    printFooter(stdout, "psMatrix", "Invert matrix and calculate determinant", true);
+
+
+    // Test C - Calculate determinant only
+    printPositiveTestHeader(stdout, "psMatrix", "Calculate determinant only");
+    det2 = psMatrixDeterminant(inImage);
+    printf("det = %f\n", *det2);
+    printFooter(stdout, "psMatrix", "Calculate determinant only", true);
+
+
+    // Test D - Free input and output images
+    printPositiveTestHeader(stdout, "psMatrix", "Free input and output images");
+    psImageFree(outImage);
+    psImageFree(inImage);
+    psFree(det2);
+    psMemCheckLeaks(0, NULL, stdout);
+    int nBad = psMemCheckCorruption(0);
+    if(nBad) {
+        printf("ERROR: Found %d bad memory blocks\n", nBad);
+    }
+    printFooter(stdout, "psMatrix" ,"Free input and output images", true);
+
+
+    // Test E - Attempt to use null input image argument
+    printNegativeTestHeader(stdout,"psMatrix", "Attempt to use null input image argument",
+                            "Invalid operation: inImage or its data is NULL.", 0);
+    psImage *badOutImage = (psImage*)psImageAlloc(3, 3, PS_TYPE_F64);
+    psMatrixInvert(badOutImage, NULL, &det);
+    printFooter(stdout, "psMatrix", "Attempt to use null input image argument", true);
+
+
+    // Test F - Attempt to use null input float argument
+    printNegativeTestHeader(stdout,"psMatrix", "Attempt to use null input float argument",
+                            "Invalid operation: determinant argument is NULL.", 0);
+    psImage *badInImage = (psImage*)psImageAlloc(3, 3, PS_TYPE_F64);
+    psMatrixInvert(badOutImage, badInImage, NULL);
+    printFooter(stdout, "psMatrix", "Attempt to use null input float argument", true);
+
+    return 0;
+}
Index: /tags/rel1_1/psLib/test/dataManip/tst_psMatrix05.c
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/tst_psMatrix05.c	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/tst_psMatrix05.c	(revision 1056)
@@ -0,0 +1,78 @@
+/** @file  tst_psMatrix_05.c
+ *
+ *  @brief Test driver for psMatrix multiplication function
+ *
+ *  This test driver contains the following tests for psMatrix test point 5:
+ *     A)  Create input and output images
+ *     B)  Multiply images
+ *     C)  Free input and output images
+ *
+ *  @author  Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.1 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2004-05-28 02:52:23 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#include "pslib.h"
+#include "psTest.h"
+
+#define PRINT_MATRIX(IMAGE)                         \
+for(int i=0; i<IMAGE->numRows; i++) {           \
+    for(int j=0; j<IMAGE->numCols; j++) {       \
+        printf("%f ", IMAGE->data.F64[i][j]);   \
+    }                                          \
+    printf("\n");                              \
+}
+
+
+int main(int argc,
+         char* argv[])
+{
+    psImage *outImage = NULL;
+    psImage *inImage1 = NULL;
+    psImage *inImage2 = NULL;
+
+
+    // Test A - Create input and output images
+    printPositiveTestHeader(stdout, "psMatrix", "Create input and output images");
+    outImage = (psImage*)psImageAlloc(2, 2, PS_TYPE_F64);
+    inImage1 = (psImage*)psImageAlloc(2, 2, PS_TYPE_F64);
+    inImage2 = (psImage*)psImageAlloc(2, 2, PS_TYPE_F64);
+    inImage1->data.F64[0][0] =  2;
+    inImage1->data.F64[0][1] =  3;
+    inImage1->data.F64[1][0] = -1;
+    inImage1->data.F64[1][1] =  2;
+    inImage2->data.F64[0][0] =  4;
+    inImage2->data.F64[0][1] =  1;
+    inImage2->data.F64[1][0] =  0;
+    inImage2->data.F64[1][1] =  6;
+    PRINT_MATRIX(inImage1);
+    printf("\n");
+    PRINT_MATRIX(inImage2);
+    printFooter(stdout, "psMatrix", "Create input and output images", true);
+
+
+    // Test B - Multiply images
+    printPositiveTestHeader(stdout, "psMatrix", "Multiply images");
+    psMatrixMultiply(outImage, inImage1, inImage2);
+    PRINT_MATRIX(outImage);
+    printFooter(stdout, "psMatrix", "Multiply images", true);
+
+
+    // Test C - Free input and output images
+    printPositiveTestHeader(stdout, "psMatrix", "Free input and output images");
+    psImageFree(outImage);
+    psImageFree(inImage1);
+    psImageFree(inImage2);
+    psMemCheckLeaks(0, NULL, stdout);
+    int nBad = psMemCheckCorruption(0);
+    if(nBad) {
+        printf("ERROR: Found %d bad memory blocks\n", nBad);
+    }
+    printFooter(stdout, "psMatrix" ,"Free input and output images", true);
+
+    return 0;
+}
Index: /tags/rel1_1/psLib/test/dataManip/tst_psMatrix06.c
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/tst_psMatrix06.c	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/tst_psMatrix06.c	(revision 1056)
@@ -0,0 +1,86 @@
+/** @file  tst_psMatrix_06.c
+ *
+ *  @brief Test driver for psMatrix Eigenvectors function
+ *
+ *  This test driver contains the following tests for psMatrix test point 6:
+ *     A)  Create input and output images
+ *     B)  Calculate Eigenvectors
+ *     C)  Free input and output images
+ *
+ *  @author  Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.1 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2004-05-28 02:52:23 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#include "pslib.h"
+#include "psTest.h"
+
+#define PRINT_MATRIX(IMAGE)                         \
+for(int i=0; i<IMAGE->numRows; i++) {           \
+    for(int j=0; j<IMAGE->numCols; j++) {       \
+        printf("%f ", IMAGE->data.F64[i][j]);   \
+    }                                          \
+    printf("\n");                              \
+}
+
+
+int main(int argc,
+         char* argv[])
+{
+    psImage *outImage = NULL;
+    psImage *inImage = NULL;
+
+
+    // Test A - Create input and output images
+    printPositiveTestHeader(stdout, "psMatrix", "Create input and output images");
+    outImage = (psImage*)psImageAlloc(4, 4, PS_TYPE_F64);
+    inImage = (psImage*)psImageAlloc(4, 4, PS_TYPE_F64);
+
+    inImage->data.F64[0][0] = 1./1.;
+    inImage->data.F64[0][1] = 1./2.;
+    inImage->data.F64[0][2] = 1./3.;
+    inImage->data.F64[0][3] = 1./4.;
+
+    inImage->data.F64[1][0] = 1./2.;
+    inImage->data.F64[1][1] = 1./3.;
+    inImage->data.F64[1][2] = 1./4.;
+    inImage->data.F64[1][3] = 1./5.;
+
+    inImage->data.F64[2][0] = 1./3.;
+    inImage->data.F64[2][1] = 1./4.;
+    inImage->data.F64[2][2] = 1./5.;
+    inImage->data.F64[2][3] = 1./6.;
+
+    inImage->data.F64[3][0] = 1./4.;
+    inImage->data.F64[3][1] = 1./5.;
+    inImage->data.F64[3][2] = 1./6.;
+    inImage->data.F64[3][3] = 1./7.;
+
+    PRINT_MATRIX(inImage);
+    printFooter(stdout, "psMatrix", "Create input and output images", true);
+
+
+    // Test B - Calculate Eigenvectors
+    printPositiveTestHeader(stdout, "psMatrix", "Calculate Eigenvectors");
+    psMatrixEigenvectors(outImage, inImage);
+    PRINT_MATRIX(outImage);
+    printFooter(stdout, "psMatrix", "Calculate Eigenvectors", true);
+
+
+    // Test C - Free input and output images
+    printPositiveTestHeader(stdout, "psMatrix", "Free input and output images");
+    psImageFree(outImage);
+    psImageFree(inImage);
+    psMemCheckLeaks(0, NULL, stdout);
+    int nBad = psMemCheckCorruption(0);
+    if(nBad) {
+        printf("ERROR: Found %d bad memory blocks\n", nBad);
+    }
+    printFooter(stdout, "psMatrix" ,"Free input and output images", true);
+
+    return 0;
+}
Index: /tags/rel1_1/psLib/test/dataManip/tst_psMatrix07.c
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/tst_psMatrix07.c	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/tst_psMatrix07.c	(revision 1056)
@@ -0,0 +1,174 @@
+/** @file  tst_psMatrix_07.c
+ *
+ *  @brief Test driver for psMatrix vector conversion functions
+ *
+ *  This test driver contains the following tests for psMatrix test point 7:
+ *     A)  Create input and output images and vectors
+ *     B)  Convert matrix to PS_DIMEN_VECTOR vector
+ *     C)  Attempt to use null image input argument
+ *     D)  Convert matrix to PS_DIMEN_TRANSV vector
+ *     E)  Improper image size
+ *     F)  Convert PS_DIMEN_VECTOR vector to matrix
+ *     G)  Attempt to use null input vector argument
+ *     H)  Convert PS_DIMEN_TRANSV vector to matrix
+ *     I)  Free input and output images and vectors
+ *
+ *  @author  Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.3 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2004-06-08 01:56:35 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#include "pslib.h"
+#include "psTest.h"
+
+#define PRINT_MATRIX(IMAGE)                         \
+for(int i=0; i<IMAGE->numRows; i++) {               \
+    for(int j=0; j<IMAGE->numCols; j++) {           \
+        printf("%f ", IMAGE->data.F64[i][j]);       \
+    }                                               \
+    printf("\n");                                   \
+}
+
+#define PRINT_VECTOR(VECTOR)                        \
+for(int i=0; i<VECTOR->n; i++) {                    \
+    printf("%f\n", VECTOR->data.F64[i]);            \
+}
+
+
+int main(int argc,
+         char* argv[])
+{
+    psVector *v1 = NULL;
+    psVector *tempVector = NULL;
+    psImage *tempImage = NULL;
+    psImage *m1 = NULL;
+    psVector *v2 = NULL;
+    psImage *m2 = NULL;
+    psImage *m3 = NULL;
+    psImage *m4 = NULL;
+    psImage *badImage = NULL;
+
+
+    // Test A - Create input and output images
+    printPositiveTestHeader(stdout, "psMatrix", "Create input and output images and vectors");
+    v1 = (psVector*)psVectorAlloc(3, PS_TYPE_F64);
+    m1 = (psImage*)psImageAlloc(1, 3, PS_TYPE_F64);
+    v2 = (psVector*)psVectorAlloc(3, PS_TYPE_F64);
+    m2 = (psImage*)psImageAlloc(1, 3, PS_TYPE_F64);
+    m3 = (psImage*)psImageAlloc(3, 1, PS_TYPE_F64);
+    m4 = (psImage*)psImageAlloc(3, 1, PS_TYPE_F64);
+    badImage = (psImage*)psImageAlloc(2, 2, PS_TYPE_F64);
+    m1->data.F64[0][0] = 0.0;
+    m1->data.F64[1][0] = 1.0;
+    m1->data.F64[2][0] = 2.0;
+    v2->data.F64[0] = 0.0;
+    v2->data.F64[1] = 1.0;
+    v2->data.F64[2] = 2.0;
+    v2->n = 3;
+    m4->data.F64[0][0] = 0.0;
+    m4->data.F64[0][1] = 1.0;
+    m4->data.F64[0][2] = 2.0;
+    PRINT_MATRIX(m1);
+    printf("\n");
+    PRINT_MATRIX(m4);
+    printf("\n");
+    PRINT_VECTOR(v2);
+    printFooter(stdout, "psMatrix", "Create input and output images and vectors", true);
+
+
+    // Test B - Convert matrix to PS_DIMEN_VECTOR vector
+    printPositiveTestHeader(stdout, "psMatrix", "Convert matrix to PS_DIMEN_VECTOR vector");
+    tempVector = v1;
+    v1 = psMatrixToVector(v1, m1);
+    PRINT_VECTOR(v1);
+    if(v1->type.dimen != PS_DIMEN_VECTOR) {
+        printf("Error: Resulting image is not PS_DIMEN_VECTOR\n");
+    } else if(v1 != tempVector) {
+        printf("Error: Return pointer not equal to output argument pointer\n");
+    }
+    printFooter(stdout, "psMatrix", "Convert matrix to PS_DIMEN_VECTOR vector", true);
+
+
+    // Test C - Attempt to use null image input argument
+    printNegativeTestHeader(stdout,"psMatrix", "Attempt to use null image input argument",
+                            "Invalid operation: inImage or its data is NULL.", 0);
+    v1 = psMatrixToVector(v1, NULL);
+    printFooter(stdout, "psMatrix", "Attempt to use null image input argument", true);
+
+
+    // Test D - Convert matrix to PS_DIMEN_TRANSV vector
+    printPositiveTestHeader(stdout, "psMatrix", "Convert matrix to PS_DIMEN_TRANSV vector");
+    v1->type.dimen = PS_DIMEN_TRANSV;
+    psMatrixToVector(v1, m4);
+    PRINT_VECTOR(v1);
+    if(v1->type.dimen != PS_DIMEN_TRANSV) {
+        printf("Error: Resulting image is not PS_DIMEN_TRANSV\n");
+    } else if(v1 != tempVector) {
+        printf("Error: Return pointer not equal to output argument pointer\n");
+    }
+    printFooter(stdout, "psMatrix", "Convert matrix to PS_DIMEN_TRANSV vector", true);
+
+
+    // Test E - Improper image size
+    printNegativeTestHeader(stdout,"psMatrix", "Improper image size",
+                            "Image does not have dim with 1 col or 1 row: (2 x 2).", 0);
+    psMatrixToVector(v1, badImage);
+    printFooter(stdout, "psMatrix", "Improper image size", true);
+
+
+    // Test F - Convert PS_DIMEN_VECTOR vector to matrix
+    printPositiveTestHeader(stdout, "psMatrix", "Convert PS_DIMEN_VECTOR vector to matrix");
+    tempImage = m2;
+    m2 = psVectorToMatrix(m2, v2);
+    PRINT_MATRIX(m2);
+    if(m2->type.dimen != PS_DIMEN_IMAGE) {
+        printf("Error: Resulting image is not PS_DIMEN_IMAGE\n");
+    } else if(m2 != tempImage) {
+        printf("Error: Return pointer not equal to output argument pointer\n");
+    }
+    printFooter(stdout, "psMatrix", "Convert PS_DIMEN_VECTOR vector to matrix", true);
+
+
+    // Test G - Attempt to use null input vector argument
+    printNegativeTestHeader(stdout,"psMatrix", "Attempt to use null input vector argument",
+                            "Invalid operation: inVector or its data is NULL.", 0);
+    psVectorToMatrix(m2, NULL);
+    printFooter(stdout, "psMatrix", "Attempt to use null input vector argument", true);
+
+
+    // Test H - Convert PS_DIMEN_TRANSV vector to matrix
+    printPositiveTestHeader(stdout, "psMatrix", "Convert PS_DIMEN_TRANSV vector to matrix");
+    v2->type.dimen = PS_DIMEN_TRANSV;
+    tempImage = m3;
+    psVectorToMatrix(m3, v2);
+    PRINT_MATRIX(m3);
+    if(m3->type.dimen != PS_DIMEN_IMAGE) {
+        printf("Error: Resulting image is not PS_DIMEN_IMAGE\n");
+    } else if(m3 != tempImage) {
+        printf("Error: Return pointer not equal to output argument pointer\n");
+    }
+    printFooter(stdout, "psMatrix", "Convert PS_DIMEN_TRANSV vector to matrix", true);
+
+
+    // Test I - Free input and output images
+    printPositiveTestHeader(stdout, "psMatrix", "Free input and output images and vectors");
+    psImageFree(m1);
+    psVectorFree(v1);
+    psImageFree(m2);
+    psVectorFree(v2);
+    psImageFree(m3);
+    psImageFree(m4);
+    psImageFree(badImage);
+    psMemCheckLeaks(0, NULL, stdout);
+    int nBad = psMemCheckCorruption(0);
+    if(nBad) {
+        printf("ERROR: Found %d bad memory blocks\n", nBad);
+    }
+    printFooter(stdout, "psMatrix" ,"Free input and output images and vectors", true);
+
+    return 0;
+}
Index: /tags/rel1_1/psLib/test/dataManip/tst_psStats00.c
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/tst_psStats00.c	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/tst_psStats00.c	(revision 1056)
@@ -0,0 +1,204 @@
+/*****************************************************************************
+    This routine must ensure that PS_STAT_SAMPLE_MEAN is correctly computed
+    by the procedure psArrayStats().
+ *****************************************************************************/
+#include <stdio.h>
+#include "pslib.h"
+#include "psTest.h"
+#define N 10
+
+int main()
+{
+    psStats *myStats    = NULL;
+    psStats *myStats2    = NULL;
+    int testStatus      = true;
+    int globalTestStatus = true;
+    int i               = 0;
+    psVector *myVector  = NULL;
+    psVector *maskVector= NULL;
+    float mean          = 0.0;
+    float realMeanNoMask   = 0.0;
+    float realMeanWithMask = 0.0;
+    int count           = 0;
+    int currentId       = psMemGetId();
+    int memLeaks        = 0;
+
+    /*************************************************************************/
+    /*  Allocate and initialize data structures                      */
+    /*************************************************************************/
+    myStats = psStatsAlloc(PS_STAT_SAMPLE_MEAN);
+    myVector = psVectorAlloc(N, PS_TYPE_F32);
+    myVector->n = N;
+    maskVector = psVectorAlloc(N, PS_TYPE_U8);
+    maskVector->n = N;
+
+    mean = 0.0;
+    realMeanWithMask = 0.0;
+    // Set the appropriate values for the vector data.
+    for (i=0;i<N;i++) {
+        myVector->data.F32[i] = (float) i;
+    }
+
+    // Set the mask vector and calculate the expected maximum.
+    for (i=0;i<N;i++) {
+        realMeanNoMask+= myVector->data.F32[i];
+
+        if (i < (N/2)) {
+            maskVector->data.U8[i] = 0;
+            realMeanWithMask+= myVector->data.F32[i];
+            count++;
+        } else {
+            maskVector->data.U8[i] = 1;
+        }
+    }
+
+
+    realMeanNoMask /= (float) N;
+    realMeanWithMask /= (float) count;
+
+    /*************************************************************************/
+    /*  Call psVectorStats() with no vector mask.                    */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "PS_STAT_SAMPLE_MEAN: no vector mask");
+
+    myStats = psVectorStats(myStats, myVector, NULL, 0);
+    mean = myStats->sampleMean;
+
+    printf("Called psVectorStats() on a vector with no elements masked.\n");
+    printf("The expected mean was %f; the calculated mean was %f\n", realMeanNoMask, mean);
+    if (mean == realMeanNoMask) {
+        testStatus = true;
+    } else {
+        testStatus = false;
+        globalTestStatus = false;
+    }
+    printFooter(stdout,
+                "psVector functions",
+                "PS_STAT_SAMPLE_MEAN: no vector mask",
+                testStatus);
+
+    /*************************************************************************/
+    /*  Call psVectorStats() with vector mask=1.                             */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "PS_STAT_SAMPLE_MEAN: with vector mask=1");
+
+    myStats = psVectorStats(myStats, myVector, maskVector, 1);
+    mean = myStats->sampleMean;
+    printf("Called psVectorStats() on a vector with last N/2 elements masked.\n");
+    printf("The expected mean was %f; the calculated mean was %f\n", realMeanWithMask, mean);
+    if (mean == realMeanWithMask) {
+        testStatus = true;
+    } else {
+        testStatus = false;
+        globalTestStatus = false;
+    }
+
+    printFooter(stdout,
+                "psVector functions",
+                "PS_STAT_SAMPLE_MEAN: with vector mask=1",
+                testStatus);
+
+    /*************************************************************************/
+    /*  Call psVectorStats() with vector mask=2.                             */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "PS_STAT_SAMPLE_MEAN: with vector mask=2");
+
+    // Set the mask vector and calculate the expected maximum.
+    // Set the mask vector.
+    for (i=0;i<N;i++) {
+        if (maskVector->data.U8[i] == 1) {
+            maskVector->data.U8[i] = 2;
+        }
+    }
+
+    myStats = psVectorStats(myStats, myVector, maskVector, 2);
+    mean = myStats->sampleMean;
+    printf("Called psVectorStats() on a vector with last N/2 elements masked.\n");
+    printf("The expected mean was %f; the calculated mean was %f\n", realMeanWithMask, mean);
+    if (mean == realMeanWithMask) {
+        testStatus = true;
+    } else {
+        testStatus = false;
+        globalTestStatus = false;
+    }
+
+    printFooter(stdout,
+                "psVector functions",
+                "PS_STAT_SAMPLE_MEAN: with vector mask=2",
+                testStatus);
+
+    /*************************************************************************/
+    /*  Call psVectorStats() with vector mask=3.                             */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "PS_STAT_SAMPLE_MEAN: with vector mask=3");
+
+    // Set the mask vector and calculate the expected maximum.
+    // Set the mask vector.
+    for (i=0;i<N;i++) {
+        if (maskVector->data.U8[i] == 2) {
+            maskVector->data.U8[i] = 3;
+        }
+    }
+
+    myStats = psVectorStats(myStats, myVector, maskVector, 3);
+    mean = myStats->sampleMean;
+    printf("Called psVectorStats() on a vector with last N/2 elements masked.\n");
+    printf("The expected mean was %f; the calculated mean was %f\n", realMeanWithMask, mean);
+    if (mean == realMeanWithMask) {
+        testStatus = true;
+    } else {
+        testStatus = false;
+        globalTestStatus = false;
+    }
+
+    printFooter(stdout,
+                "psVector functions",
+                "PS_STAT_SAMPLE_MEAN: with vector mask=3",
+                testStatus);
+    /*************************************************************************/
+    /*  Call psVectorStats() with NULL inputs.                               */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "PS_STAT_SAMPLE_MEAN: NULL inputs");
+
+    myStats = psVectorStats(myStats, NULL, NULL, 0);
+    myStats2 = psVectorStats(NULL, myVector, NULL, 0);
+
+    printFooter(stdout,
+                "psVector functions",
+                "PS_STAT_SAMPLE_MEAN: NULL inputs",
+                testStatus);
+
+    /*************************************************************************/
+    /*  Deallocate data structures                                           */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "psStats(): deallocating memory");
+
+    psStatsFree(myStats);
+    psVectorFree(myVector);
+    psVectorFree(maskVector);
+
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,NULL);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psVector functions",
+                "psStats(): deallocating memory",
+                testStatus);
+
+    return (!globalTestStatus);
+}
Index: /tags/rel1_1/psLib/test/dataManip/tst_psStats01.c
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/tst_psStats01.c	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/tst_psStats01.c	(revision 1056)
@@ -0,0 +1,125 @@
+/*****************************************************************************
+    This routine must ensure that PS_STAT_MAX is correctly computed
+    by the procedure psVectorStats().
+ *****************************************************************************/
+#include <stdio.h>
+#include "pslib.h"
+#include "psTest.h"
+#define N 10
+
+int main()
+{
+    psStats *myStats    = NULL;
+    int testStatus      = true;
+    int globalTestStatus = true;
+    int i               = 0;
+    psVector *myVector  = NULL;
+    psVector *maskVector= NULL;
+    float max           = 0.0;
+    float realMaxNoMask   = 0.0;
+    float realMaxWithMask = 0.0;
+    int currentId       = psMemGetId();
+    int memLeaks        = 0;
+
+    /*************************************************************************/
+    /*  Allocate and initialize data structures                      */
+    /*************************************************************************/
+    myStats = psStatsAlloc(PS_STAT_MAX);
+    myVector = psVectorAlloc(N, PS_TYPE_F32);
+    myVector->n = N;
+    maskVector = psVectorAlloc(N, PS_TYPE_U8);
+    maskVector->n = N;
+
+    // Set the appropriate values for the vector data.
+    for (i=0;i<N;i++) {
+        myVector->data.F32[i] = (float) i;
+    }
+
+    // Set the mask vector and calculate the expected maximum.
+    for (i=0;i<N;i++) {
+        if (myVector->data.F32[i] > realMaxNoMask) {
+            realMaxNoMask = myVector->data.F32[i];
+        }
+
+        if (i < (N/2)) {
+            maskVector->data.U8[i] = 0;
+
+            if (myVector->data.F32[i] > realMaxWithMask) {
+                realMaxWithMask = myVector->data.F32[i];
+            }
+        } else {
+            maskVector->data.U8[i] = 1;
+            printf("Masking element %d\n", i);
+        }
+    }
+
+    /*************************************************************************/
+    /*  Call psVectorStats() with no vector mask.                    */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "PS_STAT_MAX: no vector mask");
+
+    myStats = psVectorStats(myStats, myVector, NULL, 0);
+    max = myStats->max;
+
+    printf("Called psVectorStats() on a vector with no elements masked.\n");
+    printf("The expected max was %f; the calculated max was %f\n", realMaxNoMask, max);
+    if (max == realMaxNoMask) {
+        testStatus = true;
+    } else {
+        testStatus = false;
+        globalTestStatus = false;
+    }
+    printFooter(stdout,
+                "psVector functions",
+                "PS_STAT_MAX: no vector mask",
+                testStatus);
+
+    /*************************************************************************/
+    /*  Call psVectorStats() with vector mask.                       */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "PS_STAT_MAX: with vector mask");
+
+    myStats = psVectorStats(myStats, myVector, maskVector, 1);
+    max = myStats->max;
+    printf("Called psVectorStats() on a vector with last N/2 elements masked.\n");
+    printf("The expected max was %f; the calculated max was %f\n", realMaxWithMask, max);
+    if (max == realMaxWithMask) {
+        testStatus = true;
+    } else {
+        testStatus = false;
+        globalTestStatus = false;
+    }
+
+    printFooter(stdout,
+                "psVector functions",
+                "PS_STAT_MAX: with vector mask",
+                testStatus);
+
+    /*************************************************************************/
+    /*  Deallocate data structures                                   */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "psStats(): deallocating memory");
+
+    psStatsFree(myStats);
+    psVectorFree(myVector);
+    psVectorFree(maskVector);
+
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,NULL);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psVector functions",
+                "psStats(): deallocating memory",
+                testStatus);
+
+    return (!globalTestStatus);
+}
Index: /tags/rel1_1/psLib/test/dataManip/tst_psStats02.c
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/tst_psStats02.c	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/tst_psStats02.c	(revision 1056)
@@ -0,0 +1,125 @@
+/*****************************************************************************
+    This routine must ensure that PS_STAT_MIN is correctly computed
+    by the procedure psVectorStats().
+ *****************************************************************************/
+#include <stdio.h>
+#include "pslib.h"
+#include "psTest.h"
+#define N 10
+
+int main()
+{
+    psStats *myStats    = NULL;
+    int testStatus      = true;
+    int globalTestStatus = true;
+    int i               = 0;
+    psVector *myVector  = NULL;
+    psVector *maskVector= NULL;
+    float min           = 1e99;
+    float realMinNoMask   = 1e99;
+    float realMinWithMask = 1e99;
+    int currentId       = psMemGetId();
+    int memLeaks        = 0;
+
+    /*************************************************************************/
+    /*  Allocate and initialize data structures                      */
+    /*************************************************************************/
+    myStats = psStatsAlloc(PS_STAT_MIN);
+    myVector = psVectorAlloc(N, PS_TYPE_F32);
+    myVector->n = N;
+    maskVector = psVectorAlloc(N, PS_TYPE_U8);
+    maskVector->n = N;
+
+    // Set the appropriate values for the vector data.
+    for (i=0;i<N;i++) {
+        myVector->data.F32[i] = (float) i;
+    }
+
+    // Set the mask vector and calculate the expected minimum.
+    for (i=0;i<N;i++) {
+        if (myVector->data.F32[i] < realMinNoMask) {
+            realMinNoMask = myVector->data.F32[i];
+        }
+
+        if (i < (N/2)) {
+            maskVector->data.U8[i] = 1;
+        } else {
+            maskVector->data.U8[i] = 0;
+            if (myVector->data.F32[i] < realMinWithMask) {
+                realMinWithMask = myVector->data.F32[i];
+            }
+        }
+    }
+
+    /*************************************************************************/
+    /*  Call psVectorStats() with no vector mask.                    */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "PS_STAT_MIN: no vector mask");
+
+    myStats = psVectorStats(myStats, myVector, NULL, 0);
+    min = myStats->min;
+
+    printf("Called psVectorStats() on a vector with no elements masked.\n");
+    printf("The expected min was %f; the calculated min was %f\n",
+           realMinNoMask, min);
+    if (min == realMinNoMask) {
+        testStatus = true;
+    } else {
+        testStatus = false;
+        globalTestStatus = false;
+    }
+    printFooter(stdout,
+                "psVector functions",
+                "PS_STAT_MIN: no vector mask",
+                testStatus);
+
+    /*************************************************************************/
+    /*  Call psVectorStats() with vector mask.                       */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "PS_STAT_MIN: with vector mask");
+
+    myStats = psVectorStats(myStats, myVector, maskVector, 1);
+    min = myStats->min;
+    printf("Called psVectorStats() on a vector with last N/2 elements masked.\n");
+    printf("The expected min was %f; the calculated min was %f\n",
+           realMinWithMask, min);
+    if (min == realMinWithMask) {
+        testStatus = true;
+    } else {
+        testStatus = false;
+        globalTestStatus = false;
+    }
+
+    printFooter(stdout,
+                "psVector functions",
+                "PS_STAT_MIN: with vector mask",
+                testStatus);
+
+    /*************************************************************************/
+    /*  Deallocate data structures                                   */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "psStats(): deallocating memory");
+
+    psStatsFree(myStats);
+    psVectorFree(myVector);
+    psVectorFree(maskVector);
+
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,NULL);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psVector functions",
+                "psStats(): deallocating memory",
+                testStatus);
+
+    return (!globalTestStatus);
+}
Index: /tags/rel1_1/psLib/test/dataManip/tst_psStats03.c
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/tst_psStats03.c	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/tst_psStats03.c	(revision 1056)
@@ -0,0 +1,120 @@
+/*****************************************************************************
+    This routine must ensure that PS_STAT_SAMPLE_MEDIAN is correctly computed
+    by the procedure psVectorStats().
+ *****************************************************************************/
+#include <stdio.h>
+#include "pslib.h"
+#include "psTest.h"
+#define N1 1029   // This should be an odd number.
+#define N ((4 * N1) + 1)
+
+int main()
+{
+    psStats *myStats    = NULL;
+    int testStatus      = true;
+    int globalTestStatus = true;
+    int i               = 0;
+    psVector *myVector  = NULL;
+    psVector *maskVector= NULL;
+    float median        = 1e99;
+    float realMedianWithMask = (float) (N-3)/4;
+    float realMedianNoMask = (float) (N-1)/2;
+    int currentId       = psMemGetId();
+    int memLeaks        = 0;
+
+    /*************************************************************************/
+    /*  Allocate and initialize data structures                      */
+    /*************************************************************************/
+    myStats = psStatsAlloc(PS_STAT_SAMPLE_MEDIAN);
+    myVector = psVectorAlloc(N, PS_TYPE_F32);
+    myVector->n = N;
+    maskVector = psVectorAlloc(N, PS_TYPE_U8);
+    maskVector->n = N;
+
+    // Set the appropriate values for the vector data.
+    for (i=0;i<N;i++) {
+        myVector->data.F32[i] = (float) i;
+    }
+
+    // Set the mask vector and calculate the expected median.
+    for (i=0;i<N;i++) {
+        if (i < (N/2)) {
+            maskVector->data.U8[i] = 0;
+        } else {
+            maskVector->data.U8[i] = 1;
+        }
+    }
+
+    /*************************************************************************/
+    /*  Call psVectorStats() with no vector mask.                    */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "PS_STAT_SAMPLE_MEDIAN: no vector mask");
+
+    myStats = psVectorStats(myStats, myVector, NULL, 0);
+    median = myStats->sampleMedian;
+
+    printf("Called psVectorStats() on a vector with no elements masked.\n");
+    printf("The expected median was %f.  The calculated median was %f.\n",
+           realMedianNoMask, median);
+    if (median == realMedianNoMask) {
+        testStatus = true;
+    } else {
+        testStatus = false;
+        globalTestStatus = false;
+    }
+
+    printFooter(stdout,
+                "psStats functions",
+                "PS_STAT_SAMPLE_MEDIAN: no vector mask",
+                testStatus);
+
+    /*************************************************************************/
+    /*  Call psVectorStats() with vector mask.                       */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "PS_STAT_SAMPLE_MEDIAN: with vector mask");
+
+    myStats = psVectorStats(myStats, myVector, maskVector, 1);
+    median = myStats->sampleMedian;
+    printf("Called psVectorStats() on a vector with last N/2 elements masked.\n");
+    printf("The expected median was %f.  The calculated median was %f.\n",
+           realMedianWithMask, median);
+    if (median == realMedianWithMask) {
+        testStatus = true;
+    } else {
+        testStatus = false;
+        globalTestStatus = false;
+    }
+
+    printFooter(stdout,
+                "psStats functions",
+                "PS_STAT_SAMPLE_MEDIAN: with vector mask",
+                testStatus);
+
+    /*************************************************************************/
+    /*  Deallocate data structures                                   */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "psStats(): deallocating memory");
+
+    psStatsFree(myStats);
+    psVectorFree(myVector);
+    psVectorFree(maskVector);
+
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,NULL);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psStats functions",
+                "psStats(): deallocating memory",
+                testStatus);
+
+    return (!globalTestStatus);
+}
Index: /tags/rel1_1/psLib/test/dataManip/tst_psStats04.c
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/tst_psStats04.c	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/tst_psStats04.c	(revision 1056)
@@ -0,0 +1,82 @@
+/*****************************************************************************
+    This routine must ensure that PS_STAT_NVALUES is correctly computed
+    by the procedure psVectorStats().
+ 
+    Note: The NVALUES stat was removed from the IfA requirements spec.  So,
+    this test is no longer in use.
+ *****************************************************************************/
+#include <stdio.h>
+#include "pslib.h"
+#include "psTest.h"
+#define N1 1029
+#define N ((4 * N1) + 1)
+
+int main()
+{
+    psStats *myStats    = NULL;
+    int testStatus      = true;
+    int i               = 0;
+    psVector *myVector  = NULL;
+    psVector *maskVector= NULL;
+
+    /*************************************************************************/
+    /*  Allocate and initialize data structures                      */
+    /*************************************************************************/
+    myStats = psStatsAlloc(PS_STAT_NVALUES);
+    myVector = psVectorAlloc(N, PS_TYPE_F32);
+    myVector->n = N;
+    maskVector = psVectorAlloc(N, PS_TYPE_U8);
+    maskVector->n = N;
+
+    // Set the appropriate values for the vector data.
+    for (i=0;i<N;i++) {
+        myVector->data.F32[i] = (float) i;
+    }
+
+    // Set the mask vector and calculate the expected maximum.
+    for (i=0;i<N;i++) {
+        if (i < (N/2)) {
+            maskVector->data.U8[i] = 0;
+        } else {
+            maskVector->data.U8[i] = 1;
+        }
+    }
+
+    /*************************************************************************/
+    /*  Call psVectorStats() with no vector mask.                    */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "PS_STAT_NVALUES");
+
+    myStats = psVectorStats(myStats, myVector, NULL, 0);
+
+    printf("Called psVectorStats() on a vector with no elements masked.\n");
+    printf("The expected nvalues was %d.  The calculated nvalues was %d.\n",
+           N, myStats->nValues);
+    if (myStats->nValues == N) {
+        testStatus = true;
+    } else {
+        testStatus = false;
+    }
+
+    /*************************************************************************/
+    /*  Call psVectorStats() with vector mask.                       */
+    /*************************************************************************/
+    myStats = psVectorStats(myStats, myVector, maskVector, 1);
+    printf("Called psVectorStats() on a vector with last N/2 elements masked.\n");
+    printf("The expected nvalues was %d.  The calculated nvalues was %d.\n",
+           N/2, myStats->nValues);
+    if (myStats->nValues == N/2) {
+        testStatus = true;
+    } else {
+        testStatus = false;
+    }
+
+    printFooter(stdout,
+                "psHash functions",
+                "psHashAlloc()",
+                testStatus);
+
+    return (!testStatus);
+}
Index: /tags/rel1_1/psLib/test/dataManip/tst_psStats05.c
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/tst_psStats05.c	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/tst_psStats05.c	(revision 1056)
@@ -0,0 +1,88 @@
+/*****************************************************************************
+    This routine must ensure that the psStats structure is correctly
+    allocated and deallocated by the procedure psArrayStats().
+ *****************************************************************************/
+#include <stdio.h>
+#include "pslib.h"
+#include "psTest.h"
+#define MISC_FLOAT_NUMBER 345.0
+
+int main()
+{
+    psStats *myStats    = NULL;
+    int testStatus      = true;
+    int currentId       = psMemGetId();
+    int memLeaks        = 0;
+
+    /*************************************************************************/
+    /*  Allocate and initialize data structures                      */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "Allocate the psStats structure.");
+
+    myStats = psStatsAlloc(PS_STAT_SAMPLE_MEAN);
+    myStats->sampleMean = MISC_FLOAT_NUMBER;
+    myStats->sampleMedian = MISC_FLOAT_NUMBER;
+    myStats->sampleStdev = MISC_FLOAT_NUMBER;
+    myStats->sampleUQ = MISC_FLOAT_NUMBER;
+    myStats->sampleLQ = MISC_FLOAT_NUMBER;
+    myStats->sampleLimit = MISC_FLOAT_NUMBER;
+    myStats->robustMean = MISC_FLOAT_NUMBER;
+    myStats->robustMedian = MISC_FLOAT_NUMBER;
+    myStats->robustMode = MISC_FLOAT_NUMBER;
+    myStats->robustStdev = MISC_FLOAT_NUMBER;
+    myStats->robustUQ = MISC_FLOAT_NUMBER;
+    myStats->robustLQ = MISC_FLOAT_NUMBER;
+    myStats->robustN50 = MISC_FLOAT_NUMBER;
+    myStats->robustNfit = MISC_FLOAT_NUMBER;
+    myStats->clippedMean = MISC_FLOAT_NUMBER;
+    myStats->clippedStdev = MISC_FLOAT_NUMBER;
+    myStats->clipSigma = MISC_FLOAT_NUMBER;
+    myStats->clipIter = MISC_FLOAT_NUMBER;
+    myStats->min = MISC_FLOAT_NUMBER;
+    myStats->max = MISC_FLOAT_NUMBER;
+    myStats->binsize = MISC_FLOAT_NUMBER;
+    myStats->options = 0x0;
+
+    psMemCheckCorruption(1);
+
+    printFooter(stdout,
+                "psStats functions",
+                "Allocate the psStats structure.",
+                testStatus);
+
+    /*************************************************************************/
+    /*  Deallocate data structures                                   */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "Deallocate the psStats structure.");
+    psStatsFree(myStats);
+
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,NULL);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+    psMemCheckCorruption(1);
+
+    printFooter(stdout,
+                "psStats functions",
+                "Deallocate the psStats structure.",
+                testStatus);
+
+
+
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "Deallocate NULL psStats structure.");
+    psStatsFree(NULL);
+    printFooter(stdout,
+                "psStats functions",
+                "Deallocate NULL psStats structure.",
+                testStatus);
+
+
+    return (!testStatus);
+}
Index: /tags/rel1_1/psLib/test/dataManip/tst_psStats06.c
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/tst_psStats06.c	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/tst_psStats06.c	(revision 1056)
@@ -0,0 +1,128 @@
+/*****************************************************************************
+    This routine must ensure that PS_STAT_SAMPLE_STDEV is correctly computed
+    by the procedure psArrayStats().
+ *****************************************************************************/
+#include <stdio.h>
+#include "pslib.h"
+#include "psTest.h"
+#include "psTest.h"
+#include "float.h"
+#include <math.h>
+
+#define N 15
+
+int main()
+{
+    psStats *myStats    = NULL;
+    int testStatus      = true;
+    int globalTestStatus = true;
+    int i               = 0;
+    psVector *myVector  = NULL;
+    psVector *maskVector= NULL;
+    float stdev         = 0.0;
+    // NOTE: These values were calculated by running the function on the data.
+    // A: They must be changed if we adjust the number of data points.
+    // B: We don't really know that they are correct.
+    float realStdevNoMask   = 4.472136;
+    float realStdevWithMask = 2.160247;
+    int count           = 0;
+    int currentId       = psMemGetId();
+    int memLeaks        = 0;
+
+    /*************************************************************************/
+    /*  Allocate and initialize data structures                      */
+    /*************************************************************************/
+    myStats = psStatsAlloc(PS_STAT_SAMPLE_STDEV);
+    myVector = psVectorAlloc(N, PS_TYPE_F32);
+    myVector->n = N;
+    maskVector = psVectorAlloc(N, PS_TYPE_U8);
+    maskVector->n = N;
+
+    stdev = 0.0;
+    // Set the appropriate values for the vector data.
+    for (i=0;i<N;i++) {
+        myVector->data.F32[i] = (float) i;
+    }
+
+    // Set the mask vector and calculate the expected maximum.
+    for (i=0;i<N;i++) {
+        if (i < (N/2)) {
+            maskVector->data.U8[i] = 0;
+            count++;
+        } else {
+            maskVector->data.U8[i] = 1;
+        }
+    }
+
+    /*************************************************************************/
+    /*  Call psVectorStats() with no vector mask.                    */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "PS_STAT_SAMPLE_STDEV: no vector mask");
+
+    myStats = psVectorStats(myStats, myVector, NULL, 0);
+    stdev = myStats->sampleStdev;
+
+    printf("Called psVectorStats() on a vector with no elements masked.\n");
+    printf("The expected stdev was %f; the calculated stdev was %f\n",
+           realStdevNoMask, stdev);
+    if (fabs(stdev - realStdevNoMask) <= 2.0 * FLT_EPSILON) {
+        testStatus = true;
+    } else {
+        testStatus = false;
+        globalTestStatus = false;
+    }
+    printFooter(stdout,
+                "psVector functions",
+                "PS_STAT_SAMPLE_STDEV: no vector mask",
+                testStatus);
+
+    /*************************************************************************/
+    /*  Call psVectorStats() with vector mask.                       */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "PS_STAT_SAMPLE_STDEV: with vector mask");
+
+    myStats = psVectorStats(myStats, myVector, maskVector, 1);
+    stdev = myStats->sampleStdev;
+    printf("Called psVectorStats() on a vector with last N/2 elements masked.\n");
+    printf("The expected stdev was %f; the calculated stdev was %f\n",
+           realStdevWithMask, stdev);
+    if (fabs(stdev - realStdevWithMask) <= 2.0 * FLT_EPSILON) {
+        testStatus = true;
+    } else {
+        testStatus = false;
+        globalTestStatus = false;
+    }
+
+    printFooter(stdout,
+                "psVector functions",
+                "PS_STAT_SAMPLE_STDEV: with vector mask",
+                testStatus);
+
+    /*************************************************************************/
+    /*  Deallocate data structures                                   */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "psStats(): deallocating memory");
+
+    psStatsFree(myStats);
+    psVectorFree(myVector);
+    psVectorFree(maskVector);
+
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,NULL);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psVector functions",
+                "psStats(): deallocating memory",
+                testStatus);
+
+    return (!globalTestStatus);
+}
Index: /tags/rel1_1/psLib/test/dataManip/tst_psStats07.c
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/tst_psStats07.c	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/tst_psStats07.c	(revision 1056)
@@ -0,0 +1,413 @@
+/*****************************************************************************
+    This routine must ensure that PS_STAT_ROBUST_QUARTILE is correctly computed
+    by the procedure psArrayStats().
+ *****************************************************************************/
+#include <stdio.h>
+#include "pslib.h"
+#include "psTest.h"
+#include "psTest.h"
+#include "float.h"
+#include <math.h>
+
+#define N 15
+
+int main()
+{
+    psStats *myStats    = NULL;
+    int testStatus      = true;
+    int globalTestStatus = true;
+    int i               = 0;
+    psVector *myVector  = NULL;
+    psVector *maskVector= NULL;
+    // NOTE: These values were calculated by running the function on the data.
+    // A: They must be changed if we adjust the number of data points.
+    // B: We don't really know that they are correct.
+    float realMeanNoMask   = 0.0;
+    float realMedianNoMask = 0.0;
+    float realModeNoMask   = -1.0;
+    float realStdevNoMask  = 0.0;
+    float realLQNoMask     = 0.0;
+    float realUQNoMask     = 0.0;
+    float realN50NoMask    = 0.0;
+    float realNfitNoMask   = 0.0;
+    float realMeanWithMask   = 0.0;
+    float realMedianWithMask = 0.0;
+    float realModeWithMask   = 40.0;
+    float realStdevWithMask  = 0.0;
+    float realLQWithMask     = 0.0;
+    float realUQWithMask     = 0.0;
+    float realN50WithMask    = 0.0;
+    float realNfitWithMask   = 0.0;
+    int count           = 0;
+    int currentId       = psMemGetId();
+    int memLeaks        = 0;
+
+    /*************************************************************************/
+    /*  Allocate and initialize data structures                      */
+    /*************************************************************************/
+    myStats = psStatsAlloc(PS_STAT_ROBUST_MEAN |
+                           PS_STAT_ROBUST_MEDIAN |
+                           PS_STAT_ROBUST_MODE |
+                           PS_STAT_ROBUST_STDEV |
+                           PS_STAT_ROBUST_QUARTILE);
+
+    myVector = psVectorAlloc(N, PS_TYPE_F32);
+    myVector->n = N;
+    maskVector = psVectorAlloc(N, PS_TYPE_U8);
+    maskVector->n = N;
+
+    // Set the appropriate values for the vector data.
+    for (i=0;i<N;i++) {
+        myVector->data.F32[i] = (float) i;
+    }
+
+    // Set the mask vector and calculate the expected maximum.
+    for (i=0;i<N;i++) {
+        if (i < (N/2)) {
+            maskVector->data.U8[i] = 0;
+            count++;
+        } else {
+            maskVector->data.U8[i] = 1;
+        }
+    }
+
+    /*************************************************************************/
+    /*  Call psVectorStats() with no vector mask.                    */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "PS_STAT_ROBUST_STATS: robust mean: no vector mask");
+
+    printf("Calling psVectorStats() on a vector with no elements masked.\n");
+    myStats = psVectorStats(myStats, myVector, NULL, 0);
+    printf("Called psVectorStats() on a vector with no elements masked.\n");
+
+    printf("The expected Mean was %f; the calculated Mean was %f\n",
+           realMeanNoMask, myStats->robustMean);
+    if (fabs(myStats->robustMean - realMeanNoMask) <= 2.0 * FLT_EPSILON) {
+        testStatus = true;
+    } else {
+        testStatus = false;
+        globalTestStatus = false;
+    }
+    printFooter(stdout,
+                "psVector functions",
+                "PS_STAT_ROBUST_STATS: robust mean: no vector mask",
+                testStatus);
+
+
+
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "PS_STAT_ROBUST_STATS: robust Median: no vector mask");
+
+    printf("The expected Median was %f; the calculated Median was %f\n",
+           realMedianNoMask, myStats->robustMedian);
+    if (fabs(myStats->robustMedian - realMedianNoMask) <= 2.0 * FLT_EPSILON) {
+        testStatus = true;
+    } else {
+        testStatus = false;
+        globalTestStatus = false;
+    }
+    printFooter(stdout,
+                "psVector functions",
+                "PS_STAT_ROBUST_STATS: robust Median: no vector mask",
+                testStatus);
+
+
+
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "PS_STAT_ROBUST_STATS: robust Mode: no vector mask");
+
+    printf("The expected Mode was %f; the calculated Mode was %f\n",
+           realModeNoMask, myStats->robustMode);
+    if (fabs(myStats->robustMode - realModeNoMask) <= 2.0 * FLT_EPSILON) {
+        testStatus = true;
+    } else {
+        testStatus = false;
+        globalTestStatus = false;
+    }
+    printFooter(stdout,
+                "psVector functions",
+                "PS_STAT_ROBUST_STATS: robust Mode: no vector mask",
+                testStatus);
+
+
+
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "PS_STAT_ROBUST_STATS: robust Stdev: no vector mask");
+
+    printf("The expected Stdev was %f; the calculated Stdev was %f\n",
+           realStdevNoMask, myStats->robustStdev);
+    if (fabs(myStats->robustStdev - realStdevNoMask) <= 2.0 * FLT_EPSILON) {
+        testStatus = true;
+    } else {
+        testStatus = false;
+        globalTestStatus = false;
+    }
+    printFooter(stdout,
+                "psVector functions",
+                "PS_STAT_ROBUST_STATS: robust Stdev: no vector mask",
+                testStatus);
+
+
+
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "PS_STAT_ROBUST_STATS: lower quartile: no vector mask");
+
+    printf("The expected LQ was %f; the calculated LQ was %f\n",
+           realLQNoMask, myStats->robustLQ);
+    if (fabs(myStats->robustLQ - realLQNoMask) <= 2.0 * FLT_EPSILON) {
+        testStatus = true;
+    } else {
+        testStatus = false;
+        globalTestStatus = false;
+    }
+    printFooter(stdout,
+                "psVector functions",
+                "PS_STAT_ROBUST_STATS: lower quartile: no vector mask",
+                testStatus);
+
+
+
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "PS_STAT_ROBUST_STATS: upper quartile: no vector mask");
+
+    printf("The expected UQ was %f; the calculated UQ was %f\n",
+           realUQNoMask, myStats->robustUQ);
+    if (fabs(myStats->robustUQ - realUQNoMask) <= 2.0 * FLT_EPSILON) {
+        testStatus = true;
+    } else {
+        testStatus = false;
+        globalTestStatus = false;
+    }
+    printFooter(stdout,
+                "psVector functions",
+                "PS_STAT_ROBUST_STATS: lower quartile: no vector mask",
+                testStatus);
+
+
+
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "PS_STAT_ROBUST_STATS: robust N50: no vector mask");
+
+    printf("The expected N50 was %f; the calculated N50 was %f\n",
+           realN50NoMask, myStats->robustN50);
+    if (fabs(myStats->robustN50 - realN50NoMask) <= 2.0 * FLT_EPSILON) {
+        testStatus = true;
+    } else {
+        testStatus = false;
+        globalTestStatus = false;
+    }
+    printFooter(stdout,
+                "psVector functions",
+                "PS_STAT_ROBUST_STATS: robust N50: no vector mask",
+                testStatus);
+
+
+
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "PS_STAT_ROBUST_STATS: robust Nfit: no vector mask");
+
+    printf("The expected Nfit was %f; the calculated Nfit was %f\n",
+           realNfitNoMask, myStats->robustNfit);
+    if (fabs(myStats->robustNfit - realNfitNoMask) <= 2.0 * FLT_EPSILON) {
+        testStatus = true;
+    } else {
+        testStatus = false;
+        globalTestStatus = false;
+    }
+    printFooter(stdout,
+                "psVector functions",
+                "PS_STAT_ROBUST_STATS: robust Nfit: no vector mask",
+                testStatus);
+
+
+    /*************************************************************************/
+    /*  Call psVectorStats() with vector mask.                       */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "PS_STAT_ROBUST_STATS: robust mean: with vector mask");
+
+    printf("Calling psVectorStats() on a vector with elements masked.\n");
+    myStats = psVectorStats(myStats, myVector, maskVector, 1);
+    printf("Called psVectorStats() on a vector with elements masked.\n");
+    printf("The expected Mean was %f; the calculated Mean was %f\n",
+           realMeanWithMask, myStats->robustMean);
+    if (fabs(myStats->robustMean - realMeanWithMask) <= 2.0 * FLT_EPSILON) {
+        testStatus = true;
+    } else {
+        testStatus = false;
+        globalTestStatus = false;
+    }
+    printFooter(stdout,
+                "psVector functions",
+                "PS_STAT_ROBUST_STATS: robust mean: with vector mask",
+                testStatus);
+
+
+
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "PS_STAT_ROBUST_STATS: robust Median: with vector mask");
+
+    printf("The expected Median was %f; the calculated Median was %f\n",
+           realMedianWithMask, myStats->robustMedian);
+    if (fabs(myStats->robustMedian - realMedianWithMask) <= 2.0 * FLT_EPSILON) {
+        testStatus = true;
+    } else {
+        testStatus = false;
+        globalTestStatus = false;
+    }
+    printFooter(stdout,
+                "psVector functions",
+                "PS_STAT_ROBUST_STATS: robust Median: with vector mask",
+                testStatus);
+
+
+
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "PS_STAT_ROBUST_STATS: robust Mode: with vector mask");
+
+    printf("The expected Mode was %f; the calculated Mode was %f\n",
+           realModeWithMask, myStats->robustMode);
+    if (fabs(myStats->robustMode - realModeWithMask) <= 2.0 * FLT_EPSILON) {
+        testStatus = true;
+    } else {
+        testStatus = false;
+        globalTestStatus = false;
+    }
+    printFooter(stdout,
+                "psVector functions",
+                "PS_STAT_ROBUST_STATS: robust Mode: with vector mask",
+                testStatus);
+
+
+
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "PS_STAT_ROBUST_STATS: robust Stdev: with vector mask");
+
+    printf("The expected Stdev was %f; the calculated Stdev was %f\n",
+           realStdevWithMask, myStats->robustStdev);
+    if (fabs(myStats->robustStdev - realStdevWithMask) <= 2.0 * FLT_EPSILON) {
+        testStatus = true;
+    } else {
+        testStatus = false;
+        globalTestStatus = false;
+    }
+    printFooter(stdout,
+                "psVector functions",
+                "PS_STAT_ROBUST_STATS: robust Stdev: with vector mask",
+                testStatus);
+
+
+
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "PS_STAT_ROBUST_STATS: lower quartile: with vector mask");
+
+    printf("The expected LQ was %f; the calculated LQ was %f\n",
+           realLQWithMask, myStats->robustLQ);
+    if (fabs(myStats->robustLQ - realLQWithMask) <= 2.0 * FLT_EPSILON) {
+        testStatus = true;
+    } else {
+        testStatus = false;
+        globalTestStatus = false;
+    }
+    printFooter(stdout,
+                "psVector functions",
+                "PS_STAT_ROBUST_STATS: lower quartile: with vector mask",
+                testStatus);
+
+
+
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "PS_STAT_ROBUST_STATS: upper quartile: with vector mask");
+
+    printf("The expected UQ was %f; the calculated UQ was %f\n",
+           realUQWithMask, myStats->robustUQ);
+    if (fabs(myStats->robustUQ - realUQWithMask) <= 2.0 * FLT_EPSILON) {
+        testStatus = true;
+    } else {
+        testStatus = false;
+        globalTestStatus = false;
+    }
+    printFooter(stdout,
+                "psVector functions",
+                "PS_STAT_ROBUST_STATS: lower quartile: with vector mask",
+                testStatus);
+
+
+
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "PS_STAT_ROBUST_STATS: robust N50: with vector mask");
+
+    printf("The expected N50 was %f; the calculated N50 was %f\n",
+           realN50WithMask, myStats->robustN50);
+    if (fabs(myStats->robustN50 - realN50WithMask) <= 2.0 * FLT_EPSILON) {
+        testStatus = true;
+    } else {
+        testStatus = false;
+        globalTestStatus = false;
+    }
+    printFooter(stdout,
+                "psVector functions",
+                "PS_STAT_ROBUST_STATS: robust N50: with vector mask",
+                testStatus);
+
+
+
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "PS_STAT_ROBUST_STATS: robust Nfit: with vector mask");
+
+    printf("The expected Nfit was %f; the calculated Nfit was %f\n",
+           realNfitWithMask, myStats->robustNfit);
+    if (fabs(myStats->robustNfit - realNfitWithMask) <= 2.0 * FLT_EPSILON) {
+        testStatus = true;
+    } else {
+        testStatus = false;
+        globalTestStatus = false;
+    }
+    printFooter(stdout,
+                "psVector functions",
+                "PS_STAT_ROBUST_STATS: robust Nfit: with vector mask",
+                testStatus);
+
+
+
+    /*************************************************************************/
+    /*  Deallocate data structures                                   */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "psStats(): deallocating memory");
+
+    psStatsFree(myStats);
+    psVectorFree(myVector);
+    psVectorFree(maskVector);
+
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,NULL);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psVector functions",
+                "psStats(): deallocating memory",
+                testStatus);
+
+    return (!globalTestStatus);
+}
Index: /tags/rel1_1/psLib/test/dataManip/tst_psStats08.c
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/tst_psStats08.c	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/tst_psStats08.c	(revision 1056)
@@ -0,0 +1,172 @@
+/*****************************************************************************
+    This routine must ensure that PS_STAT_SAMPLE_QUARTILE is correctly computed
+    by the procedure psArrayStats().
+ *****************************************************************************/
+#include <stdio.h>
+#include "pslib.h"
+#include "psTest.h"
+#include "psTest.h"
+#include "float.h"
+#include <math.h>
+
+#define N1 25  //
+#define N (8 * N1) // Don't change this (N must be a multiple of 8)
+
+int main()
+{
+    psStats *myStats    = NULL;
+    int testStatus      = true;
+    int globalTestStatus = true;
+    int i               = 0;
+    psVector *myVector  = NULL;
+    psVector *maskVector= NULL;
+    // NOTE: These values were calculated by running the function on the data.
+    // A: They must be changed if we adjust the number of data points.
+    // B: We don't really know that they are correct.
+    float realLQNoMask   = N/4.0;
+    float realUQNoMask   = 3.0 * (N/4.0);
+    float realLQWithMask   = N/8.0;
+    float realUQWithMask   = 3.0 * (N/8.0);
+    int count           = 0;
+    int currentId       = psMemGetId();
+    int memLeaks        = 0;
+
+    /*************************************************************************/
+    /*  Allocate and initialize data structures                      */
+    /*************************************************************************/
+    myStats = psStatsAlloc(PS_STAT_SAMPLE_QUARTILE);
+    myVector = psVectorAlloc(N, PS_TYPE_F32);
+    myVector->n = N;
+    maskVector = psVectorAlloc(N, PS_TYPE_U8);
+    maskVector->n = N;
+
+    // Set the appropriate values for the vector data.
+    for (i=0;i<N;i++) {
+        myVector->data.F32[i] = (float) i;
+    }
+
+    // Set the mask vector and calculate the expected maximum.
+    for (i=0;i<N;i++) {
+        if (i < (N/2)) {
+            maskVector->data.U8[i] = 0;
+            count++;
+        } else {
+            maskVector->data.U8[i] = 1;
+        }
+    }
+
+    /*************************************************************************/
+    /*  Call psVectorStats() with no vector mask.                    */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "PS_STAT_SAMPLE_LQ: no vector mask");
+
+    myStats = psVectorStats(myStats, myVector, NULL, 0);
+
+    printf("Called psVectorStats() on a vector with no elements masked.\n");
+    printf("The expected sampleLQ was %f; the calculated sampleLQ was %f\n",
+           realLQNoMask, myStats->sampleLQ);
+    if (fabs(realLQNoMask - myStats->sampleLQ) <= 2.0 * FLT_EPSILON) {
+        testStatus = true;
+    } else {
+        testStatus = false;
+        globalTestStatus = false;
+    }
+    printFooter(stdout,
+                "psVector functions",
+                "PS_STAT_SAMPLE_LQ: no vector mask",
+                testStatus);
+
+
+
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "PS_STAT_SAMPLE_UQ: no vector mask");
+
+    myStats = psVectorStats(myStats, myVector, NULL, 0);
+
+    printf("Called psVectorStats() on a vector with no elements masked.\n");
+    printf("The expected sampleUQ was %f; the calculated sampleUQ was %f\n",
+           realUQNoMask, myStats->sampleUQ);
+    if (fabs(realUQNoMask - myStats->sampleUQ) <= 2.0 * FLT_EPSILON) {
+        testStatus = true;
+    } else {
+        testStatus = false;
+        globalTestStatus = false;
+    }
+    printFooter(stdout,
+                "psVector functions",
+                "PS_STAT_SAMPLE_UQ: no vector mask",
+                testStatus);
+
+    /*************************************************************************/
+    /*  Call psVectorStats() with vector mask.                       */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "PS_STAT_SAMPLE_LQ: with vector mask");
+
+    myStats = psVectorStats(myStats, myVector, maskVector, 1);
+
+    printf("Called psVectorStats() on a vector with elements masked.\n");
+    printf("The expected sampleLQ was %f; the calculated sampleLQ was %f\n",
+           realLQWithMask, myStats->sampleLQ);
+    if (fabs(realLQWithMask - myStats->sampleLQ) <= 2.0 * FLT_EPSILON) {
+        testStatus = true;
+    } else {
+        testStatus = false;
+        globalTestStatus = false;
+    }
+    printFooter(stdout,
+                "psVector functions",
+                "PS_STAT_SAMPLE_LQ: with vector mask",
+                testStatus);
+
+
+
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "PS_STAT_SAMPLE_UQ: with vector mask");
+
+    myStats = psVectorStats(myStats, myVector, maskVector, 1);
+
+    printf("Called psVectorStats() on a vector with elements masked.\n");
+    printf("The expected sampleUQ was %f; the calculated sampleUQ was %f\n",
+           realUQWithMask, myStats->sampleUQ);
+    if (fabs(realUQWithMask - myStats->sampleUQ) <= 2.0 * FLT_EPSILON) {
+        testStatus = true;
+    } else {
+        testStatus = false;
+        globalTestStatus = false;
+    }
+    printFooter(stdout,
+                "psVector functions",
+                "PS_STAT_SAMPLE_UQ: with vector mask",
+                testStatus);
+
+
+    /*************************************************************************/
+    /*  Deallocate data structures                                   */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "psStats(): deallocating memory");
+
+    psStatsFree(myStats);
+    psVectorFree(myVector);
+    psVectorFree(maskVector);
+
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,NULL);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psVector functions",
+                "psStats(): deallocating memory",
+                testStatus);
+
+    return (!globalTestStatus);
+}
Index: /tags/rel1_1/psLib/test/dataManip/tst_psStats09.c
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/tst_psStats09.c	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/tst_psStats09.c	(revision 1056)
@@ -0,0 +1,146 @@
+/*****************************************************************************
+    This routine must ensure that PS_STAT_CLIPPED_MEAN and
+    PS_STAT_CLIPPED_STDEV is calculate correctly by the procedure
+    psVectorStats().
+ *****************************************************************************/
+#include <stdio.h>
+#include "pslib.h"
+#include "psTest.h"
+#include "psTest.h"
+#include "psImageStats.h"
+#include "float.h"
+#include <math.h>
+
+#define N 500
+#define MY_MEAN  30.0
+#define MY_RANGE 2.0
+
+int main()
+{
+    psStats *myStats    = NULL;
+    int testStatus      = true;
+    int globalTestStatus = true;
+    int i               = 0;
+    psVector *maskVector= NULL;
+    psVector *myGaussData  = NULL;
+    // NOTE: These values were calculated by running the function on the data.
+    // A: They must be changed if we adjust the number of data points.
+    // B: We don't really know that they are correct.
+    //    float realclippedMeanNoMask  = 0.0;
+    //    float realclippedStdevNoMask = 0.0;
+    //    float realclippedMeanWithMask  = 0.0;
+    //    float realclippedStdevWithMask = 0.0;
+    int count           = 0;
+    int currentId       = psMemGetId();
+    int memLeaks        = 0;
+
+    /*************************************************************************/
+    /*  Allocate and initialize data structures                      */
+    /*************************************************************************/
+    myStats = psStatsAlloc(PS_STAT_CLIPPED_MEAN |
+                           PS_STAT_CLIPPED_STDEV);
+
+    myGaussData = psVectorAlloc(N, PS_TYPE_F32);
+    myGaussData->n = myGaussData->nalloc;
+    for (i=0;i<N;i++) {
+        myGaussData->data.F32[i] = MY_MEAN - (MY_RANGE/1.9) +
+                                   (MY_RANGE) * ((float) i) / ((float) N);
+    }
+
+    maskVector = psVectorAlloc(N, PS_TYPE_U8);
+    maskVector->n = N;
+
+    // Set the mask vector and calculate the expected maximum.
+    for (i=0;i<N;i++) {
+        if (i < (N/2)) {
+            maskVector->data.U8[i] = 0;
+            count++;
+        } else {
+            maskVector->data.U8[i] = 1;
+        }
+    }
+
+    /*************************************************************************/
+    /*  Call psVectorStats() with no vector mask.                    */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "PS_STAT_CLIPPED_MEAN: no vector mask");
+
+    myStats = psVectorStats(myStats, myGaussData, NULL, 0);
+
+    printf("Called psVectorStats() on a vector with no elements masked.\n");
+    printf("The calculated clippedMean was %f\n", myStats->clippedMean);
+
+    printFooter(stdout,
+                "psVector functions",
+                "PS_STAT_CLIPPED_MEAN/STDEV: no vector mask",
+                testStatus);
+
+
+
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "PS_STAT_CLIPPED_STDEV: no vector mask");
+
+    printf("Called psVectorStats() on a vector with no elements masked.\n");
+    printf("The calculated clippedStdev was %f\n", myStats->clippedStdev);
+
+    printFooter(stdout,
+                "psVector functions",
+                "PS_STAT_CLIPPED_MEAN/STDEV: no vector mask",
+                testStatus);
+
+    /*************************************************************************/
+    /*  Call psVectorStats() with vector mask.                       */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "PS_STAT_CLIPPED_MEAN: vector mask");
+
+    myStats = psVectorStats(myStats, myGaussData, maskVector, 1);
+
+    printf("Called psVectorStats() on a vector with elements masked.\n");
+    printf("The calculated clippedMean was %f\n", myStats->clippedMean);
+    printFooter(stdout,
+                "psVector functions",
+                "PS_STAT_CLIPPED_MEAN/STDEV: vector mask",
+                testStatus);
+
+
+
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "PS_STAT_CLIPPED_STDEV: vector mask");
+
+    printf("Called psVectorStats() on a vector with elements masked.\n");
+    printf("The calculated clippedStdev was %f\n", myStats->clippedStdev);
+    printFooter(stdout,
+                "psVector functions",
+                "PS_STAT_CLIPPED_MEAN/STDEV: vector mask",
+                testStatus);
+
+    /*************************************************************************/
+    /*  Deallocate data structures                                   */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "psStats(): deallocating memory");
+
+    psStatsFree(myStats);
+    psVectorFree(myGaussData);
+    psVectorFree(maskVector);
+
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,NULL);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psVector functions",
+                "psStats(): deallocating memory",
+                testStatus);
+
+    return (!globalTestStatus);
+}
Index: /tags/rel1_1/psLib/test/dataManip/tst_psVectorFFT.c
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/tst_psVectorFFT.c	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/tst_psVectorFFT.c	(revision 1056)
@@ -0,0 +1,380 @@
+/** @file  tst_psVectorFFT.c
+ *
+ *  @brief Contains the tests for psFFT.[ch]
+ *
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.1 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-12 01:34:10 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include <math.h>
+#include <float.h>
+
+#include "psTest.h"
+#include "pslib.h"
+
+#define GENIMAGE(img,c,r,TYP, valueFcn) \
+img = psImageAlloc(c,r,PS_TYPE_##TYP); \
+for (unsigned int row=0;row<r;row++) { \
+    ps##TYP* imgRow = img->data.TYP[row]; \
+    for (unsigned int col=0;col<c;col++) { \
+        imgRow[col] = (ps##TYP)(valueFcn); \
+    } \
+}
+
+static int testVectorFFT(void);
+static int testVectorRealImaginary(void);
+static int testVectorComplex(void);
+static int testVectorConjugate(void);
+static int testVectorPowerSpectrum(void);
+
+testDescription tests[] = {
+                              {testVectorFFT,"600-testVectorFFT",0},
+                              {testVectorRealImaginary,"601-testVectorRealImaginary",0},
+                              {testVectorComplex,"602-testVectorComplex",0},
+                              {testVectorConjugate,"603-testVectorConjugate",0},
+                              {testVectorPowerSpectrum,"604-testVectorPowerSpectrum",0},
+                              {NULL}
+                          };
+
+int main()
+{
+    psLogSetLevel(PS_LOG_INFO);
+
+    if (! runTestSuite(stderr,"psFFT",tests)) {
+        psAbort(__FILE__,"One or more tests failed");
+    }
+    return 0;
+}
+
+int testVectorFFT(void)
+{
+    psVector* vec = NULL;
+    psVector* vec2 = NULL;
+    psVector* vec3 = NULL;
+
+    /*
+    1. assign a vector to a sinisoid
+    2. perform a forward transform
+    3. verify that the only significant component cooresponds to the freqency of the input in step 1.
+    4. perform a reverse transform
+    5. compare to original (should be equal to within a reasonable error)
+    */
+
+    // 1. assign a vector to a sinisoid
+    vec=psVectorAlloc(100,PS_TYPE_F32);
+    vec->n = vec->nalloc;
+    for (unsigned int n = 0; n<100; n++) {
+        vec->data.F32[n] = sinf((psF32)n / 50.0f * M_PI);
+    }
+
+    // 2. perform a forward transform
+    vec2 = psVectorFFT(NULL,vec,PS_FFT_FORWARD);
+    if (vec2->type.type != PS_TYPE_C32) {
+        psError(__func__,"FFT didn't produce complex values?");
+        return 1;
+    }
+
+
+    // 3. verify that the only significant component cooresponds to the freqency of the input in step 1.
+    for (unsigned int n = 0; n<100; n++) {
+        if (n==1 || n==99) {
+            if (fabsf(cabsf(vec2->data.C32[n]) - 50.0f) > 0.1f) {
+                psError(__func__,"FFT didn't work for vector (n=%d)",n);
+                return 2;
+            }
+        } else {
+            if (fabsf(cabsf(vec2->data.C32[n])) > 0.1f) {
+                psError(__func__,"FFT didn't work for vector (n=%d)",n);
+                return 3;
+            }
+        }
+    }
+
+    // 4. perform a reverse transform
+    vec3 = psVectorFFT(NULL,vec2,PS_FFT_REVERSE);
+    if (vec3->type.type != PS_TYPE_C32) {
+        psError(__func__,"FFT didn't produce complex values?");
+        return 4;
+    }
+    for (unsigned int n = 0; n<100; n++) {
+        psF32 val =sinf((psF32)n / 50.0f * M_PI);
+        psF32 vecVal = crealf(vec3->data.C32[n])/100;
+        if (fabsf(vecVal - val) > 0.1f) {
+            psError(__func__,"Reverse FFT didn't give me the original vector back (n=%d) (%.2f vs %.2f)",
+                    n,vecVal,val);
+            return 5;
+        }
+    }
+
+    psVectorFree(vec);
+    psVectorFree(vec2);
+    psVectorFree(vec3);
+
+    return 0;
+}
+
+int testVectorRealImaginary(void)
+{
+    psVector* vec = NULL;
+    psVector* vec2 = NULL;
+    psVector* vec3 = NULL;
+
+    /*
+    1. create a C32 complex vector with distinctly different real and imaginary parts.
+    2. call psVectorReal and psVectorImaginary
+    3. compare results to the real/imaginary components of input
+    */
+
+    // 1. create a C32 complex vector with distinctly different real and imaginary parts.
+    vec=psVectorAlloc(100,PS_TYPE_C32);
+    vec->n = vec->nalloc;
+    for (unsigned int n = 0; n<100; n++) {
+        vec->data.C32[n] = n + I * (n*2);
+    }
+
+    // 2. call psVectorReal and psVectorImaginary
+    vec2 = psVectorReal(vec2,vec);
+    if (vec2 == NULL) {
+        psError(__func__,"psVectorReal returned a NULL?");
+        return 1;
+    }
+    if (vec2->type.type != PS_TYPE_F32) {
+        psError(__func__,"psVectorReal returned a wrong type (%d)?",
+                vec2->type.type);
+        return 2;
+    }
+
+    vec3 = psVectorImaginary(vec3,vec);
+    if (vec3 == NULL) {
+        psError(__func__,"psVectorImaginary returned a NULL?");
+        return 3;
+    }
+    if (vec3->type.type != PS_TYPE_F32) {
+        psError(__func__,"psVectorImaginary returned a wrong type (%d)?",
+                vec3->type.type);
+        return 4;
+    }
+
+    // 3. compare results to the real/imaginary components of input
+    for (unsigned int n = 0; n<100; n++) {
+        psF32 r = n;
+        psF32 i = (n*2);
+        if (fabsf(vec2->data.F32[n] -r) > FLT_EPSILON) {
+            psError(__func__,"psVectorReal didn't return the real portion at n=%d",
+                    n);
+            return 5;
+        }
+        if (fabsf(vec3->data.F32[n] -i) > FLT_EPSILON) {
+            psError(__func__,"psVectorImaginary didn't return the real portion at n=%d",
+                    n);
+            return 6;
+        }
+    }
+
+    psVectorFree(vec);
+    psVectorFree(vec2);
+    psVectorFree(vec3);
+
+    return 0;
+}
+
+int testVectorComplex(void)
+{
+    psVector* vec = NULL;
+    psVector* vec2 = NULL;
+    psVector* vec3 = NULL;
+
+    /*
+    1. create two unique psF32 vectors of the same size
+    2. call psVectorComplex
+    3. verify that the result is a psC32
+    4. call psVectorReal and psVectorImaginary on step 2 results
+    5. compare step 4 results to input.
+
+    6. create a psF32 and a psF64 vector of the same size
+    7. call psVectorComplex
+    8. verify that an appropriate error occurred.
+
+    9. create two psf32 vectors of different sizes
+    10. call psVectorComplex
+    11. verify thet an appropriate error occurred.
+    */
+
+    // 1. create two unique psF32 vectors of the same size
+    vec=psVectorAlloc(100,PS_TYPE_F32);
+    vec2=psVectorAlloc(100,PS_TYPE_F32);
+    vec->n = vec->nalloc;
+    vec2->n = vec2->nalloc;
+    for (unsigned int n = 0; n<100; n++) {
+        vec->data.F32[n] = n;
+        vec2->data.F32[n] = (n*2);
+    }
+
+    // 2. call psVectorComplex
+    vec3 = psVectorComplex(vec3,vec,vec2);
+
+    // 3. verify that the result is a psC32
+    if (vec3->type.type != PS_TYPE_C32) {
+        psError(__func__,"Vector Type from psVectorComplex is not complex? (%d)",
+                vec3->type.type);
+        return 1;
+    }
+
+    // 4. call psVectorReal and psVectorImaginary on step 2 results (not needed, just use crealf/cimagf)
+    // 5. compare step 4 results to input.
+    for (unsigned int n = 0; n<100; n++) {
+        if (fabsf(crealf(vec3->data.C32[n]) - n) > FLT_EPSILON ||
+                fabsf(cimagf(vec3->data.C32[n]) - (n*2)) > FLT_EPSILON) {
+            psError(__func__,"psVectorComplex result is invalid (n=%d, %.2f+%.2fi)",
+                    n,crealf(vec3->data.C32[n]),cimagf(vec3->data.C32[n]));
+            return 2;
+        };
+    }
+
+
+    // 6. create a psF32 and a psF64 vector of the same size
+    vec2 = psVectorRecycle(vec2,PS_TYPE_F64, 100);
+
+    // 7. call psVectorComplex
+    psLogMsg(__func__,PS_LOG_INFO, "Following should be an error (type mismatch).");
+    vec3 = psVectorComplex(vec3,vec,vec2);
+    // 8. verify that an appropriate error occurred. (this partially has to be done via inspection)
+    if (vec3 != NULL) {
+        psError(__func__,"psVectorComplex returned a vector though input types mismatched.");
+        return 3;
+    }
+
+    // 9. create two psf32 vectors of different sizes
+    vec2 = psVectorRecycle(vec2,PS_TYPE_F32,200);
+
+    // 10. call psVectorComplex
+    vec3 = psVectorComplex(vec3,vec,vec2);
+
+    // 11. verify thet an appropriate error occurred. (actually, it isn't an error...)
+    if (vec3->n != 100) {
+        psError(__func__,"psVectorComplex returned a vector though input sizes mismatched.");
+        return 4;
+    }
+
+    psVectorFree(vec);
+    psVectorFree(vec2);
+    psVectorFree(vec3);
+
+    return 0;
+}
+
+int testVectorConjugate(void)
+{
+    psVector* vec = NULL;
+    psVector* vec2 = NULL;
+
+    /*
+    1. create a psC32 with unique real and imaginary values.
+    2. call psVectorConjugate
+    3. verify result is psC32
+    4. verify each value is conjugate of input (a+bi -> a-bi)
+    */
+
+    // 1. create a psC32 with unique real and imaginary values.
+    vec=psVectorAlloc(100,PS_TYPE_C32);
+    vec->n = vec->nalloc;
+    for (unsigned int n = 0; n<100; n++) {
+        vec->data.C32[n] = n + I * (n*2);
+    }
+
+    // 2. call psVectorConjugate
+    vec2 = psVectorConjugate(vec2,vec);
+
+    // 3. verify result is psC32
+    if (vec2->type.type != PS_TYPE_C32) {
+        psError(__func__,"the psVectorConjugate didn't return a C32 vector");
+        return 1;
+    }
+
+    // 4. verify each value is conjugate of input (a+bi -> a-bi)
+    for (unsigned int n = 0; n<100; n++) {
+        if (fabsf(crealf(vec->data.C32[n]) - crealf(vec2->data.C32[n])) > FLT_EPSILON ||
+                fabsf(cimagf(vec->data.C32[n]) + cimagf(vec2->data.C32[n])) > FLT_EPSILON) {
+            psError(__func__,"psVectorComplex result is invalid (n=%d, %.2f+%.2fi)",
+                    n,crealf(vec2->data.C32[n]),cimagf(vec2->data.C32[n]));
+            return 2;
+        };
+    }
+
+    psVectorFree(vec);
+    psVectorFree(vec2);
+
+    return 0;
+}
+
+int testVectorPowerSpectrum(void)
+{
+    psVector* vec = NULL;
+    psVector* vec2 = NULL;
+    psF32 val;
+
+    /*
+    1. create a psC32 vector with unique real and imaginary components
+    2. call psVectorPowerSpectrum
+    3. verify result is psF32
+    4. verify the values are the square of the absolute values of the original
+    */
+
+    // 1. create a psC32 vector with unique real and imaginary components
+    vec=psVectorAlloc(100,PS_TYPE_C32);
+    vec->n = vec->nalloc;
+    for (unsigned int n = 0; n<100; n++) {
+        vec->data.C32[n] = n + I * sinf(((psF32)n) / 50.f * M_PI);
+    }
+
+    // 2. call psVectorPowerSpectrum
+    vec2 = psVectorPowerSpectrum(vec2,vec);
+
+    // 3. verify result is psF32
+    if (vec2->type.type != PS_TYPE_F32) {
+        psError(__func__,"the type was not PS_TYPE_F32.");
+        return 1;
+    }
+
+    // 4. verify the values are the square of the absolute values of the original
+    //   (ADD specifies something else)
+    //   P_0 = |C_0|^2/N^2
+    //   P_j = (|C_j|^2+|C_N-j|^2)/N^2
+    //   P_N/2 = |C_N/2|^2/N^2
+    //  where j = 1,2,...,(N/2-1)
+
+    val = cabsf(vec->data.C32[0])*cabsf(vec->data.C32[0])/100/100;
+    if (fabsf(vec2->data.F32[0] - val) > FLT_EPSILON) {
+        psError(__func__,"psVectorPowerSpectrum result is invalid (n=0, %.2f %.2f)",
+                vec2->data.F32[0],val);
+        return 2;
+    };
+
+    for (unsigned int n = 1; n<50; n++) {
+        val = ( cabsf(vec->data.C32[n])*cabsf(vec->data.C32[n])+
+                cabsf(vec->data.C32[100-n])*cabsf(vec->data.C32[100-n]) ) /100/100;
+
+        if (fabsf(val - vec2->data.F32[n]) > FLT_EPSILON) {
+            psError(__func__,"psVectorPowerSpectrum result is invalid (n=%d, %.2f %.2f)",
+                    n,vec2->data.F32[n],val);
+            return 2;
+        };
+    }
+
+    val = cabsf(vec->data.C32[50])*cabsf(vec->data.C32[50])/100/100;
+    if (fabsf(vec2->data.F32[50] - val) > FLT_EPSILON) {
+        psError(__func__,"psVectorPowerSpectrum result is invalid (n=50, %.2f %.2f)",
+                vec2->data.F32[0],val);
+        return 2;
+    };
+
+    psVectorFree(vec);
+    psVectorFree(vec2);
+
+    return 0;
+}
Index: /tags/rel1_1/psLib/test/dataManip/verified/tst_psFunc00.stdout
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/verified/tst_psFunc00.stdout	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/verified/tst_psFunc00.stdout	(revision 1056)
@@ -0,0 +1,80 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psFunc00.c                                             *
+*            TestPoint: psFunctions functions{Allocate/Deallocate the psPolynomial1D structure.} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+At (x) = (5.000000): 2070.000000
+
+---> TESTPOINT PASSED (psStats functions{Allocate/Deallocate the psPolynomial1D structure.} | tst_psFunc00.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psFunc00.c                                             *
+*            TestPoint: psFunctions functions{Allocate/Deallocate the psPolynomial2D structure.} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+At (x, y) = (5.000000, 5.000000): 322920.000000
+
+---> TESTPOINT PASSED (psStats functions{Allocate/Deallocate the psPolynomial2D structure.} | tst_psFunc00.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psFunc00.c                                             *
+*            TestPoint: psFunctions functions{Allocate/Deallocate the psPolynomial3D structure.} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+At (x, y, z) = (5.000000, 5.000000, 5.000000): 1261325568.000000
+
+---> TESTPOINT PASSED (psStats functions{Allocate/Deallocate the psPolynomial3D structure.} | tst_psFunc00.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psFunc00.c                                             *
+*            TestPoint: psFunctions functions{Allocate/Deallocate the psPolynomial4D structure.} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+At (w, x, y, z) = (5.000000, 5.000000, 5.000000, 5.000000): 123176004616192.000000
+
+---> TESTPOINT PASSED (psStats functions{Allocate/Deallocate the psPolynomial4D structure.} | tst_psFunc00.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psFunc00.c                                             *
+*            TestPoint: psFunctions functions{Allocate/Deallocate the psDPolynomial1D structure.} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+At (x) = (5.000000): 2070.000000
+
+---> TESTPOINT PASSED (psStats functions{Allocate/Deallocate the psDPolynomial1D structure.} | tst_psFunc00.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psFunc00.c                                             *
+*            TestPoint: psFunctions functions{Allocate/Deallocate the psDPolynomial2D structure.} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+At (x, y) = (5.000000, 5.000000): 322920.000000
+
+---> TESTPOINT PASSED (psStats functions{Allocate/Deallocate the psDPolynomial2D structure.} | tst_psFunc00.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psFunc00.c                                             *
+*            TestPoint: psFunctions functions{Allocate/Deallocate the psDPolynomial3D structure.} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+At (x, y, z) = (5.000000, 5.000000, 5.000000): 1261325520.000000
+
+---> TESTPOINT PASSED (psStats functions{Allocate/Deallocate the psDPolynomial3D structure.} | tst_psFunc00.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psFunc00.c                                             *
+*            TestPoint: psFunctions functions{Allocate/Deallocate the psDPolynomial4D structure.} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+At (w, x, y, z) = (5.000000, 5.000000, 5.000000, 5.000000): 123176004981120.000000
+
+---> TESTPOINT PASSED (psStats functions{Allocate/Deallocate the psDPolynomial4D structure.} | tst_psFunc00.c)
+
Index: /tags/rel1_1/psLib/test/dataManip/verified/tst_psFunc01.stdout
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/verified/tst_psFunc01.stdout	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/verified/tst_psFunc01.stdout	(revision 1056)
@@ -0,0 +1,108 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psFunc01.c                                             *
+*            TestPoint: psFunctions functions{psGaussian()}                        *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+normal psGaussian(0.000000) is 0.000000
+normal psGaussian(2.000000) is 0.000000
+normal psGaussian(4.000000) is 0.000000
+normal psGaussian(6.000000) is 0.000000
+normal psGaussian(8.000000) is 0.000000
+normal psGaussian(10.000000) is 0.000000
+normal psGaussian(12.000000) is 0.000000
+normal psGaussian(14.000000) is 0.000000
+normal psGaussian(16.000000) is 0.000000
+normal psGaussian(18.000000) is 0.000000
+normal psGaussian(20.000000) is 0.000001
+normal psGaussian(22.000000) is 0.000067
+normal psGaussian(24.000000) is 0.002216
+normal psGaussian(26.000000) is 0.026995
+normal psGaussian(28.000000) is 0.120985
+normal psGaussian(30.000000) is 0.199471
+normal psGaussian(32.000000) is 0.120985
+normal psGaussian(34.000000) is 0.026995
+normal psGaussian(36.000000) is 0.002216
+normal psGaussian(38.000000) is 0.000067
+normal psGaussian(40.000000) is 0.000001
+normal psGaussian(42.000000) is 0.000000
+normal psGaussian(44.000000) is 0.000000
+normal psGaussian(46.000000) is 0.000000
+normal psGaussian(48.000000) is 0.000000
+normal psGaussian(50.000000) is 0.000000
+normal psGaussian(52.000000) is 0.000000
+normal psGaussian(54.000000) is 0.000000
+normal psGaussian(56.000000) is 0.000000
+normal psGaussian(58.000000) is 0.000000
+NON-normal psGaussian(0.000000) is 0.000000
+NON-normal psGaussian(2.000000) is 0.000000
+NON-normal psGaussian(4.000000) is 0.000000
+NON-normal psGaussian(6.000000) is 0.000000
+NON-normal psGaussian(8.000000) is 0.000000
+NON-normal psGaussian(10.000000) is 0.000000
+NON-normal psGaussian(12.000000) is 0.000000
+NON-normal psGaussian(14.000000) is 0.000000
+NON-normal psGaussian(16.000000) is 0.000000
+NON-normal psGaussian(18.000000) is 0.000000
+NON-normal psGaussian(20.000000) is 0.000004
+NON-normal psGaussian(22.000000) is 0.000335
+NON-normal psGaussian(24.000000) is 0.011109
+NON-normal psGaussian(26.000000) is 0.135335
+NON-normal psGaussian(28.000000) is 0.606531
+NON-normal psGaussian(30.000000) is 1.000000
+NON-normal psGaussian(32.000000) is 0.606531
+NON-normal psGaussian(34.000000) is 0.135335
+NON-normal psGaussian(36.000000) is 0.011109
+NON-normal psGaussian(38.000000) is 0.000335
+NON-normal psGaussian(40.000000) is 0.000004
+NON-normal psGaussian(42.000000) is 0.000000
+NON-normal psGaussian(44.000000) is 0.000000
+NON-normal psGaussian(46.000000) is 0.000000
+NON-normal psGaussian(48.000000) is 0.000000
+NON-normal psGaussian(50.000000) is 0.000000
+NON-normal psGaussian(52.000000) is 0.000000
+NON-normal psGaussian(54.000000) is 0.000000
+NON-normal psGaussian(56.000000) is 0.000000
+NON-normal psGaussian(58.000000) is 0.000000
+
+---> TESTPOINT PASSED (psFunctions functions{psGaussian()} | tst_psFunc01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psFunc01.c                                             *
+*            TestPoint: psFunctions functions{psGaussianDev()}                     *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Gaussian Deviate [0] is 30.267838
+Gaussian Deviate [1] is 29.823797
+Gaussian Deviate [2] is 33.348816
+Gaussian Deviate [3] is 31.467281
+Gaussian Deviate [4] is 31.995049
+Gaussian Deviate [5] is 27.444996
+Gaussian Deviate [6] is 25.206570
+Gaussian Deviate [7] is 28.641439
+Gaussian Deviate [8] is 29.921818
+Gaussian Deviate [9] is 31.787111
+Gaussian Deviate [10] is 29.964705
+Gaussian Deviate [11] is 27.406887
+Gaussian Deviate [12] is 28.664040
+Gaussian Deviate [13] is 30.363417
+Gaussian Deviate [14] is 31.662102
+Gaussian Deviate [15] is 28.903503
+Gaussian Deviate [16] is 28.723936
+Gaussian Deviate [17] is 30.014177
+Gaussian Deviate [18] is 28.660292
+Gaussian Deviate [19] is 28.344475
+Gaussian Deviate [20] is 31.225000
+Gaussian Deviate [21] is 29.264824
+Gaussian Deviate [22] is 29.421013
+Gaussian Deviate [23] is 28.166250
+Gaussian Deviate [24] is 28.832390
+Gaussian Deviate [25] is 30.129230
+Gaussian Deviate [26] is 30.093487
+Gaussian Deviate [27] is 28.498547
+Gaussian Deviate [28] is 29.711535
+Gaussian Deviate [29] is 32.951122
+
+---> TESTPOINT PASSED (psFunctions functions{psGaussianDev()} | tst_psFunc01.c)
+
Index: /tags/rel1_1/psLib/test/dataManip/verified/tst_psHist00.stdout
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/verified/tst_psHist00.stdout	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/verified/tst_psHist00.stdout	(revision 1056)
@@ -0,0 +1,87 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHist00.c                                             *
+*            TestPoint: psStats functions{Allocate the psHistogram structure.}     *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Bin number 0 bounds: (20.000000 - 30.000000)
+
+---> TESTPOINT PASSED (psStats functions{Allocate the psHistogram structure.} | tst_psHist00.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHist00.c                                             *
+*            TestPoint: psStats functions{Allocate the psHistogram structure.}     *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Bin number 0 bounds: (20.000000 - 25.000000)
+Bin number 1 bounds: (25.000000 - 30.000000)
+
+---> TESTPOINT PASSED (psStats functions{Allocate the psHistogram structure.} | tst_psHist00.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHist00.c                                             *
+*            TestPoint: psStats functions{Allocate the psHistogram structure.}     *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Bin number 0 bounds: (20.000000 - 21.000000)
+Bin number 1 bounds: (21.000000 - 22.000000)
+Bin number 2 bounds: (22.000000 - 23.000000)
+Bin number 3 bounds: (23.000000 - 24.000000)
+Bin number 4 bounds: (24.000000 - 25.000000)
+Bin number 5 bounds: (25.000000 - 26.000000)
+Bin number 6 bounds: (26.000000 - 27.000000)
+Bin number 7 bounds: (27.000000 - 28.000000)
+Bin number 8 bounds: (28.000000 - 29.000000)
+Bin number 9 bounds: (29.000000 - 30.000000)
+
+---> TESTPOINT PASSED (psStats functions{Allocate the psHistogram structure.} | tst_psHist00.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHist00.c                                             *
+*            TestPoint: psStats functions{Allocate the psHistogram structure.}     *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Bin number 0 bounds: (20.000000 - 20.500000)
+Bin number 1 bounds: (20.500000 - 21.000000)
+Bin number 2 bounds: (21.000000 - 21.500000)
+Bin number 3 bounds: (21.500000 - 22.000000)
+Bin number 4 bounds: (22.000000 - 22.500000)
+Bin number 5 bounds: (22.500000 - 23.000000)
+Bin number 6 bounds: (23.000000 - 23.500000)
+Bin number 7 bounds: (23.500000 - 24.000000)
+Bin number 8 bounds: (24.000000 - 24.500000)
+Bin number 9 bounds: (24.500000 - 25.000000)
+Bin number 10 bounds: (25.000000 - 25.500000)
+Bin number 11 bounds: (25.500000 - 26.000000)
+Bin number 12 bounds: (26.000000 - 26.500000)
+Bin number 13 bounds: (26.500000 - 27.000000)
+Bin number 14 bounds: (27.000000 - 27.500000)
+Bin number 15 bounds: (27.500000 - 28.000000)
+Bin number 16 bounds: (28.000000 - 28.500000)
+Bin number 17 bounds: (28.500000 - 29.000000)
+Bin number 18 bounds: (29.000000 - 29.500000)
+Bin number 19 bounds: (29.500000 - 30.000000)
+
+---> TESTPOINT PASSED (psStats functions{Allocate the psHistogram structure.} | tst_psHist00.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHist00.c                                             *
+*            TestPoint: psStats functions{Allocate the psHistogram structure. (UPPER<LOWER)} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psStats functions{Allocate the psHistogram structure. (UPPER<LOWER)} | tst_psHist00.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHist00.c                                             *
+*            TestPoint: psStats functions{Deallocate the psHistogram structure.}   *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psStats functions{Deallocate the psHistogram structure.} | tst_psHist00.c)
+
Index: /tags/rel1_1/psLib/test/dataManip/verified/tst_psHist01.stdout
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/verified/tst_psHist01.stdout	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/verified/tst_psHist01.stdout	(revision 1056)
@@ -0,0 +1,78 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHist01.c                                             *
+*            TestPoint: psStats functions{Allocate the psHistogram structure.}     *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Bin number 0 bounds: (20.000000 - 30.000000)
+
+---> TESTPOINT PASSED (psStats functions{Allocate the psHistogram structure.} | tst_psHist01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHist01.c                                             *
+*            TestPoint: psStats functions{Allocate the psHistogram structure.}     *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Bin number 0 bounds: (20.000000 - 25.000000)
+Bin number 1 bounds: (25.000000 - 30.000000)
+
+---> TESTPOINT PASSED (psStats functions{Allocate the psHistogram structure.} | tst_psHist01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHist01.c                                             *
+*            TestPoint: psStats functions{Allocate the psHistogram structure.}     *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Bin number 0 bounds: (20.000000 - 21.000000)
+Bin number 1 bounds: (21.000000 - 22.000000)
+Bin number 2 bounds: (22.000000 - 23.000000)
+Bin number 3 bounds: (23.000000 - 24.000000)
+Bin number 4 bounds: (24.000000 - 25.000000)
+Bin number 5 bounds: (25.000000 - 26.000000)
+Bin number 6 bounds: (26.000000 - 27.000000)
+Bin number 7 bounds: (27.000000 - 28.000000)
+Bin number 8 bounds: (28.000000 - 29.000000)
+Bin number 9 bounds: (29.000000 - 30.000000)
+
+---> TESTPOINT PASSED (psStats functions{Allocate the psHistogram structure.} | tst_psHist01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHist01.c                                             *
+*            TestPoint: psStats functions{Allocate the psHistogram structure.}     *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Bin number 0 bounds: (20.000000 - 20.500000)
+Bin number 1 bounds: (20.500000 - 21.000000)
+Bin number 2 bounds: (21.000000 - 21.500000)
+Bin number 3 bounds: (21.500000 - 22.000000)
+Bin number 4 bounds: (22.000000 - 22.500000)
+Bin number 5 bounds: (22.500000 - 23.000000)
+Bin number 6 bounds: (23.000000 - 23.500000)
+Bin number 7 bounds: (23.500000 - 24.000000)
+Bin number 8 bounds: (24.000000 - 24.500000)
+Bin number 9 bounds: (24.500000 - 25.000000)
+Bin number 10 bounds: (25.000000 - 25.500000)
+Bin number 11 bounds: (25.500000 - 26.000000)
+Bin number 12 bounds: (26.000000 - 26.500000)
+Bin number 13 bounds: (26.500000 - 27.000000)
+Bin number 14 bounds: (27.000000 - 27.500000)
+Bin number 15 bounds: (27.500000 - 28.000000)
+Bin number 16 bounds: (28.000000 - 28.500000)
+Bin number 17 bounds: (28.500000 - 29.000000)
+Bin number 18 bounds: (29.000000 - 29.500000)
+Bin number 19 bounds: (29.500000 - 30.000000)
+
+---> TESTPOINT PASSED (psStats functions{Allocate the psHistogram structure.} | tst_psHist01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHist01.c                                             *
+*            TestPoint: psStats functions{Deallocate the psHistogram structure.}   *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psStats functions{Deallocate the psHistogram structure.} | tst_psHist01.c)
+
Index: /tags/rel1_1/psLib/test/dataManip/verified/tst_psHist02.stdout
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/verified/tst_psHist02.stdout	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/verified/tst_psHist02.stdout	(revision 1056)
@@ -0,0 +1,156 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHist02.c                                             *
+*            TestPoint: psStats functions{Allocate and Perform Histogram, no mask} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Bin number 0 bounds: (20.000000 - 30.000000) data (10000)
+
+---> TESTPOINT PASSED (psStats functions{Allocate and Perform Histogram, no mask} | tst_psHist02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHist02.c                                             *
+*            TestPoint: psStats functions{Allocate and Perform Histogram with mask} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Bin number 0 bounds: (20.000000 - 30.000000) data (5000)
+
+---> TESTPOINT PASSED (psStats functions{Allocate and Perform Histogram with mask} | tst_psHist02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHist02.c                                             *
+*            TestPoint: psStats functions{Allocate and Perform Histogram, no mask} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Bin number 0 bounds: (20.000000 - 25.000000) data (5000)
+Bin number 1 bounds: (25.000000 - 30.000000) data (5000)
+
+---> TESTPOINT PASSED (psStats functions{Allocate and Perform Histogram, no mask} | tst_psHist02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHist02.c                                             *
+*            TestPoint: psStats functions{Allocate and Perform Histogram with mask} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Bin number 0 bounds: (20.000000 - 25.000000) data (5000)
+Bin number 1 bounds: (25.000000 - 30.000000) data (0)
+
+---> TESTPOINT PASSED (psStats functions{Allocate and Perform Histogram with mask} | tst_psHist02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHist02.c                                             *
+*            TestPoint: psStats functions{Allocate and Perform Histogram, no mask} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Bin number 0 bounds: (20.000000 - 21.000000) data (1000)
+Bin number 1 bounds: (21.000000 - 22.000000) data (1000)
+Bin number 2 bounds: (22.000000 - 23.000000) data (1000)
+Bin number 3 bounds: (23.000000 - 24.000000) data (1000)
+Bin number 4 bounds: (24.000000 - 25.000000) data (1000)
+Bin number 5 bounds: (25.000000 - 26.000000) data (1000)
+Bin number 6 bounds: (26.000000 - 27.000000) data (1000)
+Bin number 7 bounds: (27.000000 - 28.000000) data (1000)
+Bin number 8 bounds: (28.000000 - 29.000000) data (1000)
+Bin number 9 bounds: (29.000000 - 30.000000) data (1000)
+
+---> TESTPOINT PASSED (psStats functions{Allocate and Perform Histogram, no mask} | tst_psHist02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHist02.c                                             *
+*            TestPoint: psStats functions{Allocate and Perform Histogram with mask} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Bin number 0 bounds: (20.000000 - 21.000000) data (1000)
+Bin number 1 bounds: (21.000000 - 22.000000) data (1000)
+Bin number 2 bounds: (22.000000 - 23.000000) data (1000)
+Bin number 3 bounds: (23.000000 - 24.000000) data (1000)
+Bin number 4 bounds: (24.000000 - 25.000000) data (1000)
+Bin number 5 bounds: (25.000000 - 26.000000) data (0)
+Bin number 6 bounds: (26.000000 - 27.000000) data (0)
+Bin number 7 bounds: (27.000000 - 28.000000) data (0)
+Bin number 8 bounds: (28.000000 - 29.000000) data (0)
+Bin number 9 bounds: (29.000000 - 30.000000) data (0)
+
+---> TESTPOINT PASSED (psStats functions{Allocate and Perform Histogram with mask} | tst_psHist02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHist02.c                                             *
+*            TestPoint: psStats functions{Allocate and Perform Histogram, no mask} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Bin number 0 bounds: (20.000000 - 20.500000) data (500)
+Bin number 1 bounds: (20.500000 - 21.000000) data (500)
+Bin number 2 bounds: (21.000000 - 21.500000) data (500)
+Bin number 3 bounds: (21.500000 - 22.000000) data (500)
+Bin number 4 bounds: (22.000000 - 22.500000) data (500)
+Bin number 5 bounds: (22.500000 - 23.000000) data (500)
+Bin number 6 bounds: (23.000000 - 23.500000) data (500)
+Bin number 7 bounds: (23.500000 - 24.000000) data (500)
+Bin number 8 bounds: (24.000000 - 24.500000) data (500)
+Bin number 9 bounds: (24.500000 - 25.000000) data (500)
+Bin number 10 bounds: (25.000000 - 25.500000) data (500)
+Bin number 11 bounds: (25.500000 - 26.000000) data (500)
+Bin number 12 bounds: (26.000000 - 26.500000) data (500)
+Bin number 13 bounds: (26.500000 - 27.000000) data (500)
+Bin number 14 bounds: (27.000000 - 27.500000) data (500)
+Bin number 15 bounds: (27.500000 - 28.000000) data (500)
+Bin number 16 bounds: (28.000000 - 28.500000) data (500)
+Bin number 17 bounds: (28.500000 - 29.000000) data (500)
+Bin number 18 bounds: (29.000000 - 29.500000) data (500)
+Bin number 19 bounds: (29.500000 - 30.000000) data (500)
+
+---> TESTPOINT PASSED (psStats functions{Allocate and Perform Histogram, no mask} | tst_psHist02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHist02.c                                             *
+*            TestPoint: psStats functions{Allocate and Perform Histogram with mask} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Bin number 0 bounds: (20.000000 - 20.500000) data (500)
+Bin number 1 bounds: (20.500000 - 21.000000) data (500)
+Bin number 2 bounds: (21.000000 - 21.500000) data (500)
+Bin number 3 bounds: (21.500000 - 22.000000) data (500)
+Bin number 4 bounds: (22.000000 - 22.500000) data (500)
+Bin number 5 bounds: (22.500000 - 23.000000) data (500)
+Bin number 6 bounds: (23.000000 - 23.500000) data (500)
+Bin number 7 bounds: (23.500000 - 24.000000) data (500)
+Bin number 8 bounds: (24.000000 - 24.500000) data (500)
+Bin number 9 bounds: (24.500000 - 25.000000) data (500)
+Bin number 10 bounds: (25.000000 - 25.500000) data (0)
+Bin number 11 bounds: (25.500000 - 26.000000) data (0)
+Bin number 12 bounds: (26.000000 - 26.500000) data (0)
+Bin number 13 bounds: (26.500000 - 27.000000) data (0)
+Bin number 14 bounds: (27.000000 - 27.500000) data (0)
+Bin number 15 bounds: (27.500000 - 28.000000) data (0)
+Bin number 16 bounds: (28.000000 - 28.500000) data (0)
+Bin number 17 bounds: (28.500000 - 29.000000) data (0)
+Bin number 18 bounds: (29.000000 - 29.500000) data (0)
+Bin number 19 bounds: (29.500000 - 30.000000) data (0)
+
+---> TESTPOINT PASSED (psStats functions{Allocate and Perform Histogram with mask} | tst_psHist02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHist02.c                                             *
+*            TestPoint: psStats functions{Calling psHistogramVector() with various NULL inputs.} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psStats functions{Calling psHistogramVector() with various NULL inputs.} | tst_psHist02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHist02.c                                             *
+*            TestPoint: psStats functions{Deallocate the psHistogram structure.}   *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psStats functions{Deallocate the psHistogram structure.} | tst_psHist02.c)
+
Index: /tags/rel1_1/psLib/test/dataManip/verified/tst_psMatrix01.stdout
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/verified/tst_psMatrix01.stdout	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/verified/tst_psMatrix01.stdout	(revision 1056)
@@ -0,0 +1,45 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix01.c                                           *
+*            TestPoint: psMatrix{Create input and output images}                   *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+7.000000 8.000000 9.000000 
+4.000000 5.000000 6.000000 
+1.000000 2.000000 3.000000 
+
+---> TESTPOINT PASSED (psMatrix{Create input and output images} | tst_psMatrix01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix01.c                                           *
+*            TestPoint: psMatrix{Transpose input image into output image}          *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+3.000000 6.000000 9.000000 
+2.000000 5.000000 8.000000 
+1.000000 4.000000 7.000000 
+
+---> TESTPOINT PASSED (psMatrix{Transpose input image into output image} | tst_psMatrix01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix01.c                                           *
+*            TestPoint: psMatrix{ranspose input image into auto allocated NULL output image} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+3.000000 6.000000 9.000000 
+2.000000 5.000000 8.000000 
+1.000000 4.000000 7.000000 
+
+---> TESTPOINT PASSED (psMatrix{ranspose input image into auto allocated NULL output image} | tst_psMatrix01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix01.c                                           *
+*            TestPoint: psMatrix{Free images and check for leaks}                  *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMatrix{Free images and check for leaks} | tst_psMatrix01.c)
+
Index: /tags/rel1_1/psLib/test/dataManip/verified/tst_psMatrix02.stderr
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/verified/tst_psMatrix02.stderr	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/verified/tst_psMatrix02.stderr	(revision 1056)
@@ -0,0 +1,6 @@
+ <DATE> <TIME> <HOST> |E|psMatrixTranspo|Invalid operation: Pointer to inImage is same as outImage.
+ <DATE> <TIME> <HOST> |E|psMatrixTranspo|Invalid operation: inImage or its data is NULL.
+ <DATE> <TIME> <HOST> |E|psMatrixTranspo|Invalid operation: inImage not PS_TYPE_F64.
+ <DATE> <TIME> <HOST> |E|psMatrixTranspo|Invalid operation: inImage not square array.
+ <DATE> <TIME> <HOST> |E|psMatrixTranspo|Invalid operation: outImage not PS_TYPE_F64.
+ <DATE> <TIME> <HOST> |E|psMatrixTranspo|Invalid operation: outImage not square array.
Index: /tags/rel1_1/psLib/test/dataManip/verified/tst_psMatrix02.stdout
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/verified/tst_psMatrix02.stdout	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/verified/tst_psMatrix02.stdout	(revision 1056)
@@ -0,0 +1,66 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix02.c                                           *
+*            TestPoint: psMatrix{Input pointer same as output pointer}             *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Invalid operation: Pointer to inImage is same as outImage. *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMatrix{Input pointer same as output pointer} | tst_psMatrix02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix02.c                                           *
+*            TestPoint: psMatrix{Null input psImage}                               *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Invalid operation: inImage or its data is NULL.            *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMatrix{Null input psImage} | tst_psMatrix02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix02.c                                           *
+*            TestPoint: psMatrix{Incorrect type for input pointer}                 *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: |Invalid operation: inImage not PS_TYPE_F64.               *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMatrix{Incorrect type for input pointer} | tst_psMatrix02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix02.c                                           *
+*            TestPoint: psMatrix{Matrix not square for input pointer}              *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Invalid operation: inImage not square array.               *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMatrix{Matrix not square for input pointer} | tst_psMatrix02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix02.c                                           *
+*            TestPoint: psMatrix{Incorrect type for output pointer}                *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Invalid operation: outImage not PS_TYPE_F64.               *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMatrix{Incorrect type for output pointer} | tst_psMatrix02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix02.c                                           *
+*            TestPoint: psMatrix{Matrix not square for output pointer}             *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Invalid operation: outImage not square array.              *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMatrix{Matrix not square for output pointer} | tst_psMatrix02.c)
+
Index: /tags/rel1_1/psLib/test/dataManip/verified/tst_psMatrix03.stderr
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/verified/tst_psMatrix03.stderr	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/verified/tst_psMatrix03.stderr	(revision 1056)
@@ -0,0 +1,3 @@
+ <DATE> <TIME> <HOST> |E|    psMatrixLUD|Invalid operation: inImage or its data is NULL.
+ <DATE> <TIME> <HOST> |E|psMatrixLUSolve|Invalid operation: inVector or its data is NULL.
+ <DATE> <TIME> <HOST> |E|psMatrixLUSolve|Invalid operation: inImage or its data is NULL.
Index: /tags/rel1_1/psLib/test/dataManip/verified/tst_psMatrix03.stdout
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/verified/tst_psMatrix03.stdout	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/verified/tst_psMatrix03.stdout	(revision 1056)
@@ -0,0 +1,83 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix03.c                                           *
+*            TestPoint: psMatrix{Create input and output images and vectors}       *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+3.000000 1.000000 -2.000000 
+4.000000 5.000000 6.000000 
+2.000000 4.000000 6.000000 
+
+18.000000
+24.000000
+4.000000
+
+---> TESTPOINT PASSED (psMatrix{Create input and output images and vectors} | tst_psMatrix03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix03.c                                           *
+*            TestPoint: psMatrix{Calculate LU matrix}                              *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+0.500000 -0.545455 -0.545455 
+0.750000 -2.750000 -6.500000 
+4.000000 5.000000 6.000000 
+
+---> TESTPOINT PASSED (psMatrix{Calculate LU matrix} | tst_psMatrix03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix03.c                                           *
+*            TestPoint: psMatrix{Determine solution to matrix equation}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+4.000000
+-2.000000
+3.000000
+Error: Resulting image is not PS_DIMEN_VECTOR
+
+---> TESTPOINT PASSED (psMatrix{Determine solution to matrix equation} | tst_psMatrix03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix03.c                                           *
+*            TestPoint: psMatrix{Free input and output images and vectors}         *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMatrix{Free input and output images and vectors} | tst_psMatrix03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix03.c                                           *
+*            TestPoint: psMatrix{Attempt to use null image input argument}         *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Invalid operation: inImage or its data is NULL.            *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMatrix{Attempt to use null image input argument} | tst_psMatrix03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix03.c                                           *
+*            TestPoint: psMatrix{Attempt to use null input vector argument}        *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Invalid operation: inVector or its data is NULL.           *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMatrix{Attempt to use null input vector argument} | tst_psMatrix03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix03.c                                           *
+*            TestPoint: psMatrix{Attempt to use null LU image argument}            *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Invalid operation: inImage or its data is NULL.            *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMatrix{Attempt to use null LU image argument} | tst_psMatrix03.c)
+
Index: /tags/rel1_1/psLib/test/dataManip/verified/tst_psMatrix04.stderr
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/verified/tst_psMatrix04.stderr	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/verified/tst_psMatrix04.stderr	(revision 1056)
@@ -0,0 +1,2 @@
+ <DATE> <TIME> <HOST> |E| psMatrixInvert|Invalid operation: inImage or its data is NULL.
+ <DATE> <TIME> <HOST> |E| psMatrixInvert|Invalid operation: determinant argument is NULL.
Index: /tags/rel1_1/psLib/test/dataManip/verified/tst_psMatrix04.stdout
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/verified/tst_psMatrix04.stdout	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/verified/tst_psMatrix04.stdout	(revision 1056)
@@ -0,0 +1,67 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix04.c                                           *
+*            TestPoint: psMatrix{Create input and output images}                   *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+3.000000 5.000000 7.000000 
+0.000000 1.000000 -1.000000 
+2.000000 4.000000 3.000000 
+
+---> TESTPOINT PASSED (psMatrix{Create input and output images} | tst_psMatrix04.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix04.c                                           *
+*            TestPoint: psMatrix{Invert matrix and calculate determinant}          *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+-1.000000 0.666667 0.666667 
+-1.000000 1.666667 0.666667 
+4.000000 -4.333333 -2.333333 
+
+det = 3.000000
+
+---> TESTPOINT PASSED (psMatrix{Invert matrix and calculate determinant} | tst_psMatrix04.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix04.c                                           *
+*            TestPoint: psMatrix{Calculate determinant only}                       *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+det = 3.000000
+
+---> TESTPOINT PASSED (psMatrix{Calculate determinant only} | tst_psMatrix04.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix04.c                                           *
+*            TestPoint: psMatrix{Free input and output images}                     *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMatrix{Free input and output images} | tst_psMatrix04.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix04.c                                           *
+*            TestPoint: psMatrix{Attempt to use null input image argument}         *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Invalid operation: inImage or its data is NULL.            *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMatrix{Attempt to use null input image argument} | tst_psMatrix04.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix04.c                                           *
+*            TestPoint: psMatrix{Attempt to use null input float argument}         *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Invalid operation: determinant argument is NULL.           *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMatrix{Attempt to use null input float argument} | tst_psMatrix04.c)
+
Index: /tags/rel1_1/psLib/test/dataManip/verified/tst_psMatrix05.stdout
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/verified/tst_psMatrix05.stdout	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/verified/tst_psMatrix05.stdout	(revision 1056)
@@ -0,0 +1,34 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix05.c                                           *
+*            TestPoint: psMatrix{Create input and output images}                   *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+2.000000 3.000000 
+-1.000000 2.000000 
+
+4.000000 1.000000 
+0.000000 6.000000 
+
+---> TESTPOINT PASSED (psMatrix{Create input and output images} | tst_psMatrix05.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix05.c                                           *
+*            TestPoint: psMatrix{Multiply images}                                  *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+8.000000 20.000000 
+-4.000000 11.000000 
+
+---> TESTPOINT PASSED (psMatrix{Multiply images} | tst_psMatrix05.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix05.c                                           *
+*            TestPoint: psMatrix{Free input and output images}                     *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMatrix{Free input and output images} | tst_psMatrix05.c)
+
Index: /tags/rel1_1/psLib/test/dataManip/verified/tst_psMatrix06.stdout
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/verified/tst_psMatrix06.stdout	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/verified/tst_psMatrix06.stdout	(revision 1056)
@@ -0,0 +1,35 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix06.c                                           *
+*            TestPoint: psMatrix{Create input and output images}                   *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+1.000000 0.500000 0.333333 0.250000 
+0.500000 0.333333 0.250000 0.200000 
+0.333333 0.250000 0.200000 0.166667 
+0.250000 0.200000 0.166667 0.142857 
+
+---> TESTPOINT PASSED (psMatrix{Create input and output images} | tst_psMatrix06.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix06.c                                           *
+*            TestPoint: psMatrix{Calculate Eigenvectors}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+0.792608 0.582076 -0.179186 -0.029193 
+0.451923 -0.370502 0.741918 0.328712 
+0.322416 -0.509579 -0.100228 -0.791411 
+0.252161 -0.514048 -0.638283 0.514553 
+
+---> TESTPOINT PASSED (psMatrix{Calculate Eigenvectors} | tst_psMatrix06.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix06.c                                           *
+*            TestPoint: psMatrix{Free input and output images}                     *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMatrix{Free input and output images} | tst_psMatrix06.c)
+
Index: /tags/rel1_1/psLib/test/dataManip/verified/tst_psMatrix07.stderr
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/verified/tst_psMatrix07.stderr	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/verified/tst_psMatrix07.stderr	(revision 1056)
@@ -0,0 +1,3 @@
+ <DATE> <TIME> <HOST> |E|psMatrixToVecto|Invalid operation: inImage or its data is NULL.
+ <DATE> <TIME> <HOST> |E|psMatrixToVecto|Image does not have dim with 1 col or 1 row: (2 x 2).
+ <DATE> <TIME> <HOST> |E|psVectorToMatri|Invalid operation: inVector or its data is NULL.
Index: /tags/rel1_1/psLib/test/dataManip/verified/tst_psMatrix07.stdout
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/verified/tst_psMatrix07.stdout	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/verified/tst_psMatrix07.stdout	(revision 1056)
@@ -0,0 +1,106 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix07.c                                           *
+*            TestPoint: psMatrix{Create input and output images and vectors}       *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+0.000000 
+1.000000 
+2.000000 
+
+0.000000 1.000000 2.000000 
+
+0.000000
+1.000000
+2.000000
+
+---> TESTPOINT PASSED (psMatrix{Create input and output images and vectors} | tst_psMatrix07.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix07.c                                           *
+*            TestPoint: psMatrix{Convert matrix to PS_DIMEN_VECTOR vector}         *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+0.000000
+1.000000
+2.000000
+
+---> TESTPOINT PASSED (psMatrix{Convert matrix to PS_DIMEN_VECTOR vector} | tst_psMatrix07.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix07.c                                           *
+*            TestPoint: psMatrix{Attempt to use null image input argument}         *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Invalid operation: inImage or its data is NULL.            *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMatrix{Attempt to use null image input argument} | tst_psMatrix07.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix07.c                                           *
+*            TestPoint: psMatrix{Convert matrix to PS_DIMEN_TRANSV vector}         *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+0.000000
+1.000000
+2.000000
+
+---> TESTPOINT PASSED (psMatrix{Convert matrix to PS_DIMEN_TRANSV vector} | tst_psMatrix07.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix07.c                                           *
+*            TestPoint: psMatrix{Improper image size}                              *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Image does not have dim with 1 col or 1 row: (2 x 2).      *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMatrix{Improper image size} | tst_psMatrix07.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix07.c                                           *
+*            TestPoint: psMatrix{Convert PS_DIMEN_VECTOR vector to matrix}         *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+0.000000 
+1.000000 
+2.000000 
+
+---> TESTPOINT PASSED (psMatrix{Convert PS_DIMEN_VECTOR vector to matrix} | tst_psMatrix07.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix07.c                                           *
+*            TestPoint: psMatrix{Attempt to use null input vector argument}        *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Invalid operation: inVector or its data is NULL.           *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMatrix{Attempt to use null input vector argument} | tst_psMatrix07.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix07.c                                           *
+*            TestPoint: psMatrix{Convert PS_DIMEN_TRANSV vector to matrix}         *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+0.000000 1.000000 2.000000 
+
+---> TESTPOINT PASSED (psMatrix{Convert PS_DIMEN_TRANSV vector to matrix} | tst_psMatrix07.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix07.c                                           *
+*            TestPoint: psMatrix{Free input and output images and vectors}         *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMatrix{Free input and output images and vectors} | tst_psMatrix07.c)
+
Index: /tags/rel1_1/psLib/test/dataManip/verified/tst_psStats00.stdout
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/verified/tst_psStats00.stdout	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/verified/tst_psStats00.stdout	(revision 1056)
@@ -0,0 +1,62 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats00.c                                            *
+*            TestPoint: psStats functions{PS_STAT_SAMPLE_MEAN: no vector mask}     *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Called psVectorStats() on a vector with no elements masked.
+The expected mean was 4.500000; the calculated mean was 4.500000
+
+---> TESTPOINT PASSED (psVector functions{PS_STAT_SAMPLE_MEAN: no vector mask} | tst_psStats00.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats00.c                                            *
+*            TestPoint: psStats functions{PS_STAT_SAMPLE_MEAN: with vector mask=1} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Called psVectorStats() on a vector with last N/2 elements masked.
+The expected mean was 2.000000; the calculated mean was 2.000000
+
+---> TESTPOINT PASSED (psVector functions{PS_STAT_SAMPLE_MEAN: with vector mask=1} | tst_psStats00.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats00.c                                            *
+*            TestPoint: psStats functions{PS_STAT_SAMPLE_MEAN: with vector mask=2} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Called psVectorStats() on a vector with last N/2 elements masked.
+The expected mean was 2.000000; the calculated mean was 2.000000
+
+---> TESTPOINT PASSED (psVector functions{PS_STAT_SAMPLE_MEAN: with vector mask=2} | tst_psStats00.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats00.c                                            *
+*            TestPoint: psStats functions{PS_STAT_SAMPLE_MEAN: with vector mask=3} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Called psVectorStats() on a vector with last N/2 elements masked.
+The expected mean was 2.000000; the calculated mean was 2.000000
+
+---> TESTPOINT PASSED (psVector functions{PS_STAT_SAMPLE_MEAN: with vector mask=3} | tst_psStats00.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats00.c                                            *
+*            TestPoint: psStats functions{PS_STAT_SAMPLE_MEAN: NULL inputs}        *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psVector functions{PS_STAT_SAMPLE_MEAN: NULL inputs} | tst_psStats00.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats00.c                                            *
+*            TestPoint: psStats functions{psStats(): deallocating memory}          *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psVector functions{psStats(): deallocating memory} | tst_psStats00.c)
+
Index: /tags/rel1_1/psLib/test/dataManip/verified/tst_psStats01.stdout
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/verified/tst_psStats01.stdout	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/verified/tst_psStats01.stdout	(revision 1056)
@@ -0,0 +1,36 @@
+Masking element 5
+Masking element 6
+Masking element 7
+Masking element 8
+Masking element 9
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats01.c                                            *
+*            TestPoint: psStats functions{PS_STAT_MAX: no vector mask}             *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Called psVectorStats() on a vector with no elements masked.
+The expected max was 9.000000; the calculated max was 9.000000
+
+---> TESTPOINT PASSED (psVector functions{PS_STAT_MAX: no vector mask} | tst_psStats01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats01.c                                            *
+*            TestPoint: psStats functions{PS_STAT_MAX: with vector mask}           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Called psVectorStats() on a vector with last N/2 elements masked.
+The expected max was 4.000000; the calculated max was 4.000000
+
+---> TESTPOINT PASSED (psVector functions{PS_STAT_MAX: with vector mask} | tst_psStats01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats01.c                                            *
+*            TestPoint: psStats functions{psStats(): deallocating memory}          *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psVector functions{psStats(): deallocating memory} | tst_psStats01.c)
+
Index: /tags/rel1_1/psLib/test/dataManip/verified/tst_psStats02.stdout
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/verified/tst_psStats02.stdout	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/verified/tst_psStats02.stdout	(revision 1056)
@@ -0,0 +1,31 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats02.c                                            *
+*            TestPoint: psStats functions{PS_STAT_MIN: no vector mask}             *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Called psVectorStats() on a vector with no elements masked.
+The expected min was 0.000000; the calculated min was 0.000000
+
+---> TESTPOINT PASSED (psVector functions{PS_STAT_MIN: no vector mask} | tst_psStats02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats02.c                                            *
+*            TestPoint: psStats functions{PS_STAT_MIN: with vector mask}           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Called psVectorStats() on a vector with last N/2 elements masked.
+The expected min was 5.000000; the calculated min was 5.000000
+
+---> TESTPOINT PASSED (psVector functions{PS_STAT_MIN: with vector mask} | tst_psStats02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats02.c                                            *
+*            TestPoint: psStats functions{psStats(): deallocating memory}          *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psVector functions{psStats(): deallocating memory} | tst_psStats02.c)
+
Index: /tags/rel1_1/psLib/test/dataManip/verified/tst_psStats03.stdout
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/verified/tst_psStats03.stdout	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/verified/tst_psStats03.stdout	(revision 1056)
@@ -0,0 +1,31 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats03.c                                            *
+*            TestPoint: psStats functions{PS_STAT_SAMPLE_MEDIAN: no vector mask}   *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Called psVectorStats() on a vector with no elements masked.
+The expected median was 2058.000000.  The calculated median was 2058.000000.
+
+---> TESTPOINT PASSED (psStats functions{PS_STAT_SAMPLE_MEDIAN: no vector mask} | tst_psStats03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats03.c                                            *
+*            TestPoint: psStats functions{PS_STAT_SAMPLE_MEDIAN: with vector mask} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Called psVectorStats() on a vector with last N/2 elements masked.
+The expected median was 1028.500000.  The calculated median was 1028.500000.
+
+---> TESTPOINT PASSED (psStats functions{PS_STAT_SAMPLE_MEDIAN: with vector mask} | tst_psStats03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats03.c                                            *
+*            TestPoint: psStats functions{psStats(): deallocating memory}          *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psStats functions{psStats(): deallocating memory} | tst_psStats03.c)
+
Index: /tags/rel1_1/psLib/test/dataManip/verified/tst_psStats05.stdout
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/verified/tst_psStats05.stdout	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/verified/tst_psStats05.stdout	(revision 1056)
@@ -0,0 +1,27 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats05.c                                            *
+*            TestPoint: psStats functions{Allocate the psStats structure.}         *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psStats functions{Allocate the psStats structure.} | tst_psStats05.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats05.c                                            *
+*            TestPoint: psStats functions{Deallocate the psStats structure.}       *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psStats functions{Deallocate the psStats structure.} | tst_psStats05.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats05.c                                            *
+*            TestPoint: psStats functions{Deallocate NULL psStats structure.}      *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psStats functions{Deallocate NULL psStats structure.} | tst_psStats05.c)
+
Index: /tags/rel1_1/psLib/test/dataManip/verified/tst_psStats06.stdout
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/verified/tst_psStats06.stdout	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/verified/tst_psStats06.stdout	(revision 1056)
@@ -0,0 +1,31 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats06.c                                            *
+*            TestPoint: psStats functions{PS_STAT_SAMPLE_STDEV: no vector mask}    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Called psVectorStats() on a vector with no elements masked.
+The expected stdev was 4.472136; the calculated stdev was 4.472136
+
+---> TESTPOINT PASSED (psVector functions{PS_STAT_SAMPLE_STDEV: no vector mask} | tst_psStats06.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats06.c                                            *
+*            TestPoint: psStats functions{PS_STAT_SAMPLE_STDEV: with vector mask}  *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Called psVectorStats() on a vector with last N/2 elements masked.
+The expected stdev was 2.160247; the calculated stdev was 2.160247
+
+---> TESTPOINT PASSED (psVector functions{PS_STAT_SAMPLE_STDEV: with vector mask} | tst_psStats06.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats06.c                                            *
+*            TestPoint: psStats functions{psStats(): deallocating memory}          *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psVector functions{psStats(): deallocating memory} | tst_psStats06.c)
+
Index: /tags/rel1_1/psLib/test/dataManip/verified/tst_psStats07.stdout
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/verified/tst_psStats07.stdout	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/verified/tst_psStats07.stdout	(revision 1056)
@@ -0,0 +1,173 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats07.c                                            *
+*            TestPoint: psStats functions{PS_STAT_ROBUST_STATS: robust mean: no vector mask} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Calling psVectorStats() on a vector with no elements masked.
+Called psVectorStats() on a vector with no elements masked.
+The expected Mean was 0.000000; the calculated Mean was 0.000000
+
+---> TESTPOINT PASSED (psVector functions{PS_STAT_ROBUST_STATS: robust mean: no vector mask} | tst_psStats07.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats07.c                                            *
+*            TestPoint: psStats functions{PS_STAT_ROBUST_STATS: robust Median: no vector mask} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+The expected Median was 0.000000; the calculated Median was 0.000000
+
+---> TESTPOINT PASSED (psVector functions{PS_STAT_ROBUST_STATS: robust Median: no vector mask} | tst_psStats07.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats07.c                                            *
+*            TestPoint: psStats functions{PS_STAT_ROBUST_STATS: robust Mode: no vector mask} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+The expected Mode was -1.000000; the calculated Mode was -1.000000
+
+---> TESTPOINT PASSED (psVector functions{PS_STAT_ROBUST_STATS: robust Mode: no vector mask} | tst_psStats07.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats07.c                                            *
+*            TestPoint: psStats functions{PS_STAT_ROBUST_STATS: robust Stdev: no vector mask} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+The expected Stdev was 0.000000; the calculated Stdev was 0.000000
+
+---> TESTPOINT PASSED (psVector functions{PS_STAT_ROBUST_STATS: robust Stdev: no vector mask} | tst_psStats07.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats07.c                                            *
+*            TestPoint: psStats functions{PS_STAT_ROBUST_STATS: lower quartile: no vector mask} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+The expected LQ was 0.000000; the calculated LQ was 0.000000
+
+---> TESTPOINT PASSED (psVector functions{PS_STAT_ROBUST_STATS: lower quartile: no vector mask} | tst_psStats07.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats07.c                                            *
+*            TestPoint: psStats functions{PS_STAT_ROBUST_STATS: upper quartile: no vector mask} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+The expected UQ was 0.000000; the calculated UQ was 0.000000
+
+---> TESTPOINT PASSED (psVector functions{PS_STAT_ROBUST_STATS: lower quartile: no vector mask} | tst_psStats07.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats07.c                                            *
+*            TestPoint: psStats functions{PS_STAT_ROBUST_STATS: robust N50: no vector mask} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+The expected N50 was 0.000000; the calculated N50 was 0.000000
+
+---> TESTPOINT PASSED (psVector functions{PS_STAT_ROBUST_STATS: robust N50: no vector mask} | tst_psStats07.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats07.c                                            *
+*            TestPoint: psStats functions{PS_STAT_ROBUST_STATS: robust Nfit: no vector mask} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+The expected Nfit was 0.000000; the calculated Nfit was 0.000000
+
+---> TESTPOINT PASSED (psVector functions{PS_STAT_ROBUST_STATS: robust Nfit: no vector mask} | tst_psStats07.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats07.c                                            *
+*            TestPoint: psStats functions{PS_STAT_ROBUST_STATS: robust mean: with vector mask} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Calling psVectorStats() on a vector with elements masked.
+Called psVectorStats() on a vector with elements masked.
+The expected Mean was 0.000000; the calculated Mean was 0.000000
+
+---> TESTPOINT PASSED (psVector functions{PS_STAT_ROBUST_STATS: robust mean: with vector mask} | tst_psStats07.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats07.c                                            *
+*            TestPoint: psStats functions{PS_STAT_ROBUST_STATS: robust Median: with vector mask} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+The expected Median was 0.000000; the calculated Median was 0.000000
+
+---> TESTPOINT PASSED (psVector functions{PS_STAT_ROBUST_STATS: robust Median: with vector mask} | tst_psStats07.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats07.c                                            *
+*            TestPoint: psStats functions{PS_STAT_ROBUST_STATS: robust Mode: with vector mask} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+The expected Mode was 40.000000; the calculated Mode was 40.000000
+
+---> TESTPOINT PASSED (psVector functions{PS_STAT_ROBUST_STATS: robust Mode: with vector mask} | tst_psStats07.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats07.c                                            *
+*            TestPoint: psStats functions{PS_STAT_ROBUST_STATS: robust Stdev: with vector mask} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+The expected Stdev was 0.000000; the calculated Stdev was 0.000000
+
+---> TESTPOINT PASSED (psVector functions{PS_STAT_ROBUST_STATS: robust Stdev: with vector mask} | tst_psStats07.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats07.c                                            *
+*            TestPoint: psStats functions{PS_STAT_ROBUST_STATS: lower quartile: with vector mask} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+The expected LQ was 0.000000; the calculated LQ was 0.000000
+
+---> TESTPOINT PASSED (psVector functions{PS_STAT_ROBUST_STATS: lower quartile: with vector mask} | tst_psStats07.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats07.c                                            *
+*            TestPoint: psStats functions{PS_STAT_ROBUST_STATS: upper quartile: with vector mask} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+The expected UQ was 0.000000; the calculated UQ was 0.000000
+
+---> TESTPOINT PASSED (psVector functions{PS_STAT_ROBUST_STATS: lower quartile: with vector mask} | tst_psStats07.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats07.c                                            *
+*            TestPoint: psStats functions{PS_STAT_ROBUST_STATS: robust N50: with vector mask} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+The expected N50 was 0.000000; the calculated N50 was 0.000000
+
+---> TESTPOINT PASSED (psVector functions{PS_STAT_ROBUST_STATS: robust N50: with vector mask} | tst_psStats07.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats07.c                                            *
+*            TestPoint: psStats functions{PS_STAT_ROBUST_STATS: robust Nfit: with vector mask} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+The expected Nfit was 0.000000; the calculated Nfit was 0.000000
+
+---> TESTPOINT PASSED (psVector functions{PS_STAT_ROBUST_STATS: robust Nfit: with vector mask} | tst_psStats07.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats07.c                                            *
+*            TestPoint: psStats functions{psStats(): deallocating memory}          *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psVector functions{psStats(): deallocating memory} | tst_psStats07.c)
+
Index: /tags/rel1_1/psLib/test/dataManip/verified/tst_psStats08.stdout
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/verified/tst_psStats08.stdout	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/verified/tst_psStats08.stdout	(revision 1056)
@@ -0,0 +1,53 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats08.c                                            *
+*            TestPoint: psStats functions{PS_STAT_SAMPLE_LQ: no vector mask}       *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Called psVectorStats() on a vector with no elements masked.
+The expected sampleLQ was 50.000000; the calculated sampleLQ was 50.000000
+
+---> TESTPOINT PASSED (psVector functions{PS_STAT_SAMPLE_LQ: no vector mask} | tst_psStats08.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats08.c                                            *
+*            TestPoint: psStats functions{PS_STAT_SAMPLE_UQ: no vector mask}       *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Called psVectorStats() on a vector with no elements masked.
+The expected sampleUQ was 150.000000; the calculated sampleUQ was 150.000000
+
+---> TESTPOINT PASSED (psVector functions{PS_STAT_SAMPLE_UQ: no vector mask} | tst_psStats08.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats08.c                                            *
+*            TestPoint: psStats functions{PS_STAT_SAMPLE_LQ: with vector mask}     *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Called psVectorStats() on a vector with elements masked.
+The expected sampleLQ was 25.000000; the calculated sampleLQ was 25.000000
+
+---> TESTPOINT PASSED (psVector functions{PS_STAT_SAMPLE_LQ: with vector mask} | tst_psStats08.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats08.c                                            *
+*            TestPoint: psStats functions{PS_STAT_SAMPLE_UQ: with vector mask}     *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Called psVectorStats() on a vector with elements masked.
+The expected sampleUQ was 75.000000; the calculated sampleUQ was 75.000000
+
+---> TESTPOINT PASSED (psVector functions{PS_STAT_SAMPLE_UQ: with vector mask} | tst_psStats08.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats08.c                                            *
+*            TestPoint: psStats functions{psStats(): deallocating memory}          *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psVector functions{psStats(): deallocating memory} | tst_psStats08.c)
+
Index: /tags/rel1_1/psLib/test/dataManip/verified/tst_psStats09.stdout
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/verified/tst_psStats09.stdout	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/verified/tst_psStats09.stdout	(revision 1056)
@@ -0,0 +1,53 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats09.c                                            *
+*            TestPoint: psStats functions{PS_STAT_CLIPPED_MEAN: no vector mask}    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Called psVectorStats() on a vector with no elements masked.
+The calculated clippedMean was 29.945370
+
+---> TESTPOINT PASSED (psVector functions{PS_STAT_CLIPPED_MEAN/STDEV: no vector mask} | tst_psStats09.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats09.c                                            *
+*            TestPoint: psStats functions{PS_STAT_CLIPPED_STDEV: no vector mask}   *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Called psVectorStats() on a vector with no elements masked.
+The calculated clippedStdev was 0.577927
+
+---> TESTPOINT PASSED (psVector functions{PS_STAT_CLIPPED_MEAN/STDEV: no vector mask} | tst_psStats09.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats09.c                                            *
+*            TestPoint: psStats functions{PS_STAT_CLIPPED_MEAN: vector mask}       *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Called psVectorStats() on a vector with elements masked.
+The calculated clippedMean was 29.945370
+
+---> TESTPOINT PASSED (psVector functions{PS_STAT_CLIPPED_MEAN/STDEV: vector mask} | tst_psStats09.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats09.c                                            *
+*            TestPoint: psStats functions{PS_STAT_CLIPPED_STDEV: vector mask}      *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Called psVectorStats() on a vector with elements masked.
+The calculated clippedStdev was 0.285787
+
+---> TESTPOINT PASSED (psVector functions{PS_STAT_CLIPPED_MEAN/STDEV: vector mask} | tst_psStats09.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats09.c                                            *
+*            TestPoint: psStats functions{psStats(): deallocating memory}          *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psVector functions{psStats(): deallocating memory} | tst_psStats09.c)
+
Index: /tags/rel1_1/psLib/test/dataManip/verified/tst_psVectorFFT.stderr
===================================================================
--- /tags/rel1_1/psLib/test/dataManip/verified/tst_psVectorFFT.stderr	(revision 1056)
+++ /tags/rel1_1/psLib/test/dataManip/verified/tst_psVectorFFT.stderr	(revision 1056)
@@ -0,0 +1,47 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVectorFFT.c                                          *
+*            TestPoint: psFFT{600-testVectorFFT}                                   *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psFFT{600-testVectorFFT} | tst_psVectorFFT.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVectorFFT.c                                          *
+*            TestPoint: psFFT{601-testVectorRealImaginary}                         *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psFFT{601-testVectorRealImaginary} | tst_psVectorFFT.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVectorFFT.c                                          *
+*            TestPoint: psFFT{602-testVectorComplex}                               *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+ <DATE> <TIME> <HOST> |I|testVectorCompl|Following should be an error (type mismatch).
+ <DATE> <TIME> <HOST> |E|psVectorComplex|The inputs to psVectorComplex must be the same type.
+
+---> TESTPOINT PASSED (psFFT{602-testVectorComplex} | tst_psVectorFFT.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVectorFFT.c                                          *
+*            TestPoint: psFFT{603-testVectorConjugate}                             *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psFFT{603-testVectorConjugate} | tst_psVectorFFT.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVectorFFT.c                                          *
+*            TestPoint: psFFT{604-testVectorPowerSpectrum}                         *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psFFT{604-testVectorPowerSpectrum} | tst_psVectorFFT.c)
+
Index: /tags/rel1_1/psLib/test/image/tst_psImage.c
===================================================================
--- /tags/rel1_1/psLib/test/image/tst_psImage.c	(revision 1056)
+++ /tags/rel1_1/psLib/test/image/tst_psImage.c	(revision 1056)
@@ -0,0 +1,1022 @@
+/** @file  tst_psImage.c
+ *
+ *  @brief Contains the tests for psImage.[ch]
+ *
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.18 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-14 23:03:43 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include <math.h>
+#include <float.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "psTest.h"
+#include "pslib.h"
+#include "psType.h"
+
+static int testImageAlloc(void);
+static int testImageSubset(void);
+static int testImageCopy(void);
+static int testImageClip(void);
+static int testImageClipNAN(void);
+static int testImageOverlay(void);
+
+testDescription tests[] = {
+                              {testImageAlloc,"546/548-testImageAlloc/Free",0},
+                              {testImageSubset,"547/550-testImageSubset",0},
+                              {testImageCopy,"551-testImageCopy",0},
+                              {testImageClip,"571-testImageClip",0},
+                              {testImageClipNAN,"572-testImageClipNAN",0},
+                              {testImageOverlay,"573-testImageOverlay",0},
+                              {NULL}
+                          };
+
+int main()
+{
+    psLogSetLevel(PS_LOG_INFO);
+    testImageOverlay();
+    if (! runTestSuite(stderr,"psImage",tests)) {
+        psError(__FILE__,"One or more tests failed");
+        return 1;
+    }
+    return 0;
+}
+
+int testImageAlloc(void)
+{
+    psImage* image = NULL;
+    unsigned int sizes = 6;
+    unsigned int numCols[] = {0,1,1,100,100,150};
+    unsigned int numRows[] = {0,1,100,1,150,100};
+    unsigned int types = 12;
+    psElemType type[] = { PS_TYPE_S8, PS_TYPE_S16, PS_TYPE_S32, PS_TYPE_S64,
+                          PS_TYPE_U8, PS_TYPE_U16, PS_TYPE_U32, PS_TYPE_U64,
+                          PS_TYPE_F32, PS_TYPE_F64, PS_TYPE_C32, PS_TYPE_C64 };
+
+    psLogMsg(__func__,PS_LOG_INFO,"#546 - psImageAlloc shall allocate memory for a psImage structure");
+
+    for (unsigned int t=0;t<types;t++) {
+        psLogMsg(__func__,PS_LOG_INFO,"Testing psImage with type %xh",type[t]);
+
+        for (unsigned int i=0;i<sizes;i++) {
+
+            image = psImageAlloc(numCols[i],numRows[i],type[t]);
+
+            if (image == NULL) {
+                if (numRows[i] == 0 || numCols[i] == 0) {
+                    continue;
+                }
+                psError(__func__,"psImageAlloc returned NULL for type %x, size %dx%d.",
+                        type[t], numCols[i], numRows[i]);
+                psImageFree(image);
+                return 1;
+            }
+
+            if (image->type.dimen != PS_DIMEN_IMAGE || image->type.type != type[t]) {
+                psError(__func__,"psImageAlloc allocated wrong dimen/type (%d/%d), should be "
+                        "PS_IMAGE_DIMEN/%d", image->type.dimen, image->type.type, type[t]);
+                psImageFree(image);
+                return 2;
+            }
+
+            if (image->numCols != numCols[i] || image->numRows != numRows[i]) {
+                psError(__func__,"psImageAlloc allocated wrong size %dx%d, should be %dx%d (type = %d)",
+                        image->numCols, image->numRows, numCols[i], numRows[i],type[t]);
+                psImageFree(image);
+                return 3;
+            }
+
+            if (image->col0 != 0 || image->row0 != 0) {
+                psError(__func__,"psImageAlloc returned row0/col0 of %d/%d.  Should be 0/0.",
+                        image->row0, image->row0);
+                psImageFree(image);
+                return 4;
+            }
+
+            if (image->parent != NULL) {
+                psError(__func__,"psImageAlloc returned non-NULL parent");
+                psImageFree(image);
+                return 5;
+            }
+
+            if (image->nChildren != 0) {
+                psError(__func__,"psImageAlloc returned non-zero number of children");
+                psImageFree(image);
+                return 6;
+            }
+
+            if (image->children != NULL) {
+                psError(__func__,"psImageAlloc returned non-NULL children vector");
+                psImageFree(image);
+                return 7;
+            }
+
+            switch (type[t]) {
+            case PS_TYPE_U16: {
+                    unsigned int rows = numRows[i];
+                    unsigned int cols = numCols[i];
+
+                    for (int r=0;r<rows;r++) {
+                        for (int c=0;c<cols;c++) {
+                            image->data.U16[r][c] = 2*c+r;
+                        }
+                    }
+                    for (int r=0;r<rows;r++) {
+                        for (int c=0;c<cols;c++) {
+                            if (image->data.U16[r][c] != 2*c+r) {
+                                psError(__func__,"Could not set all pixels in uint16 image at (%d,%d)",c,r);
+                                psImageFree(image);
+                                return 8;
+                            }
+                        }
+                    }
+                }
+                break;
+            case PS_TYPE_F32: {
+                    unsigned int rows = numRows[i];
+                    unsigned int cols = numCols[i];
+
+                    for (int r=0;r<rows;r++) {
+                        for (int c=0;c<cols;c++) {
+                            image->data.F32[r][c] = 2.0f*c+r;
+                        }
+                    }
+                    for (int r=0;r<rows;r++) {
+                        for (int c=0;c<cols;c++) {
+                            if (fabsf(image->data.F32[r][c] - (2.0f*c+r)) > FLT_EPSILON) {
+                                psError(__func__,"Could not set all pixels in float image at (%d,%d)",c,r);
+                                psImageFree(image);
+                                return 8;
+                            }
+                        }
+                    }
+                }
+                break;
+            case PS_TYPE_F64: {
+                    unsigned int rows = numRows[i];
+                    unsigned int cols = numCols[i];
+
+                    for (int r=0;r<rows;r++) {
+                        for (int c=0;c<cols;c++) {
+                            image->data.F64[r][c] = 2.0f*c+r;
+                        }
+                    }
+                    for (int r=0;r<rows;r++) {
+                        for (int c=0;c<cols;c++) {
+                            if (fabs(image->data.F64[r][c] - (2.0f*c+r)) > DBL_EPSILON) {
+                                psError(__func__,"Could not set all pixels in double image at (%d,%d)",c,r);
+                                psImageFree(image);
+                                return 8;
+                            }
+                        }
+                    }
+                }
+                break;
+            case PS_TYPE_C32: {
+                    unsigned int rows = numRows[i];
+                    unsigned int cols = numCols[i];
+
+                    for (int r=0;r<rows;r++) {
+                        for (int c=0;c<cols;c++) {
+                            image->data.C32[r][c] = r + I * c;
+                        }
+                    }
+                    for (int r=0;r<rows;r++) {
+                        for (int c=0;c<cols;c++) {
+                            if (fabsf(crealf(image->data.C32[r][c]) - r) > FLT_EPSILON ||
+                                    fabsf(cimagf(image->data.C32[r][c]) - c) > FLT_EPSILON ) {
+                                psError(__func__,"Could not set all pixels in complex image at (%d,%d)",c,r);
+                                psImageFree(image);
+                                return 8;
+                            }
+                        }
+                    }
+                }
+                break;
+            default: {
+                    // ignore type and just use as byte bucket.
+                    unsigned int rows = numRows[i];
+                    unsigned int cols = numCols[i]*PSELEMTYPE_SIZEOF(type[t]);
+
+                    for (int r=0;r<rows;r++) {
+                        for (int c=0;c<cols;c++) {
+                            image->data.U8[r][c] = (uint8_t)(r + c);
+                        }
+                    }
+                    for (int r=0;r<rows;r++) {
+                        for (int c=0;c<cols;c++) {
+                            if (image->data.U8[r][c] != (uint8_t)(r + c)) {
+                                psError(__func__,"Could not set all pixels in image (type=%d) at (%d,%d)",
+                                        type[t],c,r);
+                                psImageFree(image);
+                                return 8;
+                            }
+                        }
+                    }
+                }
+            }
+
+            // #548: Verify no memory leaks or corruption are detected after a valid psImage structure with no
+            // children is freed.
+            psImageFree(image);
+        }
+    }
+
+    // #548: Verify program execution doesn't stop, if the input psImage structure pointer is null.
+    psImageFree(NULL);
+
+    // #548: Verify no memory leaks or corruption are detected after a valid psImage structure with multiple
+    // children isfreed.
+    image = psImageAlloc(100,100,PS_TYPE_F32);
+    psImageSubset(NULL,image,50,50,0,0);
+    psImageSubset(NULL,image,50,50,20,20);
+
+    psImageFree(image);
+
+    return 0;
+}
+
+// #547: psImageSubset shall create child image of a specified size from a parent psImage structure
+int testImageSubset(void)
+{
+    psImage preSubsetStruct;
+    psImage* original;
+    psImage* subset1 = NULL;
+    psImage* subset2 = NULL;
+    psImage* subset3 = NULL;
+    int c = 128;
+    int r = 256;
+
+    original = psImageAlloc(c,r,PS_TYPE_U32);
+    for (int row=0;row<r;row++) {
+        for (int col=0;col<c;col++) {
+            original->data.F32[row][col] = row*1000+col;
+        }
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"memcpy(&preSubsetStruct,original,sizeof(psImage));");
+    memcpy(&preSubsetStruct,original,sizeof(psImage));
+
+    psLogMsg(__func__,PS_LOG_INFO,"subset1 = psImageAlloc(c/4,r/4,PS_TYPE_U8);");
+    subset1 = psImageAlloc(c/4,r/4,PS_TYPE_U8);
+
+    psLogMsg(__func__,PS_LOG_INFO,"subset2 = psImageSubset(subset1,original,c/2,r/2,c/4,r/4);");
+    subset2 = psImageSubset(subset1,original,c/2,r/2,c/4,r/4);
+
+    psLogMsg(__func__,PS_LOG_INFO,"subset3 = psImageSubset(NULL,original,c/2,r/2,0,0);");
+    subset3 = psImageSubset(NULL,original,c/2,r/2,0,0);
+
+    psLogMsg(__func__,PS_LOG_INFO,"Verify the returned psImage structure is equal to the input psImage "
+             "structure parameter out, if input parameter out is specified.");
+
+    if (subset1 != subset2 || subset2 == NULL) {
+        psError(__func__,"psImageSubset didn't recycle the psImage given");
+        return 1;
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"Verify a new psImage structure is created, if input parameter out is set "
+             "to null.");
+
+    if (subset3 == NULL) {
+        psError(__func__,"psImageSubset output was NULL for subset3.");
+        return 2;
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"Verify the returned psImage structure contains expected values in the "
+             "row member, if the input psImage structure image contains known values.");
+
+    for (int row=0;row<r/2;row++) {
+        for (int col=0;col<c/2;col++) {
+            if (subset2->data.U32[row][col] != original->data.U32[row+r/4][col+c/4]) {
+                psError(__func__,"psImageSubset output #1 was wrong at %dx%d (%d vs %d).",
+                        row,col,subset2->data.U32[row][col], original->data.U32[row+r/4][col+c/4]);
+                return 3;
+            }
+            if (subset3->data.U32[row][col] != original->data.U32[row][col]) {
+                psError(__func__,"psImageSubset output #1 was wrong at %dx%d (%d vs %d).",
+                        row,col,subset2->data.U32[row][col], original->data.U32[row][col]);
+                return 4;
+            }
+        }
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"Verify the returned psImage structure members nrow and ncol are equal to "
+             "the input parameter nrow and ncol respectively.");
+
+    if (subset3->numCols != c/2 || subset3->numRows != r/2) {
+        psError(__func__,"psImageSubset output size was not proper(%dx%d, should be %dx%d).",
+                subset3->numCols, subset3->numRows, c/2,r/2);
+        return 5;
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"Verify the returned psImage structure member type is equal to the input "
+             "psImage structure member type.");
+
+    if (subset2->type.type != PS_TYPE_U32) {
+        psError(__func__,"psImageSubset output type was not proper(%d, should be %d).",
+                subset2->type.type, PS_TYPE_U32);
+        return 6;
+    }
+    if (subset3->type.type != PS_TYPE_U32) {
+        psError(__func__,"psImageSubset output type was not proper(%d, should be %d).",
+                subset3->type.type, PS_TYPE_U32);
+        return 7;
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"Verify the returned psImage structure members row0 and col0 are equal to "
+             "the input parameters row0 and col0 respectively.");
+
+    if (subset2->col0 != c/4 || subset2->row0 != r/4) {
+        psError(__func__,"psImageSubset didn't set col0/row0 for subset2 (%d/%d, should be %d/%d).",
+                subset2->col0,subset2->row0,c/4,r/4);
+        return 8;
+    }
+    if (subset3->col0 != 0 || subset3->row0 != 0) {
+        psError(__func__,"psImageSubset didn't set col0/row0 for subset3 (%d/%d, should be %d/%d).",
+                subset3->col0,subset3->row0,0,0);
+        return 9;
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"Verify the returned psImage structure member parent is equal to the "
+             "input psImage structure pointer image.");
+
+    if (subset2->parent != original || subset3->parent != original) {
+        psError(__func__,"psImageSubset didn't set parent.");
+        return 10;
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"Verify the returned psImage structure member Nchildren is equal to "
+             "zero.");
+
+    if (subset2->nChildren != 0 || subset3->nChildren != 0) {
+        psError(__func__,"psImageSubset didn't set nChildren to zero.");
+        return 11;
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"Verify the returned psImage structure member children is null.");
+
+    if (subset2->children != NULL || subset3->children != NULL) {
+        psError(__func__,"psImageSubset didn't set children to NULL.");
+        return 11;
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"Verify the input psImage structure image only has the following members "
+             "changed: 1) Nchildren is increased by one. 2) parent contains pointer psImage structure "
+             "out at parent[Nchildren-1].");
+
+    if (original->nChildren != preSubsetStruct.nChildren+2) {
+        psError(__func__,"psImageSubset didn't increment nChildren by one per subset.");
+        return 12;
+    }
+    if (original->children[0] != subset2 || original->children[1] != subset3) {
+        psError(__func__,"psImageSubset didn't properly store the children pointers.");
+        return 13;
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"Verify the returned psImage structure pointer is null and program "
+             "execution doesn't stop, if the input parameter image is null. Also verified the input "
+             "psImage structure is not modified.");
+
+    psLogMsg(__func__,PS_LOG_INFO,"An error should follow...");
+    subset1 = psImageSubset(NULL,NULL,c/2,r/2,0,0);
+    if (subset1 != NULL) {
+        psError(__func__,"psImageSubset didn't return NULL when input image was NULL.");
+        return 14;
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"Verify the returned psImage structure pointer is null and program "
+             " execution doesn't stop, if the input parameters nrow and/or ncol are zero. Also verify "
+             "input psImage structure is not modified.");
+
+    memcpy(&preSubsetStruct,original,sizeof(psImage));
+    psLogMsg(__func__,PS_LOG_INFO,"An error should follow...");
+    subset1 = psImageSubset(NULL,original,c/2,0,0,0);
+    if (subset1 != NULL) {
+        psError(__func__,"psImageSubset didn't return NULL when numRows=0.");
+        return 15;
+    }
+    psLogMsg(__func__,PS_LOG_INFO,"An error should follow...");
+    subset1 = psImageSubset(NULL,original,0,r/2,0,0);
+    if (subset1 != NULL) {
+        psError(__func__,"psImageSubset didn't return NULL when numCols=0.");
+        return 16;
+    }
+    if (memcmp(original,&preSubsetStruct,sizeof(psImage)) != 0) {
+        psError(__func__,"psImageSubset changed the original struct though it failed to subset.");
+        return 17;
+    }
+
+
+    psLogMsg(__func__,PS_LOG_INFO,"Verify the returned psImage structure pointer is null and program "
+             "execution doesn't stop, if the input parameters row0 and col0 are not within the range of "
+             "values of psImage structure image.");
+
+    psLogMsg(__func__,PS_LOG_INFO,"An error should follow...");
+    subset1 = psImageSubset(NULL,original,c/2,r/2,c,0);
+    if (subset1 != NULL) {
+        psError(__func__,"psImageSubset didn't return NULL when subset origin was outside of "
+                "image (via cols).");
+        return 18;
+    }
+    psLogMsg(__func__,PS_LOG_INFO,"An error should follow...");
+    subset1 = psImageSubset(NULL,original,c/2,r/2,0,r);
+    if (subset1 != NULL) {
+        psError(__func__,"psImageSubset didn't return NULL when subset origin was outside of "
+                "image (via rows).");
+        return 19;
+    }
+    psLogMsg(__func__,PS_LOG_INFO,"An error should follow...");
+    subset1 = psImageSubset(NULL,original,c/2,r/2,-1,0);
+    if (subset1 != NULL) {
+        psError(__func__,"psImageSubset didn't return NULL when subset origin was outside of "
+                "image (col0=-1).");
+        return 20;
+    }
+    psLogMsg(__func__,PS_LOG_INFO,"An error should follow...");
+    subset1 = psImageSubset(NULL,original,c/2,r/2,0,-1);
+    if (subset1 != NULL) {
+        psError(__func__,"psImageSubset didn't return NULL when subset origin was outside of "
+                "image (row0=-1).");
+        return 21;
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"Verify the returned psImage structure pointer is null and program "
+             "execution doesn't stop if the input parameters nrow, ncol, row0 and col0 specify a range of "
+             "data not within the input psImage structure image.  Also verify the input psImage structure "
+             "is not modified.");
+
+    psLogMsg(__func__,PS_LOG_INFO,"An error should follow...");
+    subset1 = psImageSubset(NULL,original,c/2,r/2,c/2,0);
+    if (subset1 != NULL) {
+        psError(__func__,"psImageSubset didn't return NULL when subset was outside of image (via rows).");
+        return 22;
+    }
+    psLogMsg(__func__,PS_LOG_INFO,"An error should follow...");
+    subset1 = psImageSubset(NULL,original,c/2,r/2,0,r/2);
+    if (subset1 != NULL) {
+        psError(__func__,"psImageSubset didn't return NULL when subset was outside of image (via cols).");
+        return 23;
+    }
+    psLogMsg(__func__,PS_LOG_INFO,"An error should follow...");
+    subset1 = psImageSubset(NULL,original,c/2,r/2,c/2,r/2);
+    if (subset1 != NULL) {
+        psError(__func__,"psImageSubset didn't return NULL when subset was outside of image (via row+cols).");
+        return 24;
+    }
+
+    psLogMsg(__func__, PS_LOG_INFO, "psImageFreeChildren shall deallocate any children images of a "
+             "psImage structure");
+
+    memcpy(&preSubsetStruct,original,sizeof(psImage));
+
+    psImageFreeChildren(original);
+
+    // Verify the returned psImage structure member Nchildren is set to zero.
+    if (original->nChildren != 0) {
+        psError(__func__,"psImageFreeChildren didn't set nChildren to zero.");
+        return 25;
+    }
+
+    // Verify the returned psImage structure member children pointer is set to null.
+    if (original->children != NULL) {
+        psError(__func__,"psImageFreeChildren didn't set children ptr to NULL.");
+        return 26;
+    }
+
+    //Verify the returned psImage structure members type, nrow, ncol, row0, col0, rows and parent are not
+    // modified.
+    if (preSubsetStruct.numRows != original->numRows ||
+            preSubsetStruct.numCols != original->numCols ||
+            preSubsetStruct.row0 != original->row0 ||
+            preSubsetStruct.col0 != original->col0) {
+
+        psError(__func__,"psImageFreeChildren modified parent's non-children elements.");
+        return 27;
+    }
+
+    psImageFree(original);
+
+    return 0;
+}
+
+int testImageCopy(void)
+{
+    psImage* img = NULL;
+    psImage* img2 = NULL;
+    psImage* img3 = NULL;
+    unsigned int c = 128;
+    unsigned int r = 256;
+
+    img = psImageAlloc(c,r,PS_TYPE_F32);
+    for (unsigned row=0;row<r;row++) {
+        psF32* imgRow = img->data.F32[row];
+        for (unsigned col=0;col<c;col++) {
+            imgRow[col] = (psF32)(row+col);
+        }
+    }
+    img2 = psImageAlloc(c,r,PS_TYPE_F32);
+    for (unsigned row=0;row<r;row++) {
+        psF32* img2Row = img2->data.F32[row];
+        for (unsigned col=0;col<c;col++) {
+            img2Row[col] = 0.0f;
+        }
+    }
+
+    img3 = psImageCopy(img2,img,PS_TYPE_F32);
+
+    // Verify the returned psImage structure pointer is equal to the input parameter output.
+    if (img2 != img3) {
+        psError(__func__,"the image given for recycled wasn't");
+        return 1;
+    }
+
+    // Verify the returned psImage structure member are equal to the values in
+    // the input psImage structure input.
+
+    #define testImageCopyType(IN,OUT) \
+    img = psImageRecycle(img,c,r,PS_TYPE_##IN); \
+    for (unsigned row=0;row<r;row++) { \
+        ps##IN* imgRow = img->data.IN[row]; \
+        for (unsigned col=0;col<c;col++) { \
+            imgRow[col] = (ps##IN)(row+col); \
+        } \
+    } \
+    img2 = psImageCopy(img2,img,PS_TYPE_##OUT); \
+    if (img2 == NULL) { \
+        psError(__func__,"psImageCopy failed to copy U8."); \
+        return 2; \
+    } \
+    for (unsigned int row=0;row<r;row++) { \
+        ps##IN* imgRow = img->data.IN[row]; \
+        ps##OUT* img2Row = img2->data.OUT[row]; \
+        for (unsigned int col=0;col<c;col++) { \
+            if (abs(imgRow[col] - (ps##IN)(row+col)) > 0.5) { \
+                psError(__func__,"Input image was changed at %d,%d!", \
+                        col,row); \
+                return 2; \
+            } \
+            if (abs(img2Row[col] - (ps##OUT)(imgRow[col])) > 0.5) { \
+                psError(__func__,"returned psImage values after copy don't match at %d,%d " \
+                        "(%d vs %d)",\
+                        col,row,img2Row[col], (ps##OUT)(imgRow[col])); \
+                return 2; \
+            } \
+        } \
+    }
+
+    #define testImageCopyTypes(IN) \
+    testImageCopyType(IN,U8); \
+    testImageCopyType(IN,U16); \
+    testImageCopyType(IN,U32); \
+    testImageCopyType(IN,S8);\
+    testImageCopyType(IN,S16);\
+    testImageCopyType(IN,S32);\
+    testImageCopyType(IN,F32);\
+    testImageCopyType(IN,F64);
+
+    testImageCopyTypes(U8);
+    testImageCopyTypes(U16);
+    testImageCopyTypes(U32);
+    testImageCopyTypes(S8);
+    testImageCopyTypes(S16);
+    testImageCopyTypes(S32);
+    testImageCopyTypes(F32);
+    testImageCopyTypes(F64);
+
+    // Verify the returned psImage structure pointer is null and program
+    // execution doesn't stop, if the input parameter input is null.
+    psLogMsg(__func__,PS_LOG_INFO,"An error should follow...");
+    img3 = psImageCopy(NULL,NULL,PS_TYPE_F32);
+    if (img3 != NULL) {
+        psError(__func__,"psImageCopy didn't return NULL when input image was NULL.");
+        return 3;
+    }
+
+    psImageFree(img);
+    psImageFree(img2);
+
+    return 0;
+}
+
+int testImageClip(void)
+{
+    psImage* img = NULL;
+    unsigned int c = 128;
+    unsigned int r = 256;
+    psF32 min;
+    psF32 max;
+    int numClipped = 0;
+    int retVal;
+
+    psLogMsg(__func__,PS_LOG_INFO,
+             "psImageClip shall limit the minimum and maximum data value within a psImage structure");
+
+    /*
+
+        psImageClip shall limit the minimum and maximum data value within a
+        psImage structure to a specified min and max value.
+
+        Verify the returned integer is equal to the number of pixels clipped,
+        if the input psImage structure contains known values and input parameters
+        min and max have know values.
+
+        Verify the psImage structure specified by the input parameter input is
+        modified to contain the expected values, if the input psImage structure
+        contains known values, min and max are specified and vmin and vmax
+        parameters are known.
+
+        Verify the retuned integer is zero, psImage structure input is unmodified
+        and program executions doesn't stop, if input parameter psImage structure
+        pointer is null.
+
+        Verify the retuned integer is zero, psImage structure input is unmodified
+        and program executions doesn't stop, if input parameter min is larger than max.
+    */
+
+    // create image
+    #define testImageClipByType(datatype) \
+    img = psImageAlloc(c,r,PS_TYPE_##datatype); \
+    for (unsigned int row=0;row<r;row++) { \
+        ps##datatype* imgRow = img->data.datatype[row]; \
+        for (unsigned int col=0;col<c;col++) { \
+            imgRow[col] = (ps##datatype)(row+col); \
+        } \
+    } \
+    min = (float)r/2.0f; \
+    max = (float)r; \
+    \
+    retVal = psImageClip(img,min,-1.0f,max,-2.0f); \
+    \
+    numClipped = 0; \
+    for (unsigned int row=0;row<r;row++) { \
+        ps##datatype* imgRow = img->data.datatype[row]; \
+        for (unsigned int col=0;col<c;col++) { \
+            ps##datatype value = (ps##datatype)(row+col); \
+            if (value < (ps##datatype)min) { \
+                numClipped++; \
+                value = -1; \
+            } else if (value > (ps##datatype)max) { \
+                numClipped++; \
+                value = -2; \
+            } \
+            if (fabsf(imgRow[col]-value) > FLT_EPSILON) { \
+                psError(__func__,"Pixel value is not as expected (%d vs %d) at %u,%u", \
+                        imgRow[col],value,col,row); \
+                return 1; \
+            } \
+        } \
+    } \
+    if (retVal != numClipped) { \
+        psError(__func__,"Expected %d clips, but got %d", \
+                numClipped,retVal); \
+        return 2; \
+    } \
+    psImageFree(img);
+
+    #define testImageClipByComplexType(datatype) \
+    img = psImageAlloc(c,r,PS_TYPE_##datatype); \
+    for (unsigned int row=0;row<r;row++) { \
+        ps##datatype* imgRow = img->data.datatype[row]; \
+        for (unsigned int col=0;col<c;col++) { \
+            imgRow[col] = (ps##datatype)(row+I*col); \
+        } \
+    } \
+    min = (float)r/2.0f; \
+    max = (float)r; \
+    \
+    retVal = psImageClip(img,min,-1.0f,max,-2.0f); \
+    \
+    numClipped = 0; \
+    for (unsigned int row=0;row<r;row++) { \
+        ps##datatype* imgRow = img->data.datatype[row]; \
+        for (unsigned int col=0;col<c;col++) { \
+            ps##datatype value = row+I*col; \
+            if (cabs(value) < min) { \
+                numClipped++; \
+                value = -1.0f; \
+            } else if (cabs(value) > max) { \
+                numClipped++; \
+                value = -2.0f; \
+            } \
+            if (fabsf(creal(imgRow[col])-creal(value)) > FLT_EPSILON || \
+                    fabsf(cimag(imgRow[col])-cimag(value)) > FLT_EPSILON) { \
+                psError(__func__,"Pixel value is not as expected (%.2f+%.2fi vs %.2f+%.2fi) at %u,%u", \
+                        creal(imgRow[col]),cimag(imgRow[col]),creal(value),cimag(value),col,row); \
+                return 1; \
+            } \
+        } \
+    } \
+    if (retVal != numClipped) { \
+        psError(__func__,"Expected %d clips, but got %d", \
+                numClipped,retVal); \
+        return 2; \
+    } \
+    psImageFree(img);
+
+    psLogMsg(__func__,PS_LOG_INFO,"Testing clipping of F64 imagery");
+    testImageClipByType(F64);
+    psLogMsg(__func__,PS_LOG_INFO,"Testing clipping of F32 imagery");
+    testImageClipByType(F32);
+    psLogMsg(__func__,PS_LOG_INFO,"Testing clipping of S32 imagery");
+    testImageClipByType(S32);
+    psLogMsg(__func__,PS_LOG_INFO,"Testing clipping of S16 imagery");
+    testImageClipByType(S16);
+    psLogMsg(__func__,PS_LOG_INFO,"Testing clipping of S8 imagery");
+    testImageClipByType(S8);
+    psLogMsg(__func__,PS_LOG_INFO,"Testing clipping of U32 imagery");
+    testImageClipByType(U32);
+    psLogMsg(__func__,PS_LOG_INFO,"Testing clipping of U16 imagery");
+    testImageClipByType(U16);
+    psLogMsg(__func__,PS_LOG_INFO,"Testing clipping of U8 imagery");
+    testImageClipByType(U8);
+    psLogMsg(__func__,PS_LOG_INFO,"Testing clipping of C32 imagery");
+    testImageClipByComplexType(C32);
+    psLogMsg(__func__,PS_LOG_INFO,"Testing clipping of C64 imagery");
+    testImageClipByComplexType(C64);
+
+    // Verify the retuned integer is zero, psImage structure input is unmodified
+    // and program executions doesn't stop, if input parameter psImage structure
+    // pointer is null.
+    retVal = psImageClip(NULL,min,-1.0f,max,-2.0f);
+    if (retVal != 0) {
+        psError(__func__,"Expected zero return for clips of a NULL image.");
+        return 3;
+    }
+
+    // Verify the retuned integer is zero, psImage structure input is unmodified
+    // and program executions doesn't stop, if input parameter min is larger than max.
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error (max<min)");
+    retVal = psImageClip(img,max,-1.0f,min,-2.0f);
+    if (retVal != 0) {
+        psError(__func__,"Expected zero return for clips when max < min.");
+        return 4;
+    }
+
+    return 0;
+}
+
+int testImageClipNAN(void)
+{
+    psImage* img = NULL;
+    unsigned int c = 128;
+    unsigned int r = 256;
+    int numClipped = 0;
+    int retVal;
+
+    psLogMsg(__func__,PS_LOG_INFO,
+             "psImageClipNaN shall modified pixel values of NaN with a specified value");
+
+    /*
+        psImageClipNaN shall modify a psImage structure with pixel values set
+        to NaN to a value specified as an input parameter.
+
+        Verify the returned integer is equal to the number of pixels modified
+        and the psImage is modified at locations where NaN pixels where
+        located to the value specified in the input parameter value.
+
+        Verify the returned integer is zero and program execution doesn't stop,
+        if the input parameter psImage structure pointer is null.
+    */
+
+    // create image
+    #define testImageClipNaNByType(datatype) \
+    img = psImageAlloc(c,r,PS_TYPE_##datatype); \
+    for (unsigned row=0;row<r;row++) { \
+        ps##datatype* imgRow = img->data.datatype[row]; \
+        for (unsigned col=0;col<c;col++) { \
+            if (row == col) { \
+                imgRow[col] = NAN; \
+            } else if (row+1 == col) { \
+                imgRow[col] = INFINITY; \
+            } else { \
+                imgRow[col] = (ps##datatype)(row+col); \
+            } \
+        } \
+    } \
+    \
+    retVal = psImageClipNaN(img,-1.0f); \
+    \
+    numClipped = 0; \
+    for (unsigned row=0;row<r;row++) { \
+        ps##datatype* imgRow = img->data.datatype[row]; \
+        for (unsigned col=0;col<c;col++) { \
+            ps##datatype value = (ps##datatype)(row+col); \
+            if ( (row == col) || (row+1 == col) ) { \
+                numClipped++; \
+                value = -1.0; \
+            } \
+            if (fabsf(imgRow[col]-value) > FLT_EPSILON) { \
+                psError(__func__,"Pixel value is not as expected (%f vs %f) at %d,%d", \
+                        imgRow[col],value,col,row); \
+                return 1; \
+            } \
+        } \
+    } \
+    if (retVal != numClipped) { \
+        psError(__func__,"Expected %d clips, but got %d", \
+                numClipped,retVal); \
+        return 2; \
+    } \
+    psImageFree(img);
+
+    testImageClipNaNByType(F32);
+    testImageClipNaNByType(F64);
+
+    // Verify the retuned integer is zero, psImage structure input is unmodified
+    // and program executions doesn't stop, if input parameter psImage structure
+    // pointer is null.
+    retVal = psImageClipNaN(NULL,-1.0f);
+    if (retVal != 0) {
+        psError(__func__,"Expected zero return for clips of a NULL image.");
+        return 3;
+    }
+
+    return 0;
+}
+
+int testImageOverlay(void)
+{
+
+    psImage* img = NULL;
+    psImage* img2 = NULL;
+    unsigned int c = 128;
+    unsigned int r = 256;
+    int retVal;
+
+    /*
+    psImageSectionOverlay shall modified pixel values in a psImage structure to
+    be equal to the value of the originaldata and an overlay image with a
+    specified operation. Valid operations include =, +, -, *, /.
+
+    Verify the returned integer is zero
+    and the input parameter psImage structure is modified at the specified
+    location and range with the given overlay image and the specified
+    function. Cases should include all the valid operations. Comparison of
+    expected values should include a delta to allow for testing on
+    different platforms.
+
+    */
+
+
+
+    #define testOverlayTypeOP(DATATYPE,OP,OPSTRING) \
+    img = psImageAlloc(c,r,PS_TYPE_##DATATYPE); \
+    for (unsigned row=0;row<r;row++) { \
+        ps##DATATYPE* imgRow = img->data.DATATYPE[row]; \
+        for (unsigned col=0;col<c;col++) { \
+            imgRow[col] = 6.0; \
+        } \
+    } \
+    img2 = psImageAlloc(c/2,r/2,PS_TYPE_##DATATYPE); \
+    for (unsigned row=0;row<r/2;row++) { \
+        ps##DATATYPE* img2Row = img2->data.DATATYPE[row]; \
+        for (unsigned col=0;col<c/2;col++) { \
+            img2Row[col] = 2.0; \
+        } \
+    } \
+    retVal = psImageOverlaySection(img,img2,c/4,r/4,OPSTRING); \
+    if (retVal != 0) { \
+        psError(__func__,"psImageOverlaySection returned non-zero %s op",OPSTRING); \
+        return 1; \
+    } \
+    for (unsigned row=0;row<r;row++) { \
+        ps##DATATYPE* imgRow = img->data.DATATYPE[row]; \
+        ps##DATATYPE* img2Row = img2->data.DATATYPE[row]; \
+        for (unsigned col=0;col<c;col++) { \
+            ps##DATATYPE val = 6.0; \
+            if ( ! (row < r/4 || row >= r/2+r/4 || col < c/4 || col >= c/2+c/4)) { \
+                val OP 2.0; \
+            } \
+            if (fabsf(imgRow[col] - val) > FLT_EPSILON) { \
+                psError(__func__,"Value incorrect at %d,%d (%.2f vs %.2f for %s)", \
+                        col,row,imgRow[col],val,OPSTRING); \
+                return 2; \
+            } \
+            if (row < r/2 && col < c/2 && fabsf(img2Row[col] - 2.0) > FLT_EPSILON) { \
+                psError(__func__,"Overlay modified at %d,%d (%.2f for %s)", \
+                        col,row,img2Row[col],OPSTRING); \
+                return 2; \
+            } \
+        } \
+    } \
+    psImageFree(img); \
+    psImageFree(img2);
+
+    #define testOverlayType(DATATYPE) \
+    testOverlayTypeOP(DATATYPE,+=,"+"); \
+    testOverlayTypeOP(DATATYPE,-=,"-"); \
+    testOverlayTypeOP(DATATYPE,*=,"*");\
+    testOverlayTypeOP(DATATYPE,/=,"/");\
+    testOverlayTypeOP(DATATYPE,=,"=");
+
+    testOverlayType(C64);
+    testOverlayType(C32);
+    testOverlayType(F64);
+    testOverlayType(F32);
+    testOverlayType(S16);
+    testOverlayType(S8);
+    testOverlayType(U16);
+    testOverlayType(U8);
+
+    /*
+    Verify the returned integer is equal to non-zero and the input psImage structure
+    is unmodified, if the overlay specified is not within the data range of the
+    input psImage structure.
+    */
+
+    img = psImageAlloc(c,r,PS_TYPE_F32);
+    for (unsigned row=0;row<r;row++) {
+        psF32* imgRow = img->data.F32[row];
+        for (unsigned col=0;col<c;col++) {
+            imgRow[col] = 6.0f;
+        }
+    }
+    img2 = psImageAlloc(c,r,PS_TYPE_F32);
+    for (unsigned row=0;row<r;row++) {
+        psF32* img2Row = img2->data.F32[row];
+        for (unsigned col=0;col<c;col++) {
+            img2Row[col] = 2.0f;
+        }
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"Following should error as overlay isn't within image boundaries");
+    retVal = psImageOverlaySection(img,img2,c/4,r/4,"+");
+    if (retVal == 0) {
+        psError(__func__,"psImageOverlaySection returned zero even though "
+                "overlay too big");
+        return 3;
+    }
+    for (unsigned row=0;row<r;row++) {
+        psF32* imgRow = img->data.F32[row];
+        for (unsigned col=0;col<c;col++) {
+            if (imgRow[col] != 6.0f) {
+                psError(__func__,"Input image modified when overlay size too big");
+                return 4;
+            }
+        }
+    }
+
+    /*
+    Verify the returned integer is equal to non-zero, the input psImage
+    structure is unmodified and program execution doesn't stop, if the
+    overlay specified is null.
+    */
+
+    psLogMsg(__func__,PS_LOG_INFO,"Following should error as overlay is NULL");
+    retVal = psImageOverlaySection(img,NULL,c/4,r/4,"+");
+    if (retVal == 0) {
+        psError(__func__,"psImageOverlaySection returned zero even though "
+                "overlay too big");
+        return 5;
+    }
+    for (unsigned row=0;row<r;row++) {
+        psF32* imgRow = img->data.F32[row];
+        for (unsigned col=0;col<c;col++) {
+            if (imgRow[col] != 6.0f) {
+                psError(__func__,"Input image modified when overlay NULL");
+                return 6;
+            }
+        }
+    }
+
+    /*
+    Verify the returned integer is equal to non-zero and program execution
+    doesn't stop, if the input parameter image is null.
+    */
+
+    psLogMsg(__func__,PS_LOG_INFO,"Following should error as image input is NULL");
+    retVal = psImageOverlaySection(NULL,img2,c/4,r/4,"+");
+    if (retVal == 0) {
+        psError(__func__,"psImageOverlaySection returned zero even though "
+                "overlay too big");
+        return 7;
+    }
+
+    /*
+    Verify program execution doen't stop, if the overly image contains
+    zero values with division operation is specified.
+    */
+    for (unsigned row=0;row<r;row++) {
+        psF32* img2Row = img2->data.F32[row];
+        for (unsigned col=0;col<c;col++) {
+            img2Row[col] = 0.0f;
+        }
+    }
+    retVal = psImageOverlaySection(img,img2,0,0,"/");
+    if (retVal != 0) {
+        psError(__func__,"psImageOverlaySection returned non-zero when "
+                "checking divide-by-zero.");
+        return 8;
+    }
+
+    psImageFree(img);
+    psImageFree(img2);
+
+    return 0;
+}
Index: /tags/rel1_1/psLib/test/image/tst_psImageFFT.c
===================================================================
--- /tags/rel1_1/psLib/test/image/tst_psImageFFT.c	(revision 1056)
+++ /tags/rel1_1/psLib/test/image/tst_psImageFFT.c	(revision 1056)
@@ -0,0 +1,365 @@
+/** @file  tst_psImageFFT.c
+ *
+ *  @brief Contains the tests for psFFT.[ch]
+ *
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.2 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-12 19:46:04 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include <math.h>
+#include <float.h>
+
+#include "psTest.h"
+#include "pslib.h"
+
+#define GENIMAGE(img,c,r,TYP, valueFcn) \
+img = psImageAlloc(c,r,PS_TYPE_##TYP); \
+for (unsigned int row=0;row<r;row++) { \
+    ps##TYP* imgRow = img->data.TYP[row]; \
+    for (unsigned int col=0;col<c;col++) { \
+        imgRow[col] = (ps##TYP)(valueFcn); \
+    } \
+}
+
+static int testImageFFT(void);
+static int testImageRealImaginary(void);
+static int testImageComplex(void);
+static int testImageConjugate(void);
+static int testImagePowerSpectrum(void);
+
+testDescription tests[] = {
+                              {testImageFFT,"600-testImageFFT",0},
+                              {testImageRealImaginary,"601-testImageRealImaginary",0},
+                              {testImageComplex,"602-testImageComplex",0},
+                              {testImageConjugate,"603-testImageConjugate",0},
+                              {testImagePowerSpectrum,"604-testImagePowerSpectrum",0},
+                              {NULL}
+                          };
+
+int main()
+{
+    psLogSetLevel(PS_LOG_INFO);
+
+    if (! runTestSuite(stderr,"psFFT",tests)) {
+        psAbort(__FILE__,"One or more tests failed");
+    }
+    return 0;
+}
+
+int testImageFFT(void)
+{
+    psImage* img = NULL;
+    psImage* img2 = NULL;
+    psImage* img3 = NULL;
+    unsigned int m = 128;
+    unsigned int n = 64;
+
+    /*
+    1. assign a image to a radial sinisoid
+    2. perform a forward transform
+    3. verify that the only significant component cooresponds to the freqency of the input in step 1.
+    4. perform a reverse transform
+    5. compare to original (should be equal to within a reasonable error)
+    */
+
+    // 1. assign a image to a radial sinisoid
+    GENIMAGE(img,m,n,F32, sinf((32.0f-row)/16.0f*M_PI)+sinf((64.0f-col)/32.0f*M_PI));
+
+    // 2. perform a forward transform
+    img2 = psImageFFT(NULL,img,PS_FFT_FORWARD);
+    if (img2->type.type != PS_TYPE_C32) {
+        psError(__func__,"FFT didn't produce complex values?");
+        return 1;
+    }
+
+    // 3. verify that the only significant component cooresponds to the freqency of the input in step 1.
+    for (unsigned int row=0;row<n;row++) {
+        psC32* img2Row = img2->data.C32[row];
+        for (unsigned int col=0;col<m;col++) {
+            psF32 mag = cabsf(img2Row[col])/m/n;
+            if (mag > 0.1f) {
+                // must be (0,1) or (0,n-1) or (1,0) or (n-1,0)
+                if (! (col == 0 && (row == 1 || row == n-1))
+                        && ! (row == 0 && (col==1 || col == n-1)) ) {
+                    psError(__func__,"Result invalid at %d,%d (%.2f)",col,row,mag);
+                }
+            } else if ( (col == 0 && (row == 1 || row == n-1))
+                        || (row == 0 && (col==1 || col == n-1)) ) {
+                psError(__func__,"Result invalid at %d,%d (%.2f)",col,row,mag);
+            }
+        }
+    }
+
+    // 4. perform a reverse transform
+    img3 = psImageFFT(NULL,img2,PS_FFT_REVERSE);
+    if (img3->type.type != PS_TYPE_C32) {
+        psError(__func__,"FFT didn't produce complex values?");
+        return 4;
+    }
+
+    for (unsigned int row=0;row<n;row++) {
+        psC32* img3Row = img3->data.C32[row];
+        psF32* imgRow = img->data.F32[row];
+        for (unsigned int col=0;col<m;col++) {
+            psF32 pixel = creal(img3Row[col])/m/n;
+            if (fabsf(pixel-imgRow[col]) > 0.1) {
+                psError(__func__,"Reverse FFT didn't gime original image back (%d,%d %.2f vs %.2f)",
+                        col,row,pixel,imgRow[col]);
+                return 5;
+            }
+        }
+    }
+
+    psImageFree(img);
+    psImageFree(img2);
+    psImageFree(img3);
+
+    return 0;
+}
+
+int testImageRealImaginary(void)
+{
+    psImage* img = NULL;
+    psImage* img2 = NULL;
+    psImage* img3 = NULL;
+    unsigned int m = 128;
+    unsigned int n = 64;
+
+    /*
+    1. create a C32 complex vector with distinctly different real and imaginary parts.
+    2. call psImageReal and psImageImaginary
+    3. compare results to the real/imaginary components of input
+    */
+
+    // 1. create a C32 complex vector with distinctly different real and imaginary parts.
+    GENIMAGE(img,m,n,C32, row + I * col);
+
+    // 2. call psImageReal and psImageImaginary
+    img2 = psImageReal(img2,img);
+    if (img2 == NULL) {
+        psError(__func__,"psImageReal returned a NULL?");
+        return 1;
+    }
+    if (img2->type.type != PS_TYPE_F32) {
+        psError(__func__,"psImageReal returned a wrong type (%d)?",
+                img2->type.type);
+        return 2;
+    }
+
+    img3 = psImageImaginary(img3,img);
+    if (img3 == NULL) {
+        psError(__func__,"psImageImaginary returned a NULL?");
+        return 3;
+    }
+    if (img3->type.type != PS_TYPE_F32) {
+        psError(__func__,"psImageImaginary returned a wrong type (%d)?",
+                img3->type.type);
+        return 4;
+    }
+
+    // 3. compare results to the real/imaginary components of input
+    for (unsigned int row=0;row<n;row++) {
+        psF32* img2Row = img2->data.F32[row];
+        psF32* img3Row = img3->data.F32[row];
+        for (unsigned int col=0;col<m;col++) {
+            if (fabsf(img2Row[col] - row) > FLT_EPSILON) {
+                psError(__func__,"psImageReal didn't return the real portion at n=%d",
+                        n);
+                return 5;
+            }
+            if (fabsf(img3Row[col] - col) > FLT_EPSILON) {
+                psError(__func__,"psImageImaginary didn't return the imag portion at n=%d",
+                        n);
+                return 6;
+            }
+        }
+    }
+
+    psImageFree(img);
+    psImageFree(img2);
+    psImageFree(img3);
+
+    return 0;
+}
+
+int testImageComplex(void)
+{
+    psImage* img = NULL;
+    psImage* img2 = NULL;
+    psImage* img3 = NULL;
+    unsigned int m = 128;
+    unsigned int n = 64;
+
+    /*
+    1. create two unique psF32 vectors of the same size
+    2. call psImageComplex
+    3. verify that the result is a psC32
+    4. call psImageReal and psImageImaginary on step 2 results
+    5. compare step 4 results to input.
+
+    6. create a psF32 and a psF64 vector of the same size
+    7. call psImageComplex
+    8. verify that an appropriate error occurred.
+
+    9. create two psf32 vectors of different sizes
+    10. call psImageComplex
+    11. verify thet an appropriate error occurred.
+    */
+
+    // 1. create two unique psF32 vectors of the same size
+    GENIMAGE(img,m,n,F32,row);
+    GENIMAGE(img2,m,n,F32,col);
+
+    // 2. call psImageComplex
+    img3 = psImageComplex(img3,img,img2);
+
+    // 3. verify that the result is a psC32
+    if (img3->type.type != PS_TYPE_C32) {
+        psError(__func__,"Image Type from psImageComplex is not complex? (%d)",
+                img3->type.type);
+        return 1;
+    }
+
+    // 4. call psImageReal and psImageImaginary on step 2 results (not needed, just use crealf/cimagf)
+    // 5. compare step 4 results to input.
+    for (unsigned int row=0;row<n;row++) {
+        psC32* img3Row = img3->data.C32[row];
+        for (unsigned int col=0;col<m;col++) {
+            if (fabsf(crealf(img3Row[col]) - row) > FLT_EPSILON ||
+                    fabsf(cimagf(img3Row[col]) - col) > FLT_EPSILON) {
+                psError(__func__,"psImageComplex result is invalid (%d,%d, %.2f+%.2fi)",
+                        col,row,crealf(img3Row[col]),cimagf(img3Row[col]));
+                return 2;
+            }
+        }
+    }
+
+    // 6. create a psF32 and a psF64 image of the same size
+    img2 = psImageRecycle(img2,m,n,PS_TYPE_F64);
+
+    // 7. call psImageComplex
+    psLogMsg(__func__,PS_LOG_INFO, "Following should be an error (type mismatch).");
+    img3 = psImageComplex(img3,img,img2);
+    // 8. verify that an appropriate error occurred. (this partially has to be done via inspection)
+    if (img3 != NULL) {
+        psError(__func__,"psImageComplex returned a image though input types mismatched.");
+        return 3;
+    }
+
+    // 9. create two psf32 vectors of different sizes
+    img2 = psImageRecycle(img2,m/2,n,PS_TYPE_F32);
+
+    // 10. call psImageComplex
+    psLogMsg(__func__,PS_LOG_INFO, "Following should be an error (size mismatch).");
+    img3 = psImageComplex(img3,img,img2);
+
+    // 11. verify thet an appropriate error occurred.
+    if (img3 != NULL) {
+        psError(__func__,"psImageComplex returned a image though input sizes mismatched.");
+        return 4;
+    }
+
+    psImageFree(img);
+    psImageFree(img2);
+    psImageFree(img3);
+
+    return 0;
+}
+
+int testImageConjugate(void)
+{
+    psImage* img = NULL;
+    psImage* img2 = NULL;
+    unsigned int m = 128;
+    unsigned int n = 64;
+
+    /*
+    1. create a psC32 with unique real and imaginary values.
+    2. call psImageConjugate
+    3. verify result is psC32
+    4. verify each value is conjugate of input (a+bi -> a-bi)
+    */
+
+    // 1. create a psC32 with unique real and imaginary values.
+    GENIMAGE(img,m,n,C32, row + I * col);
+
+    // 2. call psImageConjugate
+    img2 = psImageConjugate(img2,img);
+
+    // 3. verify result is psC32
+    if (img2->type.type != PS_TYPE_C32) {
+        psError(__func__,"the psImageConjugate didn't return a C32 image.");
+        return 1;
+    }
+
+    // 4. verify each value is conjugate of input (a+bi -> a-bi)
+    for (unsigned int row=0;row<n;row++) {
+        psC32* img2Row = img2->data.C32[row];
+        for (unsigned int col=0;col<m;col++) {
+            if (fabsf(crealf(img2Row[col]) - row) > FLT_EPSILON ||
+                    fabsf(cimagf(img2Row[col]) + col) > FLT_EPSILON) {
+                psError(__func__,"psImageComplex result is invalid (%d,%d, %.2f+%.2fi)",
+                        col,row,crealf(img2Row[col]),cimagf(img2Row[col]));
+                return 2;
+            }
+        }
+    }
+
+    psImageFree(img);
+    psImageFree(img2);
+
+    return 0;
+}
+
+int testImagePowerSpectrum(void)
+{
+    psImage* img = NULL;
+    psImage* img2 = NULL;
+    unsigned int m = 128;
+    unsigned int n = 64;
+
+    /*
+    1. create a psC32 vector with unique real and imaginary components
+    2. call psImagePowerSpectrum
+    3. verify result is psF32
+    4. verify the values are the square of the absolute values of the original
+    */
+
+    // 1. create a psC32 vector with unique real and imaginary components
+    GENIMAGE(img,m,n,C32, row + I * col);
+
+    // 2. call psImagePowerSpectrum
+    img2 = psImagePowerSpectrum(img2,img);
+
+    // 3. verify result is psF32
+    if (img2->type.type != PS_TYPE_F32) {
+        psError(__func__,"the type was not PS_TYPE_F32.");
+        return 1;
+    }
+
+    // 4. verify the values are the square of the absolute values of the original
+    for (unsigned int row=0;row<n;row++) {
+        psC32* imgRow = img->data.C32[row];
+        psF32* img2Row = img2->data.F32[row];
+        for (unsigned int col=0;col<m;col++) {
+            psF32 power = cabs(imgRow[col]);
+            power *= power/n/n/m/m;
+
+            if (fabsf(img2Row[col] - power) > 2.0f*FLT_EPSILON) {
+                psError(__func__,"psImagePowerSpectrum result is invalid (%d,%d, %.2f vs %.2f)",
+                        col,row,img2Row[col],power);
+                return 2;
+            }
+        }
+    }
+
+    psImageFree(img);
+    psImageFree(img2);
+
+    return 0;
+}
Index: /tags/rel1_1/psLib/test/image/tst_psImageIO.c
===================================================================
--- /tags/rel1_1/psLib/test/image/tst_psImageIO.c	(revision 1056)
+++ /tags/rel1_1/psLib/test/image/tst_psImageIO.c	(revision 1056)
@@ -0,0 +1,327 @@
+/** @file  tst_psImageIO.c
+ *
+ *  @brief Contains the tests for psImageIO.[ch]
+ *
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.3 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-11 19:18:41 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include <math.h>
+#include <float.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include "psTest.h"
+#include "pslib.h"
+
+#define GENIMAGE(img,c,r,TYP, valueFcn) \
+img = psImageAlloc(c,r,PS_TYPE_##TYP); \
+for (unsigned int row=0;row<r;row++) { \
+    ps##TYP* imgRow = img->data.TYP[row]; \
+    for (unsigned int col=0;col<c;col++) { \
+        imgRow[col] = (ps##TYP)(valueFcn); \
+    } \
+}
+
+static int testImageRead(void);
+static int testImageWrite(void);
+
+testDescription tests[] = {
+                              {testImageRead,"567-testImageRead",0},
+                              {testImageWrite,"569-testImageWrite",0},
+                              {NULL}
+                          };
+
+int main()
+{
+    psLogSetLevel(PS_LOG_INFO);
+
+    testImageRead();
+
+    if (! runTestSuite(stderr,"psImage",tests)) {
+        psAbort(__FILE__,"One or more tests failed");
+    }
+    return 0;
+}
+
+int testImageRead(void)
+{
+    int N = 256;
+    int M = 128;
+    psImage* image = NULL;
+
+    /*
+        This function shall open the specified FITS file, read the specified data
+        and place the data into a psImage structure. This function shall generate
+        an error message and return NULL if any of the input parameters are out of
+        range, image file doesn't exist or image is zero or one dimensional.
+     
+        Verify the returned psImage structure contains expected values, if the input
+        parameter filename specifies an available FITS file with known 2dimensional
+        data, input parameters col, row, ncol, nrow, z specify data range with the
+        FITS file. Cases should include 1x1, Nx1, 1xN, NxN and MxN sub images and
+        total FITS file image. (done in macro)
+     
+        Verify the returned psImage structure is equal to the input parameter
+        'output', if specified. (done in macro)
+     
+        */
+
+    /* generate FITS file to read */
+
+    #define testReadTypeSize(m, n, readM0, readN0, readM, readN, TYP, filename) \
+    { \
+        psImage* img = NULL; \
+        psImage* img2 = NULL; \
+        psImage* img3 = NULL; \
+        psImage* img4 = NULL; \
+        psImage* img_ref = NULL; \
+        \
+        GENIMAGE(img,m,n,TYP,row+2*col); \
+        img2 = psImageCopy(img2,img,PS_TYPE_##TYP); \
+        GENIMAGE(img3,m,n,TYP,row+2*col); \
+        psImageClip(img3,100,100,400,400); \
+        img4 = psImageCopy(img4,img3,PS_TYPE_##TYP); \
+        remove(filename); \
+        if (psImageWriteSection(img3,0,0,1,NULL,0,filename) != 0) { \
+            psError(__func__,"Failed to write test image %s",filename); \
+            return 1; \
+        } \
+        if (psImageWriteSection(img,0,0,0,NULL,0,filename) != 0) { \
+            psError(__func__,"Failed to write test image %s",filename); \
+            return 2; \
+        } \
+        if (psImageWriteSection(img,0,0,1,NULL,1,filename) != 0) { \
+            psError(__func__,"Failed to write test image %s",filename); \
+            return 3; \
+        } \
+        if (psImageWriteSection(img3,0,0,0,NULL,1,filename) != 0) { \
+            psError(__func__,"Failed to write test image %s",filename); \
+            return 4; \
+        } \
+        psImageFree(img); \
+        img_ref = img = psImageAlloc(2,2,PS_TYPE_F32); \
+        psImageFree(img3); \
+        img3 = NULL; \
+        img = psImageReadSection(img,readM0,readN0,readM,readN,0,NULL,0,filename); \
+        if (img_ref != img) { \
+            psError(__func__,"psImageReadSection didn't recycle the psImage?"); \
+            return 5; \
+        } \
+        img3 = psImageReadSection(img3,readM0,readN0,readM,readN,1,NULL,0,filename); \
+        if (img == NULL) { \
+            psError(__func__,"Failed to read test image %s",filename); \
+            return 6; \
+        } \
+        for (unsigned int row = readN0; row < readN; row++) { \
+            ps##TYP* imgRow = img->data.TYP[row-readN0]; \
+            ps##TYP* img2Row = img2->data.TYP[row]; \
+            ps##TYP* img3Row = img3->data.TYP[row-readN0]; \
+            ps##TYP* img4Row = img4->data.TYP[row]; \
+            for (unsigned int col = readM0; col < readM; col++) { \
+                if (fabsf(imgRow[col-readM0]-img2Row[col]) > FLT_EPSILON) { \
+                    psError(__func__,"Image changed in I/O operation at %d,%d,0 (%.2f vs %.2f) for %s", \
+                            col,row,(psF32)imgRow[col-readM0],(psF32)img2Row[col],filename); \
+                    return 7; \
+                } \
+                if (fabsf(img3Row[col-readM0]-img4Row[col]) > FLT_EPSILON) { \
+                    psError(__func__,"Image changed in I/O operation at %d,%d,1 (%.2f vs %.2f) for %s", \
+                            col,row,(psF32)img3Row[col-readM0],(psF32)img4Row[col],filename); \
+                    return 8; \
+                } \
+            } \
+        } \
+        psImageFree(img); \
+        img = NULL; \
+        psImageFree(img3); \
+        img3 = NULL; \
+        img3 = psImageReadSection(img3,readM0,readN0,readM,readN,0,NULL,1,filename); \
+        img = psImageReadSection(img,readM0,readN0,readM,readN,1,NULL,1,filename); \
+        if (img == NULL) { \
+            psError(__func__,"Failed to read test image %s",filename); \
+            return 9; \
+        } \
+        for (unsigned int row = readN0; row < readN; row++) { \
+            ps##TYP* imgRow = img->data.TYP[row-readN0]; \
+            ps##TYP* img2Row = img2->data.TYP[row]; \
+            ps##TYP* img3Row = img3->data.TYP[row-readN0]; \
+            ps##TYP* img4Row = img4->data.TYP[row]; \
+            for (unsigned int col = readM0; col < readM; col++) { \
+                if (fabsf(imgRow[col-readM0]-img2Row[col]) > FLT_EPSILON) { \
+                    psError(__func__,"Image changed in I/O operation at %d,%d,0 (%.2f vs %.2f) for %s", \
+                            col,row,(psF32)imgRow[col-readM0],(psF32)img2Row[col],filename); \
+                    return 10; \
+                } \
+                if (fabsf(img3Row[col-readM0]-img4Row[col]) > FLT_EPSILON) { \
+                    psError(__func__,"Image changed in I/O operation at %d,%d,1 (%.2f vs %.2f) for %s", \
+                            col,row,(psF32)img3Row[col-readM0],(psF32)img4Row[col],filename); \
+                    return 11; \
+                } \
+            } \
+        } \
+        psImageFree(img); \
+        psImageFree(img2); \
+        psImageFree(img3); \
+        psImageFree(img4); \
+    }
+
+    #define testReadType(TYP,filename) \
+    mkdir("tmpImages",0777); \
+    testReadTypeSize(1,1,0,0,1,1,TYP,"tmpImages/1x1_" filename); \
+    testReadTypeSize(M,1,M/4,0,M/2,1,TYP,"tmpImages/Mx1_" filename); \
+    testReadTypeSize(1,N,0,N/4,1,N/2,TYP,"tmpImages/1xN_" filename); \
+    testReadTypeSize(M,N,M/4,N/4,M/2,N/2,TYP,"tmpImages/MxN_" filename);
+
+    testReadType(U8,"U8.fits");
+    testReadType(S8,"S8.fits");
+    testReadType(S16,"S16.fits");
+    testReadType(U16,"U16.fits");
+    testReadType(S32,"S32.fits");
+    testReadType(U32,"U32.fits");
+    testReadType(F32,"F32.fits");
+    testReadType(F64,"F64.fits");
+
+    /*
+    Verify the returned psImage structure pointer is null, error log message is
+    generated and program execution doesn't stop, if input parameter filename
+    specifies a file that doesn't exist.
+    */
+
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error as file doesn't exist.");
+    image = psImageReadSection(image,0,0,M,N,0,NULL,0,"foobar.fits");
+    if (image != NULL) {
+        psError(__func__,"Image returned though filename did not exist.");
+        return 12;
+    }
+
+    /*
+    Verify the returned psImage structure pointer is null, error log message is
+    generatedand program execution doesn't stop, if input parameter filename
+    is null.Verify the returned psImage structurepointer is null, error log
+    message is generated and program execution doesn't stop, if input
+    parameters col,row, ncol, nrow and/or z specify a data range which is not
+    within the data range of the FITS file.
+    */
+
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error as filename is NULL.");
+    image = psImageReadSection(image,0,0,M,N,0,NULL,0,NULL);
+    if (image != NULL) {
+        psError(__func__,"Image returned though filename was NULL.");
+        return 13;
+    }
+
+    /*
+    Verify the returned psImage structure pointer is null, error log message is
+    generated and program execution doesn't stop,if input parameters extname
+    and/or extnum specify an extension which is not valid in the FITS file.
+    */
+
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error as extnum is invalid.");
+    image = psImageReadSection(image,0,0,M,N,0,NULL,4,"tmpImages/MxN_F32.fits");
+    if (image != NULL) {
+        psError(__func__,"Image returned though extnum was invalid.");
+        return 14;
+    }
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error as extname is invalid.");
+    image = psImageReadSection(image,0,0,M,N,0,"bogus",0,"tmpImages/MxN_F32.fits");
+    if (image != NULL) {
+        psError(__func__,"Image returned though extnum was invalid.");
+        return 15;
+    }
+
+    /*
+    Verify the returned psImage structure pointer is null, error log message is
+    generated and program execution doesn't stop,if input parameter filename
+    specifies a FITS file that is zero or one dimensional.
+
+    XXX
+    N.B: since I can't write anything but 2 or 3 dimensional image, I can't
+    do this programatically at this time.  I verified that this functionality
+    exists in the source code via inspection. (line 101 in psImageIO.c for v1.3)
+    -rdd
+    */
+
+    return 0;
+}
+
+int testImageWrite(void)
+{
+    psImage* img = NULL;
+    psImage* img2 = NULL;
+    int m = 64;
+    int n = 96;
+
+    /*
+    This function shall write the specified section within a psImage structure
+    to a FITS file. If the specifiedfile exists, then data should overwrite the
+    section to write. If the specified file doesn't exist, it shall be created.
+    If an extenstion is specified, then a basic primary header data unit shall
+    be created.
+    */
+
+    /*
+    Verify a FITS file named filename is generated and contains expected
+    values, if the input parameter input contains known data values, input
+    parameters col, row, ncol, nrow specify a valid data region within psImage
+    structure.
+
+    Verify a FITS file named filename is generated and contains a primary
+    header data unit with extension with expected values, if the input
+    parameter input contains known data values, input parameters col, row,
+    ncol, nrow specify a valid data region within psImage structure and
+    extname and/or extnum specify an extenstion to write.
+
+    N.B. : these are done in testImageRead tests, see above.
+    */
+
+    /*
+    Verify a FITS file named filename is overwritten and contains
+    expected values, if the input parameter input contains known data values,
+    input parameters col, row, ncol, nrow specify a valid data region within
+    psImage structure.
+    */
+
+    GENIMAGE(img,m,n,F32,0);
+    GENIMAGE(img2,m,n,F32,row+2*col);
+    mkdir("tmpImages",0777);
+    remove
+        ("writeTest.fits");
+    if (psImageWriteSection(img,0,0,0,NULL,0,"tmpImages/writeTest.fits") != 0) {
+        psError(__func__,"Couldn't write writeTest.fits.");
+        return 14;
+    }
+    if (psImageWriteSection(img2,0,0,0,NULL,0,"tmpImages/writeTest.fits") != 0) {
+        psError(__func__,"Couldn't overwrite writeTest.fits.");
+        return 15;
+    }
+    psImageFree(img);
+    psImageFree(img2);
+
+    // Did it really overwrite the pixel values?  Let's read it in and see.
+    img = psImageReadSection(NULL,0,0,m,n,0,NULL,0,"tmpImages/writeTest.fits");
+    if (img == NULL) {
+        psError(__func__,"Could not read in writeTest.fits.");
+        return 16;
+    }
+    for (unsigned int row=0;row<n;row++) {
+        psF32* imgRow = img->data.F32[row];
+        for (unsigned int col=0;col<m;col++) {
+            if (fabsf(imgRow[col] - (row+2*col)) > FLT_EPSILON) {
+                psError(__func__,"The image values were not overwritten at %d,%d (%.2f vs %.2f)",
+                        col,row,imgRow[col],(row+2*col));
+                return 17;
+            }
+        }
+    }
+
+    psImageFree(img);
+
+    return 0;
+}
Index: /tags/rel1_1/psLib/test/image/tst_psImageStats00.c
===================================================================
--- /tags/rel1_1/psLib/test/image/tst_psImageStats00.c	(revision 1056)
+++ /tags/rel1_1/psLib/test/image/tst_psImageStats00.c	(revision 1056)
@@ -0,0 +1,183 @@
+/*****************************************************************************
+    This routine must ensure that the psHistogram structure is correctly
+    allocated and populated by the psImageHistogram() function.
+ *****************************************************************************/
+#include <stdio.h>
+#include "pslib.h"
+#include "psTest.h"
+#include "psMemory.h"
+#include "psImage.h"
+#include "psImageStats.h"
+#define NUM_BINS 20
+#define IMAGE_SIZE 20
+#define N 32
+#define M 64
+
+int main()
+{
+    psHistogram *myHist = NULL;
+    psHistogram *myHist2= NULL;
+    psImage *tmpImage   = NULL;
+    psImage *tmpMask    = NULL;
+    int testStatus      = true;
+    int memLeaks        = 0;
+    int nb              = 0;
+    int i               = 0;
+    int j               = 0;
+    int IMAGE_X_SIZE    = 0;
+    int IMAGE_Y_SIZE    = 0;
+    int currentId       = 0;
+
+    currentId       = psMemGetId();
+    for (nb=0;nb<6;nb++) {
+        if (nb == 0) {
+            IMAGE_X_SIZE = 1;
+            IMAGE_Y_SIZE = 1;
+        }
+        if (nb == 1) {
+            IMAGE_X_SIZE = 1;
+            IMAGE_Y_SIZE = N;
+        }
+        if (nb == 2) {
+            IMAGE_X_SIZE = N;
+            IMAGE_Y_SIZE = 1;
+        }
+        if (nb == 3) {
+            IMAGE_X_SIZE = N;
+            IMAGE_Y_SIZE = N;
+        }
+        if (nb == 4) {
+            IMAGE_X_SIZE = N;
+            IMAGE_Y_SIZE = M;
+        }
+        if (nb == 5) {
+            IMAGE_X_SIZE = M;
+            IMAGE_Y_SIZE = N;
+        }
+        printf("*******************************\n");
+        printf("* IMAGE SIZE is (%d by %d)\n", IMAGE_X_SIZE, IMAGE_Y_SIZE);
+        printf("*******************************\n");
+        /*********************************************************************/
+        /*  Allocate and initialize data structures                      */
+        /*********************************************************************/
+        tmpImage = psImageAlloc(IMAGE_X_SIZE, IMAGE_Y_SIZE, PS_TYPE_F32);
+
+        for (i=0;i<tmpImage->numRows;i++) {
+            for (j=0;j<tmpImage->numCols;j++) {
+                tmpImage->data.F32[i][j] = (float) (i + j + 0.1);
+            }
+        }
+        tmpMask = psImageAlloc(IMAGE_X_SIZE, IMAGE_Y_SIZE, PS_TYPE_U8);
+        for (i=0;i<tmpMask->numRows;i++) {
+            for (j=0;j<tmpMask->numCols;j++) {
+                if ((i > (tmpMask->numRows/2)) &&
+                        (j > (tmpMask->numCols/2))) {
+                    tmpMask->data.U8[i][j] = 1;
+                } else {
+                    tmpMask->data.U8[i][j] = 0;
+                }
+            }
+        }
+
+        /*************************************************************************/
+        /*  Calculate Histogram with no mask                             */
+        /*************************************************************************/
+        printPositiveTestHeader(stdout,
+                                "psImageStats functions",
+                                "Calculate Histogram, no mask");
+
+        myHist = psHistogramAlloc(0.0, (float) (IMAGE_X_SIZE + IMAGE_Y_SIZE),
+                                  NUM_BINS);
+        myHist = psImageHistogram(myHist, tmpImage, NULL, 0);
+        for (i=0;i<NUM_BINS;i++) {
+            printf("Bin number %d bounds: (%f - %f) data (%d)\n", i,
+                   myHist->bounds->data.F32[i],
+                   myHist->bounds->data.F32[i+1],
+                   myHist->nums->data.S32[i]);
+        }
+        psHistogramFree(myHist);
+
+        psMemCheckCorruption(1);
+        printFooter(stdout,
+                    "psImageStats functions",
+                    "Calculate Histogram, no mask",
+                    testStatus);
+
+        /*************************************************************************/
+        /*  Calculate Histogram with mask                                */
+        /*************************************************************************/
+        printPositiveTestHeader(stdout,
+                                "psImageStats functions",
+                                "Calculate Histogram with mask");
+
+        myHist = psHistogramAlloc(0.0, (float) (IMAGE_X_SIZE + IMAGE_Y_SIZE),
+                                  NUM_BINS);
+        myHist = psImageHistogram(myHist, tmpImage, tmpMask, 1);
+        for (i=0;i<NUM_BINS;i++) {
+            printf("Bin number %d bounds: (%f - %f) data (%d)\n", i,
+                   myHist->bounds->data.F32[i],
+                   myHist->bounds->data.F32[i+1],
+                   myHist->nums->data.S32[i]);
+        }
+
+        psMemCheckCorruption(1);
+        printFooter(stdout,
+                    "psImageStats functions",
+                    "Calculate Histogram with mask",
+                    testStatus);
+
+        /*************************************************************************/
+        /*  Deallocate data structures                                   */
+        /*************************************************************************/
+        printPositiveTestHeader(stdout,
+                                "psImageStats functions",
+                                "Deallocate the psHistogram/psImage structure.");
+        psHistogramFree(myHist);
+        psImageFree(tmpImage);
+        psImageFree(tmpMask);
+
+        psMemCheckCorruption(1);
+        memLeaks = psMemCheckLeaks(currentId,NULL,NULL);
+        if (0 != memLeaks) {
+            psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+        }
+
+        printFooter(stdout,
+                    "psImageStats functions",
+                    "Deallocate the psHistogram/psImage structure.",
+                    testStatus);
+    }
+    printPositiveTestHeader(stdout,
+                            "psImageStats functions",
+                            "Calling psImageHistogram() with NULL parameters");
+
+    tmpImage = psImageAlloc(IMAGE_X_SIZE, IMAGE_Y_SIZE, PS_TYPE_F32);
+    myHist  = psHistogramAlloc(0.0, (float) (IMAGE_X_SIZE + IMAGE_Y_SIZE),
+                               NUM_BINS);
+    myHist2 = psImageHistogram(NULL, tmpImage, NULL, 0);
+    if (myHist2 != NULL) {
+        printf("ERROR: myHist2 not equal to NULL\n");
+    }
+
+    myHist2 = psImageHistogram(myHist, NULL, NULL, 0);
+    myHist2 = psImageHistogram(NULL, tmpImage, NULL, 0);
+    if (myHist2 != NULL) {
+        printf("ERROR: myHist2 not equal to NULL\n");
+    }
+
+    psMemCheckCorruption(1);
+    psHistogramFree(myHist);
+    psImageFree(tmpImage);
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,NULL);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psImageStats functions",
+                "Calling psImageHistogram() with NULL parameters",
+                testStatus);
+
+    return (!testStatus);
+}
Index: /tags/rel1_1/psLib/test/image/tst_psImageStats01.c
===================================================================
--- /tags/rel1_1/psLib/test/image/tst_psImageStats01.c	(revision 1056)
+++ /tags/rel1_1/psLib/test/image/tst_psImageStats01.c	(revision 1056)
@@ -0,0 +1,182 @@
+/*****************************************************************************
+    This routine must ensure that the psImageStats() routine can correctly
+    call the psVectorStats() routine.  Since the psVectorStats() will be
+    thouroughly tested elsewhere, we will only test psImageStats() with
+    the PS_STAT_SAMPLE_MEAN here.
+ *****************************************************************************/
+#include <stdio.h>
+#include "pslib.h"
+#include "psTest.h"
+#include "psMemory.h"
+#include "psImage.h"
+#include "psImageStats.h"
+#define NUM_BINS 20
+#define N 32
+#define M 64
+
+int main()
+{
+    psStats *myStats    = NULL;
+    psStats *myStats2   = NULL;
+    psImage *tmpImage   = NULL;
+    psImage *tmpMask    = NULL;
+    int testStatus      = true;
+    int memLeaks        = 0;
+    int nb              = 0;
+    int i               = 0;
+    int j               = 0;
+    int IMAGE_X_SIZE    = 0;
+    int IMAGE_Y_SIZE    = 0;
+    int currentId       = 0;
+
+    currentId       = psMemGetId();
+    for (nb=0;nb<6;nb++) {
+        if (nb == 0) {
+            IMAGE_X_SIZE = 1;
+            IMAGE_Y_SIZE = 1;
+        }
+        if (nb == 1) {
+            IMAGE_X_SIZE = 1;
+            IMAGE_Y_SIZE = N;
+        }
+        if (nb == 2) {
+            IMAGE_X_SIZE = N;
+            IMAGE_Y_SIZE = 1;
+        }
+        if (nb == 3) {
+            IMAGE_X_SIZE = N;
+            IMAGE_Y_SIZE = N;
+        }
+        if (nb == 4) {
+            IMAGE_X_SIZE = N;
+            IMAGE_Y_SIZE = M;
+        }
+        if (nb == 5) {
+            IMAGE_X_SIZE = M;
+            IMAGE_Y_SIZE = N;
+        }
+        printf("*******************************\n");
+        printf("* IMAGE SIZE is (%d by %d)\n", IMAGE_X_SIZE, IMAGE_Y_SIZE);
+        printf("*******************************\n");
+
+        /*************************************************************************/
+        /*  Allocate and initialize data structures                      */
+        /*************************************************************************/
+        tmpImage = psImageAlloc(IMAGE_X_SIZE, IMAGE_Y_SIZE, PS_TYPE_F32);
+
+        for (i=0;i<tmpImage->numRows;i++) {
+            for (j=0;j<tmpImage->numCols;j++) {
+                tmpImage->data.F32[i][j] = (float) (i + j);
+            }
+        }
+        tmpMask = psImageAlloc(IMAGE_X_SIZE, IMAGE_Y_SIZE, PS_TYPE_U8);
+        for (i=0;i<tmpMask->numRows;i++) {
+            for (j=0;j<tmpMask->numCols;j++) {
+                if ((i > (tmpMask->numRows/2)) &&
+                        (j > (tmpMask->numCols/2))) {
+                    tmpMask->data.U8[i][j] = 1;
+                } else {
+                    tmpMask->data.U8[i][j] = 0;
+                }
+            }
+        }
+
+        myStats = psStatsAlloc(PS_STAT_SAMPLE_MEAN);
+        /*************************************************************************/
+        /*  Calculate Sample Mean with no mask                           */
+        /*************************************************************************/
+        printPositiveTestHeader(stdout,
+                                "psImageStats functions",
+                                "Calculate Sample Mean, no mask %d");
+
+        myStats = psImageStats(myStats, tmpImage, NULL, 0);
+        printf("The sample mean was %f\n", myStats->sampleMean);
+
+        psMemCheckCorruption(1);
+
+        printFooter(stdout,
+                    "psImageStats functions",
+                    "Calculate Sample Mean, no mask",
+                    testStatus);
+
+        /*************************************************************************/
+        /*  Calculate Sample Mean with mask                              */
+        /*************************************************************************/
+        printPositiveTestHeader(stdout,
+                                "psImageStats functions",
+                                "Calculate Sample Mean with mask");
+
+        myStats = psImageStats(myStats, tmpImage, tmpMask, 1);
+        printf("The sample mean was %f\n", myStats->sampleMean);
+
+        psMemCheckCorruption(1);
+
+        printFooter(stdout,
+                    "psImageStats functions",
+                    "Calculate Sample Mean with mask",
+                    testStatus);
+
+        /*************************************************************************/
+        /*  Deallocate data structures                                   */
+        /*************************************************************************/
+        printPositiveTestHeader(stdout,
+                                "psImageStats functions",
+                                "Deallocate the psStats/psImage structure.");
+        psStatsFree(myStats);
+        psImageFree(tmpImage);
+        psImageFree(tmpMask);
+
+        psMemCheckCorruption(1);
+        memLeaks = psMemCheckLeaks(currentId,NULL,NULL);
+        if (0 != memLeaks) {
+            psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+        }
+
+        printFooter(stdout,
+                    "psImageStats functions",
+                    "Deallocate the psStats/psImage structure.",
+                    testStatus);
+    }
+
+    /*************************************************************************/
+    /*  Test With Various Null Inputs                                        */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psImageStats functions",
+                            "Test With Various Null Inputs");
+
+    tmpImage = psImageAlloc(IMAGE_X_SIZE, IMAGE_Y_SIZE, PS_TYPE_F32);
+    tmpMask = psImageAlloc(IMAGE_X_SIZE, IMAGE_Y_SIZE, PS_TYPE_U8);
+    myStats = psStatsAlloc(0);
+
+    myStats2 = psImageStats(myStats, NULL, NULL, 0);
+    if (myStats2 != NULL) {
+        printf("ERROR: myStats2 = psImageStats(myStats, NULL, NULL, 0) != NULL\n");
+    }
+
+    myStats2 = psImageStats(NULL, tmpImage, NULL, 0);
+    if (myStats2 != NULL) {
+        printf("ERROR: myStats2 = psImageStats(NULL, tmpImage, NULL, 0) != NULL\n");
+    }
+
+    myStats = psImageStats(myStats, tmpImage, NULL, 0);
+    //
+    // NOTE: verify that myStats is good here.
+    //
+
+    psStatsFree(myStats);
+    psImageFree(tmpImage);
+    psImageFree(tmpMask);
+
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,NULL);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psImageStats functions",
+                "Test With Various Null Inputs",
+                testStatus);
+    return (!testStatus);
+}
Index: /tags/rel1_1/psLib/test/image/tst_psImageStats02.c
===================================================================
--- /tags/rel1_1/psLib/test/image/tst_psImageStats02.c	(revision 1056)
+++ /tags/rel1_1/psLib/test/image/tst_psImageStats02.c	(revision 1056)
@@ -0,0 +1,106 @@
+/*****************************************************************************
+    This routine must ensure that the psImageStats() routine can correctly
+    call the psVectorStats() routine.  Since the psVectorStats() will be
+    thouroughly tested elsewhere, we will only test psImageStats() with
+    the PS_STAT_SAMPLE_MEAN here.
+ 
+    NOTE: After you debug, set CHEBY_X_DIM != CHEBY_Y_DIM.
+    Also, uses non-square images.
+ *****************************************************************************/
+#include <stdio.h>
+#include "pslib.h"
+#include "psTest.h"
+#include "psMemory.h"
+#include "psImage.h"
+#include "psImageStats.h"
+#define IMAGE_SIZE 3
+#define CHEBY_X_DIM 3
+#define CHEBY_Y_DIM 3
+
+int main()
+{
+    psStats *myStats    = NULL;
+    psImage *tmpImage   = NULL;
+    psImage *outImage   = NULL;
+    psPolynomial2D *my2DPoly = NULL;
+    int testStatus      = true;
+    int memLeaks        = 0;
+    int i               = 0;
+    int j               = 0;
+    int rc              = 0;
+    int currentId       = 0;
+
+    currentId       = psMemGetId();
+    /*************************************************************************/
+    /*  Allocate and initialize data structures                      */
+    /*************************************************************************/
+    tmpImage = psImageAlloc(IMAGE_SIZE, IMAGE_SIZE, PS_TYPE_F32);
+    outImage = psImageAlloc(IMAGE_SIZE, IMAGE_SIZE, PS_TYPE_F32);
+    for (i=0;i<IMAGE_SIZE;i++) {
+        for (j=0;j<IMAGE_SIZE;j++) {
+            tmpImage->data.F32[i][j] = (float) (i + j);
+            tmpImage->data.F32[i][j] = 4.0;
+            outImage->data.F32[i][j] = 0.0;
+        }
+    }
+    my2DPoly = psPolynomial2DAlloc(CHEBY_X_DIM, CHEBY_Y_DIM);
+    /*************************************************************************/
+    /*  Calculate Chebyshev Polynomials, no mask                     */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psImageStats functions",
+                            "Calculate Chebyshev Polynomials, no mask");
+
+    my2DPoly = psImageFitPolynomial(tmpImage, my2DPoly);
+
+    psMemCheckCorruption(1);
+    printFooter(stdout,
+                "psImageStats functions",
+                "Calculate Chebyshev Polynomials, no mask",
+                testStatus);
+    /*************************************************************************/
+    /*  Evaluate Chebyshev Polynomials, no mask                      */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psImageStats functions",
+                            "Calculate Chebyshev Polynomials, no mask");
+
+    rc = psImageEvalPolynomial(outImage, my2DPoly);
+    //    for (i=0;i<IMAGE_SIZE;i++) {
+    //        for (j=0;j<IMAGE_SIZE;j++) {
+    //             printf("pixel[%d][%d] is (%f, %f)\n", i, j,
+    //                   tmpImage->data.F32[i][j],
+    //                   outImage->data.F32[i][j]);
+    //        }
+    //    }
+
+    psMemCheckCorruption(1);
+    printFooter(stdout,
+                "psImageStats functions",
+                "Calculate Chebyshev Polynomials, no mask",
+                testStatus);
+
+    /*************************************************************************/
+    /*  Deallocate data structures                                   */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psImageStats functions",
+                            "Deallocate the psStats/psImage structure.");
+    psStatsFree(myStats);
+    psImageFree(tmpImage);
+    psImageFree(outImage);
+    psPolynomial2DFree(my2DPoly);
+
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,NULL);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psImageStats functions",
+                "Deallocate the psStats/psImage structure.",
+                testStatus);
+
+    return (!testStatus);
+}
Index: /tags/rel1_1/psLib/test/image/verified/tst_psImage.stderr
===================================================================
--- /tags/rel1_1/psLib/test/image/verified/tst_psImage.stderr	(revision 1056)
+++ /tags/rel1_1/psLib/test/image/verified/tst_psImage.stderr	(revision 1056)
@@ -0,0 +1,146 @@
+ <DATE> <TIME> <HOST> |I|testImageOverla|Following should error as overlay isn't within image boundaries
+ <DATE> <TIME> <HOST> |E|psImageOverlayS|Overlay image (32,64 -> 159,319) is partially outside of the input image (128 x 256).
+ <DATE> <TIME> <HOST> |I|testImageOverla|Following should error as overlay is NULL
+ <DATE> <TIME> <HOST> |E|psImageOverlayS|one of the input images was NULL.
+ <DATE> <TIME> <HOST> |I|testImageOverla|Following should error as image input is NULL
+ <DATE> <TIME> <HOST> |E|psImageOverlayS|one of the input images was NULL.
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImage.c                                              *
+*            TestPoint: psImage{546/548-testImageAlloc/Free}                       *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+ <DATE> <TIME> <HOST> |I| testImageAlloc|#546 - psImageAlloc shall allocate memory for a psImage structure
+ <DATE> <TIME> <HOST> |I| testImageAlloc|Testing psImage with type 101h
+ <DATE> <TIME> <HOST> |E|   psImageAlloc|Invalid value for number of rows or columns (numRows=0, numCols=0).
+ <DATE> <TIME> <HOST> |I| testImageAlloc|Testing psImage with type 102h
+ <DATE> <TIME> <HOST> |E|   psImageAlloc|Invalid value for number of rows or columns (numRows=0, numCols=0).
+ <DATE> <TIME> <HOST> |I| testImageAlloc|Testing psImage with type 104h
+ <DATE> <TIME> <HOST> |E|   psImageAlloc|Invalid value for number of rows or columns (numRows=0, numCols=0).
+ <DATE> <TIME> <HOST> |I| testImageAlloc|Testing psImage with type 108h
+ <DATE> <TIME> <HOST> |E|   psImageAlloc|Invalid value for number of rows or columns (numRows=0, numCols=0).
+ <DATE> <TIME> <HOST> |I| testImageAlloc|Testing psImage with type 301h
+ <DATE> <TIME> <HOST> |E|   psImageAlloc|Invalid value for number of rows or columns (numRows=0, numCols=0).
+ <DATE> <TIME> <HOST> |I| testImageAlloc|Testing psImage with type 302h
+ <DATE> <TIME> <HOST> |E|   psImageAlloc|Invalid value for number of rows or columns (numRows=0, numCols=0).
+ <DATE> <TIME> <HOST> |I| testImageAlloc|Testing psImage with type 304h
+ <DATE> <TIME> <HOST> |E|   psImageAlloc|Invalid value for number of rows or columns (numRows=0, numCols=0).
+ <DATE> <TIME> <HOST> |I| testImageAlloc|Testing psImage with type 308h
+ <DATE> <TIME> <HOST> |E|   psImageAlloc|Invalid value for number of rows or columns (numRows=0, numCols=0).
+ <DATE> <TIME> <HOST> |I| testImageAlloc|Testing psImage with type 404h
+ <DATE> <TIME> <HOST> |E|   psImageAlloc|Invalid value for number of rows or columns (numRows=0, numCols=0).
+ <DATE> <TIME> <HOST> |I| testImageAlloc|Testing psImage with type 408h
+ <DATE> <TIME> <HOST> |E|   psImageAlloc|Invalid value for number of rows or columns (numRows=0, numCols=0).
+ <DATE> <TIME> <HOST> |I| testImageAlloc|Testing psImage with type 808h
+ <DATE> <TIME> <HOST> |E|   psImageAlloc|Invalid value for number of rows or columns (numRows=0, numCols=0).
+ <DATE> <TIME> <HOST> |I| testImageAlloc|Testing psImage with type 810h
+ <DATE> <TIME> <HOST> |E|   psImageAlloc|Invalid value for number of rows or columns (numRows=0, numCols=0).
+
+---> TESTPOINT PASSED (psImage{546/548-testImageAlloc/Free} | tst_psImage.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImage.c                                              *
+*            TestPoint: psImage{547/550-testImageSubset}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+ <DATE> <TIME> <HOST> |I|testImageSubset|memcpy(&preSubsetStruct,original,sizeof(psImage));
+ <DATE> <TIME> <HOST> |I|testImageSubset|subset1 = psImageAlloc(c/4,r/4,PS_TYPE_U8);
+ <DATE> <TIME> <HOST> |I|testImageSubset|subset2 = psImageSubset(subset1,original,c/2,r/2,c/4,r/4);
+ <DATE> <TIME> <HOST> |I|testImageSubset|subset3 = psImageSubset(NULL,original,c/2,r/2,0,0);
+ <DATE> <TIME> <HOST> |I|testImageSubset|Verify the returned psImage structure is equal to the input psImage structure parameter out, if input parameter out is specified.
+ <DATE> <TIME> <HOST> |I|testImageSubset|Verify a new psImage structure is created, if input parameter out is set to null.
+ <DATE> <TIME> <HOST> |I|testImageSubset|Verify the returned psImage structure contains expected values in the row member, if the input psImage structure image contains known values.
+ <DATE> <TIME> <HOST> |I|testImageSubset|Verify the returned psImage structure members nrow and ncol are equal to the input parameter nrow and ncol respectively.
+ <DATE> <TIME> <HOST> |I|testImageSubset|Verify the returned psImage structure member type is equal to the input psImage structure member type.
+ <DATE> <TIME> <HOST> |I|testImageSubset|Verify the returned psImage structure members row0 and col0 are equal to the input parameters row0 and col0 respectively.
+ <DATE> <TIME> <HOST> |I|testImageSubset|Verify the returned psImage structure member parent is equal to the input psImage structure pointer image.
+ <DATE> <TIME> <HOST> |I|testImageSubset|Verify the returned psImage structure member Nchildren is equal to zero.
+ <DATE> <TIME> <HOST> |I|testImageSubset|Verify the returned psImage structure member children is null.
+ <DATE> <TIME> <HOST> |I|testImageSubset|Verify the input psImage structure image only has the following members changed: 1) Nchildren is increased by one. 2) parent contains pointer psImage structure out at parent[Nchildren-1].
+ <DATE> <TIME> <HOST> |I|testImageSubset|Verify the returned psImage structure pointer is null and program execution doesn't stop, if the input parameter image is null. Also verified the input psImage structure is not modified.
+ <DATE> <TIME> <HOST> |I|testImageSubset|An error should follow...
+ <DATE> <TIME> <HOST> |E|  psImageSubset|Can not subset image because input image or its pixel buffer is NULL.
+ <DATE> <TIME> <HOST> |I|testImageSubset|Verify the returned psImage structure pointer is null and program  execution doesn't stop, if the input parameters nrow and/or ncol are zero. Also verify input psImage structure is not modified.
+ <DATE> <TIME> <HOST> |I|testImageSubset|An error should follow...
+ <DATE> <TIME> <HOST> |E|  psImageSubset|Can not subset image because number of rows or columns are zero (64x0).
+ <DATE> <TIME> <HOST> |I|testImageSubset|An error should follow...
+ <DATE> <TIME> <HOST> |E|  psImageSubset|Can not subset image because number of rows or columns are zero (0x128).
+ <DATE> <TIME> <HOST> |I|testImageSubset|Verify the returned psImage structure pointer is null and program execution doesn't stop, if the input parameters row0 and col0 are not within the range of values of psImage structure image.
+ <DATE> <TIME> <HOST> |I|testImageSubset|An error should follow...
+ <DATE> <TIME> <HOST> |E|  psImageSubset|Can not subset image because col0,row0 (128,0) is not a valid pixel location.
+ <DATE> <TIME> <HOST> |I|testImageSubset|An error should follow...
+ <DATE> <TIME> <HOST> |E|  psImageSubset|Can not subset image because col0,row0 (0,256) is not a valid pixel location.
+ <DATE> <TIME> <HOST> |I|testImageSubset|An error should follow...
+ <DATE> <TIME> <HOST> |E|  psImageSubset|Can not subset image because col0,row0 (-1,0) is not a valid pixel location.
+ <DATE> <TIME> <HOST> |I|testImageSubset|An error should follow...
+ <DATE> <TIME> <HOST> |E|  psImageSubset|Can not subset image because col0,row0 (0,-1) is not a valid pixel location.
+ <DATE> <TIME> <HOST> |I|testImageSubset|Verify the returned psImage structure pointer is null and program execution doesn't stop if the input parameters nrow, ncol, row0 and col0 specify a range of data not within the input psImage structure image.  Also verify the input psImage structure is not modified.
+ <DATE> <TIME> <HOST> |I|testImageSubset|An error should follow...
+ <DATE> <TIME> <HOST> |E|  psImageSubset|Can not subset image outside of image boundaries (size=128x256, subset=[64:128,0:128]).
+ <DATE> <TIME> <HOST> |I|testImageSubset|An error should follow...
+ <DATE> <TIME> <HOST> |E|  psImageSubset|Can not subset image outside of image boundaries (size=128x256, subset=[0:64,128:256]).
+ <DATE> <TIME> <HOST> |I|testImageSubset|An error should follow...
+ <DATE> <TIME> <HOST> |E|  psImageSubset|Can not subset image outside of image boundaries (size=128x256, subset=[64:128,128:256]).
+ <DATE> <TIME> <HOST> |I|testImageSubset|psImageFreeChildren shall deallocate any children images of a psImage structure
+
+---> TESTPOINT PASSED (psImage{547/550-testImageSubset} | tst_psImage.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImage.c                                              *
+*            TestPoint: psImage{551-testImageCopy}                                 *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+ <DATE> <TIME> <HOST> |I|  testImageCopy|An error should follow...
+ <DATE> <TIME> <HOST> |E|    psImageCopy|Can not copy image because input image or its pixel buffer is NULL.
+
+---> TESTPOINT PASSED (psImage{551-testImageCopy} | tst_psImage.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImage.c                                              *
+*            TestPoint: psImage{571-testImageClip}                                 *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+ <DATE> <TIME> <HOST> |I|  testImageClip|psImageClip shall limit the minimum and maximum data value within a psImage structure
+ <DATE> <TIME> <HOST> |I|  testImageClip|Testing clipping of F64 imagery
+ <DATE> <TIME> <HOST> |I|  testImageClip|Testing clipping of F32 imagery
+ <DATE> <TIME> <HOST> |I|  testImageClip|Testing clipping of S32 imagery
+ <DATE> <TIME> <HOST> |I|  testImageClip|Testing clipping of S16 imagery
+ <DATE> <TIME> <HOST> |I|  testImageClip|Testing clipping of S8 imagery
+ <DATE> <TIME> <HOST> |I|  testImageClip|Testing clipping of U32 imagery
+ <DATE> <TIME> <HOST> |I|  testImageClip|Testing clipping of U16 imagery
+ <DATE> <TIME> <HOST> |I|  testImageClip|Testing clipping of U8 imagery
+ <DATE> <TIME> <HOST> |I|  testImageClip|Testing clipping of C32 imagery
+ <DATE> <TIME> <HOST> |I|  testImageClip|Testing clipping of C64 imagery
+ <DATE> <TIME> <HOST> |I|  testImageClip|Following should be an error (max<min)
+ <DATE> <TIME> <HOST> |E|    psImageClip|psImageClip can not be invoked with max < min.
+
+---> TESTPOINT PASSED (psImage{571-testImageClip} | tst_psImage.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImage.c                                              *
+*            TestPoint: psImage{572-testImageClipNAN}                              *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+ <DATE> <TIME> <HOST> |I|testImageClipNA|psImageClipNaN shall modified pixel values of NaN with a specified value
+
+---> TESTPOINT PASSED (psImage{572-testImageClipNAN} | tst_psImage.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImage.c                                              *
+*            TestPoint: psImage{573-testImageOverlay}                              *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+ <DATE> <TIME> <HOST> |I|testImageOverla|Following should error as overlay isn't within image boundaries
+ <DATE> <TIME> <HOST> |E|psImageOverlayS|Overlay image (32,64 -> 159,319) is partially outside of the input image (128 x 256).
+ <DATE> <TIME> <HOST> |I|testImageOverla|Following should error as overlay is NULL
+ <DATE> <TIME> <HOST> |E|psImageOverlayS|one of the input images was NULL.
+ <DATE> <TIME> <HOST> |I|testImageOverla|Following should error as image input is NULL
+ <DATE> <TIME> <HOST> |E|psImageOverlayS|one of the input images was NULL.
+
+---> TESTPOINT PASSED (psImage{573-testImageOverlay} | tst_psImage.c)
+
Index: /tags/rel1_1/psLib/test/image/verified/tst_psImageFFT.stderr
===================================================================
--- /tags/rel1_1/psLib/test/image/verified/tst_psImageFFT.stderr	(revision 1056)
+++ /tags/rel1_1/psLib/test/image/verified/tst_psImageFFT.stderr	(revision 1056)
@@ -0,0 +1,49 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageFFT.c                                           *
+*            TestPoint: psFFT{600-testImageFFT}                                    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psFFT{600-testImageFFT} | tst_psImageFFT.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageFFT.c                                           *
+*            TestPoint: psFFT{601-testImageRealImaginary}                          *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psFFT{601-testImageRealImaginary} | tst_psImageFFT.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageFFT.c                                           *
+*            TestPoint: psFFT{602-testImageComplex}                                *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+ <DATE> <TIME> <HOST> |I|testImageComple|Following should be an error (type mismatch).
+ <DATE> <TIME> <HOST> |E| psImageComplex|The inputs to psImageComplex must be the same type.
+ <DATE> <TIME> <HOST> |I|testImageComple|Following should be an error (size mismatch).
+ <DATE> <TIME> <HOST> |E| psImageComplex|The inputs to psImageComplex must be the same dimensions.
+
+---> TESTPOINT PASSED (psFFT{602-testImageComplex} | tst_psImageFFT.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageFFT.c                                           *
+*            TestPoint: psFFT{603-testImageConjugate}                              *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psFFT{603-testImageConjugate} | tst_psImageFFT.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageFFT.c                                           *
+*            TestPoint: psFFT{604-testImagePowerSpectrum}                          *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psFFT{604-testImagePowerSpectrum} | tst_psImageFFT.c)
+
Index: /tags/rel1_1/psLib/test/image/verified/tst_psImageIO.stderr
===================================================================
--- /tags/rel1_1/psLib/test/image/verified/tst_psImageIO.stderr	(revision 1056)
+++ /tags/rel1_1/psLib/test/image/verified/tst_psImageIO.stderr	(revision 1056)
@@ -0,0 +1,34 @@
+ <DATE> <TIME> <HOST> |I|  testImageRead|Following should be an error as file doesn't exist.
+ <DATE> <TIME> <HOST> |E|psImageReadSect|Could not open file 'foobar.fits'. (could not open the named file)
+ <DATE> <TIME> <HOST> |I|  testImageRead|Following should be an error as filename is NULL.
+ <DATE> <TIME> <HOST> |E|psImageReadSect|Must specify filename; it can not be NULL.
+ <DATE> <TIME> <HOST> |I|  testImageRead|Following should be an error as extnum is invalid.
+ <DATE> <TIME> <HOST> |E|psImageReadSect|Could not index to HDU #4 for file tmpImages/MxN_F32.fits. (tried to move past end of file)
+ <DATE> <TIME> <HOST> |I|  testImageRead|Following should be an error as extname is invalid.
+ <DATE> <TIME> <HOST> |E|psImageReadSect|Could not index to 'bogus' HDU for file tmpImages/MxN_F32.fits. (illegal HDU number)
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageIO.c                                            *
+*            TestPoint: psImage{567-testImageRead}                                 *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+ <DATE> <TIME> <HOST> |I|  testImageRead|Following should be an error as file doesn't exist.
+ <DATE> <TIME> <HOST> |E|psImageReadSect|Could not open file 'foobar.fits'. (could not open the named file)
+ <DATE> <TIME> <HOST> |I|  testImageRead|Following should be an error as filename is NULL.
+ <DATE> <TIME> <HOST> |E|psImageReadSect|Must specify filename; it can not be NULL.
+ <DATE> <TIME> <HOST> |I|  testImageRead|Following should be an error as extnum is invalid.
+ <DATE> <TIME> <HOST> |E|psImageReadSect|Could not index to HDU #4 for file tmpImages/MxN_F32.fits. (tried to move past end of file)
+ <DATE> <TIME> <HOST> |I|  testImageRead|Following should be an error as extname is invalid.
+ <DATE> <TIME> <HOST> |E|psImageReadSect|Could not index to 'bogus' HDU for file tmpImages/MxN_F32.fits. (illegal HDU number)
+
+---> TESTPOINT PASSED (psImage{567-testImageRead} | tst_psImageIO.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageIO.c                                            *
+*            TestPoint: psImage{569-testImageWrite}                                *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psImage{569-testImageWrite} | tst_psImageIO.c)
+
Index: /tags/rel1_1/psLib/test/image/verified/tst_psImageStats00.stdout
===================================================================
--- /tags/rel1_1/psLib/test/image/verified/tst_psImageStats00.stdout	(revision 1056)
+++ /tags/rel1_1/psLib/test/image/verified/tst_psImageStats00.stdout	(revision 1056)
@@ -0,0 +1,429 @@
+*******************************
+* IMAGE SIZE is (1 by 1)
+*******************************
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats00.c                                       *
+*            TestPoint: psImageStats functions{Calculate Histogram, no mask}       *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Bin number 0 bounds: (0.000000 - 0.100000) data (0)
+Bin number 1 bounds: (0.100000 - 0.200000) data (1)
+Bin number 2 bounds: (0.200000 - 0.300000) data (0)
+Bin number 3 bounds: (0.300000 - 0.400000) data (0)
+Bin number 4 bounds: (0.400000 - 0.500000) data (0)
+Bin number 5 bounds: (0.500000 - 0.600000) data (0)
+Bin number 6 bounds: (0.600000 - 0.700000) data (0)
+Bin number 7 bounds: (0.700000 - 0.800000) data (0)
+Bin number 8 bounds: (0.800000 - 0.900000) data (0)
+Bin number 9 bounds: (0.900000 - 1.000000) data (0)
+Bin number 10 bounds: (1.000000 - 1.100000) data (0)
+Bin number 11 bounds: (1.100000 - 1.200000) data (0)
+Bin number 12 bounds: (1.200000 - 1.300000) data (0)
+Bin number 13 bounds: (1.300000 - 1.400000) data (0)
+Bin number 14 bounds: (1.400000 - 1.500000) data (0)
+Bin number 15 bounds: (1.500000 - 1.600000) data (0)
+Bin number 16 bounds: (1.600000 - 1.700000) data (0)
+Bin number 17 bounds: (1.700000 - 1.800000) data (0)
+Bin number 18 bounds: (1.800000 - 1.900000) data (0)
+Bin number 19 bounds: (1.900000 - 2.000000) data (0)
+
+---> TESTPOINT PASSED (psImageStats functions{Calculate Histogram, no mask} | tst_psImageStats00.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats00.c                                       *
+*            TestPoint: psImageStats functions{Calculate Histogram with mask}      *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Bin number 0 bounds: (0.000000 - 0.100000) data (0)
+Bin number 1 bounds: (0.100000 - 0.200000) data (1)
+Bin number 2 bounds: (0.200000 - 0.300000) data (0)
+Bin number 3 bounds: (0.300000 - 0.400000) data (0)
+Bin number 4 bounds: (0.400000 - 0.500000) data (0)
+Bin number 5 bounds: (0.500000 - 0.600000) data (0)
+Bin number 6 bounds: (0.600000 - 0.700000) data (0)
+Bin number 7 bounds: (0.700000 - 0.800000) data (0)
+Bin number 8 bounds: (0.800000 - 0.900000) data (0)
+Bin number 9 bounds: (0.900000 - 1.000000) data (0)
+Bin number 10 bounds: (1.000000 - 1.100000) data (0)
+Bin number 11 bounds: (1.100000 - 1.200000) data (0)
+Bin number 12 bounds: (1.200000 - 1.300000) data (0)
+Bin number 13 bounds: (1.300000 - 1.400000) data (0)
+Bin number 14 bounds: (1.400000 - 1.500000) data (0)
+Bin number 15 bounds: (1.500000 - 1.600000) data (0)
+Bin number 16 bounds: (1.600000 - 1.700000) data (0)
+Bin number 17 bounds: (1.700000 - 1.800000) data (0)
+Bin number 18 bounds: (1.800000 - 1.900000) data (0)
+Bin number 19 bounds: (1.900000 - 2.000000) data (0)
+
+---> TESTPOINT PASSED (psImageStats functions{Calculate Histogram with mask} | tst_psImageStats00.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats00.c                                       *
+*            TestPoint: psImageStats functions{Deallocate the psHistogram/psImage structure.} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psImageStats functions{Deallocate the psHistogram/psImage structure.} | tst_psImageStats00.c)
+
+*******************************
+* IMAGE SIZE is (1 by 32)
+*******************************
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats00.c                                       *
+*            TestPoint: psImageStats functions{Calculate Histogram, no mask}       *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Bin number 0 bounds: (0.000000 - 1.650000) data (2)
+Bin number 1 bounds: (1.650000 - 3.300000) data (2)
+Bin number 2 bounds: (3.300000 - 4.950000) data (1)
+Bin number 3 bounds: (4.950000 - 6.600000) data (2)
+Bin number 4 bounds: (6.600000 - 8.250000) data (2)
+Bin number 5 bounds: (8.250000 - 9.900000) data (1)
+Bin number 6 bounds: (9.900000 - 11.550000) data (2)
+Bin number 7 bounds: (11.550000 - 13.200000) data (2)
+Bin number 8 bounds: (13.200000 - 14.849999) data (1)
+Bin number 9 bounds: (14.849999 - 16.500000) data (2)
+Bin number 10 bounds: (16.500000 - 18.150000) data (2)
+Bin number 11 bounds: (18.150000 - 19.799999) data (1)
+Bin number 12 bounds: (19.799999 - 21.449999) data (2)
+Bin number 13 bounds: (21.449999 - 23.100000) data (1)
+Bin number 14 bounds: (23.100000 - 24.750000) data (2)
+Bin number 15 bounds: (24.750000 - 26.400000) data (2)
+Bin number 16 bounds: (26.400000 - 28.049999) data (1)
+Bin number 17 bounds: (28.049999 - 29.699999) data (2)
+Bin number 18 bounds: (29.699999 - 31.350000) data (2)
+Bin number 19 bounds: (31.350000 - 33.000000) data (0)
+
+---> TESTPOINT PASSED (psImageStats functions{Calculate Histogram, no mask} | tst_psImageStats00.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats00.c                                       *
+*            TestPoint: psImageStats functions{Calculate Histogram with mask}      *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Bin number 0 bounds: (0.000000 - 1.650000) data (2)
+Bin number 1 bounds: (1.650000 - 3.300000) data (2)
+Bin number 2 bounds: (3.300000 - 4.950000) data (1)
+Bin number 3 bounds: (4.950000 - 6.600000) data (2)
+Bin number 4 bounds: (6.600000 - 8.250000) data (2)
+Bin number 5 bounds: (8.250000 - 9.900000) data (1)
+Bin number 6 bounds: (9.900000 - 11.550000) data (2)
+Bin number 7 bounds: (11.550000 - 13.200000) data (2)
+Bin number 8 bounds: (13.200000 - 14.849999) data (1)
+Bin number 9 bounds: (14.849999 - 16.500000) data (2)
+Bin number 10 bounds: (16.500000 - 18.150000) data (2)
+Bin number 11 bounds: (18.150000 - 19.799999) data (1)
+Bin number 12 bounds: (19.799999 - 21.449999) data (2)
+Bin number 13 bounds: (21.449999 - 23.100000) data (1)
+Bin number 14 bounds: (23.100000 - 24.750000) data (2)
+Bin number 15 bounds: (24.750000 - 26.400000) data (2)
+Bin number 16 bounds: (26.400000 - 28.049999) data (1)
+Bin number 17 bounds: (28.049999 - 29.699999) data (2)
+Bin number 18 bounds: (29.699999 - 31.350000) data (2)
+Bin number 19 bounds: (31.350000 - 33.000000) data (0)
+
+---> TESTPOINT PASSED (psImageStats functions{Calculate Histogram with mask} | tst_psImageStats00.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats00.c                                       *
+*            TestPoint: psImageStats functions{Deallocate the psHistogram/psImage structure.} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psImageStats functions{Deallocate the psHistogram/psImage structure.} | tst_psImageStats00.c)
+
+*******************************
+* IMAGE SIZE is (32 by 1)
+*******************************
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats00.c                                       *
+*            TestPoint: psImageStats functions{Calculate Histogram, no mask}       *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Bin number 0 bounds: (0.000000 - 1.650000) data (2)
+Bin number 1 bounds: (1.650000 - 3.300000) data (2)
+Bin number 2 bounds: (3.300000 - 4.950000) data (1)
+Bin number 3 bounds: (4.950000 - 6.600000) data (2)
+Bin number 4 bounds: (6.600000 - 8.250000) data (2)
+Bin number 5 bounds: (8.250000 - 9.900000) data (1)
+Bin number 6 bounds: (9.900000 - 11.550000) data (2)
+Bin number 7 bounds: (11.550000 - 13.200000) data (2)
+Bin number 8 bounds: (13.200000 - 14.849999) data (1)
+Bin number 9 bounds: (14.849999 - 16.500000) data (2)
+Bin number 10 bounds: (16.500000 - 18.150000) data (2)
+Bin number 11 bounds: (18.150000 - 19.799999) data (1)
+Bin number 12 bounds: (19.799999 - 21.449999) data (2)
+Bin number 13 bounds: (21.449999 - 23.100000) data (1)
+Bin number 14 bounds: (23.100000 - 24.750000) data (2)
+Bin number 15 bounds: (24.750000 - 26.400000) data (2)
+Bin number 16 bounds: (26.400000 - 28.049999) data (1)
+Bin number 17 bounds: (28.049999 - 29.699999) data (2)
+Bin number 18 bounds: (29.699999 - 31.350000) data (2)
+Bin number 19 bounds: (31.350000 - 33.000000) data (0)
+
+---> TESTPOINT PASSED (psImageStats functions{Calculate Histogram, no mask} | tst_psImageStats00.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats00.c                                       *
+*            TestPoint: psImageStats functions{Calculate Histogram with mask}      *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Bin number 0 bounds: (0.000000 - 1.650000) data (2)
+Bin number 1 bounds: (1.650000 - 3.300000) data (2)
+Bin number 2 bounds: (3.300000 - 4.950000) data (1)
+Bin number 3 bounds: (4.950000 - 6.600000) data (2)
+Bin number 4 bounds: (6.600000 - 8.250000) data (2)
+Bin number 5 bounds: (8.250000 - 9.900000) data (1)
+Bin number 6 bounds: (9.900000 - 11.550000) data (2)
+Bin number 7 bounds: (11.550000 - 13.200000) data (2)
+Bin number 8 bounds: (13.200000 - 14.849999) data (1)
+Bin number 9 bounds: (14.849999 - 16.500000) data (2)
+Bin number 10 bounds: (16.500000 - 18.150000) data (2)
+Bin number 11 bounds: (18.150000 - 19.799999) data (1)
+Bin number 12 bounds: (19.799999 - 21.449999) data (2)
+Bin number 13 bounds: (21.449999 - 23.100000) data (1)
+Bin number 14 bounds: (23.100000 - 24.750000) data (2)
+Bin number 15 bounds: (24.750000 - 26.400000) data (2)
+Bin number 16 bounds: (26.400000 - 28.049999) data (1)
+Bin number 17 bounds: (28.049999 - 29.699999) data (2)
+Bin number 18 bounds: (29.699999 - 31.350000) data (2)
+Bin number 19 bounds: (31.350000 - 33.000000) data (0)
+
+---> TESTPOINT PASSED (psImageStats functions{Calculate Histogram with mask} | tst_psImageStats00.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats00.c                                       *
+*            TestPoint: psImageStats functions{Deallocate the psHistogram/psImage structure.} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psImageStats functions{Deallocate the psHistogram/psImage structure.} | tst_psImageStats00.c)
+
+*******************************
+* IMAGE SIZE is (32 by 32)
+*******************************
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats00.c                                       *
+*            TestPoint: psImageStats functions{Calculate Histogram, no mask}       *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Bin number 0 bounds: (0.000000 - 3.200000) data (10)
+Bin number 1 bounds: (3.200000 - 6.400000) data (18)
+Bin number 2 bounds: (6.400000 - 9.600000) data (27)
+Bin number 3 bounds: (9.600000 - 12.800000) data (36)
+Bin number 4 bounds: (12.800000 - 16.000000) data (45)
+Bin number 5 bounds: (16.000000 - 19.200001) data (74)
+Bin number 6 bounds: (19.200001 - 22.400000) data (66)
+Bin number 7 bounds: (22.400000 - 25.600000) data (75)
+Bin number 8 bounds: (25.600000 - 28.800001) data (84)
+Bin number 9 bounds: (28.800001 - 32.000000) data (93)
+Bin number 10 bounds: (32.000000 - 35.200001) data (118)
+Bin number 11 bounds: (35.200001 - 38.400002) data (78)
+Bin number 12 bounds: (38.400002 - 41.600002) data (69)
+Bin number 13 bounds: (41.600002 - 44.799999) data (60)
+Bin number 14 bounds: (44.799999 - 48.000000) data (51)
+Bin number 15 bounds: (48.000000 - 51.200001) data (54)
+Bin number 16 bounds: (51.200001 - 54.400002) data (30)
+Bin number 17 bounds: (54.400002 - 57.600002) data (21)
+Bin number 18 bounds: (57.600002 - 60.799999) data (12)
+Bin number 19 bounds: (60.799999 - 64.000000) data (3)
+
+---> TESTPOINT PASSED (psImageStats functions{Calculate Histogram, no mask} | tst_psImageStats00.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats00.c                                       *
+*            TestPoint: psImageStats functions{Calculate Histogram with mask}      *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Bin number 0 bounds: (0.000000 - 3.200000) data (10)
+Bin number 1 bounds: (3.200000 - 6.400000) data (18)
+Bin number 2 bounds: (6.400000 - 9.600000) data (27)
+Bin number 3 bounds: (9.600000 - 12.800000) data (36)
+Bin number 4 bounds: (12.800000 - 16.000000) data (45)
+Bin number 5 bounds: (16.000000 - 19.200001) data (74)
+Bin number 6 bounds: (19.200001 - 22.400000) data (66)
+Bin number 7 bounds: (22.400000 - 25.600000) data (75)
+Bin number 8 bounds: (25.600000 - 28.800001) data (84)
+Bin number 9 bounds: (28.800001 - 32.000000) data (93)
+Bin number 10 bounds: (32.000000 - 35.200001) data (115)
+Bin number 11 bounds: (35.200001 - 38.400002) data (66)
+Bin number 12 bounds: (38.400002 - 41.600002) data (48)
+Bin number 13 bounds: (41.600002 - 44.799999) data (30)
+Bin number 14 bounds: (44.799999 - 48.000000) data (12)
+Bin number 15 bounds: (48.000000 - 51.200001) data (0)
+Bin number 16 bounds: (51.200001 - 54.400002) data (0)
+Bin number 17 bounds: (54.400002 - 57.600002) data (0)
+Bin number 18 bounds: (57.600002 - 60.799999) data (0)
+Bin number 19 bounds: (60.799999 - 64.000000) data (0)
+
+---> TESTPOINT PASSED (psImageStats functions{Calculate Histogram with mask} | tst_psImageStats00.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats00.c                                       *
+*            TestPoint: psImageStats functions{Deallocate the psHistogram/psImage structure.} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psImageStats functions{Deallocate the psHistogram/psImage structure.} | tst_psImageStats00.c)
+
+*******************************
+* IMAGE SIZE is (32 by 64)
+*******************************
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats00.c                                       *
+*            TestPoint: psImageStats functions{Calculate Histogram, no mask}       *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Bin number 0 bounds: (0.000000 - 4.800000) data (15)
+Bin number 1 bounds: (4.800000 - 9.600000) data (40)
+Bin number 2 bounds: (9.600000 - 14.400001) data (65)
+Bin number 3 bounds: (14.400001 - 19.200001) data (90)
+Bin number 4 bounds: (19.200001 - 24.000000) data (90)
+Bin number 5 bounds: (24.000000 - 28.800001) data (135)
+Bin number 6 bounds: (28.800001 - 33.600002) data (157)
+Bin number 7 bounds: (33.600002 - 38.400002) data (160)
+Bin number 8 bounds: (38.400002 - 43.200001) data (160)
+Bin number 9 bounds: (43.200001 - 48.000000) data (128)
+Bin number 10 bounds: (48.000000 - 52.800003) data (160)
+Bin number 11 bounds: (52.800003 - 57.600002) data (160)
+Bin number 12 bounds: (57.600002 - 62.400002) data (160)
+Bin number 13 bounds: (62.400002 - 67.200005) data (150)
+Bin number 14 bounds: (67.200005 - 72.000000) data (102)
+Bin number 15 bounds: (72.000000 - 76.800003) data (105)
+Bin number 16 bounds: (76.800003 - 81.600006) data (80)
+Bin number 17 bounds: (81.600006 - 86.400002) data (55)
+Bin number 18 bounds: (86.400002 - 91.200005) data (30)
+Bin number 19 bounds: (91.200005 - 96.000000) data (6)
+
+---> TESTPOINT PASSED (psImageStats functions{Calculate Histogram, no mask} | tst_psImageStats00.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats00.c                                       *
+*            TestPoint: psImageStats functions{Calculate Histogram with mask}      *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Bin number 0 bounds: (0.000000 - 4.800000) data (15)
+Bin number 1 bounds: (4.800000 - 9.600000) data (40)
+Bin number 2 bounds: (9.600000 - 14.400001) data (65)
+Bin number 3 bounds: (14.400001 - 19.200001) data (90)
+Bin number 4 bounds: (19.200001 - 24.000000) data (90)
+Bin number 5 bounds: (24.000000 - 28.800001) data (135)
+Bin number 6 bounds: (28.800001 - 33.600002) data (157)
+Bin number 7 bounds: (33.600002 - 38.400002) data (160)
+Bin number 8 bounds: (38.400002 - 43.200001) data (160)
+Bin number 9 bounds: (43.200001 - 48.000000) data (128)
+Bin number 10 bounds: (48.000000 - 52.800003) data (154)
+Bin number 11 bounds: (52.800003 - 57.600002) data (130)
+Bin number 12 bounds: (57.600002 - 62.400002) data (105)
+Bin number 13 bounds: (62.400002 - 67.200005) data (76)
+Bin number 14 bounds: (67.200005 - 72.000000) data (42)
+Bin number 15 bounds: (72.000000 - 76.800003) data (30)
+Bin number 16 bounds: (76.800003 - 81.600006) data (6)
+Bin number 17 bounds: (81.600006 - 86.400002) data (0)
+Bin number 18 bounds: (86.400002 - 91.200005) data (0)
+Bin number 19 bounds: (91.200005 - 96.000000) data (0)
+
+---> TESTPOINT PASSED (psImageStats functions{Calculate Histogram with mask} | tst_psImageStats00.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats00.c                                       *
+*            TestPoint: psImageStats functions{Deallocate the psHistogram/psImage structure.} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psImageStats functions{Deallocate the psHistogram/psImage structure.} | tst_psImageStats00.c)
+
+*******************************
+* IMAGE SIZE is (64 by 32)
+*******************************
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats00.c                                       *
+*            TestPoint: psImageStats functions{Calculate Histogram, no mask}       *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Bin number 0 bounds: (0.000000 - 4.800000) data (15)
+Bin number 1 bounds: (4.800000 - 9.600000) data (40)
+Bin number 2 bounds: (9.600000 - 14.400001) data (65)
+Bin number 3 bounds: (14.400001 - 19.200001) data (90)
+Bin number 4 bounds: (19.200001 - 24.000000) data (90)
+Bin number 5 bounds: (24.000000 - 28.800001) data (135)
+Bin number 6 bounds: (28.800001 - 33.600002) data (157)
+Bin number 7 bounds: (33.600002 - 38.400002) data (160)
+Bin number 8 bounds: (38.400002 - 43.200001) data (160)
+Bin number 9 bounds: (43.200001 - 48.000000) data (128)
+Bin number 10 bounds: (48.000000 - 52.800003) data (160)
+Bin number 11 bounds: (52.800003 - 57.600002) data (160)
+Bin number 12 bounds: (57.600002 - 62.400002) data (160)
+Bin number 13 bounds: (62.400002 - 67.200005) data (150)
+Bin number 14 bounds: (67.200005 - 72.000000) data (102)
+Bin number 15 bounds: (72.000000 - 76.800003) data (105)
+Bin number 16 bounds: (76.800003 - 81.600006) data (80)
+Bin number 17 bounds: (81.600006 - 86.400002) data (55)
+Bin number 18 bounds: (86.400002 - 91.200005) data (30)
+Bin number 19 bounds: (91.200005 - 96.000000) data (6)
+
+---> TESTPOINT PASSED (psImageStats functions{Calculate Histogram, no mask} | tst_psImageStats00.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats00.c                                       *
+*            TestPoint: psImageStats functions{Calculate Histogram with mask}      *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Bin number 0 bounds: (0.000000 - 4.800000) data (15)
+Bin number 1 bounds: (4.800000 - 9.600000) data (40)
+Bin number 2 bounds: (9.600000 - 14.400001) data (65)
+Bin number 3 bounds: (14.400001 - 19.200001) data (90)
+Bin number 4 bounds: (19.200001 - 24.000000) data (90)
+Bin number 5 bounds: (24.000000 - 28.800001) data (135)
+Bin number 6 bounds: (28.800001 - 33.600002) data (157)
+Bin number 7 bounds: (33.600002 - 38.400002) data (160)
+Bin number 8 bounds: (38.400002 - 43.200001) data (160)
+Bin number 9 bounds: (43.200001 - 48.000000) data (128)
+Bin number 10 bounds: (48.000000 - 52.800003) data (154)
+Bin number 11 bounds: (52.800003 - 57.600002) data (130)
+Bin number 12 bounds: (57.600002 - 62.400002) data (105)
+Bin number 13 bounds: (62.400002 - 67.200005) data (76)
+Bin number 14 bounds: (67.200005 - 72.000000) data (42)
+Bin number 15 bounds: (72.000000 - 76.800003) data (30)
+Bin number 16 bounds: (76.800003 - 81.600006) data (6)
+Bin number 17 bounds: (81.600006 - 86.400002) data (0)
+Bin number 18 bounds: (86.400002 - 91.200005) data (0)
+Bin number 19 bounds: (91.200005 - 96.000000) data (0)
+
+---> TESTPOINT PASSED (psImageStats functions{Calculate Histogram with mask} | tst_psImageStats00.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats00.c                                       *
+*            TestPoint: psImageStats functions{Deallocate the psHistogram/psImage structure.} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psImageStats functions{Deallocate the psHistogram/psImage structure.} | tst_psImageStats00.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats00.c                                       *
+*            TestPoint: psImageStats functions{Calling psImageHistogram() with NULL parameters} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psImageStats functions{Calling psImageHistogram() with NULL parameters} | tst_psImageStats00.c)
+
Index: /tags/rel1_1/psLib/test/image/verified/tst_psImageStats01.stdout
===================================================================
--- /tags/rel1_1/psLib/test/image/verified/tst_psImageStats01.stdout	(revision 1056)
+++ /tags/rel1_1/psLib/test/image/verified/tst_psImageStats01.stdout	(revision 1056)
@@ -0,0 +1,201 @@
+*******************************
+* IMAGE SIZE is (1 by 1)
+*******************************
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats01.c                                       *
+*            TestPoint: psImageStats functions{Calculate Sample Mean, no mask %d}  *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+The sample mean was 0.000000
+
+---> TESTPOINT PASSED (psImageStats functions{Calculate Sample Mean, no mask} | tst_psImageStats01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats01.c                                       *
+*            TestPoint: psImageStats functions{Calculate Sample Mean with mask}    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+The sample mean was 0.000000
+
+---> TESTPOINT PASSED (psImageStats functions{Calculate Sample Mean with mask} | tst_psImageStats01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats01.c                                       *
+*            TestPoint: psImageStats functions{Deallocate the psStats/psImage structure.} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psImageStats functions{Deallocate the psStats/psImage structure.} | tst_psImageStats01.c)
+
+*******************************
+* IMAGE SIZE is (1 by 32)
+*******************************
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats01.c                                       *
+*            TestPoint: psImageStats functions{Calculate Sample Mean, no mask %d}  *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+The sample mean was 15.500000
+
+---> TESTPOINT PASSED (psImageStats functions{Calculate Sample Mean, no mask} | tst_psImageStats01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats01.c                                       *
+*            TestPoint: psImageStats functions{Calculate Sample Mean with mask}    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+The sample mean was 15.500000
+
+---> TESTPOINT PASSED (psImageStats functions{Calculate Sample Mean with mask} | tst_psImageStats01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats01.c                                       *
+*            TestPoint: psImageStats functions{Deallocate the psStats/psImage structure.} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psImageStats functions{Deallocate the psStats/psImage structure.} | tst_psImageStats01.c)
+
+*******************************
+* IMAGE SIZE is (32 by 1)
+*******************************
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats01.c                                       *
+*            TestPoint: psImageStats functions{Calculate Sample Mean, no mask %d}  *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+The sample mean was 15.500000
+
+---> TESTPOINT PASSED (psImageStats functions{Calculate Sample Mean, no mask} | tst_psImageStats01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats01.c                                       *
+*            TestPoint: psImageStats functions{Calculate Sample Mean with mask}    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+The sample mean was 15.500000
+
+---> TESTPOINT PASSED (psImageStats functions{Calculate Sample Mean with mask} | tst_psImageStats01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats01.c                                       *
+*            TestPoint: psImageStats functions{Deallocate the psStats/psImage structure.} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psImageStats functions{Deallocate the psStats/psImage structure.} | tst_psImageStats01.c)
+
+*******************************
+* IMAGE SIZE is (32 by 32)
+*******************************
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats01.c                                       *
+*            TestPoint: psImageStats functions{Calculate Sample Mean, no mask %d}  *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+The sample mean was 31.000000
+
+---> TESTPOINT PASSED (psImageStats functions{Calculate Sample Mean, no mask} | tst_psImageStats01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats01.c                                       *
+*            TestPoint: psImageStats functions{Calculate Sample Mean with mask}    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+The sample mean was 26.212767
+
+---> TESTPOINT PASSED (psImageStats functions{Calculate Sample Mean with mask} | tst_psImageStats01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats01.c                                       *
+*            TestPoint: psImageStats functions{Deallocate the psStats/psImage structure.} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psImageStats functions{Deallocate the psStats/psImage structure.} | tst_psImageStats01.c)
+
+*******************************
+* IMAGE SIZE is (32 by 64)
+*******************************
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats01.c                                       *
+*            TestPoint: psImageStats functions{Calculate Sample Mean, no mask %d}  *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+The sample mean was 47.000000
+
+---> TESTPOINT PASSED (psImageStats functions{Calculate Sample Mean, no mask} | tst_psImageStats01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats01.c                                       *
+*            TestPoint: psImageStats functions{Calculate Sample Mean with mask}    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+The sample mean was 39.656349
+
+---> TESTPOINT PASSED (psImageStats functions{Calculate Sample Mean with mask} | tst_psImageStats01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats01.c                                       *
+*            TestPoint: psImageStats functions{Deallocate the psStats/psImage structure.} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psImageStats functions{Deallocate the psStats/psImage structure.} | tst_psImageStats01.c)
+
+*******************************
+* IMAGE SIZE is (64 by 32)
+*******************************
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats01.c                                       *
+*            TestPoint: psImageStats functions{Calculate Sample Mean, no mask %d}  *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+The sample mean was 47.000000
+
+---> TESTPOINT PASSED (psImageStats functions{Calculate Sample Mean, no mask} | tst_psImageStats01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats01.c                                       *
+*            TestPoint: psImageStats functions{Calculate Sample Mean with mask}    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+The sample mean was 39.656349
+
+---> TESTPOINT PASSED (psImageStats functions{Calculate Sample Mean with mask} | tst_psImageStats01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats01.c                                       *
+*            TestPoint: psImageStats functions{Deallocate the psStats/psImage structure.} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psImageStats functions{Deallocate the psStats/psImage structure.} | tst_psImageStats01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats01.c                                       *
+*            TestPoint: psImageStats functions{Test With Various Null Inputs}      *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psImageStats functions{Test With Various Null Inputs} | tst_psImageStats01.c)
+
Index: /tags/rel1_1/psLib/test/image/verified/tst_psImageStats02.stdout
===================================================================
--- /tags/rel1_1/psLib/test/image/verified/tst_psImageStats02.stdout	(revision 1056)
+++ /tags/rel1_1/psLib/test/image/verified/tst_psImageStats02.stdout	(revision 1056)
@@ -0,0 +1,27 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats02.c                                       *
+*            TestPoint: psImageStats functions{Calculate Chebyshev Polynomials, no mask} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psImageStats functions{Calculate Chebyshev Polynomials, no mask} | tst_psImageStats02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats02.c                                       *
+*            TestPoint: psImageStats functions{Calculate Chebyshev Polynomials, no mask} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psImageStats functions{Calculate Chebyshev Polynomials, no mask} | tst_psImageStats02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats02.c                                       *
+*            TestPoint: psImageStats functions{Deallocate the psStats/psImage structure.} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psImageStats functions{Deallocate the psStats/psImage structure.} | tst_psImageStats02.c)
+
Index: /tags/rel1_1/psLib/test/psTest.c
===================================================================
--- /tags/rel1_1/psLib/test/psTest.c	(revision 1056)
+++ /tags/rel1_1/psLib/test/psTest.c	(revision 1056)
@@ -0,0 +1,130 @@
+//
+// C Implementation: psTest
+//
+// Description:
+//
+//
+// Author: Robert DeSonia <robert.desonia@mhpcc.hpc.mil>, (C) 2004
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/wait.h>
+
+#include "psTest.h"
+#include "psMemory.h"
+#include "psError.h"
+
+#define HEADER_TOP    "/***************************** TESTPOINT ******************************************\\\n"
+#define HEADER_LINE_STRING   "* %20s: %-58s *\n"
+#define HEADER_LINE_INT      "* %20s: %-58d *\n"
+#define HEADER_BOTTOM "\\**********************************************************************************/\n\n"
+
+bool p_runTestSuite(FILE *fp, const char* testPointFile, const char* packageName, testDescription tests[])
+{
+    bool success = true;
+
+    for (int index=0; tests[index].fcn != NULL; index++) {
+        success = p_runTest(fp,testPointFile,packageName,tests[index].testPointName,
+                            tests[index].fcn,tests[index].expectedReturn) && success;
+    }
+    return success;
+}
+
+bool p_runTest(FILE *fp, const char* testPointFile, const char* packageName, const char* testPointName,
+               testFcn fcn, int expectedReturn)
+{
+    int childReturn = 0;
+    pid_t child;
+
+    p_printPositiveTestHeader(fp,testPointFile,packageName,testPointName);
+
+    child = fork();
+    if (child == 0) {                   // I am the child process, run the test
+        int currentId = psMemGetId();
+        int retVal = fcn();
+        if (retVal == 0) { // only bother checking memory if test executed to end.
+            if (psMemCheckLeaks(currentId,NULL,stderr) != 0) {
+                psError(__func__,"Memory Leaks Detected");
+                retVal = 64;
+            }
+            psMemCheckCorruption(1);
+        }
+        exit(retVal);
+    } else if (child < 0) {
+        fprintf(fp,"Couldn't fork a process to run a negative test (%s|%s)",
+                packageName, testPointName);
+        abort();
+    }
+
+    waitpid(child,&childReturn,0);
+    if (WIFSIGNALED(childReturn)) {
+        childReturn =  -WTERMSIG(childReturn);
+    } else {
+        childReturn = WEXITSTATUS(childReturn);
+    }
+
+    if (childReturn != expectedReturn) {
+        fprintf(fp,"Return value mismatch: expected %d, got %d",
+                expectedReturn,childReturn);
+    }
+
+    p_printFooter(fp,testPointFile,packageName,testPointName,
+                  (childReturn==expectedReturn));
+
+    return (childReturn==expectedReturn);
+}
+
+void p_printPositiveTestHeader(FILE *fp,
+                               const char* testPointFile,
+                               const char* packageName,
+                               const char* testPointName)
+{
+    char TP[80];
+
+    snprintf(TP,80,"%s{%s}",packageName,testPointName);
+
+    fprintf(fp, HEADER_TOP);
+    fprintf(fp, HEADER_LINE_STRING, "TestFile", testPointFile);
+    fprintf(fp, HEADER_LINE_STRING, "TestPoint", TP);
+    fprintf(fp, HEADER_LINE_STRING, "TestType","Positive");
+    fprintf(fp, HEADER_BOTTOM);
+}
+
+void p_printNegativeTestHeader(FILE *fp,
+                               const char* testPointFile,
+                               const char* packageName,
+                               const char* testPointName,
+                               const char* expectedError,
+                               int exitValue)
+{
+    char TP[80];
+
+    snprintf(TP,80,"%s{%s}",packageName,testPointName);
+
+    fprintf(fp, HEADER_TOP);
+    fprintf(fp, HEADER_LINE_STRING, "TestFile", testPointFile);
+    fprintf(fp, HEADER_LINE_STRING, "TestPoint", TP);
+    fprintf(fp, HEADER_LINE_STRING,"TestType","Negative");
+    fprintf(fp, HEADER_LINE_STRING,"ExpectedErrorText",expectedError);
+    fprintf(fp, HEADER_LINE_INT,"ExpectedStatusValue",exitValue);
+    fprintf(fp, HEADER_BOTTOM);
+}
+
+
+void p_printFooter(FILE *fp,
+                   const char* testPointFile,
+                   const char* packageName,
+                   const char* testPointName,
+                   bool success)
+{
+    if (success) {
+        fprintf(fp, "\n---> TESTPOINT PASSED (%s{%s} | %s)\n\n", packageName,testPointName, testPointFile);
+    } else {
+        fprintf(fp, "\n---> TESTPOINT FAILED (%s{%s} | %s)\n\n", packageName,testPointName,testPointFile);
+    }
+}
Index: /tags/rel1_1/psLib/test/psTest.h
===================================================================
--- /tags/rel1_1/psLib/test/psTest.h	(revision 1056)
+++ /tags/rel1_1/psLib/test/psTest.h	(revision 1056)
@@ -0,0 +1,50 @@
+
+#ifndef PSTEST_H
+#define PSTEST_H
+
+#include <stdio.h>
+#include <stdbool.h>
+
+#define printPositiveTestHeader(filePtr, packageName, testPointName) \
+p_printPositiveTestHeader(filePtr, __FILE__, packageName, testPointName)
+
+#define printNegativeTestHeader(filePtr, packageName, testPointName, expectedError, exitValue) \
+p_printNegativeTestHeader(filePtr, __FILE__, packageName, testPointName, expectedError, exitValue)
+
+#define printFooter(filePtr, packageName, testPointName, success) \
+p_printFooter(filePtr, __FILE__, packageName, testPointName, success)
+
+typedef int (*testFcn)(void);
+
+typedef struct
+{
+    testFcn     fcn;
+    const char* testPointName;
+    int         expectedReturn;
+}
+testDescription;
+
+#define runTest(filePtr, packageName, testPointName, fcn, expectedReturn) \
+p_runTest(filePtr, __FILE__, packageName, testPointName, fcn, expectedReturn)
+
+#define runTestSuite(filePtr, packageName, tests) \
+p_runTestSuite(filePtr, __FILE__, packageName, tests)
+
+
+/////////////////////////// PRIVATE FUNCTIONS //////////////////////////////
+
+bool p_runTest(FILE *fp, const char* testPointFile, const char* packageName, const char* testPointName,
+               testFcn fcn, int expectedReturn);
+
+bool p_runTestSuite(FILE *fp, const char* testPointFile, const char* packageName, testDescription tests[]);
+
+void p_printPositiveTestHeader(FILE *fp, const char* testPointFile, const char* packageName,
+                               const char* testPointName);
+
+void p_printNegativeTestHeader(FILE *fp, const char* testPointFile, const char* packageName,
+                               const char* testPointName,const char* expectedError, int exitValue);
+
+void p_printFooter(FILE *fp, const char* testPointFile, const char* packageName, const char* testPointName,
+                   bool success);
+
+#endif
Index: /tags/rel1_1/psLib/test/runTest
===================================================================
--- /tags/rel1_1/psLib/test/runTest	(revision 1056)
+++ /tags/rel1_1/psLib/test/runTest	(revision 1056)
@@ -0,0 +1,301 @@
+#!/usr/bin/perl
+#
+#  This is a perl script to execute a single test driver program.  The script
+#  will examine the return value of the test driver and capture STDOUT, STDERR
+#  to files.  If the return value of the test driver is not zero, the test is
+#  deemed a failure.  STDOUT and STDERR files will be place in a subdirectory
+#  named temp and the files will be compared with verified STDOUT, STDERR files
+#  in a subdirectory named verified.  If there are no STDOUT, STDERR files in 
+#  the verified directory, the captured STDOUT, STDERR files will be scanned
+#  for words which indicate a failure.
+#
+#  Assumptions:  A verified subdirectory with STDOUT, STDERR files exists for 
+#                the test driver specified in the arguements if an exact
+#                match of the streams STDOUT, STDERR is necessary.
+#
+#  Return values:
+#                 Bit mapped values
+#                 0    Test run successfull and all tests passed
+#                 1    Verified directory did not exist
+#                 2    Verified STDOUT file did not exist
+#                 4    Verified STDERR file did not exist
+#                 8    STDOUT files did not compare
+#                16    STDERR files did not compare
+#                32    Test driver doesn't exist or is not executable
+#                64    STDOUT captured contains error strings
+#               128    STDERR captured contains error strings
+#               256    Test driver did not return zero
+#
+#  SYNOSIS:  runTest testDriverName
+#
+#  $Revison:  $  $Name: not supported by cvs2svn $
+#  $Date: 2004-06-04 02:41:17 $
+#
+#  Copyright 2004 Maui High Performance Computering Center, University of Hawaii
+#
+################################################################################
+
+# Initialize exit value
+$exitValue = 0;
+
+# Set up the PSLIB_ROOT environment variable if the user doesn't have it set
+if ( ! $ENV{'PSLIB_ROOT'}) {
+    # Use the directory directly above test
+    $PSLIB_ROOT = `cd ..;pwd`;
+    # Remove newline for the end of path returned
+    chomp($PSLIB_ROOT);
+    # Set the environment variable
+    $ENV{'PSLIB_ROOT'} = $PSLIB_ROOT;
+    # Display message that PSLIB_ROOT not found and set to 
+    print("PSLIB_ROOT not found: set to $PSLIB_ROOT\n");
+}
+
+# Add PSLIB_ROOT/lib to LD_LIBRARY_PATH and DYLD_LIBRARY_PATH environment vars
+$ENV{'LD_LIBRARY_PATH'} = "$ENV{'PSLIB_ROOT'}/lib:$ENV{'LD_LIBRARY_PATH'}";
+$ENV{'DYLD_LIBRARY_PATH'} = "$ENV{'PSLIB_ROOT'}/lib:$ENV{'DYLD_LIBRARY_PATH'}";
+
+# Get test driver name from arguement list
+$testFile = $ARGV[0];
+
+# Check if a temp directory already exists in the current work directory
+if ( !( -e "temp" )) {
+   # Create temp directory to store STDOUT, STDERR files during test run
+   `mkdir temp`;
+   # Display message of new directory created
+   print("Creating temp directory\n");
+}
+
+# Check if a verified directory exists in the current work directory
+if ( !( -e "verified" )) {
+    # Display message that verified subdirectory doesn't exist
+    print("        Verified directory doesn't exist.\n");
+    # Exit script since the test cannot be run with verified files
+    $exitValue = 1;
+}
+
+# Check if the test driver file exists and is executable
+if ( (-e $testFile) && (-x $testFile) ) {
+
+    # Display message the test driver is being executed
+    print("--- Executing test driver: $testFile\n");
+
+    # Invoke the test driver
+    system("./$testFile 1> temp/$testFile.stdout 2> temp/$testFile.stderr");
+
+    # Check the return value of the test driver.  A value other than 0
+    # indicates failure of the test driver unless the test driver is name
+    # with a leading 'a' which indicates the test driver is expecting an
+    # abort condition to terminate the driver.
+    if ( ( $? != 0  && ( $testFile !~ /^A/i)) || 
+         ( $? == 0  && ( $testFile =~ /^A/i)) ) {
+
+        # Display failure message with return value to user
+        if ( $? != 0 && ( $testFile !~ /^A/i) ) {
+            print("        Failed - Test Driver expected 0 return value (Return value $?)\n");
+        } elsif ( $? == 0 && ( $testFile =~ /^A/i) ) {
+            print("        Failed - Test Driver expected abort (Return value $?)\n");
+        }
+        $exitValue |= 256;
+    } else {
+  
+        # Test driver succeeded.
+  
+        # Create filtered version of stdout and stderr
+      
+        # Open the STDOUT file for reading
+        open(OUTFILE, "< temp/$testFile.stdout");
+        # Open mod file to place filtered STDOUT
+        open(MODFILE, ">temp/$testFile.stdout.mod");
+        # Replace the variable date, time and host information with constants
+        while( <OUTFILE> ) {
+            s/\d+:\d+:\d+/ <DATE> /;
+            s/\s+\d+:\d+:\d+\w/ <TIME> /;
+            s/\|\s*[\w\.\-\_]+\s*\|/<HOST> |/;
+            # Filter lines with malloc.  This is an artifact of memory testing
+            # with the Mac testbed
+            if ( ! m/\*\*\*\smalloc/ ) {
+               print MODFILE ($_);
+            }
+        }
+        # Close mod file
+        close(MODFILE);
+        # Close STDERR file
+        close(OUTFILE);
+
+        # Open the STDERR file for reading 
+        open(OUTFILE, "< temp/$testFile.stderr");
+        # Open mod file to place filtered STDERR
+        open(MODFILE, "> temp/$testFile.stderr.mod");
+        # Replace the variable date, time and host information with constants
+        while( <OUTFILE> ) {
+            s/\d+:\d+:\d+/ <DATE> /;
+            s/\s+\d+:\d+:\d+\w/ <TIME> /;
+            s/\|\s*[\w\.\-\_]+\s*\|/<HOST> |/;
+            # Filter lines with malloc.  This is an artifact of memory testing
+            # with the Mac testbed
+            if ( ! m/\*\*\*\smalloc/ ) {
+               print MODFILE ($_);
+            }
+        }
+        # Close mod file
+        close(MODFILE);
+        # Close STDERR file
+        close(OUTFILE);
+
+        # Compare STDOUT capture with verified file
+        $exitValue |= &compareStream("verified/$testFile.stdout");
+
+        # Check exit value to determine if verified file doesn't exist
+        if ( $exitValue & 2 ) {
+
+            # STDOUT verified doesn't exist.  Search STDOUT capture
+            # for strings indicating error or failure
+            $exitValue |= &errorStrSearch("$testFile.stdout");
+        }
+
+        # Compare STDERR capture with verified file
+        $exitValue |= &compareStream("verified/$testFile.stderr");
+
+        # Check exit value to determine if verified file doesn't exist
+        if ( $exitValue & 4 ) {
+
+            # STDERR verified doesn't exist.  Search STDERR capture
+            # for strings indicating error or failure
+            $exitValue |= &errorStrSearch("$testFile.stderr");
+        }
+    }
+} else {
+    # Since test driver doesn't exist or is not executable then display 
+    # message to user.
+    print("        Need to specify an executable test file within directory.\n");
+    
+    # Exit value set to indicate test driver doesn't exist or not executable
+    $exitValue |= 32;
+}
+
+# Exit for the script with exit value
+# Ignore the first three bit flags in exitValue since there are not indicators
+# of a failed test
+if ( ($exitValue >> 3) != 0 ) {
+    print("Test failed - return status = $exitValue\n\n");
+} else {
+    print("Test successful\n\n");
+}
+exit($exitValue);
+
+################################################################################
+#
+#  SUBROUTINE: errorStrSearch
+#
+#      Description:  This subroutine will search the file specified in its
+#                    parameter for error strings and if they do exists
+#                    the appropriate value will be returned.
+#
+#      Parameter(s): fileName - input file to search for strings
+#
+#      Return:   0  -  No error strings found
+#               64  -  Error strings found in STDOUT
+#              128  -  Error strings found in STDERR
+#
+###############################################################################
+
+sub errorStrSearch {
+    local($fileName) = @_;
+    local($returnVal) = 0;
+
+    # Open the captured file
+    open(CAPT_FILE, "<temp/$fileName");
+
+    # Scan through all the lines of the file searching for error strings
+    while ( <CAPT_FILE> ) {
+        if ( m/FAIL/i || m/FAULT/i || m/ERROR/i || m/Not Found/i
+                      || m/SIGNAL/i || m/NO SUCH FILE/i || m/\|E\|/i
+                      || m/\|A\|/i ) {
+            if ( $fileName =~ m/out/ ) {
+                print("        Failed - File $fileName contains error strings.\n");
+                $returnVal = 64;
+            } elsif ( $fileName =~ m/err/ ) {
+                print("        Failed - File $fileName contains error strings.\n");
+                $returnVal = 128;
+            }
+            last;
+        }
+    }
+    # Close the capture file
+    close(CAPT_FILE);
+    # Return the return value
+    return($returnVal);
+}
+
+################################################################################
+#
+#  SUBROUTINE: compareStream
+#
+#      Description:  This subroutine will compare the captured stream file with
+#                    a file in the verified directory if one exists.
+#
+#      Parameter(s): streamFile - input file to compare
+#
+#      Return:   0  -  Compare successful
+#                2  -  STDOUT verified file doesn't exist
+#                4  -  STDERR verified file doesn't exist
+#                8  -  STDOUT verified file doesn't compare
+#               16  -  STDERR verified file doesn't compare
+#
+###############################################################################
+
+sub compareStream {
+    local($streamFile) = @_;
+    local($returnVal) = 0;
+    local($tempFile) = "";
+
+    # Check for existence of verified STD stream files
+    if ( !( -e $streamFile) ) {
+            
+        # Display message to user that verified STDOUT file doesn't exist
+        print("        File $streamFile doesn't exist.\n");
+            
+        # Set exit value bit 1 to indicate proper failure
+        if ( $streamFile =~ /out$/ ) {
+            $returnVal |= 2;
+        } elsif ( $streamFile =~ /err$/ ) {
+            $returnVal |= 4;
+        }
+    } else {
+
+        # Verified STD stream file exists
+
+        # Create name of the temp file to compare
+        $tempFile = $streamFile; 
+        $tempFile =~ s/verified/temp/;
+        $tempFile = $tempFile . ".mod";
+   
+        # Perform difference on the STD stream files
+        $diffstdout = `diff $streamFile $tempFile`;
+
+        # Check the return value of the difference
+        if ( $? != 0 ) {
+   
+            # Difference of STD stream files failed
+
+            # Check for STDOUT in file name to convey appropirate return value
+            if ( $streamFile =~ /out$/ ) {
+               # Display message of the failure of difference to user
+               print("        Failed - STDOUT difference\n$diffstdout\n");
+  
+               # Exit value to indicate STDOUT did not compare
+               $returnVal |= 8;
+            } elsif ( $streamFile =~ /err$/ ) {
+               # Display message of the failure of difference to user
+               print("        Failed - STDERR difference\n$diffstdout\n");
+
+               # Exit value to indicate STDERR did not compare
+               $returnVal |= 16;
+            }
+        }
+    }
+    
+    # Return the result of the compare
+    return($returnVal);
+}
+
Index: /tags/rel1_1/psLib/test/sysUtils/.cvsignore
===================================================================
--- /tags/rel1_1/psLib/test/sysUtils/.cvsignore	(revision 1056)
+++ /tags/rel1_1/psLib/test/sysUtils/.cvsignore	(revision 1056)
@@ -0,0 +1,23 @@
+temp
+atst_psAbort_01
+atst_psAbort_02
+atst_psAbort_03
+tst_psError
+tst_psHash00
+tst_psHash01
+tst_psHash02
+tst_psHash03
+tst_psHash04
+tst_psLogMsg00
+tst_psLogMsg01
+tst_psLogMsg02
+tst_psLogMsg03
+tst_psMemory
+tst_psStringCopy
+tst_psTrace00
+tst_psTrace01
+tst_psTrace02
+tst_psTrace02_OUT
+tst_psTrace03
+tst_psTrace04
+core*
Index: /tags/rel1_1/psLib/test/sysUtils/Makefile
===================================================================
--- /tags/rel1_1/psLib/test/sysUtils/Makefile	(revision 1056)
+++ /tags/rel1_1/psLib/test/sysUtils/Makefile	(revision 1056)
@@ -0,0 +1,83 @@
+################################################################################
+##
+##  Makefile:   test/sysUtils
+##
+##  $Revision: 1.15 $  $Name: not supported by cvs2svn $
+##  $Date: 2004-06-11 20:36:04 $
+##
+##  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+##
+###############################################################################
+
+ifndef prefix
+    export prefix=$(shell cd ../..;pwd)
+endif
+
+include ../../src/Makefile.Globals
+
+PSLIB_INCL_DIR = ../../include
+
+PSLIB_LIB_DIR = ../../lib
+
+TARGET = atst_psAbort_01  \
+         atst_psAbort_02  \
+         atst_psAbort_03  \
+         tst_psMemory     \
+         tst_psError      \
+         tst_psHash00     \
+         tst_psHash01     \
+         tst_psHash02     \
+         tst_psHash03     \
+         tst_psHash04     \
+         tst_psLogMsg00   \
+         tst_psLogMsg01   \
+         tst_psLogMsg02   \
+         tst_psLogMsg03   \
+         tst_psStringCopy \
+         tst_psTrace00    \
+         tst_psTrace01    \
+         tst_psTrace02    \
+         tst_psTrace03    \
+         tst_psTrace04
+
+DEPENDENCIES = $(addprefix builddir/,$(addsuffix .d,$(TARGET)))
+OBJS = $(addprefix builddir/,$(addsuffix .o,$(TARGET)))
+
+all: builddir $(TARGET)
+
+builddir:
+	mkdir builddir
+
+include $(DEPENDENCIES)
+
+clean:
+	@echo "    Deleting executable and binary files for 'test/sysUtils'"
+	$(RM) $(OBJS) *.lint
+
+distclean: clean
+	$(RM) $(TARGET)
+
+builddir/%.o : %.c
+	$(CC) $(CFLAGS) $(CPPFLAGS) -I.. -I$(PSLIB_INCL_DIR) -c -o $@ $<
+
+%   : builddir/%.o
+	$(CC) -o $@ $< -L$(PSLIB_LIB_DIR) -lpslib -lpstest $(LDFLAGS)
+
+%.lint: %.c
+	splint +posixlib -exportlocal -realcompare $(INCLUDE_GLOBAL) $? > $@; cat $@
+
+builddir/%.d: %.c
+	$(CC) -MM $(CFLAGS) -I$(PSLIB_INCL_DIR) $< > $@.tmp
+	sed 's|\($*\)\.o[ :]*|builddir\/\1.o $@ : |g' $@.tmp > $@
+	$(RM) -f $@.tmp
+
+install: $(testbindir) $(testbindir)/verified $(TARGET)
+	install $(TARGET) $(testbindir)
+	install verified/*.stderr verified/*.stdout $(testbindir)/verified
+
+$(testbindir):
+	mkdir -p $(testbindir)
+
+$(testbindir)/verified:
+	mkdir -p $(testbindir)/verified
+
Index: /tags/rel1_1/psLib/test/sysUtils/atst_psAbort_01.c
===================================================================
--- /tags/rel1_1/psLib/test/sysUtils/atst_psAbort_01.c	(revision 1056)
+++ /tags/rel1_1/psLib/test/sysUtils/atst_psAbort_01.c	(revision 1056)
@@ -0,0 +1,43 @@
+/** @file  atst_psAbort_01.c
+ *
+ *  @brief Test driver for psAbort function
+ *
+ *  This test drivers contains the following test points for psAbort
+ *     1) Multiple type values in abort message
+ *
+ *  @author  Eric Van Alst, MHPCC
+ *
+ *  @version $Revision: 1.2 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2004-05-18 19:22:35 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include "pslib.h"
+#include "psTest.h"
+
+int main ( int argc,
+           char *argv[]
+         )
+{
+    int   intval = 1;
+    long  longval = 2;
+    float floatval = 3.01;
+    char  charval = 'E';
+    char  *stringval = "E R R O R";
+
+    // Test point #1 Multiple type values placed in the error string
+    printPositiveTestHeader(stderr, "psAbort","Multiple type values in abort message");
+    psAbort(__func__,
+            "ALL TYPES intval = %d longval = %ld floatval = %f charval = %c strval = %s",
+            intval, longval, floatval, charval, stringval );
+    // Since abort should never get to the next statement it would indicate
+    // a test failure
+    printFooter(stderr,"psAbort","Multiple type values in abort message",false);
+
+    // Program execution should have ended before this statement but if it
+    // does not return a zero since the expected return value of this test
+    // is a non-zero value
+    return 0;
+}
+
Index: /tags/rel1_1/psLib/test/sysUtils/atst_psAbort_02.c
===================================================================
--- /tags/rel1_1/psLib/test/sysUtils/atst_psAbort_02.c	(revision 1056)
+++ /tags/rel1_1/psLib/test/sysUtils/atst_psAbort_02.c	(revision 1056)
@@ -0,0 +1,35 @@
+/** @file  atst_psAbort_02.c
+ *
+ *  @brief Test driver for psAbort function
+ *
+ *  This test drivers contains the following test points for psAbort
+ *     2) String values in error message
+ *
+ *  @author  Eric Van Alst, MHPCC
+ *
+ *  @version $Revision: 1.2 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2004-05-18 19:22:35 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include "pslib.h"
+#include "psTest.h"
+
+int main ( int argc,
+           char *argv[]
+         )
+{
+    // Test point #2 String values in abort message
+    printPositiveTestHeader(stderr,"psAbort","String values in abort message");
+    psAbort(PS_STRING(__LINE__), "NO_VALUES");
+    // Since abort should never get to the next statement it would indicate
+    // a test failure
+    printFooter(stderr,"psAbort","String values in abort message",false);
+
+    // Program execution should have ended before this statement but if it
+    // does not return a zero since the expected return value of this test
+    // is a non-zero value
+    return 0;
+}
+
Index: /tags/rel1_1/psLib/test/sysUtils/atst_psAbort_03.c
===================================================================
--- /tags/rel1_1/psLib/test/sysUtils/atst_psAbort_03.c	(revision 1056)
+++ /tags/rel1_1/psLib/test/sysUtils/atst_psAbort_03.c	(revision 1056)
@@ -0,0 +1,35 @@
+/** @file  atst_psAbort_02.c
+ *
+ *  @brief Test driver for psAbort function
+ *
+ *  This test drivers contains the following test points for psAbort
+ *     3) Empty strings in abort message
+ *
+ *  @author  Eric Van Alst, MHPCC
+ *
+ *  @version $Revision: 1.2 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2004-05-18 19:22:35 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include "pslib.h"
+#include "psTest.h"
+
+int main ( int argc,
+           char *argv[]
+         )
+{
+    // Test point #3 Empty strings in abort message
+    printPositiveTestHeader(stderr, "psAbort","Empty strings in abort message");
+    psAbort("", "");
+    // Since abort should never get to the next statement it would indicate
+    // a test failure
+    printFooter(stderr, "psAbort","Empty strings in abort message",false);
+
+    // Program execution should have ended before this statement but if it
+    // does not return a zero since the expected return value of this test
+    // is a non-zero value
+    return 0;
+}
+
Index: /tags/rel1_1/psLib/test/sysUtils/builddir/atst_psAbort_01.d
===================================================================
--- /tags/rel1_1/psLib/test/sysUtils/builddir/atst_psAbort_01.d	(revision 1056)
+++ /tags/rel1_1/psLib/test/sysUtils/builddir/atst_psAbort_01.d	(revision 1056)
@@ -0,0 +1,8 @@
+builddir/atst_psAbort_01.o builddir/atst_psAbort_01.d : atst_psAbort_01.c ../../include/pslib.h \
+  ../../include/psMemory.h ../../include/psLogMsg.h \
+  ../../include/psTrace.h ../../include/psAbort.h ../../include/psError.h \
+  ../../include/psString.h ../../include/psType.h ../../include/psList.h \
+  ../../include/psVector.h ../../include/psHash.h ../../include/psImage.h \
+  ../../include/psBitSet.h ../../include/psSort.h ../../include/psStats.h \
+  ../../include/psMatrix.h ../../include/psFFT.h \
+  ../../include/psImageIO.h ../../include/psTest.h
Index: /tags/rel1_1/psLib/test/sysUtils/builddir/atst_psAbort_02.d
===================================================================
--- /tags/rel1_1/psLib/test/sysUtils/builddir/atst_psAbort_02.d	(revision 1056)
+++ /tags/rel1_1/psLib/test/sysUtils/builddir/atst_psAbort_02.d	(revision 1056)
@@ -0,0 +1,8 @@
+builddir/atst_psAbort_02.o builddir/atst_psAbort_02.d : atst_psAbort_02.c ../../include/pslib.h \
+  ../../include/psMemory.h ../../include/psLogMsg.h \
+  ../../include/psTrace.h ../../include/psAbort.h ../../include/psError.h \
+  ../../include/psString.h ../../include/psType.h ../../include/psList.h \
+  ../../include/psVector.h ../../include/psHash.h ../../include/psImage.h \
+  ../../include/psBitSet.h ../../include/psSort.h ../../include/psStats.h \
+  ../../include/psMatrix.h ../../include/psFFT.h \
+  ../../include/psImageIO.h ../../include/psTest.h
Index: /tags/rel1_1/psLib/test/sysUtils/builddir/atst_psAbort_03.d
===================================================================
--- /tags/rel1_1/psLib/test/sysUtils/builddir/atst_psAbort_03.d	(revision 1056)
+++ /tags/rel1_1/psLib/test/sysUtils/builddir/atst_psAbort_03.d	(revision 1056)
@@ -0,0 +1,8 @@
+builddir/atst_psAbort_03.o builddir/atst_psAbort_03.d : atst_psAbort_03.c ../../include/pslib.h \
+  ../../include/psMemory.h ../../include/psLogMsg.h \
+  ../../include/psTrace.h ../../include/psAbort.h ../../include/psError.h \
+  ../../include/psString.h ../../include/psType.h ../../include/psList.h \
+  ../../include/psVector.h ../../include/psHash.h ../../include/psImage.h \
+  ../../include/psBitSet.h ../../include/psSort.h ../../include/psStats.h \
+  ../../include/psMatrix.h ../../include/psFFT.h \
+  ../../include/psImageIO.h ../../include/psTest.h
Index: /tags/rel1_1/psLib/test/sysUtils/builddir/tst_psError.d
===================================================================
--- /tags/rel1_1/psLib/test/sysUtils/builddir/tst_psError.d	(revision 1056)
+++ /tags/rel1_1/psLib/test/sysUtils/builddir/tst_psError.d	(revision 1056)
@@ -0,0 +1,8 @@
+builddir/tst_psError.o builddir/tst_psError.d : tst_psError.c ../../include/pslib.h \
+  ../../include/psMemory.h ../../include/psLogMsg.h \
+  ../../include/psTrace.h ../../include/psAbort.h ../../include/psError.h \
+  ../../include/psString.h ../../include/psType.h ../../include/psList.h \
+  ../../include/psVector.h ../../include/psHash.h ../../include/psImage.h \
+  ../../include/psBitSet.h ../../include/psSort.h ../../include/psStats.h \
+  ../../include/psMatrix.h ../../include/psFFT.h \
+  ../../include/psImageIO.h ../../include/psTest.h
Index: /tags/rel1_1/psLib/test/sysUtils/builddir/tst_psHash00.d
===================================================================
--- /tags/rel1_1/psLib/test/sysUtils/builddir/tst_psHash00.d	(revision 1056)
+++ /tags/rel1_1/psLib/test/sysUtils/builddir/tst_psHash00.d	(revision 1056)
@@ -0,0 +1,8 @@
+builddir/tst_psHash00.o builddir/tst_psHash00.d : tst_psHash00.c ../../include/pslib.h \
+  ../../include/psMemory.h ../../include/psLogMsg.h \
+  ../../include/psTrace.h ../../include/psAbort.h ../../include/psError.h \
+  ../../include/psString.h ../../include/psType.h ../../include/psList.h \
+  ../../include/psVector.h ../../include/psHash.h ../../include/psImage.h \
+  ../../include/psBitSet.h ../../include/psSort.h ../../include/psStats.h \
+  ../../include/psMatrix.h ../../include/psFFT.h \
+  ../../include/psImageIO.h ../../include/psTest.h
Index: /tags/rel1_1/psLib/test/sysUtils/builddir/tst_psHash01.d
===================================================================
--- /tags/rel1_1/psLib/test/sysUtils/builddir/tst_psHash01.d	(revision 1056)
+++ /tags/rel1_1/psLib/test/sysUtils/builddir/tst_psHash01.d	(revision 1056)
@@ -0,0 +1,8 @@
+builddir/tst_psHash01.o builddir/tst_psHash01.d : tst_psHash01.c ../../include/pslib.h \
+  ../../include/psMemory.h ../../include/psLogMsg.h \
+  ../../include/psTrace.h ../../include/psAbort.h ../../include/psError.h \
+  ../../include/psString.h ../../include/psType.h ../../include/psList.h \
+  ../../include/psVector.h ../../include/psHash.h ../../include/psImage.h \
+  ../../include/psBitSet.h ../../include/psSort.h ../../include/psStats.h \
+  ../../include/psMatrix.h ../../include/psFFT.h \
+  ../../include/psImageIO.h ../../include/psTest.h
Index: /tags/rel1_1/psLib/test/sysUtils/builddir/tst_psHash02.d
===================================================================
--- /tags/rel1_1/psLib/test/sysUtils/builddir/tst_psHash02.d	(revision 1056)
+++ /tags/rel1_1/psLib/test/sysUtils/builddir/tst_psHash02.d	(revision 1056)
@@ -0,0 +1,8 @@
+builddir/tst_psHash02.o builddir/tst_psHash02.d : tst_psHash02.c ../../include/pslib.h \
+  ../../include/psMemory.h ../../include/psLogMsg.h \
+  ../../include/psTrace.h ../../include/psAbort.h ../../include/psError.h \
+  ../../include/psString.h ../../include/psType.h ../../include/psList.h \
+  ../../include/psVector.h ../../include/psHash.h ../../include/psImage.h \
+  ../../include/psBitSet.h ../../include/psSort.h ../../include/psStats.h \
+  ../../include/psMatrix.h ../../include/psFFT.h \
+  ../../include/psImageIO.h ../../include/psTest.h
Index: /tags/rel1_1/psLib/test/sysUtils/builddir/tst_psHash03.d
===================================================================
--- /tags/rel1_1/psLib/test/sysUtils/builddir/tst_psHash03.d	(revision 1056)
+++ /tags/rel1_1/psLib/test/sysUtils/builddir/tst_psHash03.d	(revision 1056)
@@ -0,0 +1,8 @@
+builddir/tst_psHash03.o builddir/tst_psHash03.d : tst_psHash03.c ../../include/pslib.h \
+  ../../include/psMemory.h ../../include/psLogMsg.h \
+  ../../include/psTrace.h ../../include/psAbort.h ../../include/psError.h \
+  ../../include/psString.h ../../include/psType.h ../../include/psList.h \
+  ../../include/psVector.h ../../include/psHash.h ../../include/psImage.h \
+  ../../include/psBitSet.h ../../include/psSort.h ../../include/psStats.h \
+  ../../include/psMatrix.h ../../include/psFFT.h \
+  ../../include/psImageIO.h ../../include/psTest.h
Index: /tags/rel1_1/psLib/test/sysUtils/builddir/tst_psHash04.d
===================================================================
--- /tags/rel1_1/psLib/test/sysUtils/builddir/tst_psHash04.d	(revision 1056)
+++ /tags/rel1_1/psLib/test/sysUtils/builddir/tst_psHash04.d	(revision 1056)
@@ -0,0 +1,8 @@
+builddir/tst_psHash04.o builddir/tst_psHash04.d : tst_psHash04.c ../../include/pslib.h \
+  ../../include/psMemory.h ../../include/psLogMsg.h \
+  ../../include/psTrace.h ../../include/psAbort.h ../../include/psError.h \
+  ../../include/psString.h ../../include/psType.h ../../include/psList.h \
+  ../../include/psVector.h ../../include/psHash.h ../../include/psImage.h \
+  ../../include/psBitSet.h ../../include/psSort.h ../../include/psStats.h \
+  ../../include/psMatrix.h ../../include/psFFT.h \
+  ../../include/psImageIO.h ../../include/psTest.h
Index: /tags/rel1_1/psLib/test/sysUtils/builddir/tst_psLogMsg00.d
===================================================================
--- /tags/rel1_1/psLib/test/sysUtils/builddir/tst_psLogMsg00.d	(revision 1056)
+++ /tags/rel1_1/psLib/test/sysUtils/builddir/tst_psLogMsg00.d	(revision 1056)
@@ -0,0 +1,8 @@
+builddir/tst_psLogMsg00.o builddir/tst_psLogMsg00.d : tst_psLogMsg00.c ../../include/pslib.h \
+  ../../include/psMemory.h ../../include/psLogMsg.h \
+  ../../include/psTrace.h ../../include/psAbort.h ../../include/psError.h \
+  ../../include/psString.h ../../include/psType.h ../../include/psList.h \
+  ../../include/psVector.h ../../include/psHash.h ../../include/psImage.h \
+  ../../include/psBitSet.h ../../include/psSort.h ../../include/psStats.h \
+  ../../include/psMatrix.h ../../include/psFFT.h \
+  ../../include/psImageIO.h ../../include/psTest.h
Index: /tags/rel1_1/psLib/test/sysUtils/builddir/tst_psLogMsg01.d
===================================================================
--- /tags/rel1_1/psLib/test/sysUtils/builddir/tst_psLogMsg01.d	(revision 1056)
+++ /tags/rel1_1/psLib/test/sysUtils/builddir/tst_psLogMsg01.d	(revision 1056)
@@ -0,0 +1,8 @@
+builddir/tst_psLogMsg01.o builddir/tst_psLogMsg01.d : tst_psLogMsg01.c ../../include/pslib.h \
+  ../../include/psMemory.h ../../include/psLogMsg.h \
+  ../../include/psTrace.h ../../include/psAbort.h ../../include/psError.h \
+  ../../include/psString.h ../../include/psType.h ../../include/psList.h \
+  ../../include/psVector.h ../../include/psHash.h ../../include/psImage.h \
+  ../../include/psBitSet.h ../../include/psSort.h ../../include/psStats.h \
+  ../../include/psMatrix.h ../../include/psFFT.h \
+  ../../include/psImageIO.h ../../include/psTest.h
Index: /tags/rel1_1/psLib/test/sysUtils/builddir/tst_psLogMsg02.d
===================================================================
--- /tags/rel1_1/psLib/test/sysUtils/builddir/tst_psLogMsg02.d	(revision 1056)
+++ /tags/rel1_1/psLib/test/sysUtils/builddir/tst_psLogMsg02.d	(revision 1056)
@@ -0,0 +1,8 @@
+builddir/tst_psLogMsg02.o builddir/tst_psLogMsg02.d : tst_psLogMsg02.c ../../include/pslib.h \
+  ../../include/psMemory.h ../../include/psLogMsg.h \
+  ../../include/psTrace.h ../../include/psAbort.h ../../include/psError.h \
+  ../../include/psString.h ../../include/psType.h ../../include/psList.h \
+  ../../include/psVector.h ../../include/psHash.h ../../include/psImage.h \
+  ../../include/psBitSet.h ../../include/psSort.h ../../include/psStats.h \
+  ../../include/psMatrix.h ../../include/psFFT.h \
+  ../../include/psImageIO.h ../../include/psTest.h
Index: /tags/rel1_1/psLib/test/sysUtils/builddir/tst_psLogMsg03.d
===================================================================
--- /tags/rel1_1/psLib/test/sysUtils/builddir/tst_psLogMsg03.d	(revision 1056)
+++ /tags/rel1_1/psLib/test/sysUtils/builddir/tst_psLogMsg03.d	(revision 1056)
@@ -0,0 +1,8 @@
+builddir/tst_psLogMsg03.o builddir/tst_psLogMsg03.d : tst_psLogMsg03.c ../../include/pslib.h \
+  ../../include/psMemory.h ../../include/psLogMsg.h \
+  ../../include/psTrace.h ../../include/psAbort.h ../../include/psError.h \
+  ../../include/psString.h ../../include/psType.h ../../include/psList.h \
+  ../../include/psVector.h ../../include/psHash.h ../../include/psImage.h \
+  ../../include/psBitSet.h ../../include/psSort.h ../../include/psStats.h \
+  ../../include/psMatrix.h ../../include/psFFT.h \
+  ../../include/psImageIO.h ../../include/psTest.h
Index: /tags/rel1_1/psLib/test/sysUtils/builddir/tst_psMemory.d
===================================================================
--- /tags/rel1_1/psLib/test/sysUtils/builddir/tst_psMemory.d	(revision 1056)
+++ /tags/rel1_1/psLib/test/sysUtils/builddir/tst_psMemory.d	(revision 1056)
@@ -0,0 +1,8 @@
+builddir/tst_psMemory.o builddir/tst_psMemory.d : tst_psMemory.c ../../include/psTest.h \
+  ../../include/pslib.h ../../include/psMemory.h ../../include/psLogMsg.h \
+  ../../include/psTrace.h ../../include/psAbort.h ../../include/psError.h \
+  ../../include/psString.h ../../include/psType.h ../../include/psList.h \
+  ../../include/psVector.h ../../include/psHash.h ../../include/psImage.h \
+  ../../include/psBitSet.h ../../include/psSort.h ../../include/psStats.h \
+  ../../include/psMatrix.h ../../include/psFFT.h \
+  ../../include/psImageIO.h
Index: /tags/rel1_1/psLib/test/sysUtils/builddir/tst_psStringCopy.d
===================================================================
--- /tags/rel1_1/psLib/test/sysUtils/builddir/tst_psStringCopy.d	(revision 1056)
+++ /tags/rel1_1/psLib/test/sysUtils/builddir/tst_psStringCopy.d	(revision 1056)
@@ -0,0 +1,8 @@
+builddir/tst_psStringCopy.o builddir/tst_psStringCopy.d : tst_psStringCopy.c ../../include/pslib.h \
+  ../../include/psMemory.h ../../include/psLogMsg.h \
+  ../../include/psTrace.h ../../include/psAbort.h ../../include/psError.h \
+  ../../include/psString.h ../../include/psType.h ../../include/psList.h \
+  ../../include/psVector.h ../../include/psHash.h ../../include/psImage.h \
+  ../../include/psBitSet.h ../../include/psSort.h ../../include/psStats.h \
+  ../../include/psMatrix.h ../../include/psFFT.h \
+  ../../include/psImageIO.h ../../include/psTest.h
Index: /tags/rel1_1/psLib/test/sysUtils/builddir/tst_psTrace00.d
===================================================================
--- /tags/rel1_1/psLib/test/sysUtils/builddir/tst_psTrace00.d	(revision 1056)
+++ /tags/rel1_1/psLib/test/sysUtils/builddir/tst_psTrace00.d	(revision 1056)
@@ -0,0 +1,8 @@
+builddir/tst_psTrace00.o builddir/tst_psTrace00.d : tst_psTrace00.c ../../include/pslib.h \
+  ../../include/psMemory.h ../../include/psLogMsg.h \
+  ../../include/psTrace.h ../../include/psAbort.h ../../include/psError.h \
+  ../../include/psString.h ../../include/psType.h ../../include/psList.h \
+  ../../include/psVector.h ../../include/psHash.h ../../include/psImage.h \
+  ../../include/psBitSet.h ../../include/psSort.h ../../include/psStats.h \
+  ../../include/psMatrix.h ../../include/psFFT.h \
+  ../../include/psImageIO.h ../../include/psTest.h
Index: /tags/rel1_1/psLib/test/sysUtils/builddir/tst_psTrace01.d
===================================================================
--- /tags/rel1_1/psLib/test/sysUtils/builddir/tst_psTrace01.d	(revision 1056)
+++ /tags/rel1_1/psLib/test/sysUtils/builddir/tst_psTrace01.d	(revision 1056)
@@ -0,0 +1,8 @@
+builddir/tst_psTrace01.o builddir/tst_psTrace01.d : tst_psTrace01.c ../../include/pslib.h \
+  ../../include/psMemory.h ../../include/psLogMsg.h \
+  ../../include/psTrace.h ../../include/psAbort.h ../../include/psError.h \
+  ../../include/psString.h ../../include/psType.h ../../include/psList.h \
+  ../../include/psVector.h ../../include/psHash.h ../../include/psImage.h \
+  ../../include/psBitSet.h ../../include/psSort.h ../../include/psStats.h \
+  ../../include/psMatrix.h ../../include/psFFT.h \
+  ../../include/psImageIO.h ../../include/psTest.h
Index: /tags/rel1_1/psLib/test/sysUtils/builddir/tst_psTrace02.d
===================================================================
--- /tags/rel1_1/psLib/test/sysUtils/builddir/tst_psTrace02.d	(revision 1056)
+++ /tags/rel1_1/psLib/test/sysUtils/builddir/tst_psTrace02.d	(revision 1056)
@@ -0,0 +1,8 @@
+builddir/tst_psTrace02.o builddir/tst_psTrace02.d : tst_psTrace02.c ../../include/pslib.h \
+  ../../include/psMemory.h ../../include/psLogMsg.h \
+  ../../include/psTrace.h ../../include/psAbort.h ../../include/psError.h \
+  ../../include/psString.h ../../include/psType.h ../../include/psList.h \
+  ../../include/psVector.h ../../include/psHash.h ../../include/psImage.h \
+  ../../include/psBitSet.h ../../include/psSort.h ../../include/psStats.h \
+  ../../include/psMatrix.h ../../include/psFFT.h \
+  ../../include/psImageIO.h ../../include/psTest.h
Index: /tags/rel1_1/psLib/test/sysUtils/builddir/tst_psTrace03.d
===================================================================
--- /tags/rel1_1/psLib/test/sysUtils/builddir/tst_psTrace03.d	(revision 1056)
+++ /tags/rel1_1/psLib/test/sysUtils/builddir/tst_psTrace03.d	(revision 1056)
@@ -0,0 +1,8 @@
+builddir/tst_psTrace03.o builddir/tst_psTrace03.d : tst_psTrace03.c ../../include/pslib.h \
+  ../../include/psMemory.h ../../include/psLogMsg.h \
+  ../../include/psTrace.h ../../include/psAbort.h ../../include/psError.h \
+  ../../include/psString.h ../../include/psType.h ../../include/psList.h \
+  ../../include/psVector.h ../../include/psHash.h ../../include/psImage.h \
+  ../../include/psBitSet.h ../../include/psSort.h ../../include/psStats.h \
+  ../../include/psMatrix.h ../../include/psFFT.h \
+  ../../include/psImageIO.h ../../include/psTest.h
Index: /tags/rel1_1/psLib/test/sysUtils/builddir/tst_psTrace04.d
===================================================================
--- /tags/rel1_1/psLib/test/sysUtils/builddir/tst_psTrace04.d	(revision 1056)
+++ /tags/rel1_1/psLib/test/sysUtils/builddir/tst_psTrace04.d	(revision 1056)
@@ -0,0 +1,8 @@
+builddir/tst_psTrace04.o builddir/tst_psTrace04.d : tst_psTrace04.c ../../include/pslib.h \
+  ../../include/psMemory.h ../../include/psLogMsg.h \
+  ../../include/psTrace.h ../../include/psAbort.h ../../include/psError.h \
+  ../../include/psString.h ../../include/psType.h ../../include/psList.h \
+  ../../include/psVector.h ../../include/psHash.h ../../include/psImage.h \
+  ../../include/psBitSet.h ../../include/psSort.h ../../include/psStats.h \
+  ../../include/psMatrix.h ../../include/psFFT.h \
+  ../../include/psImageIO.h ../../include/psTest.h
Index: /tags/rel1_1/psLib/test/sysUtils/tst_psError.c
===================================================================
--- /tags/rel1_1/psLib/test/sysUtils/tst_psError.c	(revision 1056)
+++ /tags/rel1_1/psLib/test/sysUtils/tst_psError.c	(revision 1056)
@@ -0,0 +1,63 @@
+/** @file  tst_psError.c
+ *
+ *  @brief Test driver for psError function
+ *
+ *  This test driver contains the following test points for psError
+ *     1)  Multiple type values in error message
+ *     2)  String values in error message
+ *     3)  Empty strings in error message
+ *
+ *  @author  Eric Van Alst, MHPCC
+ *
+ *  @version $Revision: 1.4 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2004-05-18 19:22:35 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "pslib.h"
+#include "psTest.h"
+
+int main(int argc,
+         char* argv[])
+{
+
+    int  intval=1;
+    long longval = 2;
+    float floatval = 3.01;
+    char  charval = 'E';
+    char *stringval = "E R R O R";
+    int   memBlockAllocated = 0;
+    psMemBlock  ***memBlockPtr = NULL;
+
+    // Test point #1 Multiple type values placed in the error string
+    printPositiveTestHeader(stderr,"psError","Multiple type values in error message");
+    psError(__func__,
+            "ALL TYPES intval = %d longval = %ld floatval = %f charval = %c strval = %s",
+            intval,longval,floatval,charval,stringval);
+    printFooter(stderr, "psError","Multiple type values in error message",true);
+
+    // Test point #2 String values in error message
+    printPositiveTestHeader(stderr, "psError","String values in error message");
+    psError(PS_STRING(__LINE__),"NO VALUES");
+    printFooter(stderr, "psError","String values in error message",true);
+
+    // Test point #3 Empty strings in error message
+    printPositiveTestHeader(stderr, "psError","Empty strings in error message");
+    psError("","");
+    printFooter(stderr, "psError","Empty strings in error message",true);
+
+    // Check for memory leaks
+    memBlockAllocated = psMemCheckLeaks(0, memBlockPtr, stderr);
+    if ( memBlockAllocated != 0 ) {
+        fprintf(stderr,"FAIL - Memory leak detected - Number of blocks = %d\n",memBlockAllocated);
+    }
+    // Check for memory corruption and abort if detected
+    memBlockAllocated = psMemCheckCorruption(1);
+
+    return 0;
+}
+
Index: /tags/rel1_1/psLib/test/sysUtils/tst_psHash00.c
===================================================================
--- /tags/rel1_1/psLib/test/sysUtils/tst_psHash00.c	(revision 1056)
+++ /tags/rel1_1/psLib/test/sysUtils/tst_psHash00.c	(revision 1056)
@@ -0,0 +1,64 @@
+/*****************************************************************************
+    This code will test whether a hash table can be allocated successfully,
+    then deallocated successfully.
+ *****************************************************************************/
+#include <stdio.h>
+#include "pslib.h"
+#include "psTest.h"
+#include "psHash.h"
+#define NUM_HASH_TABLE_BUCKETS 10
+int main()
+{
+    psHash *myHashTable = NULL;
+    int testStatus      = true;
+    int i               = 0;
+    int currentId = psMemGetId();
+    int memLeaks        = 0;
+    printPositiveTestHeader(stdout,
+                            "psHash functions",
+                            "psHashAlloc()");
+
+    myHashTable = psHashAlloc(NUM_HASH_TABLE_BUCKETS);
+
+    if (myHashTable == NULL) {
+        fprintf(stderr, "%s: could not allocate a hash table.", __func__);
+        testStatus = false;
+    }
+
+    if (myHashTable->nbucket != NUM_HASH_TABLE_BUCKETS) {
+        fprintf(stderr, "%s: myHashTable->nbucket not set properly.\n",
+                __func__);
+        testStatus = false;
+
+    }
+
+    if (myHashTable->buckets == NULL) {
+        fprintf(stderr, "%s: myHashTable->buckets is NULL.\n",
+                __func__);
+        testStatus = false;
+
+    }
+
+    for (i=0;i<NUM_HASH_TABLE_BUCKETS;i++) {
+        if (myHashTable->buckets[i] != NULL) {
+            fprintf(stderr, "%s: hash table bucket[%d] not equal to NULL.\n",
+                    __func__, i);
+            testStatus = false;
+        }
+    }
+
+    printFooter(stdout,
+                "psHash functions",
+                "psHashAlloc()",
+                testStatus);
+
+    psHashFree(myHashTable, NULL);
+
+    memLeaks = psMemCheckLeaks(currentId,NULL,NULL);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+    psMemCheckCorruption(1);
+
+    return (!testStatus);
+}
Index: /tags/rel1_1/psLib/test/sysUtils/tst_psHash01.c
===================================================================
--- /tags/rel1_1/psLib/test/sysUtils/tst_psHash01.c	(revision 1056)
+++ /tags/rel1_1/psLib/test/sysUtils/tst_psHash01.c	(revision 1056)
@@ -0,0 +1,71 @@
+/*****************************************************************************
+    This code will test whether a hash table can be de-allocated successfully.
+ *****************************************************************************/
+#include <stdio.h>
+#include "pslib.h"
+#include "psTest.h"
+#include "psHash.h"
+#define NUM_HASH_TABLE_BUCKETS 100
+int imGlobal = 0;
+
+typedef struct
+{
+    char *name;
+}
+ID;
+static ID *IdAlloc(const char *name)
+{
+    ID *id = psAlloc(sizeof(ID));
+    id->name = psStringCopy(name);
+
+    return id;
+}
+
+static void IdFree(ID *id)
+{
+    imGlobal++;
+    psFree(id->name);
+    psFree(id);
+}
+
+int main()
+{
+    psHash *myHashTable = NULL;
+    int testStatus      = true;
+    int currentId = psMemGetId();
+    int memLeaks        = 0;
+
+    printPositiveTestHeader(stdout,
+                            "psHash functions",
+                            "psHashFree()");
+
+    myHashTable = psHashAlloc(NUM_HASH_TABLE_BUCKETS);
+    psHashInsert(myHashTable, "ENTRY00", IdAlloc("IDA"),
+                 (void (*)(void *))IdFree);
+    psHashInsert(myHashTable, "ENTRY01", IdAlloc("IDB"),
+                 (void (*)(void *))IdFree);
+    psHashInsert(myHashTable, "ENTRY02", IdAlloc("IDC"),
+                 (void (*)(void *))IdFree);
+    psHashInsert(myHashTable, "ENTRY03", IdAlloc("IDD"),
+                 (void (*)(void *))IdFree);
+    psHashFree(myHashTable, (void (*)(void *))IdFree);
+
+    if (imGlobal != 4) {
+        fprintf(stderr, "%s: only (%d/4) entries were freed",
+                __func__, imGlobal);
+        testStatus = false;
+    }
+
+    printFooter(stdout,
+                "psHash functions",
+                "psHashFree()",
+                testStatus);
+
+    memLeaks = psMemCheckLeaks(currentId,NULL,NULL);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+    psMemCheckCorruption(1);
+
+    return (!testStatus);
+}
Index: /tags/rel1_1/psLib/test/sysUtils/tst_psHash02.c
===================================================================
--- /tags/rel1_1/psLib/test/sysUtils/tst_psHash02.c	(revision 1056)
+++ /tags/rel1_1/psLib/test/sysUtils/tst_psHash02.c	(revision 1056)
@@ -0,0 +1,89 @@
+/*****************************************************************************
+    This code will test whether hash tables entries can be inserted correctly,
+    and retrieved correctly.
+ 
+    NOTE: Add code to test whether duplicates are handled correctly (use a
+    small hash table and lots of keys).
+ *****************************************************************************/
+#include <stdio.h>
+#include <string.h>
+#include "pslib.h"
+#include "psTest.h"
+#include "psHash.h"
+#define NUM_HASH_TABLE_BUCKETS 100
+int imGlobal = 0;
+
+typedef struct
+{
+    char *name;
+}
+ID;
+static ID *IdAlloc(const char *name)
+{
+    ID *id = psAlloc(sizeof(ID));
+    id->name = psStringCopy(name);
+
+    return id;
+}
+
+static void IdFree(ID *id)
+{
+    imGlobal++;
+    psFree(id->name);
+    psFree(id);
+}
+
+int main()
+{
+    psHash *myHashTable = NULL;
+    int testStatus      = true;
+    int i               = 0;
+    ID *id = NULL;
+    char *myKeys[] = {"ENTRY00", "ENTRY01", "ENTRY02", "ENTRY03", NULL};
+    char *myData[] = {"IDA", "IDB", "IDC", "IDD", NULL};
+    int currentId = psMemGetId();
+    int memLeaks        = 0;
+
+    printPositiveTestHeader(stdout,
+                            "psHash functions",
+                            "psHashInsert()");
+
+    myHashTable = psHashAlloc(NUM_HASH_TABLE_BUCKETS);
+    i = 0;
+    while (myKeys[i] != NULL) {
+        psHashInsert(myHashTable, myKeys[i], IdAlloc(myData[i]),
+                     (void (*)(void *))IdFree);
+        i++;
+    }
+
+    i = 0;
+    while (myKeys[i] != NULL) {
+        id = psHashLookup(myHashTable, myKeys[i]);
+        if (0 != strcmp(myData[i], id->name)) {
+            fprintf(stderr, "%s: Hash table entry for key %s was %s (should be %s).\n",
+                    __func__, myKeys[i], id->name, myData[i]);
+        }
+        i++;
+    }
+    id = psHashLookup(myHashTable, "BogusKey");
+    if (id != NULL) {
+        fprintf(stderr, "%s: Hash table entry for key %s was not NULL.\n",
+                __func__, "BogusKey");
+    }
+
+    printFooter(stdout,
+                "psHash functions",
+                "psHashInsert()",
+                testStatus);
+
+    //    psHashFree(myHashTable, NULL);
+    psHashFree(myHashTable, (void (*)(void *))IdFree);
+
+    memLeaks = psMemCheckLeaks(currentId,NULL,NULL);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+    psMemCheckCorruption(1);
+
+    return (!testStatus);
+}
Index: /tags/rel1_1/psLib/test/sysUtils/tst_psHash03.c
===================================================================
--- /tags/rel1_1/psLib/test/sysUtils/tst_psHash03.c	(revision 1056)
+++ /tags/rel1_1/psLib/test/sysUtils/tst_psHash03.c	(revision 1056)
@@ -0,0 +1,129 @@
+/*****************************************************************************
+    This code will test whether hash tables entries can be removed correctly.
+ 
+    NOTE: Add code to test whether duplicates are handled correctly.
+ *****************************************************************************/
+#include <stdio.h>
+#include <string.h>
+#include "pslib.h"
+#include "psTest.h"
+#include "psHash.h"
+#include "psMemory.h"
+#define NUM_HASH_TABLE_BUCKETS 100
+int imGlobal = 0;
+int currentId = 0;
+
+typedef struct
+{
+    char *name;
+}
+ID;
+
+// NOTE: This is my own little routine I used in debugging a memory
+// leak.  I will take this out of this file later.
+void printMemBlocks(char *myString)
+{
+    psMemBlock **memBlocks = NULL;
+    psMemBlock *tmp = NULL;
+    int numBlocks = 0;
+
+    numBlocks = psMemCheckLeaks(currentId, &memBlocks, NULL);
+    printf("******************** %s ********************\n", myString);
+    printf("%d mem blocks\n", psMemCheckLeaks(currentId,NULL,NULL));
+    printf("%d blocks\n", numBlocks);
+    printf("*  ");
+    if (memBlocks != NULL) {
+        for (tmp = *memBlocks; tmp != NULL; tmp = tmp->nextBlock) {
+            printf("%d ", (int) tmp->id);
+        }
+    }
+    printf("*\n");
+    printf("*************************************************\n");
+    psFree(memBlocks);
+}
+
+static ID *IdAlloc(const char *name)
+{
+    ID *id = NULL;
+
+    id = psAlloc(sizeof(ID));
+
+    id->name = psStringCopy(name);
+
+    return id;
+}
+
+static void IdFree(ID *id)
+{
+    imGlobal++;
+    psFree(id->name);
+    psFree(id);
+}
+
+int main()
+{
+    psHash *myHashTable = NULL;
+    int testStatus      = true;
+    int i               = 0;
+    int TotalKeys       = 0;
+    ID *id = NULL;
+    char *myKeys[] = {"ENTRY00", "ENTRY01", "ENTRY02", "ENTRY03", NULL};
+    char *myData[] = {"IDA", "IDB", "IDC", "IDD", NULL};
+    int memLeaks        = 0;
+
+    currentId = psMemGetId();
+
+    printPositiveTestHeader(stdout,
+                            "psHash functions",
+                            "psHashRemove()");
+
+    myHashTable = psHashAlloc(NUM_HASH_TABLE_BUCKETS);
+
+    i = 0;
+    while (myKeys[i] != NULL) {
+        psHashInsert(myHashTable, myKeys[i], IdAlloc(myData[i]),
+                     (void (*)(void *))IdFree);
+        i++;
+    }
+    TotalKeys = i - 1;
+
+    i = TotalKeys;
+    while (i >= 0) {
+
+        id = psHashLookup(myHashTable, myKeys[i]);
+        if (0 != strcmp(myData[i], id->name)) {
+            fprintf(stderr, "%s: Hash table entry for key %s was %s (should be %s).\n",
+                    __func__, myKeys[i], id->name, myData[i]);
+        }
+        i--;
+    }
+
+    i = 0;
+    while (myKeys[i] != NULL) {
+        id = psHashRemove(myHashTable, myKeys[i], (void (*)(void *))IdFree);
+        // The psHashRemove() procedure removes the entry from the hash
+        // table, but does not delete the data.  The following is necessary
+        // to delete the data as well (which is returned from the call).
+        IdFree(id);
+        id = psHashLookup(myHashTable, myKeys[i]);
+        if (id != NULL) {
+            fprintf(stderr, "%s: Hash table entry for key %s not removed.\n",
+                    __func__, "IDA");
+        }
+        i++;
+    }
+
+    printFooter(stdout,
+                "psHash functions",
+                "psHashRemove()",
+                testStatus);
+
+    psHashFree(myHashTable, (void (*)(void *))IdFree);
+    memLeaks = psMemCheckLeaks(currentId,NULL,NULL);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+    psMemCheckCorruption(1);
+
+    return (!testStatus);
+}
Index: /tags/rel1_1/psLib/test/sysUtils/tst_psHash04.c
===================================================================
--- /tags/rel1_1/psLib/test/sysUtils/tst_psHash04.c	(revision 1056)
+++ /tags/rel1_1/psLib/test/sysUtils/tst_psHash04.c	(revision 1056)
@@ -0,0 +1,77 @@
+/*****************************************************************************
+    This code will test whether the call psHashKeyList() function works.
+ *****************************************************************************/
+#include <stdio.h>
+#include "pslib.h"
+#include "psTest.h"
+#include "psHash.h"
+#define NUM_HASH_TABLE_BUCKETS 100
+int imGlobal = 0;
+
+typedef struct
+{
+    char *name;
+}
+ID;
+static ID *IdAlloc(const char *name)
+{
+    ID *id = psAlloc(sizeof(ID));
+    id->name = psStringCopy(name);
+
+    return id;
+}
+
+static void IdFree(ID *id)
+{
+    imGlobal++;
+    psFree(id->name);
+    psFree(id);
+}
+
+int main()
+{
+    psHash *myHashTable = NULL;
+    int testStatus      = true;
+    int i               = 0;
+    char *myKeys[] = {"ENTRY00", "ENTRY01", "ENTRY02", "ENTRY03", NULL};
+    char *myData[] = {"IDA", "IDB", "IDC", "IDD", NULL};
+    int currentId = psMemGetId();
+    int memLeaks        = 0;
+    psList *myLinkList = NULL;
+    psListElem *tmp = NULL;
+
+    printPositiveTestHeader(stdout,
+                            "psHash functions",
+                            "psHashKeyList()");
+
+    myHashTable = psHashAlloc(NUM_HASH_TABLE_BUCKETS);
+    i = 0;
+    while (myKeys[i] != NULL) {
+        psHashInsert(myHashTable, myKeys[i], IdAlloc(myData[i]),
+                     (void (*)(void *))IdFree);
+        i++;
+    }
+    myLinkList = psHashKeyList(myHashTable);
+    tmp = myLinkList->head;
+    while (tmp != NULL) {
+        printf("Linked List Entries: %s\n", (char *) tmp->data);
+        tmp = tmp->next;
+    }
+
+    psListFree(myLinkList, NULL);
+
+    printFooter(stdout,
+                "psHash functions",
+                "psHashKeyList()",
+                testStatus);
+
+    psHashFree(myHashTable, (void (*)(void *))IdFree);
+
+    memLeaks = psMemCheckLeaks(currentId,NULL,NULL);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+    psMemCheckCorruption(1);
+
+    return(!testStatus);
+}
Index: /tags/rel1_1/psLib/test/sysUtils/tst_psLogMsg00.c
===================================================================
--- /tags/rel1_1/psLib/test/sysUtils/tst_psLogMsg00.c	(revision 1056)
+++ /tags/rel1_1/psLib/test/sysUtils/tst_psLogMsg00.c	(revision 1056)
@@ -0,0 +1,70 @@
+/*****************************************************************************
+    This code will test whether trace levels can be set successfully.
+    This code will test whether trace messages can be displayed with printf
+    style string.
+ *****************************************************************************/
+#include <stdio.h>
+#include "pslib.h"
+#include "psTest.h"
+
+void myLogMsg(const char *name,
+              int level,
+              const char *fmt,
+              ...)
+{
+    va_list ap;
+
+    // Test whether psVLogMsg() accept a va_list for output variables.
+    va_start(ap, fmt);
+    psVLogMsg(name, level, fmt, ap);
+    va_end(ap);
+}
+
+int main()
+{
+    int i = 0;
+    int testStatus = true;
+    int currentId = psMemGetId();
+
+    printPositiveTestHeader(stdout,
+                            "psLogMsg functions",
+                            "default log levels, printf-style strings");
+
+    // Send a log messages for levels 0:9.  Only the first four messages
+    // should actually be displayed.
+    for (i=0;i<10;i++) {
+        myLogMsg(__func__, i, "Hello World!  My level is %d %f %s\n", i,
+                 (float) i, "beep beep");
+    }
+
+    printFooter(stdout,
+                "psLogMsg functions",
+                "default log levels",
+                testStatus);
+
+
+    // Test whether psVLogMsg() accept a va_list for output variables.
+    printPositiveTestHeader(stdout,
+                            "psLogMsg functions",
+                            "default log levels, psVLogMsg()");
+
+    // Send a log messages for levels 0:9.  Only the first four messages
+    // should actually be displayed.
+    for (i=0;i<10;i++) {
+        myLogMsg(__func__, i, "Hello World!  My level is %d %f %s\n", i,
+                 (float) i, "beep beep");
+    }
+
+    printFooter(stdout,
+                "psLogMsg functions",
+                "default log levels",
+                testStatus);
+
+    if (psMemCheckLeaks(currentId,NULL,NULL) != 0) {
+        psAbort(__func__,"Memory Leaks!");
+    }
+    psMemCheckCorruption(1);
+
+    return(!testStatus);
+}
+
Index: /tags/rel1_1/psLib/test/sysUtils/tst_psLogMsg01.c
===================================================================
--- /tags/rel1_1/psLib/test/sysUtils/tst_psLogMsg01.c	(revision 1056)
+++ /tags/rel1_1/psLib/test/sysUtils/tst_psLogMsg01.c	(revision 1056)
@@ -0,0 +1,43 @@
+/*****************************************************************************
+    This code tests whether trace levels can be set successfully.
+ 
+ NOTE: This code must be modified once printFooter() is modified to include
+ a parameter that indicates we don't know whether the test passed or failed.
+ *****************************************************************************/
+#include <stdio.h>
+#include "pslib.h"
+#include "psTest.h"
+
+int main()
+{
+    int i = 0;
+    int testStatus = true;
+    int currentId = psMemGetId();
+
+    printPositiveTestHeader(stdout,
+                            "psLogMsg functions",
+                            "psLogSetLevel()");
+
+    psLogSetLevel(9);
+    // Send a log messages for levels 0:9.
+    for (i=0;i<10;i++) {
+        psLogMsg(__func__, i, "Hello World!  My level is %d\n", i);
+    }
+
+    psLogSetLevel(5);
+    psLogMsg(__func__, 6, "This should not be displayed (level %d)\n", 6);
+    psLogSetLevel(4);
+    psLogMsg(__func__, 4, "This should  be displayed (level %d)\n", 4);
+
+    printFooter(stdout,
+                "psLogMsg functions",
+                "psLogSetLevel()",
+                testStatus);
+
+    if (psMemCheckLeaks(currentId,NULL,NULL) != 0) {
+        psAbort(__func__,"Memory Leaks!");
+    }
+    psMemCheckCorruption(1);
+
+    return(!testStatus);
+}
Index: /tags/rel1_1/psLib/test/sysUtils/tst_psLogMsg02.c
===================================================================
--- /tags/rel1_1/psLib/test/sysUtils/tst_psLogMsg02.c	(revision 1056)
+++ /tags/rel1_1/psLib/test/sysUtils/tst_psLogMsg02.c	(revision 1056)
@@ -0,0 +1,95 @@
+/*****************************************************************************
+    This code tests whether the log message format can be set.
+ 
+ NOTE: This code must be modified once printFooter() is modified to include
+ a parameter that indicates we don't know whether the test passed or failed.
+ *****************************************************************************/
+#include <stdio.h>
+#include "pslib.h"
+#include "psTest.h"
+
+int main()
+{
+    int i = 0;
+    int testStatus = true;
+    int currentId = psMemGetId();
+
+    printPositiveTestHeader(stdout,
+                            "psLogMsg functions",
+                            "psLogSetFormat()");
+
+
+    printf("------------- psLogSetFormat() -------------\n");
+    psLogSetFormat("");
+    for (i=0;i<10;i++) {
+        psLogMsg(__func__, i, "Hello World!  My level is %d\n", i);
+    }
+
+    printf("------------- psLogSetFormat(T) -------------\n");
+    psLogSetFormat("T");
+    for (i=0;i<10;i++) {
+        psLogMsg(__func__, i, "Hello World!  My level is %d\n", i);
+    }
+
+    printf("------------- psLogSetFormat(H) -------------\n");
+    psLogSetFormat("TH");
+    for (i=0;i<10;i++) {
+        psLogMsg(__func__, i, "Hello World!  My level is %d\n", i);
+    }
+
+    printf("------------- psLogSetFormat(L) -------------\n");
+    psLogSetFormat("L");
+    for (i=0;i<10;i++) {
+        psLogMsg(__func__, i, "Hello World!  My level is %d\n", i);
+    }
+
+    printf("------------- psLogSetFormat(N) -------------\n");
+    psLogSetFormat("N");
+    for (i=0;i<10;i++) {
+        psLogMsg(__func__, i, "Hello World!  My level is %d\n", i);
+    }
+
+    printf("------------- psLogSetFormat(M) -------------\n");
+    psLogSetFormat("M");
+    for (i=0;i<10;i++) {
+        psLogMsg(__func__, i, "Hello World!  My level is %d\n", i);
+    }
+
+    printf("------------- psLogSetFormat(THLNM) -------------\n");
+    psLogSetFormat("THLNM");
+    for (i=0;i<10;i++) {
+        psLogMsg(__func__, i, "Hello World!  My level is %d\n", i);
+    }
+
+    printFooter(stdout,
+                "psLogMsg functions",
+                "psLogSetFormat()",
+                testStatus);
+
+
+
+
+    printPositiveTestHeader(stdout,
+                            "psLogMsg functions",
+                            "Output Format");
+
+    psLogMsg("Under 15 chars", 0, "Hello World!\n");
+    psLogMsg("This string is more than 15 chars", 0, "Hello World!\n");
+    psLogMsg(__func__, 0, "Line #1\n");
+    psLogMsg(__func__, 0, "Line #2\n");
+    psLogMsg(__func__, 0, "Line #3");
+    psLogMsg(__func__, 0, "Line #4");
+
+    printFooter(stdout,
+                "psLogMsg functions",
+                "Output Format",
+                testStatus);
+
+
+    if (psMemCheckLeaks(currentId,NULL,NULL) != 0) {
+        psAbort(__func__,"Memory Leaks!");
+    }
+    psMemCheckCorruption(1);
+
+    return(!testStatus);
+}
Index: /tags/rel1_1/psLib/test/sysUtils/tst_psLogMsg03.c
===================================================================
--- /tags/rel1_1/psLib/test/sysUtils/tst_psLogMsg03.c	(revision 1056)
+++ /tags/rel1_1/psLib/test/sysUtils/tst_psLogMsg03.c	(revision 1056)
@@ -0,0 +1,51 @@
+/*****************************************************************************
+    This code tests whether the log message can be redirected to STDERR or
+    STDOUT.
+ 
+ NOTE: This code must be modified once printFooter() is modified to include
+ a parameter that indicates we don't know whether the test passed or failed.
+ *****************************************************************************/
+#include <stdio.h>
+#include "pslib.h"
+#include "psTest.h"
+
+int main()
+{
+    int i = 0;
+    int testStatus = true;
+    int currentId = psMemGetId();
+
+    printPositiveTestHeader(stdout,
+                            "psLogMsg functions",
+                            "psLogSetDestination()");
+
+    printf("------------- psLogSetDestination(PS_LOG_NONE) -------------\n");
+    psLogSetDestination(PS_LOG_NONE);
+    for (i=0;i<10;i++) {
+        psLogMsg(__func__, i, "Hello World!  My level is %d\n", i);
+    }
+
+    printf("------------- psLogSetDestination(PS_LOG_TO_STDERR) -------------\n");
+    psLogSetDestination(PS_LOG_TO_STDERR);
+    for (i=0;i<10;i++) {
+        psLogMsg(__func__, i, "Hello World!  My level is %d\n", i);
+    }
+
+    printf("------------- psLogSetDestination(PS_LOG_TO_STDOUT) -------------\n");
+    psLogSetDestination(PS_LOG_TO_STDOUT);
+    for (i=0;i<10;i++) {
+        psLogMsg(__func__, i, "Hello World!  My level is %d\n", i);
+    }
+
+    printFooter(stdout,
+                "psLogMsg functions",
+                "psLogSetDestination()",
+                testStatus);
+
+    if (psMemCheckLeaks(currentId,NULL,NULL) != 0) {
+        psAbort(__func__,"Memory Leaks!");
+    }
+    psMemCheckCorruption(1);
+
+    return(!testStatus);
+}
Index: /tags/rel1_1/psLib/test/sysUtils/tst_psMemory.c
===================================================================
--- /tags/rel1_1/psLib/test/sysUtils/tst_psMemory.c	(revision 1056)
+++ /tags/rel1_1/psLib/test/sysUtils/tst_psMemory.c	(revision 1056)
@@ -0,0 +1,479 @@
+/** @file  tst_psMemory.c
+ *
+ *  @brief Contains the tests for psMemory.[ch]
+ *
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.16 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-14 21:36:24 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+// need to allow malloc for callback use
+#define PS_ALLOW_MALLOC 1
+
+#include <unistd.h>
+#include <sys/wait.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <limits.h>
+#include <stdlib.h>
+
+
+#include "psTest.h"
+#include "pslib.h"
+
+static int TPFreeReferencedMemory(void);
+static int TPOutOfMemory(void);
+static void* TPOutOfMemoryExhaustedCallback(size_t size);
+static int TPCheckBufferPositive(void);
+static int TPrealloc(void);
+static int TPallocCallback(void);
+static psMemoryId memAllocateCallback(const psMemBlock *ptr);
+static psMemoryId memFreeCallback(const psMemBlock *ptr);
+int TPcheckLeaks(void);
+int TPmemCorruption(void);
+void memProblemCallback(const psMemBlock *ptr, const char *file, int lineno);
+
+static int problemCallbackCalled = 0;
+static int allocCallbackCalled = 0;
+static int freeCallbackCalled = 0;
+static int exhaustedCallbackCalled = 0;
+
+testDescription tests[] = {
+                              {TPCheckBufferPositive,"449-TPCheckBufferPositive",0},
+                              {TPOutOfMemory,"450-TPOutOfMemory",-6},
+                              {TPrealloc,"451-TPrealloc",0},
+                              {TPallocCallback,"452/453-TPallocCallback",0},
+                              {TPcheckLeaks,"454-TPcheckLeaks",0},
+                              {TPmemCorruption,"455-TPmemCorruption",0},
+                              {TPFreeReferencedMemory,"456-TPFreeReferencedMemory",0},
+                              {NULL}
+                          };
+
+int main()
+{
+    psLogSetLevel(PS_LOG_INFO);
+
+    if (! runTestSuite(stderr,"psMemory",tests)) {
+        psError(__FILE__,"One or more tests failed");
+        return 1;
+    }
+    return 0;
+}
+
+// Testpoint #449, psAlloc shall allocate memory blocks writeable by caller.
+int TPCheckBufferPositive(void)
+{
+    int* mem;
+    const int size = 100;
+    int failed = 0;
+
+    psLogMsg(__func__,PS_LOG_INFO,"psAlloc shall allocate memory blocks writeable by caller.\n");
+
+    mem = (int*) psAlloc(size*sizeof(int));
+    if (mem == NULL) {
+        psError(__FILE__,"psAlloc returned a NULL value in %s!",__func__);
+        return 1;
+    }
+
+    for (int index=0;index<size;index++) {
+        mem[index]=index;
+    }
+
+    for (int index=0;index<size;index++) {
+        if (mem[index] != index) {
+            failed++;
+        }
+    }
+
+    psFree(mem);
+
+    return failed;
+}
+
+int TPFreeReferencedMemory(void)
+{
+    // create memory
+    int* mem;
+    int ref = 0;
+
+    psLogMsg(__func__,PS_LOG_INFO,"memory reference count shall be incrementable/decrementable");
+
+    mem = (int*) psAlloc(100*sizeof(int));
+
+    ref = psMemGetRefCounter(mem);
+    if (ref != 1) {
+        psError(__func__,"Expected to buffer reference count to be initially 1, but it was %d.",ref);
+        return 1;
+    }
+
+    psMemIncrRefCounter(mem);
+    psMemIncrRefCounter(mem);
+    psMemIncrRefCounter(mem);
+
+    ref = psMemGetRefCounter(mem);
+    if (ref != 4) {
+        psError(__func__,"Expected to find buffer reference count to be 4, but it was %d.",ref);
+        return 1;
+    }
+
+    psMemDecrRefCounter(mem);
+    psMemDecrRefCounter(mem);
+
+    ref = psMemGetRefCounter(mem);
+    if (ref != 2) {
+        psError(__func__,"Expected to find buffer reference count to be 2, but it was %d.",ref);
+        return 1;
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"psFree shall be just decrement a multiple refererenced pointer.");
+
+    psFree(mem);
+
+    ref = psMemGetRefCounter(mem);
+    if (ref != 1) {
+        psError(__func__,"Expected to find buffer reference count to be 1, but it was %d.",ref);
+        return 1;
+    }
+
+    psFree(mem);
+
+    return 0;
+}
+
+// Testpoint #450,  Upon requesting more memory than is available, psalloc shall call
+// the psMemExhaustedCallback.
+int TPOutOfMemory(void)
+{
+    int* mem1 = NULL;
+    int* mem2 = NULL;
+    int* mem3 = NULL;
+    int* mem4 = NULL;
+    psMemExhaustedCallback cb;
+
+    psLogMsg(__func__,PS_LOG_INFO,"Upon requesting more memory than is available, psalloc shall call "
+             "the psMemExhaustedCallback.\n");
+
+    exhaustedCallbackCalled = 0;
+
+    cb = psMemExhaustedCallbackSet(TPOutOfMemoryExhaustedCallback);
+
+    mem1 = (int*) psAlloc(UINT_MAX-1000);
+
+    psMemExhaustedCallbackSet(cb);
+
+    if (exhaustedCallbackCalled == 0) {
+        psError(__FILE__,"Called psAlloc with HUGE memory requirement and survived in %s!",__func__);
+        return 1;
+    }
+
+    psFree(mem1);
+    psFree(mem2);
+    psFree(mem3);
+    psFree(mem4);
+
+    return 0;
+}
+
+// Testpoint #451,  psRealloc shall increase/decrease memory buffer while preserving contents
+int TPrealloc(void)
+{
+    int* mem1;
+    int* mem2;
+    int* mem3;
+    const int initialSize = 100;
+
+    psLogMsg(__func__,PS_LOG_INFO,"psRealloc shall increase/decrease memory buffer while "
+             "preserving contents");
+
+    // allocate buffer with known values.
+    mem1 = (int*) psAlloc(initialSize*sizeof(int));
+    mem2 = (int*) psAlloc(initialSize*sizeof(int));
+    mem3 = (int*) psAlloc(initialSize*sizeof(int));
+    for (int lcv=0;lcv<initialSize;lcv++) {
+        mem1[lcv] = mem2[lcv] = mem3[lcv] = lcv;
+    }
+
+    psMemCheckCorruption(1);
+    psLogMsg(__func__,PS_LOG_INFO,"Expanding memory buffer.");
+
+    // realloc to 2x
+    mem1 = (int*) psRealloc(mem1, 2*initialSize*sizeof(int));
+    mem2 = (int*) psRealloc(mem2, 2*initialSize*sizeof(int));
+    mem3 = (int*) psRealloc(mem3, 2*initialSize*sizeof(int));
+
+    // check values of initial block
+    for (int i=0;i<initialSize;i++) {
+        if (mem1[i] != i || mem2[i] != i || mem3[i] != i) {
+            psError(__FILE__,"Realloc didn't preserve the contents with expanding buffer in %s.",
+                    __func__);
+            break;
+        }
+    }
+
+    psMemCheckCorruption(1);
+    psLogMsg(__func__,PS_LOG_INFO,"Shrinking memory buffer.");
+
+    // realloc to 1/2 initial value.
+    mem1 = (int*) psRealloc(mem1, (initialSize/2)*sizeof(int));
+    mem2 = (int*) psRealloc(mem2, (initialSize/2)*sizeof(int));
+    mem3 = (int*) psRealloc(mem3, (initialSize/2)*sizeof(int));
+
+    // check values of initial block
+    for (int i=0;i<initialSize/2;i++) {
+        if (mem1[i] != i || mem2[i] != i || mem3[i] != i) {
+            psError(__FILE__,"Realloc didn't preserve the contents with shrinking buffer in %s.",
+                    __func__);
+            break;
+        }
+    }
+
+    psFree(mem1);
+    psFree(mem2);
+    psFree(mem3);
+
+    return 0;
+}
+
+int TPallocCallback(void)
+{
+    int* mem1;
+    int* mem2;
+    int* mem3;
+    int currentId = psMemGetId();
+    const int initialSize = 100;
+    int mark;
+
+    allocCallbackCalled = 0;
+    freeCallbackCalled = 0;
+    psMemAllocateCallbackSet(memAllocateCallback);
+    psMemFreeCallbackSet(memFreeCallback);
+
+    psMemAllocateCallbackSetID(currentId+1);
+    psMemFreeCallbackSetID(currentId+1);
+
+    psLogMsg(__func__,PS_LOG_INFO,"call to psAlloc/psRealloc shall generate a callback if specified "
+             "memory ID is allocated.");
+
+    // allocate buffer with known values.
+    mem1 = (int*) psAlloc(initialSize*sizeof(int));
+    mem2 = (int*) psAlloc(initialSize*sizeof(int));
+    mem3 = (int*) psAlloc(initialSize*sizeof(int));
+
+    psFree(mem1);
+    psFree(mem2);
+    psFree(mem3);
+
+    if (allocCallbackCalled != 2 || freeCallbackCalled != 2) {
+        psError(__FILE__,"alloc/free callbacks were not called the proper number of times in %s",
+                __func__);
+        return 1;
+    }
+
+    allocCallbackCalled = 0;
+    freeCallbackCalled = 0;
+
+    mark = psMemGetId();
+
+    mem1 = (int*) psAlloc(initialSize*sizeof(int));
+
+    psMemAllocateCallbackSetID(mark);
+
+    mem1 = (int*) psRealloc(mem1,initialSize*2*sizeof(int));
+
+    psFree(mem1);
+
+    if (allocCallbackCalled != 2) {
+        psError(__FILE__,"realloc callbacks were not called the proper number of times in %s",
+                __func__);
+        return 1;
+    }
+
+    return 0;
+
+}
+
+int TPcheckLeaks(void)
+{
+    const int numBuffers = 5;
+    int* buffers[5];
+    int lcv;
+    int currentId = psMemGetId();
+    psMemBlock** blks;
+    int nLeaks = 0;
+    int lineMark = 0;
+
+    psLogMsg(__func__,PS_LOG_INFO,"psMemCheckLeaks shall return the number of blocks above an ID "
+             "that are still allocated");
+
+    for (lcv=0;lcv<numBuffers;lcv++) {
+        lineMark = __LINE__+1;
+        buffers[lcv] = psAlloc(sizeof(int));
+    }
+
+    for (lcv=1;lcv<numBuffers;lcv++) {
+        psFree(buffers[lcv]);
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"following psMemCheckLeaks call should produce one instance.");
+
+    nLeaks = psMemCheckLeaks(currentId, &blks, stderr);
+
+    if (nLeaks != 1) {
+        psError(__FILE__,"psMemCheckLeaks should have found 1 leak, but found %d in %s.",nLeaks,__func__);
+        return 1;
+    }
+
+    if (blks[0]->lineno != lineMark) {
+        psError(__FILE__,"psMemCheckLeaks found a leak other than the expected one (line %d vs %d) in %s.",
+                lineMark, blks[0]->lineno, __func__);
+        return 1;
+    }
+
+    psFree(buffers[0]);
+    psFree(blks);
+
+    psLogMsg(__func__,PS_LOG_INFO,"Testing psMemCheckLeaks again with a different leak location");
+    psMemCheckLeaks(currentId,NULL,stderr);
+
+    for (lcv=0;lcv<numBuffers;lcv++) {
+        lineMark = __LINE__+1;
+        buffers[lcv] = psAlloc(sizeof(int));
+    }
+
+    for (lcv=0;lcv<numBuffers-1;lcv++) {
+        psFree(buffers[lcv]);
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"following psMemCheckLeaks call should produce one error.");
+
+    nLeaks = psMemCheckLeaks(currentId, &blks, stderr);
+
+    if (nLeaks != 1) {
+        psError(__FILE__,"psMemCheckLeaks should have found 1 leak, but found %d in %s.",nLeaks,__func__);
+        return 1;
+    }
+
+    if (blks[0]->lineno != lineMark) {
+        psError(__FILE__,"psMemCheckLeaks found a leak other than the expected one in %s.",__func__);
+        return 1;
+    }
+
+    psFree(buffers[4]);
+    psFree(blks);
+
+    psLogMsg(__func__,PS_LOG_INFO,"Testing psMemCheckLeaks again with multiple leak locations.");
+
+    for (lcv=0;lcv<numBuffers;lcv++) {
+        lineMark = __LINE__+1;
+        buffers[lcv] = psAlloc(sizeof(int));
+    }
+
+    for (lcv=0;lcv<numBuffers;lcv++) {
+        if (lcv%2 == 0) {
+            psFree(buffers[lcv]);
+        }
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"following psMemCheckLeaks call should produce two errors.");
+
+    nLeaks = psMemCheckLeaks(currentId, &blks, stderr);
+
+    if (nLeaks != 2) {
+        psError(__FILE__,"psMemCheckLeaks should have found 1 leak, but found %d in %s.",nLeaks,__func__);
+        return 1;
+    }
+
+    if (blks[0]->lineno != lineMark) {
+        psError(__FILE__,"psMemCheckLeaks found a leak other than the expected one in %s.",__func__);
+        return 1;
+    }
+
+    psFree(blks);
+    psFree(buffers[1]);
+    psFree(buffers[3]);
+
+    return 0;
+}
+
+int TPmemCorruption(void)
+{
+    int* buffer = NULL;
+    int oldValue = 0;
+    int corruptions = 0;
+    psMemProblemCallback cb;
+
+    psLogMsg(__func__,PS_LOG_INFO,"psMemCheckCorruption shall detect memory corruptions");
+
+    buffer = psAlloc(sizeof(int));
+
+    // cause memory corruption via buffer underflow
+    *buffer = 1;
+    buffer--;
+    oldValue = *buffer;
+    *buffer = 2;
+
+    problemCallbackCalled = 0;
+    cb = psMemProblemCallbackSet(memProblemCallback);
+
+    psLogMsg(__func__,PS_LOG_INFO,"psMemCheckCorruption should output an error message and "
+             "memProblemCallback callback should be called.");
+
+    corruptions = psMemCheckCorruption(0);
+
+    // restore the memory problem callback
+    psMemProblemCallbackSet(cb);
+
+    // restore the value, 'uncorrupting' the buffer
+    *buffer = oldValue;
+    buffer++;
+
+    psFree(buffer);
+
+    if (corruptions != 1) {
+        psError(__FILE__,"Expected one memory corruption but found %d in %s.",
+                corruptions, __func__);
+        return 1;
+    }
+
+    if (problemCallbackCalled != 1) {
+        psError(__FILE__,"The memProblemCallback was not invoked but should have been in %s",
+                __func__);
+        return 1;
+    }
+
+    return 0;
+
+}
+
+void memProblemCallback(const psMemBlock *ptr, const char *file, int lineno)
+{
+    psLogMsg(__func__,PS_LOG_INFO,"memory callback called for id %d (%s:%d).",
+             ptr->id, file, lineno);
+    problemCallbackCalled++;
+    return;
+}
+
+psMemoryId memAllocateCallback(const psMemBlock *ptr)
+{
+    psLogMsg(__func__,PS_LOG_INFO,"block %d was (re)allocated",ptr->id);
+    allocCallbackCalled++;
+    return 1;
+}
+
+psMemoryId memFreeCallback(const psMemBlock *ptr)
+{
+    psLogMsg(__func__,PS_LOG_INFO,"block %d was freed",ptr->id);
+    freeCallbackCalled++;
+    return 1;
+}
+
+void* TPOutOfMemoryExhaustedCallback(size_t size)
+{
+    psLogMsg(__func__,PS_LOG_INFO,"Custom MemExhaustedCallback was invoked.");
+    exhaustedCallbackCalled++;
+    return NULL;
+}
Index: /tags/rel1_1/psLib/test/sysUtils/tst_psString.c
===================================================================
--- /tags/rel1_1/psLib/test/sysUtils/tst_psString.c	(revision 1056)
+++ /tags/rel1_1/psLib/test/sysUtils/tst_psString.c	(revision 1056)
@@ -0,0 +1,203 @@
+/** @file  tst_psString.c
+ *
+ *  @brief Test driver for psStringCopy functions
+ *
+ *  This test driver contains the following test points for psStringCopy
+ *  and psStringNCopy functions.
+ *    1) Verify string copy - psStringCopy
+ *    2) Verify empty string copy - psStringCopy
+ *    3) Verify string copy with length - psStringNCopy
+ *    4) Verify empty string copy with length - psStringNCopy
+ *    5) Copy string to larger string - psStringNCopy
+ *    6) Copy string with negative size - psStringNCopy
+ *    7) Verifiy creation of string literal - PS_STRING
+ * 
+ *  Return:   Number of test points which failed
+ *
+ *  @author  Eric Van Alst, MHPCC
+ *
+ *  @version $Revision: 1.6 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2004-05-18 19:22:35 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#include <string.h>
+#include "pslib.h"
+#include "psTest.h"
+
+int main( int argc,
+          char * argv[] )
+{
+    bool  tpResult = false;
+    char  stringval[20] = "E R R O R";
+    char  stringval1[20] = "e r r o r";
+    char  *stringvalnocopy = "F A I L";
+    char  *substringval = "e r r";
+    int   substringlen = 6;
+    char  *emptyval = "";
+    int   tpFails = 0;
+    char  *strResult;
+    int   increaseSize = 5;
+    int   negativeSize = -5;
+    int   result = 0;
+    int   result1 = 0;
+    int   memBlockAllocated = 0;
+    psMemBlock ***memBlockPtr = NULL;
+
+    // Test point #1 Verify string copy - psStringCopy
+    printPositiveTestHeader(stderr,"psStringCopy","Verify string copy");
+    strResult = psStringCopy(stringval);
+    // Perform string compare
+    result = strcmp(strResult, stringval);
+    // Modify original string
+    stringval[0]='G';
+    result1 = strcmp(strResult, stringval);
+    stringval[0]='E';
+    if ( ( result != 0 ) || ( result1 == 0) ) {
+        fprintf(stderr, "Failed test point #1 strcmp result = %d expected 0\n",result);
+        fprintf(stderr, "                               src = %s expected %s\n",
+                strResult, stringval);
+        fprintf(stderr, "             changed strcmp result = %d expected 1\n",result1);
+        fprintf(stderr, "             changed           src = %s expected %s\n",strResult,
+                stringval);
+        tpResult = false;
+        tpFails++;
+    } else {
+        tpResult = true;
+    }
+    // Free memory allocated
+    psFree(strResult);
+    printFooter(stderr, "psStringCopy","Verify string copy", tpResult);
+
+    // Test point #2 Verify empty string copy - psStringCopy
+    printPositiveTestHeader(stderr,"psStringCopy","Verify empty string copy");
+    strResult = psStringCopy(emptyval);
+    // Perform string compare
+    result = strcmp(strResult, emptyval);
+    if ( result != 0 ) {
+        fprintf(stderr,"Failed test point #2 strcmp result = %d expected 0\n",result);
+        fprintf(stderr,"                               src = %s expected %s\n",
+                strResult, emptyval);
+        tpResult = false;
+        tpFails++;
+    } else {
+        tpResult = true;
+    }
+    // Free memory allocated
+    psFree(strResult);
+    printFooter(stderr, "psStringCopy","Verify empty string copy", tpResult);
+
+    // Test point #3 Verify string copy with length - psStringNCopy
+    printPositiveTestHeader(stderr,"psStringNCopy","Verify string copy with length");
+    strResult = psStringNCopy(stringval1, substringlen);
+    // Perform string compare and get string length
+    result = strncmp(strResult, substringval, substringlen);
+    // Change original string
+    stringval1[0] = 'g';
+    result1 = strncmp(strResult, substringval, substringlen);
+    if ( ( result != 0 ) || ( result1 != 0 ) ) {
+        fprintf(stderr,"Failed test point #3 strcmp result = %d expected 0\n",result);
+        fprintf(stderr,"                               src = %s expected %s\n",
+                strResult, substringval);
+        fprintf(stderr,"             changed strcmp result = %d expected 0\n",result1);
+        fprintf(stderr,"                               src = %s expected %s\n",
+                strResult, substringval);
+        tpResult = false;
+        tpFails++;
+    } else {
+        tpResult = true;
+    }
+    // Free memory allocated
+    psFree(strResult);
+    printFooter(stderr, "psStringNCopy","Verify string copy with length", tpResult);
+
+    // Test point #4 Verify empty string copy with length - psStringNCopy
+    printPositiveTestHeader(stderr,"psStringNCopy", "Verify empty string copy with length");
+    strResult = psStringNCopy(stringvalnocopy, 0);
+    // Perform string compare and get sting length
+    result = strcmp(strResult, stringvalnocopy);
+    result1 = strlen(strResult);
+    if ( result == 0 ) {
+        fprintf(stderr,"Failed test point #4 strcmp result = %d didn't expected %d\n",result,0);
+        fprintf(stderr,"                               src = %s didn't expected %s\n",
+                strResult, stringvalnocopy);
+        tpResult = false;
+        tpFails++;
+    } else {
+        tpResult = true;
+    }
+    // Free memory
+    psFree(strResult);
+    printFooter(stderr, "psStringNCopy","Verify empty string copy with length", tpResult);
+
+    // Test point #5 Copy string to larger string - psStringNCopy
+    printPositiveTestHeader(stderr,"psStringNCopy", "Copy string to larger string");
+    strResult = psStringNCopy(stringval, (strlen(stringval) + increaseSize));
+    // Perform string compare and get string length
+    result = strcmp(strResult, stringval);
+    result1 = strlen(strResult);
+    // The strings should still compare
+    if ( ( result != 0 ) ||
+            ( result1 != strlen(stringval) ) ) {
+        fprintf(stderr,"Failed test point #5 strcmp result = %d expected %d\n",result,0);
+        fprintf(stderr,"                               src = %s expected %s\n",
+                strResult, stringval);
+        fprintf(stderr,"                     strlne result = %d expected %d\n",result1,
+                (int)strlen(stringval));
+        tpResult = false;
+        tpFails++;
+    } else {
+        tpResult = true;
+    }
+    // Free memory
+    psFree(strResult);
+    printFooter(stderr, "psStringNCopy", "Copy string to larger string", tpResult);
+
+    // Test point #6 Copy string with negative size - psStringNCopy
+    printPositiveTestHeader(stderr,"psStringNCopy", "Copy string with negative size");
+    strResult = psStringNCopy(stringval, negativeSize);
+    if ( strResult != NULL ) {
+        fprintf(stderr,"Failed test point #6 return value = %ld expected NULL\n",
+                (unsigned long)strResult);
+        tpResult = false;
+        tpFails++;
+    } else {
+        tpResult = true;
+    }
+    // Memory should not have been allocated
+    printFooter(stderr, "psStringNCopy", "Copy string with negative size", tpResult);
+
+    // Test point #7 Verify creation of string literal - PS_STRING
+    printPositiveTestHeader(stderr,"PS_STRING","Verify creation of string literal");
+    strResult = PS_STRING(E R R O R);
+    result = strcmp(strResult, stringval);
+    if ( result != 0 ) {
+        fprintf(stderr,"Failed test point #7 strcmp result = %d expected %d",result,0);
+        tpResult = false;
+        tpFails++;
+    } else {
+        tpResult = true;
+    }
+    // Memory should not have been allocated
+    printFooter(stderr, "PS_STRING", "Verify creation of string literal", tpResult);
+
+    // Check for memory leaks
+    memBlockAllocated = psMemCheckLeaks(0, memBlockPtr, stderr);
+    if ( memBlockAllocated != 0 ) {
+        fprintf(stderr,"Failed - Memory leaks detected - Blocks still allocated = %d\n",
+                memBlockAllocated);
+        tpFails++;
+    }
+
+    // Display test driver fail message if tpFail not zero
+    if ( tpFails != 0 ) {
+        fprintf(stderr,"Failed test driver  testpoint fail = %d expected %d\n",
+                tpFails, 0);
+    }
+
+    // Return number of test points which failed
+    return tpFails;
+}
+
Index: /tags/rel1_1/psLib/test/sysUtils/tst_psStringCopy.c
===================================================================
--- /tags/rel1_1/psLib/test/sysUtils/tst_psStringCopy.c	(revision 1056)
+++ /tags/rel1_1/psLib/test/sysUtils/tst_psStringCopy.c	(revision 1056)
@@ -0,0 +1,203 @@
+/** @file  tst_psString.c
+ *
+ *  @brief Test driver for psStringCopy functions
+ *
+ *  This test driver contains the following test points for psStringCopy
+ *  and psStringNCopy functions.
+ *    1) Verify string copy - psStringCopy
+ *    2) Verify empty string copy - psStringCopy
+ *    3) Verify string copy with length - psStringNCopy
+ *    4) Verify empty string copy with length - psStringNCopy
+ *    5) Copy string to larger string - psStringNCopy
+ *    6) Copy string with negative size - psStringNCopy
+ *    7) Verifiy creation of string literal - PS_STRING
+ * 
+ *  Return:   Number of test points which failed
+ *
+ *  @author  Eric Van Alst, MHPCC
+ *
+ *  @version $Revision: 1.6 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2004-05-18 19:22:35 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#include <string.h>
+#include "pslib.h"
+#include "psTest.h"
+
+int main( int argc,
+          char * argv[] )
+{
+    bool  tpResult = false;
+    char  stringval[20] = "E R R O R";
+    char  stringval1[20] = "e r r o r";
+    char  *stringvalnocopy = "F A I L";
+    char  *substringval = "e r r";
+    int   substringlen = 6;
+    char  *emptyval = "";
+    int   tpFails = 0;
+    char  *strResult;
+    int   increaseSize = 5;
+    int   negativeSize = -5;
+    int   result = 0;
+    int   result1 = 0;
+    int   memBlockAllocated = 0;
+    psMemBlock ***memBlockPtr = NULL;
+
+    // Test point #1 Verify string copy - psStringCopy
+    printPositiveTestHeader(stderr,"psStringCopy","Verify string copy");
+    strResult = psStringCopy(stringval);
+    // Perform string compare
+    result = strcmp(strResult, stringval);
+    // Modify original string
+    stringval[0]='G';
+    result1 = strcmp(strResult, stringval);
+    stringval[0]='E';
+    if ( ( result != 0 ) || ( result1 == 0) ) {
+        fprintf(stderr, "Failed test point #1 strcmp result = %d expected 0\n",result);
+        fprintf(stderr, "                               src = %s expected %s\n",
+                strResult, stringval);
+        fprintf(stderr, "             changed strcmp result = %d expected 1\n",result1);
+        fprintf(stderr, "             changed           src = %s expected %s\n",strResult,
+                stringval);
+        tpResult = false;
+        tpFails++;
+    } else {
+        tpResult = true;
+    }
+    // Free memory allocated
+    psFree(strResult);
+    printFooter(stderr, "psStringCopy","Verify string copy", tpResult);
+
+    // Test point #2 Verify empty string copy - psStringCopy
+    printPositiveTestHeader(stderr,"psStringCopy","Verify empty string copy");
+    strResult = psStringCopy(emptyval);
+    // Perform string compare
+    result = strcmp(strResult, emptyval);
+    if ( result != 0 ) {
+        fprintf(stderr,"Failed test point #2 strcmp result = %d expected 0\n",result);
+        fprintf(stderr,"                               src = %s expected %s\n",
+                strResult, emptyval);
+        tpResult = false;
+        tpFails++;
+    } else {
+        tpResult = true;
+    }
+    // Free memory allocated
+    psFree(strResult);
+    printFooter(stderr, "psStringCopy","Verify empty string copy", tpResult);
+
+    // Test point #3 Verify string copy with length - psStringNCopy
+    printPositiveTestHeader(stderr,"psStringNCopy","Verify string copy with length");
+    strResult = psStringNCopy(stringval1, substringlen);
+    // Perform string compare and get string length
+    result = strncmp(strResult, substringval, substringlen);
+    // Change original string
+    stringval1[0] = 'g';
+    result1 = strncmp(strResult, substringval, substringlen);
+    if ( ( result != 0 ) || ( result1 != 0 ) ) {
+        fprintf(stderr,"Failed test point #3 strcmp result = %d expected 0\n",result);
+        fprintf(stderr,"                               src = %s expected %s\n",
+                strResult, substringval);
+        fprintf(stderr,"             changed strcmp result = %d expected 0\n",result1);
+        fprintf(stderr,"                               src = %s expected %s\n",
+                strResult, substringval);
+        tpResult = false;
+        tpFails++;
+    } else {
+        tpResult = true;
+    }
+    // Free memory allocated
+    psFree(strResult);
+    printFooter(stderr, "psStringNCopy","Verify string copy with length", tpResult);
+
+    // Test point #4 Verify empty string copy with length - psStringNCopy
+    printPositiveTestHeader(stderr,"psStringNCopy", "Verify empty string copy with length");
+    strResult = psStringNCopy(stringvalnocopy, 0);
+    // Perform string compare and get sting length
+    result = strcmp(strResult, stringvalnocopy);
+    result1 = strlen(strResult);
+    if ( result == 0 ) {
+        fprintf(stderr,"Failed test point #4 strcmp result = %d didn't expected %d\n",result,0);
+        fprintf(stderr,"                               src = %s didn't expected %s\n",
+                strResult, stringvalnocopy);
+        tpResult = false;
+        tpFails++;
+    } else {
+        tpResult = true;
+    }
+    // Free memory
+    psFree(strResult);
+    printFooter(stderr, "psStringNCopy","Verify empty string copy with length", tpResult);
+
+    // Test point #5 Copy string to larger string - psStringNCopy
+    printPositiveTestHeader(stderr,"psStringNCopy", "Copy string to larger string");
+    strResult = psStringNCopy(stringval, (strlen(stringval) + increaseSize));
+    // Perform string compare and get string length
+    result = strcmp(strResult, stringval);
+    result1 = strlen(strResult);
+    // The strings should still compare
+    if ( ( result != 0 ) ||
+            ( result1 != strlen(stringval) ) ) {
+        fprintf(stderr,"Failed test point #5 strcmp result = %d expected %d\n",result,0);
+        fprintf(stderr,"                               src = %s expected %s\n",
+                strResult, stringval);
+        fprintf(stderr,"                     strlne result = %d expected %d\n",result1,
+                (int)strlen(stringval));
+        tpResult = false;
+        tpFails++;
+    } else {
+        tpResult = true;
+    }
+    // Free memory
+    psFree(strResult);
+    printFooter(stderr, "psStringNCopy", "Copy string to larger string", tpResult);
+
+    // Test point #6 Copy string with negative size - psStringNCopy
+    printPositiveTestHeader(stderr,"psStringNCopy", "Copy string with negative size");
+    strResult = psStringNCopy(stringval, negativeSize);
+    if ( strResult != NULL ) {
+        fprintf(stderr,"Failed test point #6 return value = %ld expected NULL\n",
+                (unsigned long)strResult);
+        tpResult = false;
+        tpFails++;
+    } else {
+        tpResult = true;
+    }
+    // Memory should not have been allocated
+    printFooter(stderr, "psStringNCopy", "Copy string with negative size", tpResult);
+
+    // Test point #7 Verify creation of string literal - PS_STRING
+    printPositiveTestHeader(stderr,"PS_STRING","Verify creation of string literal");
+    strResult = PS_STRING(E R R O R);
+    result = strcmp(strResult, stringval);
+    if ( result != 0 ) {
+        fprintf(stderr,"Failed test point #7 strcmp result = %d expected %d",result,0);
+        tpResult = false;
+        tpFails++;
+    } else {
+        tpResult = true;
+    }
+    // Memory should not have been allocated
+    printFooter(stderr, "PS_STRING", "Verify creation of string literal", tpResult);
+
+    // Check for memory leaks
+    memBlockAllocated = psMemCheckLeaks(0, memBlockPtr, stderr);
+    if ( memBlockAllocated != 0 ) {
+        fprintf(stderr,"Failed - Memory leaks detected - Blocks still allocated = %d\n",
+                memBlockAllocated);
+        tpFails++;
+    }
+
+    // Display test driver fail message if tpFail not zero
+    if ( tpFails != 0 ) {
+        fprintf(stderr,"Failed test driver  testpoint fail = %d expected %d\n",
+                tpFails, 0);
+    }
+
+    // Return number of test points which failed
+    return tpFails;
+}
+
Index: /tags/rel1_1/psLib/test/sysUtils/tst_psTrace00.c
===================================================================
--- /tags/rel1_1/psLib/test/sysUtils/tst_psTrace00.c	(revision 1056)
+++ /tags/rel1_1/psLib/test/sysUtils/tst_psTrace00.c	(revision 1056)
@@ -0,0 +1,62 @@
+/*****************************************************************************
+    This code will test whether trace levels can be set successfully.
+ *****************************************************************************/
+#include <stdio.h>
+#include "pslib.h"
+#include "psTest.h"
+
+int main()
+{
+    int i = 0;
+    int lev = 0;
+    int testStatus = true;
+
+    printPositiveTestHeader(stdout,
+                            "psTrace functions",
+                            "psTraceSetLevel() and psTraceGetLevel()");
+    for (i=0;i<10;i++) {
+        psTraceSetLevel(".", i);
+        lev = psTraceGetLevel(".");
+        if (lev != i) {
+            printf("ERROR: (.) expected trace level was %d, actual was %d\n",
+                   i, lev);
+            testStatus = false;
+        }
+    }
+    psTraceSetLevel(".", 3);
+
+    for (i=5;i<10;i++) {
+        psTraceSetLevel(".NODE00", i);
+        lev = psTraceGetLevel(".NODE00");
+        if (lev != i) {
+            printf("ERROR: (.NODE00) expected trace level was %d, actual was %d\n",
+                   i, lev);
+            testStatus = false;
+        }
+
+        lev = psTraceGetLevel(".");
+        if (lev != 3) {
+            printf("ERROR: (.) expected trace level was %d, actual was %d\n",
+                   i, 3);
+            testStatus = false;
+        }
+    }
+
+
+    psTraceSetLevel(".NODE00.NODE01", 4);
+    for (i=0;i<10;i++) {
+        psTraceSetLevel(".NODE00.NODE01", i);
+        lev = psTraceGetLevel(".NODE00.NODE01");
+        if (lev != i) {
+            printf("ERROR: (.NODE00.NODE01) expected trace level was %d, actual was %d\n",
+                   i, lev);
+            testStatus = false;
+        }
+    }
+
+    printFooter(stdout,
+                "psTrace functions",
+                "Testing psTraceSetLevel and psTraceGetLevel",
+                testStatus);
+    return(!testStatus);
+}
Index: /tags/rel1_1/psLib/test/sysUtils/tst_psTrace01.c
===================================================================
--- /tags/rel1_1/psLib/test/sysUtils/tst_psTrace01.c	(revision 1056)
+++ /tags/rel1_1/psLib/test/sysUtils/tst_psTrace01.c	(revision 1056)
@@ -0,0 +1,48 @@
+/*****************************************************************************
+    This code will test whether trace levels can be reset successfully.
+ *****************************************************************************/
+#include <stdio.h>
+#include "pslib.h"
+#include "psTest.h"
+
+int main()
+{
+    int i = 0;
+    int lev = 0;
+    int successFlag = true;
+
+    printPositiveTestHeader(stdout,
+                            "psTrace functions",
+                            "psTraceReset()");
+
+    for (i=0;i<10;i++) {
+        psTraceSetLevel(".", i);
+        psTraceReset();
+
+        lev = psTraceGetLevel(".");
+        if (lev != DEFAULT_TRACE_LEVEL) {
+            printf("ERROR: expected trace level was %d, actual was %d\n",
+                   i, lev);
+            successFlag = false;
+        }
+    }
+    psTraceSetLevel(".", 5);
+    psTraceSetLevel(".a", 4);
+    psTraceSetLevel(".a.b", 3);
+    psTraceSetLevel(".a.b.c", 2);
+    psTraceReset();
+    if ((DEFAULT_TRACE_LEVEL != psTraceGetLevel(".")) ||
+            (DEFAULT_TRACE_LEVEL != psTraceGetLevel(".a")) ||
+            (DEFAULT_TRACE_LEVEL != psTraceGetLevel(".a.b")) ||
+            (DEFAULT_TRACE_LEVEL != psTraceGetLevel(".a.b.c"))) {
+        printf("ERROR: trace levels were not reset properly\n");
+        successFlag = false;
+    }
+
+    printFooter(stdout,
+                "psTrace functions",
+                "psTraceReset()",
+                successFlag);
+
+    return(!successFlag);
+}
Index: /tags/rel1_1/psLib/test/sysUtils/tst_psTrace02.c
===================================================================
--- /tags/rel1_1/psLib/test/sysUtils/tst_psTrace02.c	(revision 1056)
+++ /tags/rel1_1/psLib/test/sysUtils/tst_psTrace02.c	(revision 1056)
@@ -0,0 +1,61 @@
+/*****************************************************************************
+    This code will test whether trace messages can be successfully displayed
+    and not displayed.
+ 
+    NOTE: We must verify the output for the tst_psTrace02_OUT somewhere.
+ *****************************************************************************/
+#include <stdio.h>
+#include "pslib.h"
+#include "psTest.h"
+
+int main()
+{
+    FILE *fp;
+    int nb = 0;
+
+    fp = fopen("tst_psTrace02_OUT", "w");
+    for (nb = 0 ; nb<4;nb++) {
+        if (nb == 0)
+            psTraceSetDestination(stdout);
+        if (nb == 1)
+            psTraceSetDestination(stderr);
+        if (nb == 2)
+            psTraceSetDestination(NULL);
+        if (nb == 3)
+            psTraceSetDestination(fp);
+
+        printPositiveTestHeader(stdout,
+                                "psTrace functions",
+                                "psTrace()");
+
+        psTraceSetLevel(".", 4);
+        psTrace(".", 5, "(0) This message should not be displayed (%x)\n",
+                0xbeefface);
+        psTraceSetLevel(".", 7);
+        psTrace(".", 5, "(0) This message should be displayed (%x)\n",
+                0xbeefface);
+
+        psTraceSetLevel(".a", 4);
+        psTrace(".a", 5, "(1) This message should not be displayed (%x)\n",
+                0xbeefface);
+        psTraceSetLevel(".a", 7);
+        psTrace(".a", 5, "(1) This message should be displayed (%x)\n",
+                0xbeefface);
+
+
+        psTraceSetLevel(".a.b", 4);
+        psTrace(".a.b", 5, "(2) This message should not be displayed (%x)\n",
+                0xbeefface);
+        psTraceSetLevel(".a.b", 7);
+        psTrace(".a.b", 5, "(2) This message should be displayed (%x)\n",
+                0xbeefface);
+
+        printFooter(stdout,
+                    "psTrace functions",
+                    "psTrace()",
+                    true);
+    }
+    fclose(fp);
+
+    return(0);
+}
Index: /tags/rel1_1/psLib/test/sysUtils/tst_psTrace03.c
===================================================================
--- /tags/rel1_1/psLib/test/sysUtils/tst_psTrace03.c	(revision 1056)
+++ /tags/rel1_1/psLib/test/sysUtils/tst_psTrace03.c	(revision 1056)
@@ -0,0 +1,39 @@
+/*****************************************************************************
+    This code will test whether trace messages can be printed successfully
+    with psTracePrintLevels().
+ *****************************************************************************/
+#include <stdio.h>
+#include "pslib.h"
+#include "psTest.h"
+
+int main()
+{
+    printPositiveTestHeader(stdout,
+                            "psTrace functions",
+                            "psTracePrintLevels()");
+
+    psTraceSetLevel(".", 9);
+
+    psTraceSetLevel(".a", 8);
+    psTraceSetLevel(".b", 7);
+    psTraceSetLevel(".c", 5);
+
+    psTraceSetLevel(".a.a", 4);
+    psTraceSetLevel(".a.b", 3);
+
+    psTraceSetLevel(".b.a", 2);
+    psTraceSetLevel(".b.b", 1);
+
+    psTraceSetLevel(".c.a", 0);
+    psTraceSetLevel(".c.b", 3);
+    psTraceSetLevel(".c.c", 5);
+
+    psTracePrintLevels();
+
+    printFooter(stdout,
+                "psTrace functions",
+                "psTracePrintLevels()",
+                true);
+
+    return(0);
+}
Index: /tags/rel1_1/psLib/test/sysUtils/tst_psTrace04.c
===================================================================
--- /tags/rel1_1/psLib/test/sysUtils/tst_psTrace04.c	(revision 1056)
+++ /tags/rel1_1/psLib/test/sysUtils/tst_psTrace04.c	(revision 1056)
@@ -0,0 +1,55 @@
+/*****************************************************************************
+    This code will test whether trace messages can be printed successfully
+    with psTracePrintLevels().
+ *****************************************************************************/
+#include <stdio.h>
+#include "pslib.h"
+#include "psTest.h"
+
+int main()
+{
+    printPositiveTestHeader(stdout,
+                            "psTrace functions",
+                            "Testing psTraceReset()");
+    psTraceSetLevel(".", 9);
+
+    psTraceSetLevel(".a", 8);
+    psTraceSetLevel(".b", 7);
+    psTraceSetLevel(".c", 5);
+
+    psTraceSetLevel(".a.a", 4);
+    psTraceSetLevel(".a.b", 3);
+
+    psTraceSetLevel(".b.a", 2);
+    psTraceSetLevel(".b.b", 1);
+
+    psTraceSetLevel(".c.a", 0);
+    psTraceSetLevel(".c.b", 3);
+    psTraceSetLevel(".c.c", 5);
+
+    psTraceReset();
+
+    if (psTraceGetLevel(".") ||
+            psTraceGetLevel(".a") ||
+            psTraceGetLevel(".b") ||
+            psTraceGetLevel(".c") ||
+            psTraceGetLevel(".a.a") ||
+            psTraceGetLevel(".a.b") ||
+            psTraceGetLevel(".b.a") ||
+            psTraceGetLevel(".b.b") ||
+            psTraceGetLevel(".c.a") ||
+            psTraceGetLevel(".c.b") ||
+            psTraceGetLevel(".c.c")) {
+        printFooter(stdout,
+                    "psTrace functions",
+                    "psTraceReset() did not reset all levels of the tree.",
+                    false);
+        return(1);
+    } else {
+        printFooter(stdout,
+                    "psTrace functions",
+                    "psTraceReset()",
+                    true);
+        return(0);
+    }
+}
Index: /tags/rel1_1/psLib/test/sysUtils/verified/atst_psAbort_01.stderr
===================================================================
--- /tags/rel1_1/psLib/test/sysUtils/verified/atst_psAbort_01.stderr	(revision 1056)
+++ /tags/rel1_1/psLib/test/sysUtils/verified/atst_psAbort_01.stderr	(revision 1056)
@@ -0,0 +1,7 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: atst_psAbort_01.c                                          *
+*            TestPoint: psAbort{Multiple type values in abort message}             *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+ <DATE> <TIME> <HOST> |A|           main|ALL TYPES intval = 1 longval = 2 floatval = 3.010000 charval = E strval = E R R O R
Index: /tags/rel1_1/psLib/test/sysUtils/verified/atst_psAbort_02.stderr
===================================================================
--- /tags/rel1_1/psLib/test/sysUtils/verified/atst_psAbort_02.stderr	(revision 1056)
+++ /tags/rel1_1/psLib/test/sysUtils/verified/atst_psAbort_02.stderr	(revision 1056)
@@ -0,0 +1,7 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: atst_psAbort_02.c                                          *
+*            TestPoint: psAbort{String values in abort message}                    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+ <DATE> <TIME> <HOST> |A|       __LINE__|NO_VALUES
Index: /tags/rel1_1/psLib/test/sysUtils/verified/atst_psAbort_03.stderr
===================================================================
--- /tags/rel1_1/psLib/test/sysUtils/verified/atst_psAbort_03.stderr	(revision 1056)
+++ /tags/rel1_1/psLib/test/sysUtils/verified/atst_psAbort_03.stderr	(revision 1056)
@@ -0,0 +1,7 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: atst_psAbort_03.c                                          *
+*            TestPoint: psAbort{Empty strings in abort message}                    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+ <DATE> <TIME> <HOST> |A|               |
Index: /tags/rel1_1/psLib/test/sysUtils/verified/tst_psError.stderr
===================================================================
--- /tags/rel1_1/psLib/test/sysUtils/verified/tst_psError.stderr	(revision 1056)
+++ /tags/rel1_1/psLib/test/sysUtils/verified/tst_psError.stderr	(revision 1056)
@@ -0,0 +1,30 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psError.c                                              *
+*            TestPoint: psError{Multiple type values in error message}             *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+ <DATE> <TIME> <HOST> |E|           main|ALL TYPES intval = 1 longval = 2 floatval = 3.010000 charval = E strval = E R R O R
+
+---> TESTPOINT PASSED (psError{Multiple type values in error message} | tst_psError.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psError.c                                              *
+*            TestPoint: psError{String values in error message}                    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+ <DATE> <TIME> <HOST> |E|       __LINE__|NO VALUES
+
+---> TESTPOINT PASSED (psError{String values in error message} | tst_psError.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psError.c                                              *
+*            TestPoint: psError{Empty strings in error message}                    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+ <DATE> <TIME> <HOST> |E|               |
+
+---> TESTPOINT PASSED (psError{Empty strings in error message} | tst_psError.c)
+
Index: /tags/rel1_1/psLib/test/sysUtils/verified/tst_psHash00.stdout
===================================================================
--- /tags/rel1_1/psLib/test/sysUtils/verified/tst_psHash00.stdout	(revision 1056)
+++ /tags/rel1_1/psLib/test/sysUtils/verified/tst_psHash00.stdout	(revision 1056)
@@ -0,0 +1,9 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHash00.c                                             *
+*            TestPoint: psHash functions{psHashAlloc()}                            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psHash functions{psHashAlloc()} | tst_psHash00.c)
+
Index: /tags/rel1_1/psLib/test/sysUtils/verified/tst_psHash01.stdout
===================================================================
--- /tags/rel1_1/psLib/test/sysUtils/verified/tst_psHash01.stdout	(revision 1056)
+++ /tags/rel1_1/psLib/test/sysUtils/verified/tst_psHash01.stdout	(revision 1056)
@@ -0,0 +1,9 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHash01.c                                             *
+*            TestPoint: psHash functions{psHashFree()}                             *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psHash functions{psHashFree()} | tst_psHash01.c)
+
Index: /tags/rel1_1/psLib/test/sysUtils/verified/tst_psHash02.stdout
===================================================================
--- /tags/rel1_1/psLib/test/sysUtils/verified/tst_psHash02.stdout	(revision 1056)
+++ /tags/rel1_1/psLib/test/sysUtils/verified/tst_psHash02.stdout	(revision 1056)
@@ -0,0 +1,9 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHash02.c                                             *
+*            TestPoint: psHash functions{psHashInsert()}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psHash functions{psHashInsert()} | tst_psHash02.c)
+
Index: /tags/rel1_1/psLib/test/sysUtils/verified/tst_psHash03.stdout
===================================================================
--- /tags/rel1_1/psLib/test/sysUtils/verified/tst_psHash03.stdout	(revision 1056)
+++ /tags/rel1_1/psLib/test/sysUtils/verified/tst_psHash03.stdout	(revision 1056)
@@ -0,0 +1,9 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHash03.c                                             *
+*            TestPoint: psHash functions{psHashRemove()}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psHash functions{psHashRemove()} | tst_psHash03.c)
+
Index: /tags/rel1_1/psLib/test/sysUtils/verified/tst_psHash04.stdout
===================================================================
--- /tags/rel1_1/psLib/test/sysUtils/verified/tst_psHash04.stdout	(revision 1056)
+++ /tags/rel1_1/psLib/test/sysUtils/verified/tst_psHash04.stdout	(revision 1056)
@@ -0,0 +1,13 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHash04.c                                             *
+*            TestPoint: psHash functions{psHashKeyList()}                          *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Linked List Entries: ENTRY03
+Linked List Entries: ENTRY02
+Linked List Entries: ENTRY01
+Linked List Entries: ENTRY00
+
+---> TESTPOINT PASSED (psHash functions{psHashKeyList()} | tst_psHash04.c)
+
Index: /tags/rel1_1/psLib/test/sysUtils/verified/tst_psLogMsg00.stderr
===================================================================
--- /tags/rel1_1/psLib/test/sysUtils/verified/tst_psLogMsg00.stderr	(revision 1056)
+++ /tags/rel1_1/psLib/test/sysUtils/verified/tst_psLogMsg00.stderr	(revision 1056)
@@ -0,0 +1,8 @@
+ <DATE> <TIME> <HOST> |A|           main|Hello World!  My level is 0 0.000000 beep beep
+ <DATE> <TIME> <HOST> |E|           main|Hello World!  My level is 1 1.000000 beep beep
+ <DATE> <TIME> <HOST> |W|           main|Hello World!  My level is 2 2.000000 beep beep
+ <DATE> <TIME> <HOST> |I|           main|Hello World!  My level is 3 3.000000 beep beep
+ <DATE> <TIME> <HOST> |A|           main|Hello World!  My level is 0 0.000000 beep beep
+ <DATE> <TIME> <HOST> |E|           main|Hello World!  My level is 1 1.000000 beep beep
+ <DATE> <TIME> <HOST> |W|           main|Hello World!  My level is 2 2.000000 beep beep
+ <DATE> <TIME> <HOST> |I|           main|Hello World!  My level is 3 3.000000 beep beep
Index: /tags/rel1_1/psLib/test/sysUtils/verified/tst_psLogMsg00.stdout
===================================================================
--- /tags/rel1_1/psLib/test/sysUtils/verified/tst_psLogMsg00.stdout	(revision 1056)
+++ /tags/rel1_1/psLib/test/sysUtils/verified/tst_psLogMsg00.stdout	(revision 1056)
@@ -0,0 +1,18 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psLogMsg00.c                                           *
+*            TestPoint: psLogMsg functions{default log levels, printf-style strings} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psLogMsg functions{default log levels} | tst_psLogMsg00.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psLogMsg00.c                                           *
+*            TestPoint: psLogMsg functions{default log levels, psVLogMsg()}        *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psLogMsg functions{default log levels} | tst_psLogMsg00.c)
+
Index: /tags/rel1_1/psLib/test/sysUtils/verified/tst_psLogMsg01.stderr
===================================================================
--- /tags/rel1_1/psLib/test/sysUtils/verified/tst_psLogMsg01.stderr	(revision 1056)
+++ /tags/rel1_1/psLib/test/sysUtils/verified/tst_psLogMsg01.stderr	(revision 1056)
@@ -0,0 +1,11 @@
+ <DATE> <TIME> <HOST> |A|           main|Hello World!  My level is 0
+ <DATE> <TIME> <HOST> |E|           main|Hello World!  My level is 1
+ <DATE> <TIME> <HOST> |W|           main|Hello World!  My level is 2
+ <DATE> <TIME> <HOST> |I|           main|Hello World!  My level is 3
+ <DATE> <TIME> <HOST> |4|           main|Hello World!  My level is 4
+ <DATE> <TIME> <HOST> |5|           main|Hello World!  My level is 5
+ <DATE> <TIME> <HOST> |6|           main|Hello World!  My level is 6
+ <DATE> <TIME> <HOST> |7|           main|Hello World!  My level is 7
+ <DATE> <TIME> <HOST> |8|           main|Hello World!  My level is 8
+ <DATE> <TIME> <HOST> |9|           main|Hello World!  My level is 9
+ <DATE> <TIME> <HOST> |4|           main|This should  be displayed (level 4)
Index: /tags/rel1_1/psLib/test/sysUtils/verified/tst_psLogMsg01.stdout
===================================================================
--- /tags/rel1_1/psLib/test/sysUtils/verified/tst_psLogMsg01.stdout	(revision 1056)
+++ /tags/rel1_1/psLib/test/sysUtils/verified/tst_psLogMsg01.stdout	(revision 1056)
@@ -0,0 +1,9 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psLogMsg01.c                                           *
+*            TestPoint: psLogMsg functions{psLogSetLevel()}                        *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psLogMsg functions{psLogSetLevel()} | tst_psLogMsg01.c)
+
Index: /tags/rel1_1/psLib/test/sysUtils/verified/tst_psLogMsg02.stderr
===================================================================
--- /tags/rel1_1/psLib/test/sysUtils/verified/tst_psLogMsg02.stderr	(revision 1056)
+++ /tags/rel1_1/psLib/test/sysUtils/verified/tst_psLogMsg02.stderr	(revision 1056)
@@ -0,0 +1,34 @@
+ <DATE> <TIME> <HOST> |A|           main|Hello World!  My level is 0
+ <DATE> <TIME> <HOST> |E|           main|Hello World!  My level is 1
+ <DATE> <TIME> <HOST> |W|           main|Hello World!  My level is 2
+ <DATE> <TIME> <HOST> |I|           main|Hello World!  My level is 3
+ <DATE> <TIME> <HOST> |A|           main|Hello World!  My level is 0
+ <DATE> <TIME> <HOST> |E|           main|Hello World!  My level is 1
+ <DATE> <TIME> <HOST> |W|           main|Hello World!  My level is 2
+ <DATE> <TIME> <HOST> |I|           main|Hello World!  My level is 3
+ <DATE> <TIME> <HOST> |A|           main|Hello World!  My level is 0
+ <DATE> <TIME> <HOST> |E|           main|Hello World!  My level is 1
+ <DATE> <TIME> <HOST> |W|           main|Hello World!  My level is 2
+ <DATE> <TIME> <HOST> |I|           main|Hello World!  My level is 3
+ <DATE> <TIME> <HOST> |A|           main|Hello World!  My level is 0
+ <DATE> <TIME> <HOST> |E|           main|Hello World!  My level is 1
+ <DATE> <TIME> <HOST> |W|           main|Hello World!  My level is 2
+ <DATE> <TIME> <HOST> |I|           main|Hello World!  My level is 3
+ <DATE> <TIME> <HOST> |A|           main|Hello World!  My level is 0
+ <DATE> <TIME> <HOST> |E|           main|Hello World!  My level is 1
+ <DATE> <TIME> <HOST> |W|           main|Hello World!  My level is 2
+ <DATE> <TIME> <HOST> |I|           main|Hello World!  My level is 3
+ <DATE> <TIME> <HOST> |A|           main|Hello World!  My level is 0
+ <DATE> <TIME> <HOST> |E|           main|Hello World!  My level is 1
+ <DATE> <TIME> <HOST> |W|           main|Hello World!  My level is 2
+ <DATE> <TIME> <HOST> |I|           main|Hello World!  My level is 3
+ <DATE> <TIME> <HOST> |A|           main|Hello World!  My level is 0
+ <DATE> <TIME> <HOST> |E|           main|Hello World!  My level is 1
+ <DATE> <TIME> <HOST> |W|           main|Hello World!  My level is 2
+ <DATE> <TIME> <HOST> |I|           main|Hello World!  My level is 3
+ <DATE> <TIME> <HOST> |A| Under 15 chars|Hello World!
+ <DATE> <TIME> <HOST> |A|This string is |Hello World!
+ <DATE> <TIME> <HOST> |A|           main|Line #1
+ <DATE> <TIME> <HOST> |A|           main|Line #2
+ <DATE> <TIME> <HOST> |A|           main|Line #3
+ <DATE> <TIME> <HOST> |A|           main|Line #4
Index: /tags/rel1_1/psLib/test/sysUtils/verified/tst_psLogMsg02.stdout
===================================================================
--- /tags/rel1_1/psLib/test/sysUtils/verified/tst_psLogMsg02.stdout	(revision 1056)
+++ /tags/rel1_1/psLib/test/sysUtils/verified/tst_psLogMsg02.stdout	(revision 1056)
@@ -0,0 +1,25 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psLogMsg02.c                                           *
+*            TestPoint: psLogMsg functions{psLogSetFormat()}                       *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+------------- psLogSetFormat() -------------
+------------- psLogSetFormat(T) -------------
+------------- psLogSetFormat(H) -------------
+------------- psLogSetFormat(L) -------------
+------------- psLogSetFormat(N) -------------
+------------- psLogSetFormat(M) -------------
+------------- psLogSetFormat(THLNM) -------------
+
+---> TESTPOINT PASSED (psLogMsg functions{psLogSetFormat()} | tst_psLogMsg02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psLogMsg02.c                                           *
+*            TestPoint: psLogMsg functions{Output Format}                          *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psLogMsg functions{Output Format} | tst_psLogMsg02.c)
+
Index: /tags/rel1_1/psLib/test/sysUtils/verified/tst_psLogMsg03.stderr
===================================================================
--- /tags/rel1_1/psLib/test/sysUtils/verified/tst_psLogMsg03.stderr	(revision 1056)
+++ /tags/rel1_1/psLib/test/sysUtils/verified/tst_psLogMsg03.stderr	(revision 1056)
@@ -0,0 +1,4 @@
+ <DATE> <TIME> <HOST> |A|           main|Hello World!  My level is 0
+ <DATE> <TIME> <HOST> |E|           main|Hello World!  My level is 1
+ <DATE> <TIME> <HOST> |W|           main|Hello World!  My level is 2
+ <DATE> <TIME> <HOST> |I|           main|Hello World!  My level is 3
Index: /tags/rel1_1/psLib/test/sysUtils/verified/tst_psLogMsg03.stdout
===================================================================
--- /tags/rel1_1/psLib/test/sysUtils/verified/tst_psLogMsg03.stdout	(revision 1056)
+++ /tags/rel1_1/psLib/test/sysUtils/verified/tst_psLogMsg03.stdout	(revision 1056)
@@ -0,0 +1,20 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psLogMsg03.c                                           *
+*            TestPoint: psLogMsg functions{psLogSetDestination()}                  *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+------------- psLogSetDestination(PS_LOG_NONE) -------------
+------------- psLogSetDestination(PS_LOG_TO_STDERR) -------------
+------------- psLogSetDestination(PS_LOG_TO_STDOUT) -------------
+ <DATE> <TIME> <HOST> |A|           main|
+Hello World!  My level is 0
+ <DATE> <TIME> <HOST> |E|           main|
+Hello World!  My level is 1
+ <DATE> <TIME> <HOST> |W|           main|
+Hello World!  My level is 2
+ <DATE> <TIME> <HOST> |I|           main|
+Hello World!  My level is 3
+
+---> TESTPOINT PASSED (psLogMsg functions{psLogSetDestination()} | tst_psLogMsg03.c)
+
Index: /tags/rel1_1/psLib/test/sysUtils/verified/tst_psMemory.stderr
===================================================================
--- /tags/rel1_1/psLib/test/sysUtils/verified/tst_psMemory.stderr	(revision 1056)
+++ /tags/rel1_1/psLib/test/sysUtils/verified/tst_psMemory.stderr	(revision 1056)
@@ -0,0 +1,97 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMemory.c                                             *
+*            TestPoint: psMemory{449-TPCheckBufferPositive}                        *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+ <DATE> <TIME> <HOST> |I|TPCheckBufferPo|psAlloc shall allocate memory blocks writeable by caller.
+
+---> TESTPOINT PASSED (psMemory{449-TPCheckBufferPositive} | tst_psMemory.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMemory.c                                             *
+*            TestPoint: psMemory{450-TPOutOfMemory}                                *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+ <DATE> <TIME> <HOST> |I|  TPOutOfMemory|Upon requesting more memory than is available, psalloc shall call the psMemExhaustedCallback.
+ <DATE> <TIME> <HOST> |I|TPOutOfMemoryEx|Custom MemExhaustedCallback was invoked.
+ <DATE> <TIME> <HOST> |A|      p_psAlloc|Failed to allocate 4294966295 bytes at tst_psMemory.c:164
+
+---> TESTPOINT PASSED (psMemory{450-TPOutOfMemory} | tst_psMemory.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMemory.c                                             *
+*            TestPoint: psMemory{451-TPrealloc}                                    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+ <DATE> <TIME> <HOST> |I|      TPrealloc|psRealloc shall increase/decrease memory buffer while preserving contents
+ <DATE> <TIME> <HOST> |I|      TPrealloc|Expanding memory buffer.
+ <DATE> <TIME> <HOST> |I|      TPrealloc|Shrinking memory buffer.
+
+---> TESTPOINT PASSED (psMemory{451-TPrealloc} | tst_psMemory.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMemory.c                                             *
+*            TestPoint: psMemory{452/453-TPallocCallback}                          *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+ <DATE> <TIME> <HOST> |I|TPallocCallback|call to psAlloc/psRealloc shall generate a callback if specified memory ID is allocated.
+ <DATE> <TIME> <HOST> |I|memAllocateCall|block 2 was (re)allocated
+ <DATE> <TIME> <HOST> |I|memAllocateCall|block 3 was (re)allocated
+ <DATE> <TIME> <HOST> |I|memFreeCallback|block 2 was freed
+ <DATE> <TIME> <HOST> |I|memFreeCallback|block 3 was freed
+ <DATE> <TIME> <HOST> |I|memAllocateCall|block 4 was (re)allocated
+ <DATE> <TIME> <HOST> |I|memAllocateCall|block 4 was (re)allocated
+ <DATE> <TIME> <HOST> |I|memFreeCallback|block 4 was freed
+
+---> TESTPOINT PASSED (psMemory{452/453-TPallocCallback} | tst_psMemory.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMemory.c                                             *
+*            TestPoint: psMemory{454-TPcheckLeaks}                                 *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+ <DATE> <TIME> <HOST> |I|   TPcheckLeaks|psMemCheckLeaks shall return the number of blocks above an ID that are still allocated
+ <DATE> <TIME> <HOST> |I|   TPcheckLeaks|following psMemCheckLeaks call should produce one instance.
+                   file:line ID
+         tst_psMemory.c:314  1
+ <DATE> <TIME> <HOST> |I|   TPcheckLeaks|Testing psMemCheckLeaks again with a different leak location
+ <DATE> <TIME> <HOST> |I|   TPcheckLeaks|following psMemCheckLeaks call should produce one error.
+                   file:line ID
+         tst_psMemory.c:344  11
+ <DATE> <TIME> <HOST> |I|   TPcheckLeaks|Testing psMemCheckLeaks again with multiple leak locations.
+ <DATE> <TIME> <HOST> |I|   TPcheckLeaks|following psMemCheckLeaks call should produce two errors.
+                   file:line ID
+         tst_psMemory.c:372  16
+         tst_psMemory.c:372  14
+
+---> TESTPOINT PASSED (psMemory{454-TPcheckLeaks} | tst_psMemory.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMemory.c                                             *
+*            TestPoint: psMemory{455-TPmemCorruption}                              *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+ <DATE> <TIME> <HOST> |I|TPmemCorruption|psMemCheckCorruption shall detect memory corruptions
+ <DATE> <TIME> <HOST> |I|TPmemCorruption|psMemCheckCorruption should output an error message and memProblemCallback callback should be called.
+ <DATE> <TIME> <HOST> |E|psMemCheckCorru|psMemCheckCorruption: memory block 1 is corrupted (buffer underflow)
+ <DATE> <TIME> <HOST> |I|memProblemCallb|memory callback called for id 1 (psMemCheckCorruption:228).
+
+---> TESTPOINT PASSED (psMemory{455-TPmemCorruption} | tst_psMemory.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMemory.c                                             *
+*            TestPoint: psMemory{456-TPFreeReferencedMemory}                       *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+ <DATE> <TIME> <HOST> |I|TPFreeReference|memory reference count shall be incrementable/decrementable
+ <DATE> <TIME> <HOST> |I|TPFreeReference|psFree shall be just decrement a multiple refererenced pointer.
+
+---> TESTPOINT PASSED (psMemory{456-TPFreeReferencedMemory} | tst_psMemory.c)
+
Index: /tags/rel1_1/psLib/test/sysUtils/verified/tst_psStringCopy.stderr
===================================================================
--- /tags/rel1_1/psLib/test/sysUtils/verified/tst_psStringCopy.stderr	(revision 1056)
+++ /tags/rel1_1/psLib/test/sysUtils/verified/tst_psStringCopy.stderr	(revision 1056)
@@ -0,0 +1,64 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStringCopy.c                                         *
+*            TestPoint: psStringCopy{Verify string copy}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psStringCopy{Verify string copy} | tst_psStringCopy.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStringCopy.c                                         *
+*            TestPoint: psStringCopy{Verify empty string copy}                     *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psStringCopy{Verify empty string copy} | tst_psStringCopy.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStringCopy.c                                         *
+*            TestPoint: psStringNCopy{Verify string copy with length}              *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psStringNCopy{Verify string copy with length} | tst_psStringCopy.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStringCopy.c                                         *
+*            TestPoint: psStringNCopy{Verify empty string copy with length}        *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psStringNCopy{Verify empty string copy with length} | tst_psStringCopy.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStringCopy.c                                         *
+*            TestPoint: psStringNCopy{Copy string to larger string}                *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psStringNCopy{Copy string to larger string} | tst_psStringCopy.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStringCopy.c                                         *
+*            TestPoint: psStringNCopy{Copy string with negative size}              *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+ <DATE> <TIME> <HOST> |E|     psString.c|psStringNCopy with negative count specified -5
+
+---> TESTPOINT PASSED (psStringNCopy{Copy string with negative size} | tst_psStringCopy.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStringCopy.c                                         *
+*            TestPoint: PS_STRING{Verify creation of string literal}               *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (PS_STRING{Verify creation of string literal} | tst_psStringCopy.c)
+
Index: /tags/rel1_1/psLib/test/sysUtils/verified/tst_psTrace00.stdout
===================================================================
--- /tags/rel1_1/psLib/test/sysUtils/verified/tst_psTrace00.stdout	(revision 1056)
+++ /tags/rel1_1/psLib/test/sysUtils/verified/tst_psTrace00.stdout	(revision 1056)
@@ -0,0 +1,9 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psTrace00.c                                            *
+*            TestPoint: psTrace functions{psTraceSetLevel() and psTraceGetLevel()} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psTrace functions{Testing psTraceSetLevel and psTraceGetLevel} | tst_psTrace00.c)
+
Index: /tags/rel1_1/psLib/test/sysUtils/verified/tst_psTrace01.stdout
===================================================================
--- /tags/rel1_1/psLib/test/sysUtils/verified/tst_psTrace01.stdout	(revision 1056)
+++ /tags/rel1_1/psLib/test/sysUtils/verified/tst_psTrace01.stdout	(revision 1056)
@@ -0,0 +1,9 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psTrace01.c                                            *
+*            TestPoint: psTrace functions{psTraceReset()}                          *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psTrace functions{psTraceReset()} | tst_psTrace01.c)
+
Index: /tags/rel1_1/psLib/test/sysUtils/verified/tst_psTrace02.stderr
===================================================================
--- /tags/rel1_1/psLib/test/sysUtils/verified/tst_psTrace02.stderr	(revision 1056)
+++ /tags/rel1_1/psLib/test/sysUtils/verified/tst_psTrace02.stderr	(revision 1056)
@@ -0,0 +1,3 @@
+     (0) This message should be displayed (beefface)
+     (1) This message should be displayed (beefface)
+     (2) This message should be displayed (beefface)
Index: /tags/rel1_1/psLib/test/sysUtils/verified/tst_psTrace02.stdout
===================================================================
--- /tags/rel1_1/psLib/test/sysUtils/verified/tst_psTrace02.stdout	(revision 1056)
+++ /tags/rel1_1/psLib/test/sysUtils/verified/tst_psTrace02.stdout	(revision 1056)
@@ -0,0 +1,42 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psTrace02.c                                            *
+*            TestPoint: psTrace functions{psTrace()}                               *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+     (0) This message should be displayed (beefface)
+     (1) This message should be displayed (beefface)
+     (2) This message should be displayed (beefface)
+
+---> TESTPOINT PASSED (psTrace functions{psTrace()} | tst_psTrace02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psTrace02.c                                            *
+*            TestPoint: psTrace functions{psTrace()}                               *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psTrace functions{psTrace()} | tst_psTrace02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psTrace02.c                                            *
+*            TestPoint: psTrace functions{psTrace()}                               *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+     (0) This message should be displayed (beefface)
+     (1) This message should be displayed (beefface)
+     (2) This message should be displayed (beefface)
+
+---> TESTPOINT PASSED (psTrace functions{psTrace()} | tst_psTrace02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psTrace02.c                                            *
+*            TestPoint: psTrace functions{psTrace()}                               *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psTrace functions{psTrace()} | tst_psTrace02.c)
+
Index: /tags/rel1_1/psLib/test/sysUtils/verified/tst_psTrace03.stdout
===================================================================
--- /tags/rel1_1/psLib/test/sysUtils/verified/tst_psTrace03.stdout	(revision 1056)
+++ /tags/rel1_1/psLib/test/sysUtils/verified/tst_psTrace03.stdout	(revision 1056)
@@ -0,0 +1,20 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psTrace03.c                                            *
+*            TestPoint: psTrace functions{psTracePrintLevels()}                    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+.                    9
+ a                   8
+  a                  4
+  b                  3
+ b                   7
+  a                  2
+  b                  1
+ c                   5
+  a                  0
+  b                  3
+  c                  5
+
+---> TESTPOINT PASSED (psTrace functions{psTracePrintLevels()} | tst_psTrace03.c)
+
Index: /tags/rel1_1/psLib/test/sysUtils/verified/tst_psTrace04.stdout
===================================================================
--- /tags/rel1_1/psLib/test/sysUtils/verified/tst_psTrace04.stdout	(revision 1056)
+++ /tags/rel1_1/psLib/test/sysUtils/verified/tst_psTrace04.stdout	(revision 1056)
@@ -0,0 +1,9 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psTrace04.c                                            *
+*            TestPoint: psTrace functions{Testing psTraceReset()}                  *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psTrace functions{psTraceReset()} | tst_psTrace04.c)
+
