3rdParty: Remove boost-numeric, ANN and atlas

Signed-off-by: Przemo Firszt <przemo@firszt.eu>
This commit is contained in:
Przemo Firszt
2015-07-15 10:27:42 +01:00
parent 945638c405
commit ea0cc96c15
154 changed files with 0 additions and 37527 deletions

View File

@@ -1 +0,0 @@
add_subdirectory(src)

View File

@@ -1,47 +0,0 @@
ANN: Approximate Nearest Neighbors
Version: 1.1.1
Release Date: Aug 4, 2006
----------------------------------------------------------------------------
Copyright (c) 1997-2005 University of Maryland and Sunil Arya and David
Mount All Rights Reserved.
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser Public License as published by the
Free Software Foundation; either version 2.1 of the License, or (at your
option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser Public License for more details.
A copy of the terms and conditions of the license can be found in
License.txt or online at
http://www.gnu.org/copyleft/lesser.html
To obtain a copy, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Disclaimer
----------
The University of Maryland and the authors make no representations about
the suitability or fitness of this software for any purpose. It is
provided "as is" without express or implied warranty.
---------------------------------------------------------------------
Authors
-------
David Mount
Dept of Computer Science
University of Maryland,
College Park, MD 20742 USA
mount@cs.umd.edu
http://www.cs.umd.edu/~mount/
Sunil Arya
Dept of Computer Science
Hong University of Science and Technology
Clearwater Bay, HONG KONG
arya@cs.ust.hk
http://www.cs.ust.hk/faculty/arya/

View File

@@ -1,450 +0,0 @@
----------------------------------------------------------------------
The ANN Library (all versions) is provided under the terms and
conditions of the GNU Lesser General Public Library, which is stated
below. It can also be found at:
http://www.gnu.org/copyleft/lesser.html
----------------------------------------------------------------------
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence the
version number 2.1.]
Preamble
The licenses for most software are designed to take away your freedom to
share and change it. By contrast, the GNU General Public Licenses are
intended to guarantee your freedom to share and change free software--to
make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the Free
Software Foundation and other authors who decide to use it. You can use
it too, but we suggest you first think carefully about whether this
license or the ordinary General Public License is the better strategy to
use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish); that you receive source code or can get it if
you want it; that you can change the software and use pieces of it in
new free programs; and that you are informed that you can do these
things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for you
if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis or
for a fee, you must give the recipients all the rights that we gave you.
You must make sure that they, too, receive or can get the source code.
If you link other code with the library, you must provide complete
object files to the recipients, so that they can relink them with the
library after making changes to the library and recompiling it. And you
must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that there is
no warranty for the free library. Also, if the library is modified by
someone else and passed on, the recipients should know that what they
have is not the original version, so that the original author's
reputation will not be affected by problems that might be introduced by
others.
Finally, software patents pose a constant threat to the existence of any
free program. We wish to make sure that a company cannot effectively
restrict the users of a free program by obtaining a restrictive license
from a patent holder. Therefore, we insist that any patent license
obtained for a version of the library must be consistent with the full
freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the ordinary
GNU General Public License. This license, the GNU Lesser General Public
License, applies to certain designated libraries, and is quite different
from the ordinary General Public License. We use this license for
certain libraries in order to permit linking those libraries into
non-free programs.
When a program is linked with a library, whether statically or using a
shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the entire
combination fits its criteria of freedom. The Lesser General Public
License permits more lax criteria for linking other code with the
library.
We call this license the "Lesser" General Public License because it does
Less to protect the user's freedom than the ordinary General Public
License. It also provides other free software developers Less of an
advantage over competing non-free programs. These disadvantages are the
reason we use the ordinary General Public License for many libraries.
However, the Lesser license provides advantages in certain special
circumstances.
For example, on rare occasions, there may be a special need to encourage
the widest possible use of a certain library, so that it becomes a
de-facto standard. To achieve this, non-free programs must be allowed to
use the library. A more frequent case is that a free library does the
same job as widely used non-free libraries. In this case, there is
little to gain by limiting the free library to free software only, so we
use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of free
software. For example, permission to use the GNU C Library in non-free
programs enables many more people to use the whole GNU operating system,
as well as its variant, the GNU/Linux operating system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is linked
with the Library has the freedom and the wherewithal to run that program
using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or other
authorized party saying it may be distributed under the terms of this
Lesser General Public License (also called "this License"). Each
licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work which
has been distributed under these terms. A "work based on the Library"
means either the Library or any derivative work under copyright law:
that is to say, a work containing the Library or a portion of it, either
verbatim or with modifications and/or translated straightforwardly into
another language. (Hereinafter, translation is included without
limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for making
modifications to it. For a library, complete source code means all the
source code for all modules it contains, plus any associated interface
definition files, plus the scripts used to control compilation and
installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of running
a program using the Library is not restricted, and output from such a
program is covered only if its contents constitute a work based on the
Library (independent of the use of the Library in a tool for writing
it). Whether that is true depends on what the Library does and what the
program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's complete
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the notices
that refer to this License and to the absence of any warranty; and
distribute a copy of this License along with the Library.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Library or any portion of
it, thus forming a work based on the Library, and copy and distribute
such modifications or work under the terms of Section 1 above, provided
that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the application.
Therefore, Subsection 2d requires that any application-supplied function
or table used by this function must be optional: if the application does
not supply it, the square root function must still compute square
roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library, and
can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based on
the Library, the distribution of the whole must be on the terms of this
License, whose permissions for other licensees extend to the entire
whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or
contest your rights to work written entirely by you; rather, the intent
is to exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the
Library with the Library (or with a work based on the Library) on a
volume of a storage or distribution medium does not bring the other work
under the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so that
they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in these
notices.
Once this change is made in a given copy, it is irreversible for that
copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of the
Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or derivative
of it, under Section 2) in object code or executable form under the
terms of Sections 1 and 2 above provided that you accompany it with the
complete corresponding machine-readable source code, which must be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange.
If distribution of object code is made by offering access to copy from a
designated place, then offering equivalent access to copy the source
code from the same place satisfies the requirement to distribute the
source code, even though third parties are not compelled to copy the
source along with the object code.
5. A program that contains no derivative of any portion of the Library,
but is designed to work with the Library by being compiled or linked
with it, is called a "work that uses the Library". Such a work, in
isolation, is not a derivative work of the Library, and therefore falls
outside the scope of this License.
However, linking a "work that uses the Library" with the Library creates
an executable that is a derivative of the Library (because it contains
portions of the Library), rather than a "work that uses the library".
The executable is therefore covered by this License. Section 6 states
terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be linked
without the Library, or if the work is itself a library. The threshold
for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data structure
layouts and accessors, and small macros and small inline functions (ten
lines or less in length), then the use of the object file is
unrestricted, regardless of whether it is legally a derivative work.
(Executables containing this object code plus portions of the Library
will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6, whether
or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or link a
"work that uses the Library" with the Library to produce a work
containing portions of the Library, and distribute that work under terms
of your choice, provided that the terms permit modification of the work
for the customer's own use and reverse engineering for debugging such
modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work during
execution displays copyright notices, you must include the copyright
notice for the Library among them, as well as a reference directing the
user to the copy of this License. Also, you must do one of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood that
the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at least
three years, to give the same user the materials specified in
Subsection 6a, above, for a charge no more than the cost of
performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the Library"
must include any data and utility programs needed for reproducing the
executable from it. However, as a special exception, the materials to be
distributed need not include anything that is normally distributed (in
either source or binary form) with the major components (compiler,
kernel, and so on) of the operating system on which the executable runs,
unless that component itself accompanies the executable.
It may happen that this requirement contradicts the license restrictions
of other proprietary libraries that do not normally accompany the
operating system. Such a contradiction means you cannot use both them
and the Library together in an executable that you distribute.
7. You may place library facilities that are a work based on the Library
side-by-side in a single library together with other library facilities
not covered by this License, and distribute such a combined library,
provided that the separate distribution of the work based on the Library
and of the other library facilities is otherwise permitted, and provided
that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute the
Library except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense, link with, or distribute the
Library is void, and will automatically terminate your rights under this
License. However, parties who have received copies, or rights, from you
under this License will not have their licenses terminated so long as
such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and all
its terms and conditions for copying, distributing or modifying the
Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot distribute
so as to satisfy simultaneously your obligations under this License and
any other pertinent obligations, then as a consequence you may not
distribute the Library at all. For example, if a patent license would
not permit royalty-free redistribution of the Library by all those who
receive copies directly or indirectly through you, then the only way you
could satisfy both it and this License would be to refrain entirely from
distribution of the Library.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply, and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is implemented
by public license practices. Many people have made generous
contributions to the wide range of software distributed through that
system in reliance on consistent application of that system; it is up to
the author/donor to decide if he or she is willing to distribute
software through any other system and a licensee cannot impose that
choice.
This section is intended to make thoroughly clear what is believed to be
a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may
add an explicit geographical distribution limitation excluding those
countries, so that distribution is permitted only in or among countries
not thus excluded. In such case, this License incorporates the
limitation as if written in the body of this License.
13. The Free Software Foundation may publish revised and/or new versions
of the Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a license
version number, you may choose any version ever published by the Free
Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free Software
Foundation; we sometimes make exceptions for this. Our decision will be
guided by the two goals of preserving the free status of all derivatives
of our free software and of promoting the sharing and reuse of software
generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH
YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR
DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL
DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY
(INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED
INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF
THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR
OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

View File

@@ -1,46 +0,0 @@
Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dll", "dll\dll.vcproj", "{A7D00B21-CB9C-4BBB-8DEE-51025104F867}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample", "sample\sample.vcproj", "{C76F5A10-7A4A-4546-9414-296DB38BE825}"
ProjectSection(ProjectDependencies) = postProject
{A7D00B21-CB9C-4BBB-8DEE-51025104F867} = {A7D00B21-CB9C-4BBB-8DEE-51025104F867}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test", "test\test.vcproj", "{6AC673C7-7B3F-4520-A761-647B212A4BEF}"
ProjectSection(ProjectDependencies) = postProject
{A7D00B21-CB9C-4BBB-8DEE-51025104F867} = {A7D00B21-CB9C-4BBB-8DEE-51025104F867}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ann2fig", "ann2fig\ann2fig.vcproj", "{622DD7D8-0C0A-4303-9176-C9A8AF467E70}"
ProjectSection(ProjectDependencies) = postProject
{A7D00B21-CB9C-4BBB-8DEE-51025104F867} = {A7D00B21-CB9C-4BBB-8DEE-51025104F867}
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{A7D00B21-CB9C-4BBB-8DEE-51025104F867}.Debug|Win32.ActiveCfg = Debug|Win32
{A7D00B21-CB9C-4BBB-8DEE-51025104F867}.Debug|Win32.Build.0 = Debug|Win32
{A7D00B21-CB9C-4BBB-8DEE-51025104F867}.Release|Win32.ActiveCfg = Release|Win32
{A7D00B21-CB9C-4BBB-8DEE-51025104F867}.Release|Win32.Build.0 = Release|Win32
{C76F5A10-7A4A-4546-9414-296DB38BE825}.Debug|Win32.ActiveCfg = Debug|Win32
{C76F5A10-7A4A-4546-9414-296DB38BE825}.Debug|Win32.Build.0 = Debug|Win32
{C76F5A10-7A4A-4546-9414-296DB38BE825}.Release|Win32.ActiveCfg = Release|Win32
{C76F5A10-7A4A-4546-9414-296DB38BE825}.Release|Win32.Build.0 = Release|Win32
{6AC673C7-7B3F-4520-A761-647B212A4BEF}.Debug|Win32.ActiveCfg = Debug|Win32
{6AC673C7-7B3F-4520-A761-647B212A4BEF}.Debug|Win32.Build.0 = Debug|Win32
{6AC673C7-7B3F-4520-A761-647B212A4BEF}.Release|Win32.ActiveCfg = Release|Win32
{6AC673C7-7B3F-4520-A761-647B212A4BEF}.Release|Win32.Build.0 = Release|Win32
{622DD7D8-0C0A-4303-9176-C9A8AF467E70}.Debug|Win32.ActiveCfg = Debug|Win32
{622DD7D8-0C0A-4303-9176-C9A8AF467E70}.Debug|Win32.Build.0 = Debug|Win32
{622DD7D8-0C0A-4303-9176-C9A8AF467E70}.Release|Win32.ActiveCfg = Release|Win32
{622DD7D8-0C0A-4303-9176-C9A8AF467E70}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@@ -1,53 +0,0 @@
#-----------------------------------------------------------------------------
# Makefile for Windows Versions.
#
# ANN: Approximate Nearest Neighbors
# Version: 1.1.1 08/04/06
#-----------------------------------------------------------------------------
# Copyright (c) 1997-2005 University of Maryland and Sunil Arya and
# David Mount. All Rights Reserved.
#
# This software and related documentation is part of the Approximate
# Nearest Neighbor Library (ANN). This software is provided under
# the provisions of the Lesser GNU Public License (LGPL). See the
# file ../ReadMe.txt for further information.
#
# The University of Maryland (U.M.) and the authors make no
# representations about the suitability or fitness of this software for
# any purpose. It is provided "as is" without express or implied
# warranty.
#-----------------------------------------------------------------------------
# Revision 1.0 05/03/05
# Initial release
# Revision 1.1.1 08/04/06
# Added copyright/license
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# This is not used for compiling the dll. It is just used for cleaning
# things up for distribution. For compilcation, open the Ann.sln
# solution file in Microsoft Windows Visual Studio.NET.
#-----------------------------------------------------------------------------
default:
@echo "Enter one of the following:"
@echo " make clean remove object files"
@echo " make realclean remove library and executable files"
@echo " "
@echo "See file Makefile for other compilation options."
#-----------------------------------------------------------------------------
# Remove .o files and core files
#-----------------------------------------------------------------------------
clean:
-rm -f -r ann2fig/Debug ann2fig/Release
-rm -f -r dll/Debug dll/Release
-rm -f -r sample/Debug sample/Release
-rm -f -r test/Debug test/Release
-rm -f Ann.ncb Ann.suo
#-----------------------------------------------------------------------------
# Remove everthing that can be remade
#-----------------------------------------------------------------------------
realclean: clean
-rm -f bin/*

View File

@@ -1,134 +0,0 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="ann2fig"
ProjectGUID="{622DD7D8-0C0A-4303-9176-C9A8AF467E70}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="Debug"
IntermediateDirectory="Debug"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\include"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="5"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="..\bin\ann2fig.exe"
LinkIncremental="2"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/ann2fig.pdb"
SubSystem="1"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="Release"
IntermediateDirectory="Release"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="..\..\include"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
RuntimeLibrary="4"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="..\bin\ann2fig.exe"
LinkIncremental="1"
GenerateDebugInformation="TRUE"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
<File
RelativePath="..\..\ann2fig\ann2fig.cpp">
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -1,452 +0,0 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="dll"
SccProjectName=""
SccLocalPath="">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\Debug"
IntermediateDirectory=".\Debug"
ConfigurationType="2"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\include"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;DLL_EXPORTS;ANN_PERF;ANN_NO_RANDOM"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
PrecompiledHeaderThrough="stdafx.h"
PrecompiledHeaderFile=".\Debug/dll.pch"
AssemblerListingLocation=".\Debug/"
ObjectFile=".\Debug/"
ProgramDataBaseFileName=".\Debug/"
WarningLevel="3"
SuppressStartupBanner="TRUE"
DebugInformationFormat="4"
CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="..\bin\ANN.dll"
LinkIncremental="0"
SuppressStartupBanner="TRUE"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile=".\Debug\ANN.pdb"
ImportLibrary=".\Debug\ANN.lib"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="_DEBUG"
MkTypLibCompatible="TRUE"
SuppressStartupBanner="TRUE"
TargetEnvironment="1"
TypeLibraryName=".\Debug/dll.tlb"
HeaderFileName=""/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="3081"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory=".\Release"
IntermediateDirectory=".\Release"
ConfigurationType="2"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\include"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;DLL_EXPORTS;ANN_NO_RANDOM"
StringPooling="TRUE"
RuntimeLibrary="0"
EnableFunctionLevelLinking="TRUE"
UsePrecompiledHeader="0"
PrecompiledHeaderThrough="stdafx.h"
PrecompiledHeaderFile=".\Release/dll.pch"
AssemblerListingLocation=".\Release/"
ObjectFile=".\Release/"
ProgramDataBaseFileName=".\Release/"
WarningLevel="3"
SuppressStartupBanner="TRUE"
CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="..\bin\ANN.dll"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
ProgramDatabaseFile=".\Release\ANN.pdb"
ImportLibrary=".\Release\ANN.lib"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="NDEBUG"
MkTypLibCompatible="TRUE"
SuppressStartupBanner="TRUE"
TargetEnvironment="1"
TypeLibraryName=".\Release/dll.tlb"
HeaderFileName=""/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="3081"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
<File
RelativePath="..\..\src\ANN.cpp">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;DLL_EXPORTS"
BasicRuntimeChecks="3"
UsePrecompiledHeader="0"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;DLL_EXPORTS"
UsePrecompiledHeader="0"/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\src\bd_fix_rad_search.cpp">
</File>
<File
RelativePath="..\..\src\bd_pr_search.cpp">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;DLL_EXPORTS"
BasicRuntimeChecks="3"
UsePrecompiledHeader="0"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;DLL_EXPORTS"
UsePrecompiledHeader="0"/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\src\bd_search.cpp">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;DLL_EXPORTS"
BasicRuntimeChecks="3"
UsePrecompiledHeader="0"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;DLL_EXPORTS"
UsePrecompiledHeader="0"/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\src\bd_tree.cpp">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;DLL_EXPORTS"
BasicRuntimeChecks="3"
UsePrecompiledHeader="0"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;DLL_EXPORTS"
UsePrecompiledHeader="0"/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\src\brute.cpp">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;DLL_EXPORTS"
BasicRuntimeChecks="3"
UsePrecompiledHeader="0"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;DLL_EXPORTS"
UsePrecompiledHeader="0"/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\src\kd_dump.cpp">
</File>
<File
RelativePath="..\..\src\kd_fix_rad_search.cpp">
</File>
<File
RelativePath="..\..\src\kd_pr_search.cpp">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;DLL_EXPORTS"
BasicRuntimeChecks="3"
UsePrecompiledHeader="0"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;DLL_EXPORTS"
UsePrecompiledHeader="0"/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\src\kd_search.cpp">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;DLL_EXPORTS"
BasicRuntimeChecks="3"
UsePrecompiledHeader="0"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;DLL_EXPORTS"
UsePrecompiledHeader="0"/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\src\kd_split.cpp">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;DLL_EXPORTS"
BasicRuntimeChecks="3"
UsePrecompiledHeader="0"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;DLL_EXPORTS"
UsePrecompiledHeader="0"/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\src\kd_tree.cpp">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;DLL_EXPORTS"
BasicRuntimeChecks="3"
UsePrecompiledHeader="0"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;DLL_EXPORTS"
UsePrecompiledHeader="0"/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\src\kd_util.cpp">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;DLL_EXPORTS"
BasicRuntimeChecks="3"
UsePrecompiledHeader="0"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;DLL_EXPORTS"
UsePrecompiledHeader="0"/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\src\perf.cpp">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;DLL_EXPORTS"
BasicRuntimeChecks="3"
UsePrecompiledHeader="0"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;DLL_EXPORTS"
UsePrecompiledHeader="0"/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl">
<File
RelativePath="..\..\include\Ann\ANN.h">
</File>
<File
RelativePath="..\..\include\Ann\ANNperf.h">
</File>
<File
RelativePath="..\..\include\Ann\ANNx.h">
</File>
<File
RelativePath="..\..\src\bd_tree.h">
</File>
<File
RelativePath="..\..\src\kd_fix_rad_search.h">
</File>
<File
RelativePath="..\..\src\kd_pr_search.h">
</File>
<File
RelativePath="..\..\src\kd_search.h">
</File>
<File
RelativePath="..\..\src\kd_split.h">
</File>
<File
RelativePath="..\..\src\kd_tree.h">
</File>
<File
RelativePath="..\..\src\kd_util.h">
</File>
<File
RelativePath="..\..\src\pr_queue.h">
</File>
<File
RelativePath="..\..\src\pr_queue_k.h">
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">
</Filter>
<File
RelativePath="ReadMe.txt">
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -1,194 +0,0 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="sample"
SccProjectName=""
SccLocalPath=""
Keyword="MFCProj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\Debug"
IntermediateDirectory=".\Debug"
ConfigurationType="1"
UseOfMFC="2"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\include"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;ANN_NO_RANDOM;ANN_PERF"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
PrecompiledHeaderThrough="stdafx.h"
PrecompiledHeaderFile=".\Debug/sample.pch"
AssemblerListingLocation=".\Debug/"
ObjectFile=".\Debug/"
ProgramDataBaseFileName=".\Debug/"
WarningLevel="3"
SuppressStartupBanner="TRUE"
DebugInformationFormat="4"
CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib"
OutputFile="..\bin\ann_sample.exe"
LinkIncremental="2"
SuppressStartupBanner="TRUE"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile=".\Debug/sample.pdb"
SubSystem="1"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Debug/sample.tlb"
HeaderFileName=""/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="3081"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory=".\Release"
IntermediateDirectory=".\Release"
ConfigurationType="1"
UseOfMFC="2"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\include"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;ANN_NO_RANDOM"
StringPooling="TRUE"
RuntimeLibrary="2"
EnableFunctionLevelLinking="TRUE"
UsePrecompiledHeader="0"
PrecompiledHeaderThrough="stdafx.h"
PrecompiledHeaderFile=".\Release/sample.pch"
AssemblerListingLocation=".\Release/"
ObjectFile=".\Release/"
ProgramDataBaseFileName=".\Release/"
WarningLevel="3"
SuppressStartupBanner="TRUE"
CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib"
OutputFile="..\bin\ann_sample.exe"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
ProgramDatabaseFile=".\Release/sample.pdb"
SubSystem="1"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Release/sample.tlb"
HeaderFileName=""/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="3081"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
<File
RelativePath="..\..\sample\ann_sample.cpp">
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl">
</Filter>
<Filter
Name="Test Data"
Filter="">
<File
RelativePath="data_pts">
<FileConfiguration
Name="Debug|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCustomBuildTool"/>
</FileConfiguration>
</File>
<File
RelativePath="query_pts">
<FileConfiguration
Name="Debug|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCustomBuildTool"/>
</FileConfiguration>
</File>
<File
RelativePath="sample.out">
<FileConfiguration
Name="Debug|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCustomBuildTool"/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">
</Filter>
<File
RelativePath="ReadMe.txt">
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -1,220 +0,0 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="test"
SccProjectName=""
SccLocalPath=""
Keyword="MFCProj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Release|Win32"
OutputDirectory=".\Release"
IntermediateDirectory=".\Release"
ConfigurationType="1"
UseOfMFC="2"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\include"
PreprocessorDefinitions="NDEBUG;PREP;WIN32;_CONSOLE;ANN_NO_RANDOM"
StringPooling="TRUE"
RuntimeLibrary="2"
EnableFunctionLevelLinking="TRUE"
UsePrecompiledHeader="0"
PrecompiledHeaderThrough="stdafx.h"
PrecompiledHeaderFile=".\Release/test.pch"
AssemblerListingLocation=".\Release/"
ObjectFile=".\Release/"
ProgramDataBaseFileName=".\Release/"
WarningLevel="3"
SuppressStartupBanner="TRUE"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib"
OutputFile="..\bin\ann_test.exe"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
ProgramDatabaseFile=".\Release/test.pdb"
SubSystem="1"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Release/test.tlb"
HeaderFileName=""/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="3081"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\Debug"
IntermediateDirectory=".\Debug"
ConfigurationType="1"
UseOfMFC="2"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\include"
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;ANN_NO_RANDOM;ANN_PERF"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
PrecompiledHeaderThrough="stdafx.h"
PrecompiledHeaderFile=".\Debug/test.pch"
AssemblerListingLocation=".\Debug/"
ObjectFile=".\Debug/"
ProgramDataBaseFileName=".\Debug/"
WarningLevel="3"
SuppressStartupBanner="TRUE"
DebugInformationFormat="4"
CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib"
OutputFile="..\bin\ann_test.exe"
LinkIncremental="2"
SuppressStartupBanner="TRUE"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile=".\Debug/test.pdb"
SubSystem="1"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Debug/test.tlb"
HeaderFileName=""/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="3081"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
<File
RelativePath="..\..\test\ann_test.cpp">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
PreprocessorDefinitions=""
UsePrecompiledHeader="0"/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"
UsePrecompiledHeader="0"/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\test\rand.cpp">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
PreprocessorDefinitions=""
UsePrecompiledHeader="0"/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"
UsePrecompiledHeader="0"/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl">
<File
RelativePath="..\..\test\rand.h">
</File>
</Filter>
<Filter
Name="Test Data"
Filter="">
<File
RelativePath="test1.data">
</File>
<File
RelativePath="test1.in">
</File>
<File
RelativePath="test1.query">
</File>
<File
RelativePath="test2.in">
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">
</Filter>
<File
RelativePath="ReadMe.txt">
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -1,194 +0,0 @@
#-----------------------------------------------------------------------
# Makefile variations depending on different configurations
#
# ANN: Approximate Nearest Neighbors
# Version: 1.1 05/03/05
#
# (This Make-config structure is based on the one used by Mesa by Brian
# Paul. If you succeed in porting ANN to your favorite system, please
# send email to mount@cs.umd.edu, and I'll try to include it in this
# list.)
#
#----------------------------------------------------------------------
# The following configuration-dependent variables are passed to each
# the Makefile in subdirectories:
#
# ANNLIB The name of the ANN library file (usually libANN.a)
# C++ The C compiler (usually CC or g++)
# MAKELIB The command and flags to make a library file (usually
# "ar ...")
# CFLAGS Flags to C++ compiler
# RANLIB For "ranlib" = use ranlib, "true" = don't use ranlib
#----------------------------------------------------------------------
# Revision 0.1 09/06/97
# Initial release
# Revision 0.2 06/24/98
# Minor changes to fix compilation errors on SGI systems.
# Revision 1.0 04/01/05
# Modifications for alpha with cxx
# Removed CFLAGS2 options (just write your own)
# Removed -DUSING... (Compilers are pretty consistent these days)
# Added linux-g++ target
# Revision 1.1 05/03/05
# Added macosx-g++ target
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# Compilation options (add these, as desired, to the CFLAGS variable
# in the desired compilation target below). For example,
#
# "CFLAGS = -O3 -Wall -DANN_PERF"
#
# -g Debugging.
# -O? Run-time optimization.
# -Wall Be verbose about warnings.
#
# -DANN_PERF Enable performance evaluation. (This may slow execution
# slightly.)
#
# -DANN_NO_LIMITS_H
# Use this if limits.h or float.h does not exist on your
# system. (Also see include/ANN/ANN.h for other changes
# needed.)
#
# -DANN_NO_RANDOM
# Use this option if srandom()/random() are not available
# on your system. Pseudo-random number generation is used
# in the utility program test/ann_test. The combination
# srandom()/random() is considered the best pseudo-random
# number generator, but is not available on all systems.
# If they are not available on your system (for example,
# Visual C++) then srand()/rand() will be used instead by
# setting this parameter.
#
# -DWIN32
# This is used only for compilation under windows systems
# (but instead of using this, use the various .vcproj
# files in the MS_WIN32 directory).
#-----------------------------------------------------------------------------
# Linux using g++
linux-g++:
$(MAKE) targets \
"ANNLIB = libANN.a" \
"C++ = g++" \
"CFLAGS = -O3" \
"MAKELIB = ar ruv" \
"RANLIB = true"
# Mac OS X using g++
macosx-g++:
$(MAKE) targets \
"ANNLIB = libANN.a" \
"C++ = g++" \
"CFLAGS = -O3" \
"MAKELIB = libtool -static -o " \
"RANLIB = true"
# SunOS5
sunos5:
$(MAKE) targets \
"ANNLIB = libANN.a" \
"C++ = CC" \
"CFLAGS = -O" \
"MAKELIB = ar ruv" \
"RANLIB = true"
# SunOS5 with shared libraries
sunos5-sl:
$(MAKE) targets \
"ANNLIB = libANN.a" \
"C++ = CC" \
"CFLAGS = -Kpic -O" \
"MAKELIB = ld -G -o" \
"RANLIB = true"
# SunOS5 with g++
sunos5-g++:
$(MAKE) targets \
"ANNLIB = libANN.a" \
"C++ = g++" \
"CFLAGS = -O3" \
"MAKELIB = ar ruv" \
"RANLIB = true"
# SunOS5 with g++ and shared libraries
sunos5-g++-sl:
$(MAKE) targets \
"ANNLIB = libANN.so" \
"C++ = g++" \
"CFLAGS = -fpic -O3" \
"MAKELIB = ld -G -o" \
"RANLIB = true"
#-----------------------------------------------------------------------
# Used for the author's testing and debugging only
#-----------------------------------------------------------------------
# debugging version for authors
authors-debug:
$(MAKE) targets \
"ANNLIB = libANN.a" \
"C++ = g++" \
"CFLAGS = -g -DANN_PERF -Wall" \
"MAKELIB = ar ruv" \
"RANLIB = true"
# performance testing version for authors
authors-perf:
$(MAKE) targets \
"ANNLIB = libANN.a" \
"C++ = g++" \
"CFLAGS = -O3 -DANN_PERF -Wall" \
"MAKELIB = ar ruv" \
"RANLIB = true"
#-----------------------------------------------------------------------
# Some older ones that I have not tested with the latest version.
#-----------------------------------------------------------------------
sgi:
$(MAKE) targets \
"ANNLIB = libANN.a" \
"C++ = CC -ansi" \
"CFLAGS = -O2" \
"MAKELIB = ar ruv" \
"RANLIB = true"
# DEC Alpha with g++
alpha-g++:
$(MAKE) targets \
"ANNLIB = libANN.a" \
"C++ = g++" \
"CFLAGS = -O3" \
"MAKELIB = ar ruv" \
"RANLIB = ranlib"
# SunOS4
sunos4:
$(MAKE) targets \
"ANNLIB = libANN.a" \
"C++ = CC" \
"CFLAGS = -O" \
"MAKELIB = ar ruv" \
"RANLIB = ranlib"
# SunOS4 with g++
sunos4-g++:
$(MAKE) targets \
"ANNLIB = libANN.a" \
"C++ = g++" \
"CFLAGS = -O3" \
"MAKELIB = ar ruv" \
"RANLIB = ranlib"
# SunOS4 with g++ and shared libraries
sunos4-g++-sl:
$(MAKE) targets \
"ANNLIB = libANN.so" \
"C++ = g++" \
"CC = g++" \
"CFLAGS = -fPIC -O3" \
"MAKELIB = ld -assert pure-text -o" \
"RANLIB = true"

View File

@@ -1,68 +0,0 @@
ANN: Approximate Nearest Neighbors
Version: 1.1.1
Release date: Aug 4, 2006
----------------------------------------------------------------------------
Copyright (c) 1997-2005 University of Maryland and Sunil Arya and David
Mount. All Rights Reserved. See Copyright.txt and License.txt for
complete information on terms and conditions of use and distribution of
this software.
----------------------------------------------------------------------------
Authors
-------
David Mount
Dept of Computer Science
University of Maryland,
College Park, MD 20742 USA
mount@cs.umd.edu
http://www.cs.umd.edu/~mount/
Sunil Arya
Dept of Computer Science
Hong University of Science and Technology
Clearwater Bay, HONG KONG
arya@cs.ust.hk
http://www.cs.ust.hk/faculty/arya/
Introduction
------------
ANN is a library written in the C++ programming language to support both
exact and approximate nearest neighbor searching in spaces of various
dimensions. It was implemented by David M. Mount of the University of
Maryland, and Sunil Arya of the Hong Kong University of Science and
Technology. ANN (pronounced like the name ``Ann'') stands for
Approximate Nearest Neighbors. ANN is also a testbed containing
programs and procedures for generating data sets, collecting and
analyzing statistics on the performance of nearest neighbor algorithms
and data structures, and visualizing the geometric structure of these
data structures.
The ANN source code and documentation is available from the following
web page:
http://www.cs.umd.edu/~mount/ANN
For more information on ANN and its use, see the ``ANN Programming
Manual,'' which is provided with the software distribution.
----------------------------------------------------------------------------
History
Version 0.1 03/04/98
Preliminary release
Version 0.2 06/24/98
Changes for SGI compiler.
Version 1.0 04/01/05
Fixed a number of small bugs
Added dump/load operations
Added annClose to eliminate minor memory leak
Improved compatibility with current C++ compilers
Added compilation for Microsoft Visual Studio.NET
Added compilation for Linux 2.x
Version 1.1 05/03/05
Added make target for Mac OS X
Added fixed-radius range searching and counting
Added instructions on compiling/using ANN on Windows platforms
Fixed minor output bug in ann2fig
Version 1.1.1 08/04/06
Added "planted" distribution
Updated old source comments for GNU LPL.

View File

@@ -1,87 +0,0 @@
#-----------------------------------------------------------------------------
# Makefile for ann2fig
#
# ANN: Approximate Nearest Neighbors
# Version: 1.1.1 08/04/06
#-----------------------------------------------------------------------------
# Copyright (c) 1997-2005 University of Maryland and Sunil Arya and
# David Mount. All Rights Reserved.
#
# This software and related documentation is part of the Approximate
# Nearest Neighbor Library (ANN). This software is provided under
# the provisions of the Lesser GNU Public License (LGPL). See the
# file ../ReadMe.txt for further information.
#
# The University of Maryland (U.M.) and the authors make no
# representations about the suitability or fitness of this software for
# any purpose. It is provided "as is" without express or implied
# warranty.
#-----------------------------------------------------------------------------
# Revision 0.1 03/04/98
# Initial release
# Revision 1.1.1 08/04/06
# Added copyright/license
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# Basic definitions
# BASEDIR where include, src, lib, ... are
# INCDIR include directory
# LIBDIR library directory
# BINDIR bin directory
# LDFLAGS loader flags
# ANNLIB ANN library
# OTHERLIB other libraries
#-----------------------------------------------------------------------------
BASEDIR = ..
INCDIR = $(BASEDIR)/include
LIBDIR = $(BASEDIR)/lib
BINDIR = $(BASEDIR)/bin
LDFLAGS = -L$(LIBDIR)
ANNLIBS = -lANN
OTHERLIBS = -lm
#-----------------------------------------------------------------------------
# Some more definitions
# ANN2FIG name of executable
#-----------------------------------------------------------------------------
ANN2FIG = ann2fig
SOURCES = ann2fig.cpp
OBJECTS = $(SOURCES:.cpp=.o)
#-----------------------------------------------------------------------------
# Make the program
#-----------------------------------------------------------------------------
default:
@echo "Specify a target configuration"
targets: $(BINDIR)/$(ANN2FIG)
$(BINDIR)/$(ANN2FIG): $(OBJECTS)
$(C++) $(OBJECTS) -o $(ANN2FIG) $(LDFLAGS) $(ANNLIBS) $(OTHERLIBS)
mv $(ANN2FIG) $(BINDIR)
#-----------------------------------------------------------------------------
# configuration definitions
#-----------------------------------------------------------------------------
include ../Make-config
#-----------------------------------------------------------------------------
# Objects
#-----------------------------------------------------------------------------
ann2fig.o: ann2fig.cpp
$(C++) -c -I$(INCDIR) ann2fig.cpp
#-----------------------------------------------------------------------------
# Cleaning
#-----------------------------------------------------------------------------
clean:
-rm -f *.o core
realclean: clean

View File

@@ -1,586 +0,0 @@
//----------------------------------------------------------------------
// File: ann2fig.cpp
// Programmer: David Mount
// Last modified: 05/03/05
// Description: convert ann dump file to fig file
//----------------------------------------------------------------------
// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and
// David Mount. All Rights Reserved.
//
// This software and related documentation is part of the Approximate
// Nearest Neighbor Library (ANN). This software is provided under
// the provisions of the Lesser GNU Public License (LGPL). See the
// file ../ReadMe.txt for further information.
//
// The University of Maryland (U.M.) and the authors make no
// representations about the suitability or fitness of this software for
// any purpose. It is provided "as is" without express or implied
// warranty.
//----------------------------------------------------------------------
// History:
// Revision 0.1 03/04/98
// Initial release
// Revision 1.0 04/01/05
// Changed dump file suffix from .ann to .dmp.
// Revision 1.1 05/03/05
// Fixed usage output string.
//----------------------------------------------------------------------
// This program inputs an ann dump file of a search structure
// perhaps along with point coordinates, and outputs a fig (Ver 3.1)
// file (see fig2dev (1)) displaying the tree. The fig file may
// then be displayed using xfig, or converted to any of a number of
// other formats using fig2dev.
//
// If the dimension is 2 then the entire tree is display. If the
// dimension is larger than 2 then the user has the option of
// selecting which two dimensions will be displayed, and the slice
// value for each of the remaining dimensions. All leaf cells
// intersecting the slice are shown along with the points in these
// cells. See the procedure getArgs() below for the command-line
// arguments.
//----------------------------------------------------------------------
#include <cstdio> // C standard I/O
#include <fstream> // file I/O
#include <string> // string manipulation
#include <ANN/ANNx.h> // all ANN includes
using namespace std; // make std:: accessible
//----------------------------------------------------------------------
// Globals and their defaults
//----------------------------------------------------------------------
const int STRING_LEN = 500; // string lengths
const int MAX_DIM = 1000; // maximum dimension
const double DEF_SLICE_VAL = 0; // default slice value
const char FIG_HEAD[] = {"#FIG 3.1"}; // fig file header
const char DUMP_SUFFIX[] = {".dmp"}; // suffix for dump file
const char FIG_SUFFIX[] = {".fig"}; // suffix for fig file
char file_name[STRING_LEN]; // (root) file name (say xxx)
char infile_name[STRING_LEN];// input file name (xxx.dmp)
char outfile_name[STRING_LEN];// output file name (xxx.fig)
char caption[STRING_LEN]; // caption line (= command line)
ofstream ofile; // output file stream
ifstream ifile; // input file stream
int dim_x = 0; // horizontal dimension
int dim_y = 1; // vertical dimension
double slice_val[MAX_DIM]; // array of slice values
double u_per_in = 1200; // fig units per inch (version 3.1)
double in_size = 5; // size of figure (in inches)
double in_low_x = 1; // fig upper left corner (in inches)
double in_low_y = 1; // fig upper left corner (in inches)
double u_size = 6000; // size of figure (in units)
double u_low_x = 1200; // fig upper left corner (in units)
double u_low_y = 1200; // fig upper left corner (in units)
int pt_size = 10; // point size (in fig units)
int dim; // dimension
int n_pts; // number of points
ANNpointArray pts = NULL; // point array
double scale; // scale factor for transformation
double offset_x; // offsets for transformation
double offset_y;
// transformations
#define TRANS_X(p) (offset_x + scale*(p[dim_x]))
#define TRANS_Y(p) (offset_y - scale*(p[dim_y]))
//----------------------------------------------------------------------
// Error handler
//----------------------------------------------------------------------
void Error(char *msg, ANNerr level)
{
if (level == ANNabort) {
cerr << "ann2fig: ERROR------->" << msg << "<-------------ERROR\n";
exit(1);
}
else {
cerr << "ann2fig: WARNING----->" << msg << "<-------------WARNING\n";
}
}
//----------------------------------------------------------------------
// set_slice_val - set all slice values to given value
//----------------------------------------------------------------------
void set_slice_val(double val)
{
for (int i = 0; i < MAX_DIM; i++) {
slice_val[i] = val;
}
}
//----------------------------------------------------------------------
// getArgs - get input arguments
//
// Syntax:
// ann2fig [-upi scale] [-x low_x] [-y low_y]
// [-sz size] [-dx dim_x] [-dy dim_y] [-sl dim value]*
// [-ps pointsize]
// file
//
// where:
// -upi scale fig units per inch (default = 1200)
// -x low_x x and y offset of upper left corner (inches)
// -y low_y ...(default = 1)
// -sz size maximum side length of figure (in inches)
// ...(default = 5)
// -dx dim_x horizontal dimension (default = 0)
// -dy dim_y vertical dimension (default = 1)
// -sv value default slice value (default = 0)
// -sl dim value each such pair defines the value along the
// ...given dimension at which to slice. This
// ...may be supplied for all dimensions except
// ...dim_x and dim_y.
// -ps pointsize size of points in fig units (def = 10)
// file file (input=file.dmp, output=file.fig)
//
//----------------------------------------------------------------------
void getArgs(int argc, char **argv)
{
int i;
int sl_dim; // temp slice dimension
double sl_val; // temp slice value
set_slice_val(DEF_SLICE_VAL); // set initial slice-values
if (argc <= 1) {
cerr << "Syntax:\n\
ann2fig [-upi scale] [-x low_x] [-y low_y]\n\
[-sz size] [-dx dim_x] [-dy dim_y] [-sl dim value]*\n\
file\n\
\n\
where:\n\
-upi scale fig units per inch (default = 1200)\n\
-x low_x x and y offset of upper left corner (inches)\n\
-y low_y ...(default = 1)\n\
-sz size maximum side length of figure (in inches)\n\
...(default = 5)\n\
-dx dim_x horizontal dimension (default = 0)\n\
-dy dim_y vertical dimension (default = 1)\n\
-sv value default slice value (default = 0)\n\
-sl dim value each such pair defines the value along the\n\
...given dimension at which to slice. This\n\
...may be supplied for each dimension except\n\
...dim_x and dim_y.\n\
-ps pointsize size of points in fig units (def = 10)\n\
file file (input=file.dmp, output=file.fig)\n";
exit(0);
}
ANNbool fileSeen = ANNfalse; // file argument seen?
for (i = 1; i < argc; i++) {
if (!strcmp(argv[i], "-upi")) { // process -upi option
sscanf(argv[++i], "%lf", &u_per_in);
}
else if (!strcmp(argv[i], "-x")) { // process -x option
sscanf(argv[++i], "%lf", &in_low_x);
}
else if (!strcmp(argv[i], "-y")) { // process -y option
sscanf(argv[++i], "%lf", &in_low_y);
}
else if (!strcmp(argv[i], "-sz")) { // process -sz option
sscanf(argv[++i], "%lf", &in_size);
}
else if (!strcmp(argv[i], "-dx")) { // process -dx option
sscanf(argv[++i], "%d", &dim_x);
}
else if (!strcmp(argv[i], "-dy")) { // process -dy option
sscanf(argv[++i], "%d", &dim_y);
}
else if (!strcmp(argv[i], "-sv")) { // process -sv option
sscanf(argv[++i], "%lf", &sl_val);
set_slice_val(sl_val); // set slice values
}
else if (!strcmp(argv[i], "-sl")) { // process -sl option
sscanf(argv[++i], "%d", &sl_dim);
if (sl_dim < 0 || sl_dim >= MAX_DIM) {
Error("Slice dimension out of bounds", ANNabort);
}
sscanf(argv[++i], "%lf", &slice_val[sl_dim]);
}
if (!strcmp(argv[i], "-ps")) { // process -ps option
sscanf(argv[++i], "%i", &pt_size);
}
else { // must be file name
fileSeen = ANNtrue;
sscanf(argv[i], "%s", file_name);
strcpy(infile_name, file_name); // copy to input file name
strcat(infile_name, DUMP_SUFFIX);
strcpy(outfile_name, file_name); // copy to output file name
strcat(outfile_name, FIG_SUFFIX);
}
}
if (!fileSeen) { // no file seen
Error("File argument is required", ANNabort);
}
ifile.open(infile_name, ios::in); // open for reading
if (!ifile) {
Error("Cannot open input file", ANNabort);
}
ofile.open(outfile_name, ios::out); // open for writing
if (!ofile) {
Error("Cannot open output file", ANNabort);
}
u_low_x = u_per_in * in_low_x; // convert inches to fig units
u_low_y = u_per_in * in_low_y;
u_size = u_per_in * in_size;
strcpy(caption, argv[0]); // copy command line to caption
for (i = 1; i < argc; i++) {
strcat(caption, " ");
strcat(caption, argv[i]);
}
}
//----------------------------------------------------------------------
// Graphics utilities for fig output
//
// writeHeader write header for fig file
// writePoint write a point
// writeBox write a box
// writeLine write a line
//----------------------------------------------------------------------
void writeHeader()
{
ofile << FIG_HEAD << "\n" // fig file header
<< "Portrait\n"
<< "Center\n"
<< "Inches\n"
<< (int) u_per_in << " 2\n";
}
void writePoint(ANNpoint p) // write a single point
{
// filled black point object
ofile << "1 3 0 1 -1 7 0 0 0 0.000 1 0.0000 ";
int cent_x = (int) TRANS_X(p); // transform center coords
int cent_y = (int) TRANS_Y(p);
ofile << cent_x << " " << cent_y << " " // write center, radius, bounds
<< pt_size << " " << pt_size << " "
<< cent_x << " " << cent_y << " "
<< cent_x + pt_size << " " << cent_y + pt_size << "\n";
}
void writeBox(const ANNorthRect &r) // write box
{
// unfilled box object
ofile << "2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5\n";
int p0_x = (int) TRANS_X(r.lo); // transform endpoints
int p0_y = (int) TRANS_Y(r.lo);
int p1_x = (int) TRANS_X(r.hi);
int p1_y = (int) TRANS_Y(r.hi);
ofile << "\t"
<< p0_x << " " << p0_y << " " // write vertices
<< p1_x << " " << p0_y << " "
<< p1_x << " " << p1_y << " "
<< p0_x << " " << p1_y << " "
<< p0_x << " " << p0_y << "\n";
}
void writeLine(ANNpoint p0, ANNpoint p1) // write line
{
// unfilled line object
ofile << "2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2\n";
int p0_x = (int) TRANS_X(p0); // transform endpoints
int p0_y = (int) TRANS_Y(p0);
int p1_x = (int) TRANS_X(p1);
int p1_y = (int) TRANS_Y(p1);
ofile << "\t"
<< p0_x << " " << p0_y << " " // write vertices
<< p1_x << " " << p1_y << "\n";
}
void writeCaption( // write caption text
const ANNorthRect &bnd_box, // bounding box
char *caption) // caption
{
if (!strcmp(caption, "\0")) return; // null string?
int px = (int) TRANS_X(bnd_box.lo); // put .5 in. lower left
int py = (int) (TRANS_Y(bnd_box.lo) + 0.50 * u_per_in);
ofile << "4 0 -1 0 0 0 20 0.0000 4 255 2000 ";
ofile << px << " " << py << " " << caption << "\\001\n";
}
//----------------------------------------------------------------------
// overlap - test whether a box overlap slicing region
//
// The slicing region is a 2-dimensional plane in space
// which contains points (x1, x2, ..., xn) satisfying the
// n-2 linear equalities:
//
// xi == slice_val[i] for i != dim_x, dim_y
//
// This procedure returns true of the box defined by
// corner points box.lo and box.hi overlap this plane.
//----------------------------------------------------------------------
ANNbool overlap(const ANNorthRect &box)
{
for (int i = 0; i < dim; i++) {
if (i != dim_x && i != dim_y &&
(box.lo[i] > slice_val[i] || box.hi[i] < slice_val[i]))
return ANNfalse;
}
return ANNtrue;
}
//----------------------------------------------------------------------
// readTree, recReadTree - inputs tree and outputs figure
//
// readTree procedure initializes things and then calls recReadTree
// which does all the work.
//
// recReadTree reads in a node of the tree, makes any recursive
// calls as needed to input the children of this node (if internal)
// and maintains the bounding box. Note that the bounding box
// is modified within this procedure, but it is the responsibility
// of the procedure that it be restored to its original value
// on return.
//
// Recall that these are the formats. The tree is given in
// preorder.
//
// Leaf node:
// leaf <n_pts> <bkt[0]> <bkt[1]> ... <bkt[n-1]>
// Splitting nodes:
// split <cut_dim> <cut_val> <lo_bound> <hi_bound>
// Shrinking nodes:
// shrink <n_bnds>
// <cut_dim> <cut_val> <side>
// <cut_dim> <cut_val> <side>
// ... (repeated n_bnds times)
//
// On reading a leaf we determine whether we should output the
// cell's points (if dimension = 2 or this cell overlaps the
// slicing region). For splitting nodes we check whether the
// current cell overlaps the slicing plane and whether the
// cutting dimension coincides with either the x or y drawing
// dimensions. If so, we output the corresponding splitting
// segment.
//----------------------------------------------------------------------
void recReadTree(ANNorthRect &box)
{
char tag[STRING_LEN]; // tag (leaf, split, shrink)
int n_pts; // number of points in leaf
int idx; // point index
int cd; // cut dimension
ANNcoord cv; // cut value
ANNcoord lb; // low bound
ANNcoord hb; // high bound
int n_bnds; // number of bounding sides
int sd; // which side
ifile >> tag; // input node tag
if (strcmp(tag, "leaf") == 0) { // leaf node
ifile >> n_pts; // input number of points
// check for overlap
if (dim == 2 || overlap(box)) {
for (int i = 0; i < n_pts; i++) { // yes, write the points
ifile >> idx;
writePoint(pts[idx]);
}
}
else { // input but ignore points
for (int i = 0; i < n_pts; i++) {
ifile >> idx;
}
}
}
else if (strcmp(tag, "split") == 0) { // splitting node
ifile >> cd >> cv >> lb >> hb;
if (lb != box.lo[cd] || hb != box.hi[cd]) {
Error("Bounding box coordinates are fishy", ANNwarn);
}
ANNcoord lv = box.lo[cd]; // save bounds for cutting dim
ANNcoord hv = box.hi[cd];
//--------------------------------------------------------------
// The following code is rather fragile so modify at your
// own risk. We first decrease the high-end of the bounding
// box down to the cutting plane and then read the left subtree.
// Then we increase the low-end of the bounding box up to the
// cutting plane (thus collapsing the bounding box to a d-1
// dimensional hyperrectangle). Then we draw the projection of
// its diagonal if it crosses the slicing plane. This will have
// the effect of drawing its intersection on the slicing plane.
// Then we restore the high-end of the bounding box and read
// the right subtree. Finally we restore the low-end of the
// bounding box, before returning.
//--------------------------------------------------------------
box.hi[cd] = cv; // decrease high bounds
recReadTree(box); // read left subtree
// check for overlap
box.lo[cd] = cv; // increase low bounds
if (dim == 2 || overlap(box)) { // check for overlap
if (cd == dim_x || cd == dim_y) { // cut through slice plane
writeLine(box.lo, box.hi); // draw cutting line
}
}
box.hi[cd] = hv; // restore high bounds
recReadTree(box); // read right subtree
box.lo[cd] = lv; // restore low bounds
}
else if (strcmp(tag, "shrink") == 0) { // splitting node
ANNorthRect inner(dim, box); // copy bounding box
ifile >> n_bnds; // number of bounding sides
for (int i = 0; i < n_bnds; i++) {
ifile >> cd >> cv >> sd; // input bounding halfspace
ANNorthHalfSpace hs(cd, cv, sd); // create orthogonal halfspace
hs.project(inner.lo); // intersect by projecting
hs.project(inner.hi);
}
if (dim == 2 || overlap(inner)) {
writeBox(inner); // draw inner rectangle
}
recReadTree(inner); // read inner subtree
recReadTree(box); // read outer subtree
}
else {
Error("Illegal node type in dump file", ANNabort);
}
}
void readTree(ANNorthRect &bnd_box)
{
writeHeader(); // output header
writeBox(bnd_box); // draw bounding box
writeCaption(bnd_box, caption); // write caption
recReadTree(bnd_box); // do it
}
//----------------------------------------------------------------------
// readANN - read the ANN dump file
//
// This procedure reads in the dump file. See the format below.
// It first reads the header line with version number. If the
// points section is present it reads them (otherwise just leaves
// points = NULL), and then it reads the tree section. It inputs
// the bounding box and determines the parameters for transforming
// the image to figure units. It then invokes the procedure
// readTree to do all the real work.
//
// Dump File Format: <xxx> = coordinate value (ANNcoord)
//
// #ANN <version number> <comments> [END_OF_LINE]
// points <dim> <n_pts> (point coordinates: this is optional)
// 0 <xxx> <xxx> ... <xxx> (point indices and coordinates)
// 1 <xxx> <xxx> ... <xxx>
// ...
// tree <dim> <n_pts> <bkt_size>
// <xxx> <xxx> ... <xxx> (lower end of bounding box)
// <xxx> <xxx> ... <xxx> (upper end of bounding box)
// If the tree is null, then a single line "null" is
// output. Otherwise the nodes of the tree are printed
// one per line in preorder. Leaves and splitting nodes
// have the following formats:
// Leaf node:
// leaf <n_pts> <bkt[0]> <bkt[1]> ... <bkt[n-1]>
// Splitting nodes:
// split <cut_dim> <cut_val> <lo_bound> <hi_bound>
// Shrinking nodes:
// shrink <n_bnds>
// <cut_dim> <cut_val> <side>
// <cut_dim> <cut_val> <side>
// ... (repeated n_bnds times)
//
// Note: Infinite lo_ and hi_bounds are printed as the special
// values "-INF" and "+INF", respectively. We do not
// check for this, because the current version of ANN
// starts with a finite bounding box if the tree is
// nonempty.
//----------------------------------------------------------------------
void readANN()
{
int j;
char str[STRING_LEN]; // storage for string
char version[STRING_LEN]; // storage for version
int bkt_size; // bucket size
ifile >> str; // input header
if (strcmp(str, "#ANN") != 0) { // incorrect header
Error("Incorrect header for dump file", ANNabort);
}
ifile.getline(version, STRING_LEN); // get version (ignore)
ifile >> str; // get major heading
if (strcmp(str, "points") == 0) { // points section
ifile >> dim; // read dimension
ifile >> n_pts; // number of points
pts = annAllocPts(n_pts, dim); // allocate points
for (int i = 0; i < n_pts; i++) { // input point coordinates
int idx; // point index
ifile >> idx; // input point index
if (idx < 0 || idx >= n_pts) {
Error("Point index is out of range", ANNabort);
}
for (j = 0; j < dim; j++) {
ifile >> pts[idx][j]; // read point coordinates
}
}
ifile >> str; // get next major heading
}
if (strcmp(str, "tree") == 0) { // tree section
ifile >> dim; // read dimension
if (dim_x > dim || dim_y > dim) {
Error("Dimensions out of bounds", ANNabort);
}
ifile >> n_pts; // number of points
ifile >> bkt_size; // bucket size (ignored)
// read bounding box
ANNorthRect bnd_box(dim); // create bounding box
for (j = 0; j < dim; j++) {
ifile >> bnd_box.lo[j]; // read box low coordinates
}
for (j = 0; j < dim; j++) {
ifile >> bnd_box.hi[j]; // read box high coordinates
}
// compute scaling factors
double box_len_x = bnd_box.hi[dim_x] - bnd_box.lo[dim_x];
double box_len_y = bnd_box.hi[dim_y] - bnd_box.lo[dim_y];
// longer side determines scale
if (box_len_x > box_len_y) scale = u_size/box_len_x;
else scale = u_size/box_len_y;
// compute offsets
offset_x = u_low_x - scale*bnd_box.lo[dim_x];
offset_y = u_low_y + scale*bnd_box.hi[dim_y];
readTree(bnd_box); // read the tree and process
}
else if (strcmp(str, "null") == 0) return; // empty tree
else {
cerr << "Input string: " << str << "\n";
Error("Illegal ann format. Expecting section heading", ANNabort);
}
}
//----------------------------------------------------------------------
// Main program
//
// Gets the command-line arguments and invokes the main scanning
// procedure.
//----------------------------------------------------------------------
int main(int argc, char **argv)
{
getArgs(argc, argv); // get input arguments
readANN(); // read the dump file
return 0;
}

Binary file not shown.

View File

@@ -1,826 +0,0 @@
//----------------------------------------------------------------------
// File: ANN.h
// Programmer: Sunil Arya and David Mount
// Last modified: 05/03/05 (Release 1.1)
// Description: Basic include file for approximate nearest
// neighbor searching.
//----------------------------------------------------------------------
// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and
// David Mount. All Rights Reserved.
//
// This software and related documentation is part of the Approximate
// Nearest Neighbor Library (ANN). This software is provided under
// the provisions of the Lesser GNU Public License (LGPL). See the
// file ../ReadMe.txt for further information.
//
// The University of Maryland (U.M.) and the authors make no
// representations about the suitability or fitness of this software for
// any purpose. It is provided "as is" without express or implied
// warranty.
//----------------------------------------------------------------------
// History:
// Revision 0.1 03/04/98
// Initial release
// Revision 1.0 04/01/05
// Added copyright and revision information
// Added ANNcoordPrec for coordinate precision.
// Added methods theDim, nPoints, maxPoints, thePoints to ANNpointSet.
// Cleaned up C++ structure for modern compilers
// Revision 1.1 05/03/05
// Added fixed-radius k-NN searching
//----------------------------------------------------------------------
//----------------------------------------------------------------------
// ANN - approximate nearest neighbor searching
// ANN is a library for approximate nearest neighbor searching,
// based on the use of standard and priority search in kd-trees
// and balanced box-decomposition (bbd) trees. Here are some
// references to the main algorithmic techniques used here:
//
// kd-trees:
// Friedman, Bentley, and Finkel, ``An algorithm for finding
// best matches in logarithmic expected time,'' ACM
// Transactions on Mathematical Software, 3(3):209-226, 1977.
//
// Priority search in kd-trees:
// Arya and Mount, ``Algorithms for fast vector quantization,''
// Proc. of DCC '93: Data Compression Conference, eds. J. A.
// Storer and M. Cohn, IEEE Press, 1993, 381-390.
//
// Approximate nearest neighbor search and bbd-trees:
// Arya, Mount, Netanyahu, Silverman, and Wu, ``An optimal
// algorithm for approximate nearest neighbor searching,''
// 5th Ann. ACM-SIAM Symposium on Discrete Algorithms,
// 1994, 573-582.
//----------------------------------------------------------------------
#ifndef ANN_H
#define ANN_H
#ifdef WIN32
//----------------------------------------------------------------------
// For Microsoft Visual C++, externally accessible symbols must be
// explicitly indicated with DLL_API, which is somewhat like "extern."
//
// The following ifdef block is the standard way of creating macros
// which make exporting from a DLL simpler. All files within this DLL
// are compiled with the DLL_EXPORTS preprocessor symbol defined on the
// command line. In contrast, projects that use (or import) the DLL
// objects do not define the DLL_EXPORTS symbol. This way any other
// project whose source files include this file see DLL_API functions as
// being imported from a DLL, wheras this DLL sees symbols defined with
// this macro as being exported.
//----------------------------------------------------------------------
#ifdef DLL_EXPORTS
#define DLL_API __declspec(dllexport)
#else
#define DLL_API __declspec(dllimport)
#endif
//----------------------------------------------------------------------
// DLL_API is ignored for all other systems
//----------------------------------------------------------------------
#else
#define DLL_API
#endif
//----------------------------------------------------------------------
// basic includes
//----------------------------------------------------------------------
#include <cmath> // math includes
#include <iostream> // I/O streams
//----------------------------------------------------------------------
// Limits
// There are a number of places where we use the maximum double value as
// default initializers (and others may be used, depending on the
// data/distance representation). These can usually be found in limits.h
// (as LONG_MAX, INT_MAX) or in float.h (as DBL_MAX, FLT_MAX).
//
// Not all systems have these files. If you are using such a system,
// you should set the preprocessor symbol ANN_NO_LIMITS_H when
// compiling, and modify the statements below to generate the
// appropriate value. For practical purposes, this does not need to be
// the maximum double value. It is sufficient that it be at least as
// large than the maximum squared distance between between any two
// points.
//----------------------------------------------------------------------
#ifdef ANN_NO_LIMITS_H // limits.h unavailable
#include <cvalues> // replacement for limits.h
const double ANN_DBL_MAX = MAXDOUBLE; // insert maximum double
#else
#include <climits>
#include <cfloat>
const double ANN_DBL_MAX = DBL_MAX;
#endif
#define ANNversion "1.1.1" // ANN version and information
#define ANNversionCmt ""
#define ANNcopyright "David M. Mount and Sunil Arya"
#define ANNlatestRev "Aug 4, 2006"
//----------------------------------------------------------------------
// ANNbool
// This is a simple boolean type. Although ANSI C++ is supposed
// to support the type bool, some compilers do not have it.
//----------------------------------------------------------------------
enum ANNbool {ANNfalse = 0, ANNtrue = 1}; // ANN boolean type (non ANSI C++)
//----------------------------------------------------------------------
// ANNcoord, ANNdist
// ANNcoord and ANNdist are the types used for representing
// point coordinates and distances. They can be modified by the
// user, with some care. It is assumed that they are both numeric
// types, and that ANNdist is generally of an equal or higher type
// from ANNcoord. A variable of type ANNdist should be large
// enough to store the sum of squared components of a variable
// of type ANNcoord for the number of dimensions needed in the
// application. For example, the following combinations are
// legal:
//
// ANNcoord ANNdist
// --------- -------------------------------
// short short, int, long, float, double
// int int, long, float, double
// long long, float, double
// float float, double
// double double
//
// It is the user's responsibility to make sure that overflow does
// not occur in distance calculation.
//----------------------------------------------------------------------
typedef double ANNcoord; // coordinate data type
typedef double ANNdist; // distance data type
//----------------------------------------------------------------------
// ANNidx
// ANNidx is a point index. When the data structure is built, the
// points are given as an array. Nearest neighbor results are
// returned as an integer index into this array. To make it
// clearer when this is happening, we define the integer type
// ANNidx. Indexing starts from 0.
//
// For fixed-radius near neighbor searching, it is possible that
// there are not k nearest neighbors within the search radius. To
// indicate this, the algorithm returns ANN_NULL_IDX as its result.
// It should be distinguishable from any valid array index.
//----------------------------------------------------------------------
typedef int ANNidx; // point index
const ANNidx ANN_NULL_IDX = -1; // a NULL point index
//----------------------------------------------------------------------
// Infinite distance:
// The code assumes that there is an "infinite distance" which it
// uses to initialize distances before performing nearest neighbor
// searches. It should be as larger or larger than any legitimate
// nearest neighbor distance.
//
// On most systems, these should be found in the standard include
// file <limits.h> or possibly <float.h>. If you do not have these
// file, some suggested values are listed below, assuming 64-bit
// long, 32-bit int and 16-bit short.
//
// ANNdist ANN_DIST_INF Values (see <limits.h> or <float.h>)
// ------- ------------ ------------------------------------
// double DBL_MAX 1.79769313486231570e+308
// float FLT_MAX 3.40282346638528860e+38
// long LONG_MAX 0x7fffffffffffffff
// int INT_MAX 0x7fffffff
// short SHRT_MAX 0x7fff
//----------------------------------------------------------------------
const ANNdist ANN_DIST_INF = ANN_DBL_MAX;
//----------------------------------------------------------------------
// Significant digits for tree dumps:
// When floating point coordinates are used, the routine that dumps
// a tree needs to know roughly how many significant digits there
// are in a ANNcoord, so it can output points to full precision.
// This is defined to be ANNcoordPrec. On most systems these
// values can be found in the standard include files <limits.h> or
// <float.h>. For integer types, the value is essentially ignored.
//
// ANNcoord ANNcoordPrec Values (see <limits.h> or <float.h>)
// -------- ------------ ------------------------------------
// double DBL_DIG 15
// float FLT_DIG 6
// long doesn't matter 19
// int doesn't matter 10
// short doesn't matter 5
//----------------------------------------------------------------------
#ifdef DBL_DIG // number of sig. bits in ANNcoord
const int ANNcoordPrec = DBL_DIG;
#else
const int ANNcoordPrec = 15; // default precision
#endif
//----------------------------------------------------------------------
// Self match?
// In some applications, the nearest neighbor of a point is not
// allowed to be the point itself. This occurs, for example, when
// computing all nearest neighbors in a set. By setting the
// parameter ANN_ALLOW_SELF_MATCH to ANNfalse, the nearest neighbor
// is the closest point whose distance from the query point is
// strictly positive.
//----------------------------------------------------------------------
const ANNbool ANN_ALLOW_SELF_MATCH = ANNtrue;
//----------------------------------------------------------------------
// Norms and metrics:
// ANN supports any Minkowski norm for defining distance. In
// particular, for any p >= 1, the L_p Minkowski norm defines the
// length of a d-vector (v0, v1, ..., v(d-1)) to be
//
// (|v0|^p + |v1|^p + ... + |v(d-1)|^p)^(1/p),
//
// (where ^ denotes exponentiation, and |.| denotes absolute
// value). The distance between two points is defined to be the
// norm of the vector joining them. Some common distance metrics
// include
//
// Euclidean metric p = 2
// Manhattan metric p = 1
// Max metric p = infinity
//
// In the case of the max metric, the norm is computed by taking
// the maxima of the absolute values of the components. ANN is
// highly "coordinate-based" and does not support general distances
// functions (e.g. those obeying just the triangle inequality). It
// also does not support distance functions based on
// inner-products.
//
// For the purpose of computing nearest neighbors, it is not
// necessary to compute the final power (1/p). Thus the only
// component that is used by the program is |v(i)|^p.
//
// ANN parameterizes the distance computation through the following
// macros. (Macros are used rather than procedures for
// efficiency.) Recall that the distance between two points is
// given by the length of the vector joining them, and the length
// or norm of a vector v is given by formula:
//
// |v| = ROOT(POW(v0) # POW(v1) # ... # POW(v(d-1)))
//
// where ROOT, POW are unary functions and # is an associative and
// commutative binary operator mapping the following types:
//
// ** POW: ANNcoord --> ANNdist
// ** #: ANNdist x ANNdist --> ANNdist
// ** ROOT: ANNdist (>0) --> double
//
// For early termination in distance calculation (partial distance
// calculation) we assume that POW and # together are monotonically
// increasing on sequences of arguments, meaning that for all
// v0..vk and y:
//
// POW(v0) #...# POW(vk) <= (POW(v0) #...# POW(vk)) # POW(y).
//
// Incremental Distance Calculation:
// The program uses an optimized method of computing distances for
// kd-trees and bd-trees, called incremental distance calculation.
// It is used when distances are to be updated when only a single
// coordinate of a point has been changed. In order to use this,
// we assume that there is an incremental update function DIFF(x,y)
// for #, such that if:
//
// s = x0 # ... # xi # ... # xk
//
// then if s' is equal to s but with xi replaced by y, that is,
//
// s' = x0 # ... # y # ... # xk
//
// then the length of s' can be computed by:
//
// |s'| = |s| # DIFF(xi,y).
//
// Thus, if # is + then DIFF(xi,y) is (yi-x). For the L_infinity
// norm we make use of the fact that in the program this function
// is only invoked when y > xi, and hence DIFF(xi,y)=y.
//
// Finally, for approximate nearest neighbor queries we assume
// that POW and ROOT are related such that
//
// v*ROOT(x) = ROOT(POW(v)*x)
//
// Here are the values for the various Minkowski norms:
//
// L_p: p even: p odd:
// ------------------------- ------------------------
// POW(v) = v^p POW(v) = |v|^p
// ROOT(x) = x^(1/p) ROOT(x) = x^(1/p)
// # = + # = +
// DIFF(x,y) = y - x DIFF(x,y) = y - x
//
// L_inf:
// POW(v) = |v|
// ROOT(x) = x
// # = max
// DIFF(x,y) = y
//
// By default the Euclidean norm is assumed. To change the norm,
// uncomment the appropriate set of macros below.
//----------------------------------------------------------------------
//----------------------------------------------------------------------
// Use the following for the Euclidean norm
//----------------------------------------------------------------------
#define ANN_POW(v) ((v)*(v))
#define ANN_ROOT(x) sqrt(x)
#define ANN_SUM(x,y) ((x) + (y))
#define ANN_DIFF(x,y) ((y) - (x))
//----------------------------------------------------------------------
// Use the following for the L_1 (Manhattan) norm
//----------------------------------------------------------------------
// #define ANN_POW(v) fabs(v)
// #define ANN_ROOT(x) (x)
// #define ANN_SUM(x,y) ((x) + (y))
// #define ANN_DIFF(x,y) ((y) - (x))
//----------------------------------------------------------------------
// Use the following for a general L_p norm
//----------------------------------------------------------------------
// #define ANN_POW(v) pow(fabs(v),p)
// #define ANN_ROOT(x) pow(fabs(x),1/p)
// #define ANN_SUM(x,y) ((x) + (y))
// #define ANN_DIFF(x,y) ((y) - (x))
//----------------------------------------------------------------------
// Use the following for the L_infinity (Max) norm
//----------------------------------------------------------------------
// #define ANN_POW(v) fabs(v)
// #define ANN_ROOT(x) (x)
// #define ANN_SUM(x,y) ((x) > (y) ? (x) : (y))
// #define ANN_DIFF(x,y) (y)
//----------------------------------------------------------------------
// Array types
// The following array types are of basic interest. A point is
// just a dimensionless array of coordinates, a point array is a
// dimensionless array of points. A distance array is a
// dimensionless array of distances and an index array is a
// dimensionless array of point indices. The latter two are used
// when returning the results of k-nearest neighbor queries.
//----------------------------------------------------------------------
typedef ANNcoord* ANNpoint; // a point
typedef ANNpoint* ANNpointArray; // an array of points
typedef ANNdist* ANNdistArray; // an array of distances
typedef ANNidx* ANNidxArray; // an array of point indices
//----------------------------------------------------------------------
// Basic point and array utilities:
// The following procedures are useful supplements to ANN's nearest
// neighbor capabilities.
//
// annDist():
// Computes the (squared) distance between a pair of points.
// Note that this routine is not used internally by ANN for
// computing distance calculations. For reasons of efficiency
// this is done using incremental distance calculation. Thus,
// this routine cannot be modified as a method of changing the
// metric.
//
// Because points (somewhat like strings in C) are stored as
// pointers. Consequently, creating and destroying copies of
// points may require storage allocation. These procedures do
// this.
//
// annAllocPt() and annDeallocPt():
// Allocate a deallocate storage for a single point, and
// return a pointer to it. The argument to AllocPt() is
// used to initialize all components.
//
// annAllocPts() and annDeallocPts():
// Allocate and deallocate an array of points as well a
// place to store their coordinates, and initializes the
// points to point to their respective coordinates. It
// allocates point storage in a contiguous block large
// enough to store all the points. It performs no
// initialization.
//
// annCopyPt():
// Creates a copy of a given point, allocating space for
// the new point. It returns a pointer to the newly
// allocated copy.
//----------------------------------------------------------------------
DLL_API ANNdist annDist(
int dim, // dimension of space
ANNpoint p, // points
ANNpoint q);
DLL_API ANNpoint annAllocPt(
int dim, // dimension
ANNcoord c = 0); // coordinate value (all equal)
DLL_API ANNpointArray annAllocPts(
int n, // number of points
int dim); // dimension
DLL_API void annDeallocPt(
ANNpoint &p); // deallocate 1 point
DLL_API void annDeallocPts(
ANNpointArray &pa); // point array
DLL_API ANNpoint annCopyPt(
int dim, // dimension
ANNpoint source); // point to copy
//----------------------------------------------------------------------
//Overall structure: ANN supports a number of different data structures
//for approximate and exact nearest neighbor searching. These are:
//
// ANNbruteForce A simple brute-force search structure.
// ANNkd_tree A kd-tree tree search structure. ANNbd_tree
// A bd-tree tree search structure (a kd-tree with shrink
// capabilities).
//
// At a minimum, each of these data structures support k-nearest
// neighbor queries. The nearest neighbor query, annkSearch,
// returns an integer identifier and the distance to the nearest
// neighbor(s) and annRangeSearch returns the nearest points that
// lie within a given query ball.
//
// Each structure is built by invoking the appropriate constructor
// and passing it (at a minimum) the array of points, the total
// number of points and the dimension of the space. Each structure
// is also assumed to support a destructor and member functions
// that return basic information about the point set.
//
// Note that the array of points is not copied by the data
// structure (for reasons of space efficiency), and it is assumed
// to be constant throughout the lifetime of the search structure.
//
// The search algorithm, annkSearch, is given the query point (q),
// and the desired number of nearest neighbors to report (k), and
// the error bound (eps) (whose default value is 0, implying exact
// nearest neighbors). It returns two arrays which are assumed to
// contain at least k elements: one (nn_idx) contains the indices
// (within the point array) of the nearest neighbors and the other
// (dd) contains the squared distances to these nearest neighbors.
//
// The search algorithm, annkFRSearch, is a fixed-radius kNN
// search. In addition to a query point, it is given a (squared)
// radius bound. (This is done for consistency, because the search
// returns distances as squared quantities.) It does two things.
// First, it computes the k nearest neighbors within the radius
// bound, and second, it returns the total number of points lying
// within the radius bound. It is permitted to set k = 0, in which
// case it effectively answers a range counting query. If the
// error bound epsilon is positive, then the search is approximate
// in the sense that it is free to ignore any point that lies
// outside a ball of radius r/(1+epsilon), where r is the given
// (unsquared) radius bound.
//
// The generic object from which all the search structures are
// dervied is given below. It is a virtual object, and is useless
// by itself.
//----------------------------------------------------------------------
class DLL_API ANNpointSet {
public:
virtual ~ANNpointSet() {} // virtual distructor
virtual void annkSearch( // approx k near neighbor search
ANNpoint q, // query point
int k, // number of near neighbors to return
ANNidxArray nn_idx, // nearest neighbor array (modified)
ANNdistArray dd, // dist to near neighbors (modified)
double eps=0.0 // error bound
) = 0; // pure virtual (defined elsewhere)
virtual int annkFRSearch( // approx fixed-radius kNN search
ANNpoint q, // query point
ANNdist sqRad, // squared radius
int k = 0, // number of near neighbors to return
ANNidxArray nn_idx = NULL, // nearest neighbor array (modified)
ANNdistArray dd = NULL, // dist to near neighbors (modified)
double eps=0.0 // error bound
) = 0; // pure virtual (defined elsewhere)
virtual int theDim() = 0; // return dimension of space
virtual int nPoints() = 0; // return number of points
// return pointer to points
virtual ANNpointArray thePoints() = 0;
};
//----------------------------------------------------------------------
// Brute-force nearest neighbor search:
// The brute-force search structure is very simple but inefficient.
// It has been provided primarily for the sake of comparison with
// and validation of the more complex search structures.
//
// Query processing is the same as described above, but the value
// of epsilon is ignored, since all distance calculations are
// performed exactly.
//
// WARNING: This data structure is very slow, and should not be
// used unless the number of points is very small.
//
// Internal information:
// ---------------------
// This data structure bascially consists of the array of points
// (each a pointer to an array of coordinates). The search is
// performed by a simple linear scan of all the points.
//----------------------------------------------------------------------
class DLL_API ANNbruteForce: public ANNpointSet {
int dim; // dimension
int n_pts; // number of points
ANNpointArray pts; // point array
public:
ANNbruteForce( // constructor from point array
ANNpointArray pa, // point array
int n, // number of points
int dd); // dimension
~ANNbruteForce(); // destructor
void annkSearch( // approx k near neighbor search
ANNpoint q, // query point
int k, // number of near neighbors to return
ANNidxArray nn_idx, // nearest neighbor array (modified)
ANNdistArray dd, // dist to near neighbors (modified)
double eps=0.0); // error bound
int annkFRSearch( // approx fixed-radius kNN search
ANNpoint q, // query point
ANNdist sqRad, // squared radius
int k = 0, // number of near neighbors to return
ANNidxArray nn_idx = NULL, // nearest neighbor array (modified)
ANNdistArray dd = NULL, // dist to near neighbors (modified)
double eps=0.0); // error bound
int theDim() // return dimension of space
{ return dim; }
int nPoints() // return number of points
{ return n_pts; }
ANNpointArray thePoints() // return pointer to points
{ return pts; }
};
//----------------------------------------------------------------------
// kd- and bd-tree splitting and shrinking rules
// kd-trees supports a collection of different splitting rules.
// In addition to the standard kd-tree splitting rule proposed
// by Friedman, Bentley, and Finkel, we have introduced a
// number of other splitting rules, which seem to perform
// as well or better (for the distributions we have tested).
//
// The splitting methods given below allow the user to tailor
// the data structure to the particular data set. They are
// are described in greater details in the kd_split.cc source
// file. The method ANN_KD_SUGGEST is the method chosen (rather
// subjectively) by the implementors as the one giving the
// fastest performance, and is the default splitting method.
//
// As with splitting rules, there are a number of different
// shrinking rules. The shrinking rule ANN_BD_NONE does no
// shrinking (and hence produces a kd-tree tree). The rule
// ANN_BD_SUGGEST uses the implementors favorite rule.
//----------------------------------------------------------------------
enum ANNsplitRule {
ANN_KD_STD = 0, // the optimized kd-splitting rule
ANN_KD_MIDPT = 1, // midpoint split
ANN_KD_FAIR = 2, // fair split
ANN_KD_SL_MIDPT = 3, // sliding midpoint splitting method
ANN_KD_SL_FAIR = 4, // sliding fair split method
ANN_KD_SUGGEST = 5}; // the authors' suggestion for best
const int ANN_N_SPLIT_RULES = 6; // number of split rules
enum ANNshrinkRule {
ANN_BD_NONE = 0, // no shrinking at all (just kd-tree)
ANN_BD_SIMPLE = 1, // simple splitting
ANN_BD_CENTROID = 2, // centroid splitting
ANN_BD_SUGGEST = 3}; // the authors' suggested choice
const int ANN_N_SHRINK_RULES = 4; // number of shrink rules
//----------------------------------------------------------------------
// kd-tree:
// The main search data structure supported by ANN is a kd-tree.
// The main constructor is given a set of points and a choice of
// splitting method to use in building the tree.
//
// Construction:
// -------------
// The constructor is given the point array, number of points,
// dimension, bucket size (default = 1), and the splitting rule
// (default = ANN_KD_SUGGEST). The point array is not copied, and
// is assumed to be kept constant throughout the lifetime of the
// search structure. There is also a "load" constructor that
// builds a tree from a file description that was created by the
// Dump operation.
//
// Search:
// -------
// There are two search methods:
//
// Standard search (annkSearch()):
// Searches nodes in tree-traversal order, always visiting
// the closer child first.
// Priority search (annkPriSearch()):
// Searches nodes in order of increasing distance of the
// associated cell from the query point. For many
// distributions the standard search seems to work just
// fine, but priority search is safer for worst-case
// performance.
//
// Printing:
// ---------
// There are two methods provided for printing the tree. Print()
// is used to produce a "human-readable" display of the tree, with
// indenation, which is handy for debugging. Dump() produces a
// format that is suitable reading by another program. There is a
// "load" constructor, which constructs a tree which is assumed to
// have been saved by the Dump() procedure.
//
// Performance and Structure Statistics:
// -------------------------------------
// The procedure getStats() collects statistics information on the
// tree (its size, height, etc.) See ANNperf.h for information on
// the stats structure it returns.
//
// Internal information:
// ---------------------
// The data structure consists of three major chunks of storage.
// The first (implicit) storage are the points themselves (pts),
// which have been provided by the users as an argument to the
// constructor, or are allocated dynamically if the tree is built
// using the load constructor). These should not be changed during
// the lifetime of the search structure. It is the user's
// responsibility to delete these after the tree is destroyed.
//
// The second is the tree itself (which is dynamically allocated in
// the constructor) and is given as a pointer to its root node
// (root). These nodes are automatically deallocated when the tree
// is deleted. See the file src/kd_tree.h for further information
// on the structure of the tree nodes.
//
// Each leaf of the tree does not contain a pointer directly to a
// point, but rather contains a pointer to a "bucket", which is an
// array consisting of point indices. The third major chunk of
// storage is an array (pidx), which is a large array in which all
// these bucket subarrays reside. (The reason for storing them
// separately is the buckets are typically small, but of varying
// sizes. This was done to avoid fragmentation.) This array is
// also deallocated when the tree is deleted.
//
// In addition to this, the tree consists of a number of other
// pieces of information which are used in searching and for
// subsequent tree operations. These consist of the following:
//
// dim Dimension of space
// n_pts Number of points currently in the tree
// n_max Maximum number of points that are allowed
// in the tree
// bkt_size Maximum bucket size (no. of points per leaf)
// bnd_box_lo Bounding box low point
// bnd_box_hi Bounding box high point
// splitRule Splitting method used
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------
// Some types and objects used by kd-tree functions
// See src/kd_tree.h and src/kd_tree.cpp for definitions
//----------------------------------------------------------------------
class ANNkdStats; // stats on kd-tree
class ANNkd_node; // generic node in a kd-tree
typedef ANNkd_node* ANNkd_ptr; // pointer to a kd-tree node
class DLL_API ANNkd_tree: public ANNpointSet {
protected:
int dim; // dimension of space
int n_pts; // number of points in tree
int bkt_size; // bucket size
ANNpointArray pts; // the points
ANNidxArray pidx; // point indices (to pts array)
ANNkd_ptr root; // root of kd-tree
ANNpoint bnd_box_lo; // bounding box low point
ANNpoint bnd_box_hi; // bounding box high point
void SkeletonTree( // construct skeleton tree
int n, // number of points
int dd, // dimension
int bs, // bucket size
ANNpointArray pa = NULL, // point array (optional)
ANNidxArray pi = NULL); // point indices (optional)
public:
ANNkd_tree( // build skeleton tree
int n = 0, // number of points
int dd = 0, // dimension
int bs = 1); // bucket size
ANNkd_tree( // build from point array
ANNpointArray pa, // point array
int n, // number of points
int dd, // dimension
int bs = 1, // bucket size
ANNsplitRule split = ANN_KD_SUGGEST); // splitting method
ANNkd_tree( // build from dump file
std::istream& in); // input stream for dump file
~ANNkd_tree(); // tree destructor
void annkSearch( // approx k near neighbor search
ANNpoint q, // query point
int k, // number of near neighbors to return
ANNidxArray nn_idx, // nearest neighbor array (modified)
ANNdistArray dd, // dist to near neighbors (modified)
double eps=0.0); // error bound
void annkPriSearch( // priority k near neighbor search
ANNpoint q, // query point
int k, // number of near neighbors to return
ANNidxArray nn_idx, // nearest neighbor array (modified)
ANNdistArray dd, // dist to near neighbors (modified)
double eps=0.0); // error bound
int annkFRSearch( // approx fixed-radius kNN search
ANNpoint q, // the query point
ANNdist sqRad, // squared radius of query ball
int k, // number of neighbors to return
ANNidxArray nn_idx = NULL, // nearest neighbor array (modified)
ANNdistArray dd = NULL, // dist to near neighbors (modified)
double eps=0.0); // error bound
int theDim() // return dimension of space
{ return dim; }
int nPoints() // return number of points
{ return n_pts; }
ANNpointArray thePoints() // return pointer to points
{ return pts; }
virtual void Print( // print the tree (for debugging)
ANNbool with_pts, // print points as well?
std::ostream& out); // output stream
virtual void Dump( // dump entire tree
ANNbool with_pts, // print points as well?
std::ostream& out); // output stream
virtual void getStats( // compute tree statistics
ANNkdStats& st); // the statistics (modified)
};
//----------------------------------------------------------------------
// Box decomposition tree (bd-tree)
// The bd-tree is inherited from a kd-tree. The main difference
// in the bd-tree and the kd-tree is a new type of internal node
// called a shrinking node (in the kd-tree there is only one type
// of internal node, a splitting node). The shrinking node
// makes it possible to generate balanced trees in which the
// cells have bounded aspect ratio, by allowing the decomposition
// to zoom in on regions of dense point concentration. Although
// this is a nice idea in theory, few point distributions are so
// densely clustered that this is really needed.
//----------------------------------------------------------------------
class DLL_API ANNbd_tree: public ANNkd_tree {
public:
ANNbd_tree( // build skeleton tree
int n, // number of points
int dd, // dimension
int bs = 1) // bucket size
: ANNkd_tree(n, dd, bs) {} // build base kd-tree
ANNbd_tree( // build from point array
ANNpointArray pa, // point array
int n, // number of points
int dd, // dimension
int bs = 1, // bucket size
ANNsplitRule split = ANN_KD_SUGGEST, // splitting rule
ANNshrinkRule shrink = ANN_BD_SUGGEST); // shrinking rule
ANNbd_tree( // build from dump file
std::istream& in); // input stream for dump file
};
//----------------------------------------------------------------------
// Other functions
// annMaxPtsVisit Sets a limit on the maximum number of points
// to visit in the search.
// annClose Can be called when all use of ANN is finished.
// It clears up a minor memory leak.
//----------------------------------------------------------------------
DLL_API void annMaxPtsVisit( // max. pts to visit in search
int maxPts); // the limit
DLL_API void annClose(); // called to end use of ANN
#endif

View File

@@ -1,223 +0,0 @@
//----------------------------------------------------------------------
// File: ANNperf.h
// Programmer: Sunil Arya and David Mount
// Last modified: 03/04/98 (Release 0.1)
// Description: Include file for ANN performance stats
//
// Some of the code for statistics gathering has been adapted
// from the SmplStat.h package in the g++ library.
//----------------------------------------------------------------------
// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and
// David Mount. All Rights Reserved.
//
// This software and related documentation is part of the Approximate
// Nearest Neighbor Library (ANN). This software is provided under
// the provisions of the Lesser GNU Public License (LGPL). See the
// file ../ReadMe.txt for further information.
//
// The University of Maryland (U.M.) and the authors make no
// representations about the suitability or fitness of this software for
// any purpose. It is provided "as is" without express or implied
// warranty.
//----------------------------------------------------------------------
// History:
// Revision 0.1 03/04/98
// Initial release
// Revision 1.0 04/01/05
// Added ANN_ prefix to avoid name conflicts.
//----------------------------------------------------------------------
#ifndef ANNperf_H
#define ANNperf_H
//----------------------------------------------------------------------
// basic includes
//----------------------------------------------------------------------
#include <ANN/ANN.h> // basic ANN includes
//----------------------------------------------------------------------
// kd-tree stats object
// This object is used for collecting information about a kd-tree
// or bd-tree.
//----------------------------------------------------------------------
class ANNkdStats { // stats on kd-tree
public:
int dim; // dimension of space
int n_pts; // no. of points
int bkt_size; // bucket size
int n_lf; // no. of leaves (including trivial)
int n_tl; // no. of trivial leaves (no points)
int n_spl; // no. of splitting nodes
int n_shr; // no. of shrinking nodes (for bd-trees)
int depth; // depth of tree
float sum_ar; // sum of leaf aspect ratios
float avg_ar; // average leaf aspect ratio
//
// reset stats
void reset(int d=0, int n=0, int bs=0)
{
dim = d; n_pts = n; bkt_size = bs;
n_lf = n_tl = n_spl = n_shr = depth = 0;
sum_ar = avg_ar = 0.0;
}
ANNkdStats() // basic constructor
{ reset(); }
void merge(const ANNkdStats &st); // merge stats from child
};
//----------------------------------------------------------------------
// ANNsampStat
// A sample stat collects numeric (double) samples and returns some
// simple statistics. Its main functions are:
//
// reset() Reset to no samples.
// += x Include sample x.
// samples() Return number of samples.
// mean() Return mean of samples.
// stdDev() Return standard deviation
// min() Return minimum of samples.
// max() Return maximum of samples.
//----------------------------------------------------------------------
class DLL_API ANNsampStat {
int n; // number of samples
double sum; // sum
double sum2; // sum of squares
double minVal, maxVal; // min and max
public :
void reset() // reset everything
{
n = 0;
sum = sum2 = 0;
minVal = ANN_DBL_MAX;
maxVal = -ANN_DBL_MAX;
}
ANNsampStat() { reset(); } // constructor
void operator+=(double x) // add sample
{
n++; sum += x; sum2 += x*x;
if (x < minVal) minVal = x;
if (x > maxVal) maxVal = x;
}
int samples() { return n; } // number of samples
double mean() { return sum/n; } // mean
// standard deviation
double stdDev() { return sqrt((sum2 - (sum*sum)/n)/(n-1));}
double min() { return minVal; } // minimum
double max() { return maxVal; } // maximum
};
//----------------------------------------------------------------------
// Operation count updates
//----------------------------------------------------------------------
#ifdef ANN_PERF
#define ANN_FLOP(n) {ann_Nfloat_ops += (n);}
#define ANN_LEAF(n) {ann_Nvisit_lfs += (n);}
#define ANN_SPL(n) {ann_Nvisit_spl += (n);}
#define ANN_SHR(n) {ann_Nvisit_shr += (n);}
#define ANN_PTS(n) {ann_Nvisit_pts += (n);}
#define ANN_COORD(n) {ann_Ncoord_hts += (n);}
#else
#define ANN_FLOP(n)
#define ANN_LEAF(n)
#define ANN_SPL(n)
#define ANN_SHR(n)
#define ANN_PTS(n)
#define ANN_COORD(n)
#endif
//----------------------------------------------------------------------
// Performance statistics
// The following data and routines are used for computing performance
// statistics for nearest neighbor searching. Because these routines
// can slow the code down, they can be activated and deactiviated by
// defining the ANN_PERF variable, by compiling with the option:
// -DANN_PERF
//----------------------------------------------------------------------
//----------------------------------------------------------------------
// Global counters for performance measurement
//
// visit_lfs The number of leaf nodes visited in the
// tree.
//
// visit_spl The number of splitting nodes visited in the
// tree.
//
// visit_shr The number of shrinking nodes visited in the
// tree.
//
// visit_pts The number of points visited in all the
// leaf nodes visited. Equivalently, this
// is the number of points for which distance
// calculations are performed.
//
// coord_hts The number of times a coordinate of a
// data point is accessed. This is generally
// less than visit_pts*d if partial distance
// calculation is used. This count is low
// in the sense that if a coordinate is hit
// many times in the same routine we may
// count it only once.
//
// float_ops The number of floating point operations.
// This includes all operations in the heap
// as well as distance calculations to boxes.
//
// average_err The average error of each query (the
// error of the reported point to the true
// nearest neighbor). For k nearest neighbors
// the error is computed k times.
//
// rank_err The rank error of each query (the difference
// in the rank of the reported point and its
// true rank).
//
// data_pts The number of data points. This is not
// a counter, but used in stats computation.
//----------------------------------------------------------------------
extern int ann_Ndata_pts; // number of data points
extern int ann_Nvisit_lfs; // number of leaf nodes visited
extern int ann_Nvisit_spl; // number of splitting nodes visited
extern int ann_Nvisit_shr; // number of shrinking nodes visited
extern int ann_Nvisit_pts; // visited points for one query
extern int ann_Ncoord_hts; // coordinate hits for one query
extern int ann_Nfloat_ops; // floating ops for one query
extern ANNsampStat ann_visit_lfs; // stats on leaf nodes visits
extern ANNsampStat ann_visit_spl; // stats on splitting nodes visits
extern ANNsampStat ann_visit_shr; // stats on shrinking nodes visits
extern ANNsampStat ann_visit_nds; // stats on total nodes visits
extern ANNsampStat ann_visit_pts; // stats on points visited
extern ANNsampStat ann_coord_hts; // stats on coordinate hits
extern ANNsampStat ann_float_ops; // stats on floating ops
//----------------------------------------------------------------------
// The following need to be part of the public interface, because
// they are accessed outside the DLL in ann_test.cpp.
//----------------------------------------------------------------------
DLL_API extern ANNsampStat ann_average_err; // average error
DLL_API extern ANNsampStat ann_rank_err; // rank error
//----------------------------------------------------------------------
// Declaration of externally accessible routines for statistics
//----------------------------------------------------------------------
DLL_API void annResetStats(int data_size); // reset stats for a set of queries
DLL_API void annResetCounts(); // reset counts for one queries
DLL_API void annUpdateStats(); // update stats with current counts
DLL_API void annPrintStats(ANNbool validate); // print statistics for a run
#endif

View File

@@ -1,167 +0,0 @@
//----------------------------------------------------------------------
// File: ANNx.h
// Programmer: Sunil Arya and David Mount
// Last modified: 03/04/98 (Release 0.1)
// Description: Internal include file for ANN
//
// These declarations are of use in manipulating some of
// the internal data objects appearing in ANN, but are not
// needed for applications just using the nearest neighbor
// search.
//
// Typical users of ANN should not need to access this file.
//----------------------------------------------------------------------
// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and
// David Mount. All Rights Reserved.
//
// This software and related documentation is part of the Approximate
// Nearest Neighbor Library (ANN). This software is provided under
// the provisions of the Lesser GNU Public License (LGPL). See the
// file ../ReadMe.txt for further information.
//
// The University of Maryland (U.M.) and the authors make no
// representations about the suitability or fitness of this software for
// any purpose. It is provided "as is" without express or implied
// warranty.
//----------------------------------------------------------------------
// History:
// Revision 0.1 03/04/98
// Initial release
// Revision 1.0 04/01/05
// Changed LO, HI, IN, OUT to ANN_LO, ANN_HI, etc.
//----------------------------------------------------------------------
#ifndef ANNx_H
#define ANNx_H
#include <iomanip> // I/O manipulators
#include <ANN/ANN.h> // ANN includes
//----------------------------------------------------------------------
// Global constants and types
//----------------------------------------------------------------------
enum {ANN_LO=0, ANN_HI=1}; // splitting indices
enum {ANN_IN=0, ANN_OUT=1}; // shrinking indices
// what to do in case of error
enum ANNerr {ANNwarn = 0, ANNabort = 1};
//----------------------------------------------------------------------
// Maximum number of points to visit
// We have an option for terminating the search early if the
// number of points visited exceeds some threshold. If the
// threshold is 0 (its default) this means there is no limit
// and the algorithm applies its normal termination condition.
//----------------------------------------------------------------------
extern int ANNmaxPtsVisited; // maximum number of pts visited
extern int ANNptsVisited; // number of pts visited in search
//----------------------------------------------------------------------
// Global function declarations
//----------------------------------------------------------------------
void annError( // ANN error routine
char *msg, // error message
ANNerr level); // level of error
void annPrintPt( // print a point
ANNpoint pt, // the point
int dim, // the dimension
std::ostream &out); // output stream
//----------------------------------------------------------------------
// Orthogonal (axis aligned) rectangle
// Orthogonal rectangles are represented by two points, one
// for the lower left corner (min coordinates) and the other
// for the upper right corner (max coordinates).
//
// The constructor initializes from either a pair of coordinates,
// pair of points, or another rectangle. Note that all constructors
// allocate new point storage. The destructor deallocates this
// storage.
//
// BEWARE: Orthogonal rectangles should be passed ONLY BY REFERENCE.
// (C++'s default copy constructor will not allocate new point
// storage, then on return the destructor free's storage, and then
// you get into big trouble in the calling procedure.)
//----------------------------------------------------------------------
class ANNorthRect {
public:
ANNpoint lo; // rectangle lower bounds
ANNpoint hi; // rectangle upper bounds
//
ANNorthRect( // basic constructor
int dd, // dimension of space
ANNcoord l=0, // default is empty
ANNcoord h=0)
{ lo = annAllocPt(dd, l); hi = annAllocPt(dd, h); }
ANNorthRect( // (almost a) copy constructor
int dd, // dimension
const ANNorthRect &r) // rectangle to copy
{ lo = annCopyPt(dd, r.lo); hi = annCopyPt(dd, r.hi); }
ANNorthRect( // construct from points
int dd, // dimension
ANNpoint l, // low point
ANNpoint h) // hight point
{ lo = annCopyPt(dd, l); hi = annCopyPt(dd, h); }
~ANNorthRect() // destructor
{ annDeallocPt(lo); annDeallocPt(hi); }
ANNbool inside(int dim, ANNpoint p);// is point p inside rectangle?
};
void annAssignRect( // assign one rect to another
int dim, // dimension (both must be same)
ANNorthRect &dest, // destination (modified)
const ANNorthRect &source); // source
//----------------------------------------------------------------------
// Orthogonal (axis aligned) halfspace
// An orthogonal halfspace is represented by an integer cutting
// dimension cd, coordinate cutting value, cv, and side, sd, which is
// either +1 or -1. Our convention is that point q lies in the (closed)
// halfspace if (q[cd] - cv)*sd >= 0.
//----------------------------------------------------------------------
class ANNorthHalfSpace {
public:
int cd; // cutting dimension
ANNcoord cv; // cutting value
int sd; // which side
//
ANNorthHalfSpace() // default constructor
{ cd = 0; cv = 0; sd = 0; }
ANNorthHalfSpace( // basic constructor
int cdd, // dimension of space
ANNcoord cvv, // cutting value
int sdd) // side
{ cd = cdd; cv = cvv; sd = sdd; }
ANNbool in(ANNpoint q) const // is q inside halfspace?
{ return (ANNbool) ((q[cd] - cv)*sd >= 0); }
ANNbool out(ANNpoint q) const // is q outside halfspace?
{ return (ANNbool) ((q[cd] - cv)*sd < 0); }
ANNdist dist(ANNpoint q) const // (squared) distance from q
{ return (ANNdist) ANN_POW(q[cd] - cv); }
void setLowerBound(int d, ANNpoint p)// set to lower bound at p[i]
{ cd = d; cv = p[d]; sd = +1; }
void setUpperBound(int d, ANNpoint p)// set to upper bound at p[i]
{ cd = d; cv = p[d]; sd = -1; }
void project(ANNpoint &q) // project q (modified) onto halfspace
{ if (out(q)) q[cd] = cv; }
};
// array of halfspaces
typedef ANNorthHalfSpace *ANNorthHSArray;
#endif

View File

@@ -1,90 +0,0 @@
#-----------------------------------------------------------------------------
# Makefile for the sample program
#
# ANN: Approximate Nearest Neighbors
# Version: 1.1.1 08/04/06
#-----------------------------------------------------------------------------
# Copyright (c) 1997-2005 University of Maryland and Sunil Arya and
# David Mount. All Rights Reserved.
#
# This software and related documentation is part of the Approximate
# Nearest Neighbor Library (ANN). This software is provided under
# the provisions of the Lesser GNU Public License (LGPL). See the
# file ../ReadMe.txt for further information.
#
# The University of Maryland (U.M.) and the authors make no
# representations about the suitability or fitness of this software for
# any purpose. It is provided "as is" without express or implied
# warranty.
#-----------------------------------------------------------------------------
# Revision 0.1 03/04/98
# Initial release
# Revision 1.1.1 08/04/06
# Added copyright/license
#-----------------------------------------------------------------------------
# Note: For full performance measurements, it is assumed that the library
# and this program have both been compiled with the -DPERF flag. See the
# Makefile in the ANN base directory for this flag.
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# Basic definitions
# BASEDIR where include, src, lib, ... are
# INCDIR include directory
# LIBDIR library directory
# BINDIR bin directory
# LDFLAGS loader flags
# ANNLIBS libraries
#-----------------------------------------------------------------------------
BASEDIR = ..
INCDIR = $(BASEDIR)/include
LIBDIR = $(BASEDIR)/lib
BINDIR = $(BASEDIR)/bin
LDFLAGS = -L$(LIBDIR)
ANNLIBS = -lANN -lm
#-----------------------------------------------------------------------------
# Some more definitions
# ANNSAMP name of sample program
#-----------------------------------------------------------------------------
ANNSAMP = ann_sample
SAMPSOURCES = ann_sample.cpp
SAMPOBJECTS = $(SAMPSOURCES:.cpp=.o)
#-----------------------------------------------------------------------------
# Make the program
#-----------------------------------------------------------------------------
default:
@echo "Specify a target configuration"
targets: $(BINDIR)/$(ANNSAMP)
$(BINDIR)/$(ANNSAMP): $(SAMPOBJECTS) $(LIBDIR)/$(ANNLIB)
$(C++) $(SAMPOBJECTS) -o $(ANNSAMP) $(LDFLAGS) $(ANNLIBS)
mv $(ANNSAMP) $(BINDIR)
#-----------------------------------------------------------------------------
# configuration definitions
#-----------------------------------------------------------------------------
include ../Make-config
#-----------------------------------------------------------------------------
# Objects
#-----------------------------------------------------------------------------
ann_sample.o: ann_sample.cpp
$(C++) -c -I$(INCDIR) $(CFLAGS) ann_sample.cpp
#-----------------------------------------------------------------------------
# Cleaning
#-----------------------------------------------------------------------------
clean:
-rm -f *.o *.out core
realclean: clean

View File

@@ -1,198 +0,0 @@
//----------------------------------------------------------------------
// File: ann_sample.cpp
// Programmer: Sunil Arya and David Mount
// Last modified: 03/04/98 (Release 0.1)
// Description: Sample program for ANN
//----------------------------------------------------------------------
// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and
// David Mount. All Rights Reserved.
//
// This software and related documentation is part of the Approximate
// Nearest Neighbor Library (ANN). This software is provided under
// the provisions of the Lesser GNU Public License (LGPL). See the
// file ../ReadMe.txt for further information.
//
// The University of Maryland (U.M.) and the authors make no
// representations about the suitability or fitness of this software for
// any purpose. It is provided "as is" without express or implied
// warranty.
//----------------------------------------------------------------------
#include <cstdlib> // C standard library
#include <cstdio> // C I/O (for sscanf)
#include <cstring> // string manipulation
#include <fstream> // file I/O
#include <ANN/ANN.h> // ANN declarations
using namespace std; // make std:: accessible
//----------------------------------------------------------------------
// ann_sample
//
// This is a simple sample program for the ANN library. After compiling,
// it can be run as follows.
//
// ann_sample [-d dim] [-max mpts] [-nn k] [-e eps] [-df data] [-qf query]
//
// where
// dim is the dimension of the space (default = 2)
// mpts maximum number of data points (default = 1000)
// k number of nearest neighbors per query (default 1)
// eps is the error bound (default = 0.0)
// data file containing data points
// query file containing query points
//
// Results are sent to the standard output.
//----------------------------------------------------------------------
//----------------------------------------------------------------------
// Parameters that are set in getArgs()
//----------------------------------------------------------------------
void getArgs(int argc, char **argv); // get command-line arguments
int k = 1; // number of nearest neighbors
int dim = 2; // dimension
double eps = 0; // error bound
int maxPts = 1000; // maximum number of data points
istream* dataIn = NULL; // input for data points
istream* queryIn = NULL; // input for query points
bool readPt(istream &in, ANNpoint p) // read point (false on EOF)
{
for (int i = 0; i < dim; i++) {
if(!(in >> p[i])) return false;
}
return true;
}
void printPt(ostream &out, ANNpoint p) // print point
{
out << "(" << p[0];
for (int i = 1; i < dim; i++) {
out << ", " << p[i];
}
out << ")\n";
}
int main(int argc, char **argv)
{
int nPts; // actual number of data points
ANNpointArray dataPts; // data points
ANNpoint queryPt; // query point
ANNidxArray nnIdx; // near neighbor indices
ANNdistArray dists; // near neighbor distances
ANNkd_tree* kdTree; // search structure
getArgs(argc, argv); // read command-line arguments
queryPt = annAllocPt(dim); // allocate query point
dataPts = annAllocPts(maxPts, dim); // allocate data points
nnIdx = new ANNidx[k]; // allocate near neigh indices
dists = new ANNdist[k]; // allocate near neighbor dists
nPts = 0; // read data points
cout << "Data Points:\n";
while (nPts < maxPts && readPt(*dataIn, dataPts[nPts])) {
printPt(cout, dataPts[nPts]);
nPts++;
}
kdTree = new ANNkd_tree( // build search structure
dataPts, // the data points
nPts, // number of points
dim); // dimension of space
while (readPt(*queryIn, queryPt)) { // read query points
cout << "Query point: "; // echo query point
printPt(cout, queryPt);
kdTree->annkSearch( // search
queryPt, // query point
k, // number of near neighbors
nnIdx, // nearest neighbors (returned)
dists, // distance (returned)
eps); // error bound
cout << "\tNN:\tIndex\tDistance\n";
for (int i = 0; i < k; i++) { // print summary
dists[i] = sqrt(dists[i]); // unsquare distance
cout << "\t" << i << "\t" << nnIdx[i] << "\t" << dists[i] << "\n";
}
}
delete [] nnIdx; // clean things up
delete [] dists;
delete kdTree;
annClose(); // done with ANN
return EXIT_SUCCESS;
}
//----------------------------------------------------------------------
// getArgs - get command line arguments
//----------------------------------------------------------------------
void getArgs(int argc, char **argv)
{
static ifstream dataStream; // data file stream
static ifstream queryStream; // query file stream
if (argc <= 1) { // no arguments
cerr << "Usage:\n\n"
<< " ann_sample [-d dim] [-max m] [-nn k] [-e eps] [-df data]"
" [-qf query]\n\n"
<< " where:\n"
<< " dim dimension of the space (default = 2)\n"
<< " m maximum number of data points (default = 1000)\n"
<< " k number of nearest neighbors per query (default 1)\n"
<< " eps the error bound (default = 0.0)\n"
<< " data name of file containing data points\n"
<< " query name of file containing query points\n\n"
<< " Results are sent to the standard output.\n"
<< "\n"
<< " To run this demo use:\n"
<< " ann_sample -df data.pts -qf query.pts\n";
exit(0);
}
int i = 1;
while (i < argc) { // read arguments
if (!strcmp(argv[i], "-d")) { // -d option
dim = atoi(argv[++i]); // get dimension to dump
}
else if (!strcmp(argv[i], "-max")) { // -max option
maxPts = atoi(argv[++i]); // get max number of points
}
else if (!strcmp(argv[i], "-nn")) { // -nn option
k = atoi(argv[++i]); // get number of near neighbors
}
else if (!strcmp(argv[i], "-e")) { // -e option
sscanf(argv[++i], "%lf", &eps); // get error bound
}
else if (!strcmp(argv[i], "-df")) { // -df option
dataStream.open(argv[++i], ios::in);// open data file
if (!dataStream) {
cerr << "Cannot open data file\n";
exit(1);
}
dataIn = &dataStream; // make this the data stream
}
else if (!strcmp(argv[i], "-qf")) { // -qf option
queryStream.open(argv[++i], ios::in);// open query file
if (!queryStream) {
cerr << "Cannot open query file\n";
exit(1);
}
queryIn = &queryStream; // make this query stream
}
else { // illegal syntax
cerr << "Unrecognized option.\n";
exit(1);
}
i++;
}
if (dataIn == NULL || queryIn == NULL) {
cerr << "-df and -qf options must be specified\n";
exit(1);
}
}

View File

@@ -1,20 +0,0 @@
-0.297462 0.176102
0.565538 -0.361496
0.909313 -0.182785
0.920712 0.478408
0.167682 0.0499836
0.305223 -0.0805835
0.114973 0.882453
0.742916 0.16376
0.0724605 -0.826775
0.690960 -0.559284
0.188485 -0.643934
0.749427 -0.942415
-0.970662 -0.223466
0.916110 0.879597
0.927417 -0.382593
-0.711327 0.278713
-0.519172 0.986146
0.135338 0.924588
-0.0837537 0.61687
0.0520465 0.896306

View File

@@ -1,10 +0,0 @@
0.0902484 -0.207129
-0.419567 0.485743
0.826225 -0.30962
0.694758 0.987088
-0.410807 -0.465182
-0.836501 0.490184
0.588289 0.656408
0.325807 0.38721
-0.532226 -0.727036
-0.52506 -0.853508

View File

@@ -1,51 +0,0 @@
Data Points:
(-0.297462, 0.176102)
(0.565538, -0.361496)
(0.909313, -0.182785)
(0.920712, 0.478408)
(0.167682, 0.0499836)
(0.305223, -0.0805835)
(0.114973, 0.882453)
(0.742916, 0.16376)
(0.0724605, -0.826775)
(0.69096, -0.559284)
(0.188485, -0.643934)
(0.749427, -0.942415)
(-0.970662, -0.223466)
(0.91611, 0.879597)
(0.927417, -0.382593)
(-0.711327, 0.278713)
(-0.519172, 0.986146)
(0.135338, 0.924588)
(-0.0837537, 0.61687)
(0.0520465, 0.896306)
Query point: (0.0902484, -0.207129)
NN: Index Distance
0 5 0.249455
Query point: (-0.419567, 0.485743)
NN: Index Distance
0 0 0.332847
Query point: (0.826225, -0.30962)
NN: Index Distance
0 14 0.124759
Query point: (0.694758, 0.987088)
NN: Index Distance
0 13 0.246071
Query point: (-0.410807, -0.465182)
NN: Index Distance
0 8 0.60357
Query point: (-0.836501, 0.490184)
NN: Index Distance
0 15 0.245741
Query point: (0.588289, 0.656408)
NN: Index Distance
0 3 0.37708
Query point: (0.325807, 0.38721)
NN: Index Distance
0 4 0.372458
Query point: (-0.532226, -0.727036)
NN: Index Distance
0 8 0.612857
Query point: (-0.52506, -0.853508)
NN: Index Distance
0 8 0.598118

View File

@@ -1,199 +0,0 @@
//----------------------------------------------------------------------
// File: ANN.cpp
// Programmer: Sunil Arya and David Mount
// Description: Methods for ANN.h and ANNx.h
// Last modified: 01/04/05 (Version 1.0)
//----------------------------------------------------------------------
// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and
// David Mount. All Rights Reserved.
//
// This software and related documentation is part of the Approximate
// Nearest Neighbor Library (ANN). This software is provided under
// the provisions of the Lesser GNU Public License (LGPL). See the
// file ../ReadMe.txt for further information.
//
// The University of Maryland (U.M.) and the authors make no
// representations about the suitability or fitness of this software for
// any purpose. It is provided "as is" without express or implied
// warranty.
//----------------------------------------------------------------------
// History:
// Revision 0.1 03/04/98
// Initial release
// Revision 1.0 04/01/05
// Added performance counting to annDist()
//----------------------------------------------------------------------
#include <ANN/ANNx.h> // all ANN includes
#include <ANN/ANNperf.h> // ANN performance
#include <cstdlib>
using namespace std; // make std:: accessible
//----------------------------------------------------------------------
// Point methods
//----------------------------------------------------------------------
//----------------------------------------------------------------------
// Distance utility.
// (Note: In the nearest neighbor search, most distances are
// computed using partial distance calculations, not this
// procedure.)
//----------------------------------------------------------------------
ANNdist annDist( // interpoint squared distance
int dim,
ANNpoint p,
ANNpoint q)
{
register int d;
register ANNcoord diff;
register ANNcoord dist;
dist = 0;
for (d = 0; d < dim; d++) {
diff = p[d] - q[d];
dist = ANN_SUM(dist, ANN_POW(diff));
}
ANN_FLOP(3*dim) // performance counts
ANN_PTS(1)
ANN_COORD(dim)
return dist;
}
//----------------------------------------------------------------------
// annPrintPoint() prints a point to a given output stream.
//----------------------------------------------------------------------
void annPrintPt( // print a point
ANNpoint pt, // the point
int dim, // the dimension
std::ostream &out) // output stream
{
for (int j = 0; j < dim; j++) {
out << pt[j];
if (j < dim-1) out << " ";
}
}
//----------------------------------------------------------------------
// Point allocation/deallocation:
//
// Because points (somewhat like strings in C) are stored
// as pointers. Consequently, creating and destroying
// copies of points may require storage allocation. These
// procedures do this.
//
// annAllocPt() and annDeallocPt() allocate a deallocate
// storage for a single point, and return a pointer to it.
//
// annAllocPts() allocates an array of points as well a place
// to store their coordinates, and initializes the points to
// point to their respective coordinates. It allocates point
// storage in a contiguous block large enough to store all the
// points. It performs no initialization.
//
// annDeallocPts() should only be used on point arrays allocated
// by annAllocPts since it assumes that points are allocated in
// a block.
//
// annCopyPt() copies a point taking care to allocate storage
// for the new point.
//
// annAssignRect() assigns the coordinates of one rectangle to
// another. The two rectangles must have the same dimension
// (and it is not possible to test this here).
//----------------------------------------------------------------------
ANNpoint annAllocPt(int dim, ANNcoord c) // allocate 1 point
{
ANNpoint p = new ANNcoord[dim];
for (int i = 0; i < dim; i++) p[i] = c;
return p;
}
ANNpointArray annAllocPts(int n, int dim) // allocate n pts in dim
{
ANNpointArray pa = new ANNpoint[n]; // allocate points
ANNpoint p = new ANNcoord[n*dim]; // allocate space for coords
for (int i = 0; i < n; i++) {
pa[i] = &(p[i*dim]);
}
return pa;
}
void annDeallocPt(ANNpoint &p) // deallocate 1 point
{
delete [] p;
p = NULL;
}
void annDeallocPts(ANNpointArray &pa) // deallocate points
{
delete [] pa[0]; // dealloc coordinate storage
delete [] pa; // dealloc points
pa = NULL;
}
ANNpoint annCopyPt(int dim, ANNpoint source) // copy point
{
ANNpoint p = new ANNcoord[dim];
for (int i = 0; i < dim; i++) p[i] = source[i];
return p;
}
// assign one rect to another
void annAssignRect(int dim, ANNorthRect &dest, const ANNorthRect &source)
{
for (int i = 0; i < dim; i++) {
dest.lo[i] = source.lo[i];
dest.hi[i] = source.hi[i];
}
}
// is point inside rectangle?
ANNbool ANNorthRect::inside(int dim, ANNpoint p)
{
for (int i = 0; i < dim; i++) {
if (p[i] < lo[i] || p[i] > hi[i]) return ANNfalse;
}
return ANNtrue;
}
//----------------------------------------------------------------------
// Error handler
//----------------------------------------------------------------------
void annError(char *msg, ANNerr level)
{
if (level == ANNabort) {
cerr << "ANN: ERROR------->" << msg << "<-------------ERROR\n";
exit(1);
}
else {
cerr << "ANN: WARNING----->" << msg << "<-------------WARNING\n";
}
}
//----------------------------------------------------------------------
// Limit on number of points visited
// We have an option for terminating the search early if the
// number of points visited exceeds some threshold. If the
// threshold is 0 (its default) this means there is no limit
// and the algorithm applies its normal termination condition.
// This is for applications where there are real time constraints
// on the running time of the algorithm.
//----------------------------------------------------------------------
int ANNmaxPtsVisited = 0; // maximum number of pts visited
int ANNptsVisited; // number of pts visited in search
//----------------------------------------------------------------------
// Global function declarations
//----------------------------------------------------------------------
void annMaxPtsVisit( // set limit on max. pts to visit in search
int maxPts) // the limit
{
ANNmaxPtsVisited = maxPts;
}

View File

@@ -1,29 +0,0 @@
add_definitions(-D_USRDLL -DDLL_EXPORTS -DANN_PERF -DANN_NO_RANDOM)
include_directories(../include)
set(ANN_SRCS
ANN.cpp brute.cpp kd_tree.cpp kd_util.cpp kd_split.cpp
kd_dump.cpp kd_search.cpp kd_pr_search.cpp kd_fix_rad_search.cpp
bd_tree.cpp bd_search.cpp bd_pr_search.cpp bd_fix_rad_search.cpp
perf.cpp bd_tree.h kd_tree.h kd_split.h kd_util.h kd_search.h
kd_pr_search.h kd_fix_rad_search.h pr_queue.h pr_queue_k.h
../include/ANN/ANN.h ../include/ANN/ANNperf.h ../include/ANN/ANNx.h
)
if(WIN32)
set(ANN_LIBS
debug MSVCRTD.LIB
debug MSVCPRTD.LIB
optimized MSVCRT.LIB
optimized MSVCPRT.LIB
Rpcrt4.lib
)
endif(WIN32)
set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/src/Main)
add_library(ANN SHARED ${ANN_SRCS})
target_link_libraries(ANN ${ANN_LIBS})
SET_BIN_DIR(ANN ANN)

View File

@@ -1,61 +0,0 @@
//----------------------------------------------------------------------
// File: bd_fix_rad_search.cpp
// Programmer: David Mount
// Description: Standard bd-tree search
// Last modified: 05/03/05 (Version 1.1)
//----------------------------------------------------------------------
// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and
// David Mount. All Rights Reserved.
//
// This software and related documentation is part of the Approximate
// Nearest Neighbor Library (ANN). This software is provided under
// the provisions of the Lesser GNU Public License (LGPL). See the
// file ../ReadMe.txt for further information.
//
// The University of Maryland (U.M.) and the authors make no
// representations about the suitability or fitness of this software for
// any purpose. It is provided "as is" without express or implied
// warranty.
//----------------------------------------------------------------------
// History:
// Revision 1.1 05/03/05
// Initial release
//----------------------------------------------------------------------
#include "bd_tree.h" // bd-tree declarations
#include "kd_fix_rad_search.h" // kd-tree FR search declarations
//----------------------------------------------------------------------
// Approximate searching for bd-trees.
// See the file kd_FR_search.cpp for general information on the
// approximate nearest neighbor search algorithm. Here we
// include the extensions for shrinking nodes.
//----------------------------------------------------------------------
//----------------------------------------------------------------------
// bd_shrink::ann_FR_search - search a shrinking node
//----------------------------------------------------------------------
void ANNbd_shrink::ann_FR_search(ANNdist box_dist)
{
// check dist calc term cond.
if (ANNmaxPtsVisited != 0 && ANNptsVisited > ANNmaxPtsVisited) return;
ANNdist inner_dist = 0; // distance to inner box
for (int i = 0; i < n_bnds; i++) { // is query point in the box?
if (bnds[i].out(ANNkdFRQ)) { // outside this bounding side?
// add to inner distance
inner_dist = (ANNdist) ANN_SUM(inner_dist, bnds[i].dist(ANNkdFRQ));
}
}
if (inner_dist <= box_dist) { // if inner box is closer
child[ANN_IN]->ann_FR_search(inner_dist);// search inner child first
child[ANN_OUT]->ann_FR_search(box_dist);// ...then outer child
}
else { // if outer box is closer
child[ANN_OUT]->ann_FR_search(box_dist);// search outer child first
child[ANN_IN]->ann_FR_search(inner_dist);// ...then outer child
}
ANN_FLOP(3*n_bnds) // increment floating ops
ANN_SHR(1) // one more shrinking node
}

View File

@@ -1,62 +0,0 @@
//----------------------------------------------------------------------
// File: bd_pr_search.cpp
// Programmer: David Mount
// Description: Priority search for bd-trees
// Last modified: 01/04/05 (Version 1.0)
//----------------------------------------------------------------------
// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and
// David Mount. All Rights Reserved.
//
// This software and related documentation is part of the Approximate
// Nearest Neighbor Library (ANN). This software is provided under
// the provisions of the Lesser GNU Public License (LGPL). See the
// file ../ReadMe.txt for further information.
//
// The University of Maryland (U.M.) and the authors make no
// representations about the suitability or fitness of this software for
// any purpose. It is provided "as is" without express or implied
// warranty.
//----------------------------------------------------------------------
//History:
// Revision 0.1 03/04/98
// Initial release
//----------------------------------------------------------------------
#include "bd_tree.h" // bd-tree declarations
#include "kd_pr_search.h" // kd priority search declarations
//----------------------------------------------------------------------
// Approximate priority searching for bd-trees.
// See the file kd_pr_search.cc for general information on the
// approximate nearest neighbor priority search algorithm. Here
// we include the extensions for shrinking nodes.
//----------------------------------------------------------------------
//----------------------------------------------------------------------
// bd_shrink::ann_search - search a shrinking node
//----------------------------------------------------------------------
void ANNbd_shrink::ann_pri_search(ANNdist box_dist)
{
ANNdist inner_dist = 0; // distance to inner box
for (int i = 0; i < n_bnds; i++) { // is query point in the box?
if (bnds[i].out(ANNprQ)) { // outside this bounding side?
// add to inner distance
inner_dist = (ANNdist) ANN_SUM(inner_dist, bnds[i].dist(ANNprQ));
}
}
if (inner_dist <= box_dist) { // if inner box is closer
if (child[ANN_OUT] != KD_TRIVIAL) // enqueue outer if not trivial
ANNprBoxPQ->insert(box_dist,child[ANN_OUT]);
// continue with inner child
child[ANN_IN]->ann_pri_search(inner_dist);
}
else { // if outer box is closer
if (child[ANN_IN] != KD_TRIVIAL) // enqueue inner if not trivial
ANNprBoxPQ->insert(inner_dist,child[ANN_IN]);
// continue with outer child
child[ANN_OUT]->ann_pri_search(box_dist);
}
ANN_FLOP(3*n_bnds) // increment floating ops
ANN_SHR(1) // one more shrinking node
}

View File

@@ -1,61 +0,0 @@
//----------------------------------------------------------------------
// File: bd_search.cpp
// Programmer: David Mount
// Description: Standard bd-tree search
// Last modified: 01/04/05 (Version 1.0)
//----------------------------------------------------------------------
// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and
// David Mount. All Rights Reserved.
//
// This software and related documentation is part of the Approximate
// Nearest Neighbor Library (ANN). This software is provided under
// the provisions of the Lesser GNU Public License (LGPL). See the
// file ../ReadMe.txt for further information.
//
// The University of Maryland (U.M.) and the authors make no
// representations about the suitability or fitness of this software for
// any purpose. It is provided "as is" without express or implied
// warranty.
//----------------------------------------------------------------------
// History:
// Revision 0.1 03/04/98
// Initial release
//----------------------------------------------------------------------
#include "bd_tree.h" // bd-tree declarations
#include "kd_search.h" // kd-tree search declarations
//----------------------------------------------------------------------
// Approximate searching for bd-trees.
// See the file kd_search.cpp for general information on the
// approximate nearest neighbor search algorithm. Here we
// include the extensions for shrinking nodes.
//----------------------------------------------------------------------
//----------------------------------------------------------------------
// bd_shrink::ann_search - search a shrinking node
//----------------------------------------------------------------------
void ANNbd_shrink::ann_search(ANNdist box_dist)
{
// check dist calc term cond.
if (ANNmaxPtsVisited != 0 && ANNptsVisited > ANNmaxPtsVisited) return;
ANNdist inner_dist = 0; // distance to inner box
for (int i = 0; i < n_bnds; i++) { // is query point in the box?
if (bnds[i].out(ANNkdQ)) { // outside this bounding side?
// add to inner distance
inner_dist = (ANNdist) ANN_SUM(inner_dist, bnds[i].dist(ANNkdQ));
}
}
if (inner_dist <= box_dist) { // if inner box is closer
child[ANN_IN]->ann_search(inner_dist); // search inner child first
child[ANN_OUT]->ann_search(box_dist); // ...then outer child
}
else { // if outer box is closer
child[ANN_OUT]->ann_search(box_dist); // search outer child first
child[ANN_IN]->ann_search(inner_dist); // ...then outer child
}
ANN_FLOP(3*n_bnds) // increment floating ops
ANN_SHR(1) // one more shrinking node
}

View File

@@ -1,417 +0,0 @@
//----------------------------------------------------------------------
// File: bd_tree.cpp
// Programmer: David Mount
// Description: Basic methods for bd-trees.
// Last modified: 01/04/05 (Version 1.0)
//----------------------------------------------------------------------
// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and
// David Mount. All Rights Reserved.
//
// This software and related documentation is part of the Approximate
// Nearest Neighbor Library (ANN). This software is provided under
// the provisions of the Lesser GNU Public License (LGPL). See the
// file ../ReadMe.txt for further information.
//
// The University of Maryland (U.M.) and the authors make no
// representations about the suitability or fitness of this software for
// any purpose. It is provided "as is" without express or implied
// warranty.
//----------------------------------------------------------------------
// History:
// Revision 0.1 03/04/98
// Initial release
// Revision l.0 04/01/05
// Fixed centroid shrink threshold condition to depend on the
// dimension.
// Moved dump routine to kd_dump.cpp.
//----------------------------------------------------------------------
#include "bd_tree.h" // bd-tree declarations
#include "kd_util.h" // kd-tree utilities
#include "kd_split.h" // kd-tree splitting rules
#include <ANN/ANNperf.h> // performance evaluation
//----------------------------------------------------------------------
// Printing a bd-tree
// These routines print a bd-tree. See the analogous procedure
// in kd_tree.cpp for more information.
//----------------------------------------------------------------------
void ANNbd_shrink::print( // print shrinking node
int level, // depth of node in tree
ostream &out) // output stream
{
child[ANN_OUT]->print(level+1, out); // print out-child
out << " ";
for (int i = 0; i < level; i++) // print indentation
out << "..";
out << "Shrink";
for (int j = 0; j < n_bnds; j++) { // print sides, 2 per line
if (j % 2 == 0) {
out << "\n"; // newline and indentation
for (int i = 0; i < level+2; i++) out << " ";
}
out << " ([" << bnds[j].cd << "]"
<< (bnds[j].sd > 0 ? ">=" : "< ")
<< bnds[j].cv << ")";
}
out << "\n";
child[ANN_IN]->print(level+1, out); // print in-child
}
//----------------------------------------------------------------------
// kd_tree statistics utility (for performance evaluation)
// This routine computes various statistics information for
// shrinking nodes. See file kd_tree.cpp for more information.
//----------------------------------------------------------------------
void ANNbd_shrink::getStats( // get subtree statistics
int dim, // dimension of space
ANNkdStats &st, // stats (modified)
ANNorthRect &bnd_box) // bounding box
{
ANNkdStats ch_stats; // stats for children
ANNorthRect inner_box(dim); // inner box of shrink
annBnds2Box(bnd_box, // enclosing box
dim, // dimension
n_bnds, // number of bounds
bnds, // bounds array
inner_box); // inner box (modified)
// get stats for inner child
ch_stats.reset(); // reset
child[ANN_IN]->getStats(dim, ch_stats, inner_box);
st.merge(ch_stats); // merge them
// get stats for outer child
ch_stats.reset(); // reset
child[ANN_OUT]->getStats(dim, ch_stats, bnd_box);
st.merge(ch_stats); // merge them
st.depth++; // increment depth
st.n_shr++; // increment number of shrinks
}
//----------------------------------------------------------------------
// bd-tree constructor
// This is the main constructor for bd-trees given a set of points.
// It first builds a skeleton kd-tree as a basis, then computes the
// bounding box of the data points, and then invokes rbd_tree() to
// actually build the tree, passing it the appropriate splitting
// and shrinking information.
//----------------------------------------------------------------------
ANNkd_ptr rbd_tree( // recursive construction of bd-tree
ANNpointArray pa, // point array
ANNidxArray pidx, // point indices to store in subtree
int n, // number of points
int dim, // dimension of space
int bsp, // bucket space
ANNorthRect &bnd_box, // bounding box for current node
ANNkd_splitter splitter, // splitting routine
ANNshrinkRule shrink); // shrinking rule
ANNbd_tree::ANNbd_tree( // construct from point array
ANNpointArray pa, // point array (with at least n pts)
int n, // number of points
int dd, // dimension
int bs, // bucket size
ANNsplitRule split, // splitting rule
ANNshrinkRule shrink) // shrinking rule
: ANNkd_tree(n, dd, bs) // build skeleton base tree
{
pts = pa; // where the points are
if (n == 0) return; // no points--no sweat
ANNorthRect bnd_box(dd); // bounding box for points
// construct bounding rectangle
annEnclRect(pa, pidx, n, dd, bnd_box);
// copy to tree structure
bnd_box_lo = annCopyPt(dd, bnd_box.lo);
bnd_box_hi = annCopyPt(dd, bnd_box.hi);
switch (split) { // build by rule
case ANN_KD_STD: // standard kd-splitting rule
root = rbd_tree(pa, pidx, n, dd, bs, bnd_box, kd_split, shrink);
break;
case ANN_KD_MIDPT: // midpoint split
root = rbd_tree(pa, pidx, n, dd, bs, bnd_box, midpt_split, shrink);
break;
case ANN_KD_SUGGEST: // best (in our opinion)
case ANN_KD_SL_MIDPT: // sliding midpoint split
root = rbd_tree(pa, pidx, n, dd, bs, bnd_box, sl_midpt_split, shrink);
break;
case ANN_KD_FAIR: // fair split
root = rbd_tree(pa, pidx, n, dd, bs, bnd_box, fair_split, shrink);
break;
case ANN_KD_SL_FAIR: // sliding fair split
root = rbd_tree(pa, pidx, n, dd, bs,
bnd_box, sl_fair_split, shrink);
break;
default:
annError("Illegal splitting method", ANNabort);
}
}
//----------------------------------------------------------------------
// Shrinking rules
//----------------------------------------------------------------------
enum ANNdecomp {SPLIT, SHRINK}; // decomposition methods
//----------------------------------------------------------------------
// trySimpleShrink - Attempt a simple shrink
//
// We compute the tight bounding box of the points, and compute
// the 2*dim ``gaps'' between the sides of the tight box and the
// bounding box. If any of the gaps is large enough relative to
// the longest side of the tight bounding box, then we shrink
// all sides whose gaps are large enough. (The reason for
// comparing against the tight bounding box, is that after
// shrinking the longest box size will decrease, and if we use
// the standard bounding box, we may decide to shrink twice in
// a row. Since the tight box is fixed, we cannot shrink twice
// consecutively.)
//----------------------------------------------------------------------
const float BD_GAP_THRESH = 0.5; // gap threshold (must be < 1)
const int BD_CT_THRESH = 2; // min number of shrink sides
ANNdecomp trySimpleShrink( // try a simple shrink
ANNpointArray pa, // point array
ANNidxArray pidx, // point indices to store in subtree
int n, // number of points
int dim, // dimension of space
const ANNorthRect &bnd_box, // current bounding box
ANNorthRect &inner_box) // inner box if shrinking (returned)
{
int i;
// compute tight bounding box
annEnclRect(pa, pidx, n, dim, inner_box);
ANNcoord max_length = 0; // find longest box side
for (i = 0; i < dim; i++) {
ANNcoord length = inner_box.hi[i] - inner_box.lo[i];
if (length > max_length) {
max_length = length;
}
}
int shrink_ct = 0; // number of sides we shrunk
for (i = 0; i < dim; i++) { // select which sides to shrink
// gap between boxes
ANNcoord gap_hi = bnd_box.hi[i] - inner_box.hi[i];
// big enough gap to shrink?
if (gap_hi < max_length*BD_GAP_THRESH)
inner_box.hi[i] = bnd_box.hi[i]; // no - expand
else shrink_ct++; // yes - shrink this side
// repeat for high side
ANNcoord gap_lo = inner_box.lo[i] - bnd_box.lo[i];
if (gap_lo < max_length*BD_GAP_THRESH)
inner_box.lo[i] = bnd_box.lo[i]; // no - expand
else shrink_ct++; // yes - shrink this side
}
if (shrink_ct >= BD_CT_THRESH) // did we shrink enough sides?
return SHRINK;
else return SPLIT;
}
//----------------------------------------------------------------------
// tryCentroidShrink - Attempt a centroid shrink
//
// We repeatedly apply the splitting rule, always to the larger subset
// of points, until the number of points decreases by the constant
// fraction BD_FRACTION. If this takes more than dim*BD_MAX_SPLIT_FAC
// splits for this to happen, then we shrink to the final inner box
// Otherwise we split.
//----------------------------------------------------------------------
const float BD_MAX_SPLIT_FAC = 0.5; // maximum number of splits allowed
const float BD_FRACTION = 0.5; // ...to reduce points by this fraction
// ...This must be < 1.
ANNdecomp tryCentroidShrink( // try a centroid shrink
ANNpointArray pa, // point array
ANNidxArray pidx, // point indices to store in subtree
int n, // number of points
int dim, // dimension of space
const ANNorthRect &bnd_box, // current bounding box
ANNkd_splitter splitter, // splitting procedure
ANNorthRect &inner_box) // inner box if shrinking (returned)
{
int n_sub = n; // number of points in subset
int n_goal = (int) (n*BD_FRACTION); // number of point in goal
int n_splits = 0; // number of splits needed
// initialize inner box to bounding box
annAssignRect(dim, inner_box, bnd_box);
while (n_sub > n_goal) { // keep splitting until goal reached
int cd; // cut dim from splitter (ignored)
ANNcoord cv; // cut value from splitter (ignored)
int n_lo; // number of points on low side
// invoke splitting procedure
(*splitter)(pa, pidx, inner_box, n_sub, dim, cd, cv, n_lo);
n_splits++; // increment split count
if (n_lo >= n_sub/2) { // most points on low side
inner_box.hi[cd] = cv; // collapse high side
n_sub = n_lo; // recurse on lower points
}
else { // most points on high side
inner_box.lo[cd] = cv; // collapse low side
pidx += n_lo; // recurse on higher points
n_sub -= n_lo;
}
}
if (n_splits > dim*BD_MAX_SPLIT_FAC)// took too many splits
return SHRINK; // shrink to final subset
else
return SPLIT;
}
//----------------------------------------------------------------------
// selectDecomp - select which decomposition to use
//----------------------------------------------------------------------
ANNdecomp selectDecomp( // select decomposition method
ANNpointArray pa, // point array
ANNidxArray pidx, // point indices to store in subtree
int n, // number of points
int dim, // dimension of space
const ANNorthRect &bnd_box, // current bounding box
ANNkd_splitter splitter, // splitting procedure
ANNshrinkRule shrink, // shrinking rule
ANNorthRect &inner_box) // inner box if shrinking (returned)
{
ANNdecomp decomp = SPLIT; // decomposition
switch (shrink) { // check shrinking rule
case ANN_BD_NONE: // no shrinking allowed
decomp = SPLIT;
break;
case ANN_BD_SUGGEST: // author's suggestion
case ANN_BD_SIMPLE: // simple shrink
decomp = trySimpleShrink(
pa, pidx, // points and indices
n, dim, // number of points and dimension
bnd_box, // current bounding box
inner_box); // inner box if shrinking (returned)
break;
case ANN_BD_CENTROID: // centroid shrink
decomp = tryCentroidShrink(
pa, pidx, // points and indices
n, dim, // number of points and dimension
bnd_box, // current bounding box
splitter, // splitting procedure
inner_box); // inner box if shrinking (returned)
break;
default:
annError("Illegal shrinking rule", ANNabort);
}
return decomp;
}
//----------------------------------------------------------------------
// rbd_tree - recursive procedure to build a bd-tree
//
// This is analogous to rkd_tree, but for bd-trees. See the
// procedure rkd_tree() in kd_split.cpp for more information.
//
// If the number of points falls below the bucket size, then a
// leaf node is created for the points. Otherwise we invoke the
// procedure selectDecomp() which determines whether we are to
// split or shrink. If splitting is chosen, then we essentially
// do exactly as rkd_tree() would, and invoke the specified
// splitting procedure to the points. Otherwise, the selection
// procedure returns a bounding box, from which we extract the
// appropriate shrinking bounds, and create a shrinking node.
// Finally the points are subdivided, and the procedure is
// invoked recursively on the two subsets to form the children.
//----------------------------------------------------------------------
ANNkd_ptr rbd_tree( // recursive construction of bd-tree
ANNpointArray pa, // point array
ANNidxArray pidx, // point indices to store in subtree
int n, // number of points
int dim, // dimension of space
int bsp, // bucket space
ANNorthRect &bnd_box, // bounding box for current node
ANNkd_splitter splitter, // splitting routine
ANNshrinkRule shrink) // shrinking rule
{
ANNdecomp decomp; // decomposition method
ANNorthRect inner_box(dim); // inner box (if shrinking)
if (n <= bsp) { // n small, make a leaf node
if (n == 0) // empty leaf node
return KD_TRIVIAL; // return (canonical) empty leaf
else // construct the node and return
return new ANNkd_leaf(n, pidx);
}
decomp = selectDecomp( // select decomposition method
pa, pidx, // points and indices
n, dim, // number of points and dimension
bnd_box, // current bounding box
splitter, shrink, // splitting/shrinking methods
inner_box); // inner box if shrinking (returned)
if (decomp == SPLIT) { // split selected
int cd; // cutting dimension
ANNcoord cv; // cutting value
int n_lo; // number on low side of cut
// invoke splitting procedure
(*splitter)(pa, pidx, bnd_box, n, dim, cd, cv, n_lo);
ANNcoord lv = bnd_box.lo[cd]; // save bounds for cutting dimension
ANNcoord hv = bnd_box.hi[cd];
bnd_box.hi[cd] = cv; // modify bounds for left subtree
ANNkd_ptr lo = rbd_tree( // build left subtree
pa, pidx, n_lo, // ...from pidx[0..n_lo-1]
dim, bsp, bnd_box, splitter, shrink);
bnd_box.hi[cd] = hv; // restore bounds
bnd_box.lo[cd] = cv; // modify bounds for right subtree
ANNkd_ptr hi = rbd_tree( // build right subtree
pa, pidx + n_lo, n-n_lo,// ...from pidx[n_lo..n-1]
dim, bsp, bnd_box, splitter, shrink);
bnd_box.lo[cd] = lv; // restore bounds
// create the splitting node
return new ANNkd_split(cd, cv, lv, hv, lo, hi);
}
else { // shrink selected
int n_in; // number of points in box
int n_bnds; // number of bounding sides
annBoxSplit( // split points around inner box
pa, // points to split
pidx, // point indices
n, // number of points
dim, // dimension
inner_box, // inner box
n_in); // number of points inside (returned)
ANNkd_ptr in = rbd_tree( // build inner subtree pidx[0..n_in-1]
pa, pidx, n_in, dim, bsp, inner_box, splitter, shrink);
ANNkd_ptr out = rbd_tree( // build outer subtree pidx[n_in..n]
pa, pidx+n_in, n - n_in, dim, bsp, bnd_box, splitter, shrink);
ANNorthHSArray bnds = NULL; // bounds (alloc in Box2Bnds and
// ...freed in bd_shrink destroyer)
annBox2Bnds( // convert inner box to bounds
inner_box, // inner box
bnd_box, // enclosing box
dim, // dimension
n_bnds, // number of bounds (returned)
bnds); // bounds array (modified)
// return shrinking node
return new ANNbd_shrink(n_bnds, bnds, in, out);
}
}

View File

@@ -1,100 +0,0 @@
//----------------------------------------------------------------------
// File: bd_tree.h
// Programmer: David Mount
// Description: Declarations for standard bd-tree routines
// Last modified: 01/04/05 (Version 1.0)
//----------------------------------------------------------------------
// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and
// David Mount. All Rights Reserved.
//
// This software and related documentation is part of the Approximate
// Nearest Neighbor Library (ANN). This software is provided under
// the provisions of the Lesser GNU Public License (LGPL). See the
// file ../ReadMe.txt for further information.
//
// The University of Maryland (U.M.) and the authors make no
// representations about the suitability or fitness of this software for
// any purpose. It is provided "as is" without express or implied
// warranty.
//----------------------------------------------------------------------
// History:
// Revision 0.1 03/04/98
// Initial release
// Revision 1.0 04/01/05
// Changed IN, OUT to ANN_IN, ANN_OUT
//----------------------------------------------------------------------
#ifndef ANN_bd_tree_H
#define ANN_bd_tree_H
#include <ANN/ANNx.h> // all ANN includes
#include "kd_tree.h" // kd-tree includes
//----------------------------------------------------------------------
// bd-tree shrinking node.
// The main addition in the bd-tree is the shrinking node, which
// is declared here.
//
// Shrinking nodes are defined by list of orthogonal halfspaces.
// These halfspaces define a (possibly unbounded) orthogonal
// rectangle. There are two children, in and out. Points that
// lie within this rectangle are stored in the in-child, and the
// other points are stored in the out-child.
//
// We use a list of orthogonal halfspaces rather than an
// orthogonal rectangle object because typically the number of
// sides of the shrinking box will be much smaller than the
// worst case bound of 2*dim.
//
// BEWARE: Note that constructor just copies the pointer to the
// bounding array, but the destructor deallocates it. This is
// rather poor practice, but happens to be convenient. The list
// is allocated in the bd-tree building procedure rbd_tree() just
// prior to construction, and is used for no other purposes.
//
// WARNING: In the near neighbor searching code it is assumed that
// the list of bounding halfspaces is irredundant, meaning that there
// are no two distinct halfspaces in the list with the same outward
// pointing normals.
//----------------------------------------------------------------------
class ANNbd_shrink : public ANNkd_node // splitting node of a kd-tree
{
int n_bnds; // number of bounding halfspaces
ANNorthHSArray bnds; // list of bounding halfspaces
ANNkd_ptr child[2]; // in and out children
public:
ANNbd_shrink( // constructor
int nb, // number of bounding halfspaces
ANNorthHSArray bds, // list of bounding halfspaces
ANNkd_ptr ic=NULL, ANNkd_ptr oc=NULL) // children
{
n_bnds = nb; // cutting dimension
bnds = bds; // assign bounds
child[ANN_IN] = ic; // set children
child[ANN_OUT] = oc;
}
~ANNbd_shrink() // destructor
{
if (child[ANN_IN]!= NULL && child[ANN_IN]!= KD_TRIVIAL)
delete child[ANN_IN];
if (child[ANN_OUT]!= NULL&& child[ANN_OUT]!= KD_TRIVIAL)
delete child[ANN_OUT];
if (bnds != NULL)
delete [] bnds; // delete bounds
}
virtual void getStats( // get tree statistics
int dim, // dimension of space
ANNkdStats &st, // statistics
ANNorthRect &bnd_box); // bounding box
virtual void print(int level, ostream &out);// print node
virtual void dump(ostream &out); // dump node
virtual void ann_search(ANNdist); // standard search
virtual void ann_pri_search(ANNdist); // priority search
virtual void ann_FR_search(ANNdist); // fixed-radius search
};
#endif

View File

@@ -1,109 +0,0 @@
//----------------------------------------------------------------------
// File: brute.cpp
// Programmer: Sunil Arya and David Mount
// Description: Brute-force nearest neighbors
// Last modified: 05/03/05 (Version 1.1)
//----------------------------------------------------------------------
// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and
// David Mount. All Rights Reserved.
//
// This software and related documentation is part of the Approximate
// Nearest Neighbor Library (ANN). This software is provided under
// the provisions of the Lesser GNU Public License (LGPL). See the
// file ../ReadMe.txt for further information.
//
// The University of Maryland (U.M.) and the authors make no
// representations about the suitability or fitness of this software for
// any purpose. It is provided "as is" without express or implied
// warranty.
//----------------------------------------------------------------------
// History:
// Revision 0.1 03/04/98
// Initial release
// Revision 1.1 05/03/05
// Added fixed-radius kNN search
//----------------------------------------------------------------------
#include <ANN/ANNx.h> // all ANN includes
#include "pr_queue_k.h" // k element priority queue
//----------------------------------------------------------------------
// Brute-force search simply stores a pointer to the list of
// data points and searches linearly for the nearest neighbor.
// The k nearest neighbors are stored in a k-element priority
// queue (which is implemented in a pretty dumb way as well).
//
// If ANN_ALLOW_SELF_MATCH is ANNfalse then data points at distance
// zero are not considered.
//
// Note that the error bound eps is passed in, but it is ignored.
// These routines compute exact nearest neighbors (which is needed
// for validation purposes in ann_test.cpp).
//----------------------------------------------------------------------
ANNbruteForce::ANNbruteForce( // constructor from point array
ANNpointArray pa, // point array
int n, // number of points
int dd) // dimension
{
dim = dd; n_pts = n; pts = pa;
}
ANNbruteForce::~ANNbruteForce() { } // destructor (empty)
void ANNbruteForce::annkSearch( // approx k near neighbor search
ANNpoint q, // query point
int k, // number of near neighbors to return
ANNidxArray nn_idx, // nearest neighbor indices (returned)
ANNdistArray dd, // dist to near neighbors (returned)
double eps) // error bound (ignored)
{
ANNmin_k mk(k); // construct a k-limited priority queue
int i;
if (k > n_pts) { // too many near neighbors?
annError("Requesting more near neighbors than data points", ANNabort);
}
// run every point through queue
for (i = 0; i < n_pts; i++) {
// compute distance to point
ANNdist sqDist = annDist(dim, pts[i], q);
if (ANN_ALLOW_SELF_MATCH || sqDist != 0)
mk.insert(sqDist, i);
}
for (i = 0; i < k; i++) { // extract the k closest points
dd[i] = mk.ith_smallest_key(i);
nn_idx[i] = mk.ith_smallest_info(i);
}
}
int ANNbruteForce::annkFRSearch( // approx fixed-radius kNN search
ANNpoint q, // query point
ANNdist sqRad, // squared radius
int k, // number of near neighbors to return
ANNidxArray nn_idx, // nearest neighbor array (returned)
ANNdistArray dd, // dist to near neighbors (returned)
double eps) // error bound
{
ANNmin_k mk(k); // construct a k-limited priority queue
int i;
int pts_in_range = 0; // number of points in query range
// run every point through queue
for (i = 0; i < n_pts; i++) {
// compute distance to point
ANNdist sqDist = annDist(dim, pts[i], q);
if (sqDist <= sqRad && // within radius bound
(ANN_ALLOW_SELF_MATCH || sqDist != 0)) { // ...and no self match
mk.insert(sqDist, i);
pts_in_range++;
}
}
for (i = 0; i < k; i++) { // extract the k closest points
if (dd != NULL)
dd[i] = mk.ith_smallest_key(i);
if (nn_idx != NULL)
nn_idx[i] = mk.ith_smallest_info(i);
}
return pts_in_range;
}

View File

@@ -1,446 +0,0 @@
//----------------------------------------------------------------------
// File: kd_dump.cc
// Programmer: David Mount
// Description: Dump and Load for kd- and bd-trees
// Last modified: 01/04/05 (Version 1.0)
//----------------------------------------------------------------------
// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and
// David Mount. All Rights Reserved.
//
// This software and related documentation is part of the Approximate
// Nearest Neighbor Library (ANN). This software is provided under
// the provisions of the Lesser GNU Public License (LGPL). See the
// file ../ReadMe.txt for further information.
//
// The University of Maryland (U.M.) and the authors make no
// representations about the suitability or fitness of this software for
// any purpose. It is provided "as is" without express or implied
// warranty.
//----------------------------------------------------------------------
// History:
// Revision 0.1 03/04/98
// Initial release
// Revision 1.0 04/01/05
// Moved dump out of kd_tree.cc into this file.
// Added kd-tree load constructor.
//----------------------------------------------------------------------
// This file contains routines for dumping kd-trees and bd-trees and
// reloading them. (It is an abuse of policy to include both kd- and
// bd-tree routines in the same file, sorry. There should be no problem
// in deleting the bd- versions of the routines if they are not
// desired.)
//----------------------------------------------------------------------
#include "kd_tree.h" // kd-tree declarations
#include "bd_tree.h" // bd-tree declarations
#include <cstring>
#include <cstdlib>
using namespace std; // make std:: available
//----------------------------------------------------------------------
// Constants
//----------------------------------------------------------------------
const int STRING_LEN = 500; // maximum string length
const double EPSILON = 1E-5; // small number for float comparison
enum ANNtreeType {KD_TREE, BD_TREE}; // tree types (used in loading)
//----------------------------------------------------------------------
// Procedure declarations
//----------------------------------------------------------------------
static ANNkd_ptr annReadDump( // read dump file
istream &in, // input stream
ANNtreeType tree_type, // type of tree expected
ANNpointArray &the_pts, // new points (if applic)
ANNidxArray &the_pidx, // point indices (returned)
int &the_dim, // dimension (returned)
int &the_n_pts, // number of points (returned)
int &the_bkt_size, // bucket size (returned)
ANNpoint &the_bnd_box_lo, // low bounding point
ANNpoint &the_bnd_box_hi); // high bounding point
static ANNkd_ptr annReadTree( // read tree-part of dump file
istream &in, // input stream
ANNtreeType tree_type, // type of tree expected
ANNidxArray the_pidx, // point indices (modified)
int &next_idx); // next index (modified)
//----------------------------------------------------------------------
// ANN kd- and bd-tree Dump Format
// The dump file begins with a header containing the version of
// ANN, an optional section containing the points, followed by
// a description of the tree. The tree is printed in preorder.
//
// Format:
// #ANN <version number> <comments> [END_OF_LINE]
// points <dim> <n_pts> (point coordinates: this is optional)
// 0 <xxx> <xxx> ... <xxx> (point indices and coordinates)
// 1 <xxx> <xxx> ... <xxx>
// ...
// tree <dim> <n_pts> <bkt_size>
// <xxx> <xxx> ... <xxx> (lower end of bounding box)
// <xxx> <xxx> ... <xxx> (upper end of bounding box)
// If the tree is null, then a single line "null" is
// output. Otherwise the nodes of the tree are printed
// one per line in preorder. Leaves and splitting nodes
// have the following formats:
// Leaf node:
// leaf <n_pts> <bkt[0]> <bkt[1]> ... <bkt[n-1]>
// Splitting nodes:
// split <cut_dim> <cut_val> <lo_bound> <hi_bound>
//
// For bd-trees:
//
// Shrinking nodes:
// shrink <n_bnds>
// <cut_dim> <cut_val> <side>
// <cut_dim> <cut_val> <side>
// ... (repeated n_bnds times)
//----------------------------------------------------------------------
void ANNkd_tree::Dump( // dump entire tree
ANNbool with_pts, // print points as well?
ostream &out) // output stream
{
out << "#ANN " << ANNversion << "\n";
out.precision(ANNcoordPrec); // use full precision in dumping
if (with_pts) { // print point coordinates
out << "points " << dim << " " << n_pts << "\n";
for (int i = 0; i < n_pts; i++) {
out << i << " ";
annPrintPt(pts[i], dim, out);
out << "\n";
}
}
out << "tree " // print tree elements
<< dim << " "
<< n_pts << " "
<< bkt_size << "\n";
annPrintPt(bnd_box_lo, dim, out); // print lower bound
out << "\n";
annPrintPt(bnd_box_hi, dim, out); // print upper bound
out << "\n";
if (root == NULL) // empty tree?
out << "null\n";
else {
root->dump(out); // invoke printing at root
}
out.precision(0); // restore default precision
}
void ANNkd_split::dump( // dump a splitting node
ostream &out) // output stream
{
out << "split " << cut_dim << " " << cut_val << " ";
out << cd_bnds[ANN_LO] << " " << cd_bnds[ANN_HI] << "\n";
child[ANN_LO]->dump(out); // print low child
child[ANN_HI]->dump(out); // print high child
}
void ANNkd_leaf::dump( // dump a leaf node
ostream &out) // output stream
{
if (this == KD_TRIVIAL) { // canonical trivial leaf node
out << "leaf 0\n"; // leaf no points
}
else{
out << "leaf " << n_pts;
for (int j = 0; j < n_pts; j++) {
out << " " << bkt[j];
}
out << "\n";
}
}
void ANNbd_shrink::dump( // dump a shrinking node
ostream &out) // output stream
{
out << "shrink " << n_bnds << "\n";
for (int j = 0; j < n_bnds; j++) {
out << bnds[j].cd << " " << bnds[j].cv << " " << bnds[j].sd << "\n";
}
child[ANN_IN]->dump(out); // print in-child
child[ANN_OUT]->dump(out); // print out-child
}
//----------------------------------------------------------------------
// Load kd-tree from dump file
// This rebuilds a kd-tree which was dumped to a file. The dump
// file contains all the basic tree information according to a
// preorder traversal. We assume that the dump file also contains
// point data. (This is to guarantee the consistency of the tree.)
// If not, then an error is generated.
//
// Indirectly, this procedure allocates space for points, point
// indices, all nodes in the tree, and the bounding box for the
// tree. When the tree is destroyed, all but the points are
// deallocated.
//
// This routine calls annReadDump to do all the work.
//----------------------------------------------------------------------
ANNkd_tree::ANNkd_tree( // build from dump file
istream &in) // input stream for dump file
{
int the_dim; // local dimension
int the_n_pts; // local number of points
int the_bkt_size; // local number of points
ANNpoint the_bnd_box_lo; // low bounding point
ANNpoint the_bnd_box_hi; // high bounding point
ANNpointArray the_pts; // point storage
ANNidxArray the_pidx; // point index storage
ANNkd_ptr the_root; // root of the tree
the_root = annReadDump( // read the dump file
in, // input stream
KD_TREE, // expecting a kd-tree
the_pts, // point array (returned)
the_pidx, // point indices (returned)
the_dim, the_n_pts, the_bkt_size, // basic tree info (returned)
the_bnd_box_lo, the_bnd_box_hi); // bounding box info (returned)
// create a skeletal tree
SkeletonTree(the_n_pts, the_dim, the_bkt_size, the_pts, the_pidx);
bnd_box_lo = the_bnd_box_lo;
bnd_box_hi = the_bnd_box_hi;
root = the_root; // set the root
}
ANNbd_tree::ANNbd_tree( // build bd-tree from dump file
istream &in) : ANNkd_tree() // input stream for dump file
{
int the_dim; // local dimension
int the_n_pts; // local number of points
int the_bkt_size; // local number of points
ANNpoint the_bnd_box_lo; // low bounding point
ANNpoint the_bnd_box_hi; // high bounding point
ANNpointArray the_pts; // point storage
ANNidxArray the_pidx; // point index storage
ANNkd_ptr the_root; // root of the tree
the_root = annReadDump( // read the dump file
in, // input stream
BD_TREE, // expecting a bd-tree
the_pts, // point array (returned)
the_pidx, // point indices (returned)
the_dim, the_n_pts, the_bkt_size, // basic tree info (returned)
the_bnd_box_lo, the_bnd_box_hi); // bounding box info (returned)
// create a skeletal tree
SkeletonTree(the_n_pts, the_dim, the_bkt_size, the_pts, the_pidx);
bnd_box_lo = the_bnd_box_lo;
bnd_box_hi = the_bnd_box_hi;
root = the_root; // set the root
}
//----------------------------------------------------------------------
// annReadDump - read a dump file
//
// This procedure reads a dump file, constructs a kd-tree
// and returns all the essential information needed to actually
// construct the tree. Because this procedure is used for
// constructing both kd-trees and bd-trees, the second argument
// is used to indicate which type of tree we are expecting.
//----------------------------------------------------------------------
static ANNkd_ptr annReadDump(
istream &in, // input stream
ANNtreeType tree_type, // type of tree expected
ANNpointArray &the_pts, // new points (returned)
ANNidxArray &the_pidx, // point indices (returned)
int &the_dim, // dimension (returned)
int &the_n_pts, // number of points (returned)
int &the_bkt_size, // bucket size (returned)
ANNpoint &the_bnd_box_lo, // low bounding point (ret'd)
ANNpoint &the_bnd_box_hi) // high bounding point (ret'd)
{
int j;
char str[STRING_LEN]; // storage for string
char version[STRING_LEN]; // ANN version number
ANNkd_ptr the_root = NULL;
//------------------------------------------------------------------
// Input file header
//------------------------------------------------------------------
in >> str; // input header
if (strcmp(str, "#ANN") != 0) { // incorrect header
annError("Incorrect header for dump file", ANNabort);
}
in.getline(version, STRING_LEN); // get version (ignore)
//------------------------------------------------------------------
// Input the points
// An array the_pts is allocated and points are read from
// the dump file.
//------------------------------------------------------------------
in >> str; // get major heading
if (strcmp(str, "points") == 0) { // points section
in >> the_dim; // input dimension
in >> the_n_pts; // number of points
// allocate point storage
the_pts = annAllocPts(the_n_pts, the_dim);
for (int i = 0; i < the_n_pts; i++) { // input point coordinates
ANNidx idx; // point index
in >> idx; // input point index
if (idx < 0 || idx >= the_n_pts) {
annError("Point index is out of range", ANNabort);
}
for (j = 0; j < the_dim; j++) {
in >> the_pts[idx][j]; // read point coordinates
}
}
in >> str; // get next major heading
}
else { // no points were input
annError("Points must be supplied in the dump file", ANNabort);
}
//------------------------------------------------------------------
// Input the tree
// After the basic header information, we invoke annReadTree
// to do all the heavy work. We create our own array of
// point indices (so we can pass them to annReadTree())
// but we do not deallocate them. They will be deallocated
// when the tree is destroyed.
//------------------------------------------------------------------
if (strcmp(str, "tree") == 0) { // tree section
in >> the_dim; // read dimension
in >> the_n_pts; // number of points
in >> the_bkt_size; // bucket size
the_bnd_box_lo = annAllocPt(the_dim); // allocate bounding box pts
the_bnd_box_hi = annAllocPt(the_dim);
for (j = 0; j < the_dim; j++) { // read bounding box low
in >> the_bnd_box_lo[j];
}
for (j = 0; j < the_dim; j++) { // read bounding box low
in >> the_bnd_box_hi[j];
}
the_pidx = new ANNidx[the_n_pts]; // allocate point index array
int next_idx = 0; // number of indices filled
// read the tree and indices
the_root = annReadTree(in, tree_type, the_pidx, next_idx);
if (next_idx != the_n_pts) { // didn't see all the points?
annError("Didn't see as many points as expected", ANNwarn);
}
}
else {
annError("Illegal dump format. Expecting section heading", ANNabort);
}
return the_root;
}
//----------------------------------------------------------------------
// annReadTree - input tree and return pointer
//
// annReadTree reads in a node of the tree, makes any recursive
// calls as needed to input the children of this node (if internal).
// It returns a pointer to the node that was created. An array
// of point indices is given along with a pointer to the next
// available location in the array. As leaves are read, their
// point indices are stored here, and the point buckets point
// to the first entry in the array.
//
// Recall that these are the formats. The tree is given in
// preorder.
//
// Leaf node:
// leaf <n_pts> <bkt[0]> <bkt[1]> ... <bkt[n-1]>
// Splitting nodes:
// split <cut_dim> <cut_val> <lo_bound> <hi_bound>
//
// For bd-trees:
//
// Shrinking nodes:
// shrink <n_bnds>
// <cut_dim> <cut_val> <side>
// <cut_dim> <cut_val> <side>
// ... (repeated n_bnds times)
//----------------------------------------------------------------------
static ANNkd_ptr annReadTree(
istream &in, // input stream
ANNtreeType tree_type, // type of tree expected
ANNidxArray the_pidx, // point indices (modified)
int &next_idx) // next index (modified)
{
char tag[STRING_LEN]; // tag (leaf, split, shrink)
int n_pts; // number of points in leaf
int cd; // cut dimension
ANNcoord cv; // cut value
ANNcoord lb; // low bound
ANNcoord hb; // high bound
int n_bnds; // number of bounding sides
int sd; // which side
in >> tag; // input node tag
if (strcmp(tag, "null") == 0) { // null tree
return NULL;
}
//------------------------------------------------------------------
// Read a leaf
//------------------------------------------------------------------
if (strcmp(tag, "leaf") == 0) { // leaf node
in >> n_pts; // input number of points
int old_idx = next_idx; // save next_idx
if (n_pts == 0) { // trivial leaf
return KD_TRIVIAL;
}
else {
for (int i = 0; i < n_pts; i++) { // input point indices
in >> the_pidx[next_idx++]; // store in array of indices
}
}
return new ANNkd_leaf(n_pts, &the_pidx[old_idx]);
}
//------------------------------------------------------------------
// Read a splitting node
//------------------------------------------------------------------
else if (strcmp(tag, "split") == 0) { // splitting node
in >> cd >> cv >> lb >> hb;
// read low and high subtrees
ANNkd_ptr lc = annReadTree(in, tree_type, the_pidx, next_idx);
ANNkd_ptr hc = annReadTree(in, tree_type, the_pidx, next_idx);
// create new node and return
return new ANNkd_split(cd, cv, lb, hb, lc, hc);
}
//------------------------------------------------------------------
// Read a shrinking node (bd-tree only)
//------------------------------------------------------------------
else if (strcmp(tag, "shrink") == 0) { // shrinking node
if (tree_type != BD_TREE) {
annError("Shrinking node not allowed in kd-tree", ANNabort);
}
in >> n_bnds; // number of bounding sides
// allocate bounds array
ANNorthHSArray bds = new ANNorthHalfSpace[n_bnds];
for (int i = 0; i < n_bnds; i++) {
in >> cd >> cv >> sd; // input bounding halfspace
// copy to array
bds[i] = ANNorthHalfSpace(cd, cv, sd);
}
// read inner and outer subtrees
ANNkd_ptr ic = annReadTree(in, tree_type, the_pidx, next_idx);
ANNkd_ptr oc = annReadTree(in, tree_type, the_pidx, next_idx);
// create new node and return
return new ANNbd_shrink(n_bnds, bds, ic, oc);
}
else {
annError("Illegal node type in dump file", ANNabort);
exit(0); // to keep the compiler happy
}
}

View File

@@ -1,183 +0,0 @@
//----------------------------------------------------------------------
// File: kd_fix_rad_search.cpp
// Programmer: Sunil Arya and David Mount
// Description: Standard kd-tree fixed-radius kNN search
// Last modified: 05/03/05 (Version 1.1)
//----------------------------------------------------------------------
// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and
// David Mount. All Rights Reserved.
//
// This software and related documentation is part of the Approximate
// Nearest Neighbor Library (ANN). This software is provided under
// the provisions of the Lesser GNU Public License (LGPL). See the
// file ../ReadMe.txt for further information.
//
// The University of Maryland (U.M.) and the authors make no
// representations about the suitability or fitness of this software for
// any purpose. It is provided "as is" without express or implied
// warranty.
//----------------------------------------------------------------------
// History:
// Revision 1.1 05/03/05
// Initial release
//----------------------------------------------------------------------
#include "kd_fix_rad_search.h" // kd fixed-radius search decls
//----------------------------------------------------------------------
// Approximate fixed-radius k nearest neighbor search
// The squared radius is provided, and this procedure finds the
// k nearest neighbors within the radius, and returns the total
// number of points lying within the radius.
//
// The method used for searching the kd-tree is a variation of the
// nearest neighbor search used in kd_search.cpp, except that the
// radius of the search ball is known. We refer the reader to that
// file for the explanation of the recursive search procedure.
//----------------------------------------------------------------------
//----------------------------------------------------------------------
// To keep argument lists short, a number of global variables
// are maintained which are common to all the recursive calls.
// These are given below.
//----------------------------------------------------------------------
int ANNkdFRDim; // dimension of space
ANNpoint ANNkdFRQ; // query point
ANNdist ANNkdFRSqRad; // squared radius search bound
double ANNkdFRMaxErr; // max tolerable squared error
ANNpointArray ANNkdFRPts; // the points
ANNmin_k* ANNkdFRPointMK; // set of k closest points
int ANNkdFRPtsVisited; // total points visited
int ANNkdFRPtsInRange; // number of points in the range
//----------------------------------------------------------------------
// annkFRSearch - fixed radius search for k nearest neighbors
//----------------------------------------------------------------------
int ANNkd_tree::annkFRSearch(
ANNpoint q, // the query point
ANNdist sqRad, // squared radius search bound
int k, // number of near neighbors to return
ANNidxArray nn_idx, // nearest neighbor indices (returned)
ANNdistArray dd, // the approximate nearest neighbor
double eps) // the error bound
{
ANNkdFRDim = dim; // copy arguments to static equivs
ANNkdFRQ = q;
ANNkdFRSqRad = sqRad;
ANNkdFRPts = pts;
ANNkdFRPtsVisited = 0; // initialize count of points visited
ANNkdFRPtsInRange = 0; // ...and points in the range
ANNkdFRMaxErr = ANN_POW(1.0 + eps);
ANN_FLOP(2) // increment floating op count
ANNkdFRPointMK = new ANNmin_k(k); // create set for closest k points
// search starting at the root
root->ann_FR_search(annBoxDistance(q, bnd_box_lo, bnd_box_hi, dim));
for (int i = 0; i < k; i++) { // extract the k-th closest points
if (dd != NULL)
dd[i] = ANNkdFRPointMK->ith_smallest_key(i);
if (nn_idx != NULL)
nn_idx[i] = ANNkdFRPointMK->ith_smallest_info(i);
}
delete ANNkdFRPointMK; // deallocate closest point set
return ANNkdFRPtsInRange; // return final point count
}
//----------------------------------------------------------------------
// kd_split::ann_FR_search - search a splitting node
// Note: This routine is similar in structure to the standard kNN
// search. It visits the subtree that is closer to the query point
// first. For fixed-radius search, there is no benefit in visiting
// one subtree before the other, but we maintain the same basic
// code structure for the sake of uniformity.
//----------------------------------------------------------------------
void ANNkd_split::ann_FR_search(ANNdist box_dist)
{
// check dist calc term condition
if (ANNmaxPtsVisited != 0 && ANNkdFRPtsVisited > ANNmaxPtsVisited) return;
// distance to cutting plane
ANNcoord cut_diff = ANNkdFRQ[cut_dim] - cut_val;
if (cut_diff < 0) { // left of cutting plane
child[ANN_LO]->ann_FR_search(box_dist);// visit closer child first
ANNcoord box_diff = cd_bnds[ANN_LO] - ANNkdFRQ[cut_dim];
if (box_diff < 0) // within bounds - ignore
box_diff = 0;
// distance to further box
box_dist = (ANNdist) ANN_SUM(box_dist,
ANN_DIFF(ANN_POW(box_diff), ANN_POW(cut_diff)));
// visit further child if in range
if (box_dist * ANNkdFRMaxErr <= ANNkdFRSqRad)
child[ANN_HI]->ann_FR_search(box_dist);
}
else { // right of cutting plane
child[ANN_HI]->ann_FR_search(box_dist);// visit closer child first
ANNcoord box_diff = ANNkdFRQ[cut_dim] - cd_bnds[ANN_HI];
if (box_diff < 0) // within bounds - ignore
box_diff = 0;
// distance to further box
box_dist = (ANNdist) ANN_SUM(box_dist,
ANN_DIFF(ANN_POW(box_diff), ANN_POW(cut_diff)));
// visit further child if close enough
if (box_dist * ANNkdFRMaxErr <= ANNkdFRSqRad)
child[ANN_LO]->ann_FR_search(box_dist);
}
ANN_FLOP(13) // increment floating ops
ANN_SPL(1) // one more splitting node visited
}
//----------------------------------------------------------------------
// kd_leaf::ann_FR_search - search points in a leaf node
// Note: The unreadability of this code is the result of
// some fine tuning to replace indexing by pointer operations.
//----------------------------------------------------------------------
void ANNkd_leaf::ann_FR_search(ANNdist box_dist)
{
register ANNdist dist; // distance to data point
register ANNcoord* pp; // data coordinate pointer
register ANNcoord* qq; // query coordinate pointer
register ANNcoord t;
register int d;
for (int i = 0; i < n_pts; i++) { // check points in bucket
pp = ANNkdFRPts[bkt[i]]; // first coord of next data point
qq = ANNkdFRQ; // first coord of query point
dist = 0;
for(d = 0; d < ANNkdFRDim; d++) {
ANN_COORD(1) // one more coordinate hit
ANN_FLOP(5) // increment floating ops
t = *(qq++) - *(pp++); // compute length and adv coordinate
// exceeds dist to k-th smallest?
if( (dist = ANN_SUM(dist, ANN_POW(t))) > ANNkdFRSqRad) {
break;
}
}
if (d >= ANNkdFRDim && // among the k best?
(ANN_ALLOW_SELF_MATCH || dist!=0)) { // and no self-match problem
// add it to the list
ANNkdFRPointMK->insert(dist, bkt[i]);
ANNkdFRPtsInRange++; // increment point count
}
}
ANN_LEAF(1) // one more leaf node visited
ANN_PTS(n_pts) // increment points visited
ANNkdFRPtsVisited += n_pts; // increment number of points visited
}

View File

@@ -1,44 +0,0 @@
//----------------------------------------------------------------------
// File: kd_fix_rad_search.h
// Programmer: Sunil Arya and David Mount
// Description: Standard kd-tree fixed-radius kNN search
// Last modified: 05/03/05 (Version 1.1)
//----------------------------------------------------------------------
// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and
// David Mount. All Rights Reserved.
//
// This software and related documentation is part of the Approximate
// Nearest Neighbor Library (ANN). This software is provided under
// the provisions of the Lesser GNU Public License (LGPL). See the
// file ../ReadMe.txt for further information.
//
// The University of Maryland (U.M.) and the authors make no
// representations about the suitability or fitness of this software for
// any purpose. It is provided "as is" without express or implied
// warranty.
//----------------------------------------------------------------------
// History:
// Revision 1.1 05/03/05
// Initial release
//----------------------------------------------------------------------
#ifndef ANN_kd_fix_rad_search_H
#define ANN_kd_fix_rad_search_H
#include "kd_tree.h" // kd-tree declarations
#include "kd_util.h" // kd-tree utilities
#include "pr_queue_k.h" // k-element priority queue
#include <ANN/ANNperf.h> // performance evaluation
//----------------------------------------------------------------------
// Global variables
// These are active for the life of each call to
// annRangeSearch(). They are set to save the number of
// variables that need to be passed among the various search
// procedures.
//----------------------------------------------------------------------
extern ANNpoint ANNkdFRQ; // query point (static copy)
#endif

View File

@@ -1,219 +0,0 @@
//----------------------------------------------------------------------
// File: kd_pr_search.cpp
// Programmer: Sunil Arya and David Mount
// Description: Priority search for kd-trees
// Last modified: 01/04/05 (Version 1.0)
//----------------------------------------------------------------------
// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and
// David Mount. All Rights Reserved.
//
// This software and related documentation is part of the Approximate
// Nearest Neighbor Library (ANN). This software is provided under
// the provisions of the Lesser GNU Public License (LGPL). See the
// file ../ReadMe.txt for further information.
//
// The University of Maryland (U.M.) and the authors make no
// representations about the suitability or fitness of this software for
// any purpose. It is provided "as is" without express or implied
// warranty.
//----------------------------------------------------------------------
// History:
// Revision 0.1 03/04/98
// Initial release
//----------------------------------------------------------------------
#include "kd_pr_search.h" // kd priority search declarations
//----------------------------------------------------------------------
// Approximate nearest neighbor searching by priority search.
// The kd-tree is searched for an approximate nearest neighbor.
// The point is returned through one of the arguments, and the
// distance returned is the SQUARED distance to this point.
//
// The method used for searching the kd-tree is called priority
// search. (It is described in Arya and Mount, ``Algorithms for
// fast vector quantization,'' Proc. of DCC '93: Data Compression
// Conference}, eds. J. A. Storer and M. Cohn, IEEE Press, 1993,
// 381--390.)
//
// The cell of the kd-tree containing the query point is located,
// and cells are visited in increasing order of distance from the
// query point. This is done by placing each subtree which has
// NOT been visited in a priority queue, according to the closest
// distance of the corresponding enclosing rectangle from the
// query point. The search stops when the distance to the nearest
// remaining rectangle exceeds the distance to the nearest point
// seen by a factor of more than 1/(1+eps). (Implying that any
// point found subsequently in the search cannot be closer by more
// than this factor.)
//
// The main entry point is annkPriSearch() which sets things up and
// then call the recursive routine ann_pri_search(). This is a
// recursive routine which performs the processing for one node in
// the kd-tree. There are two versions of this virtual procedure,
// one for splitting nodes and one for leaves. When a splitting node
// is visited, we determine which child to continue the search on
// (the closer one), and insert the other child into the priority
// queue. When a leaf is visited, we compute the distances to the
// points in the buckets, and update information on the closest
// points.
//
// Some trickery is used to incrementally update the distance from
// a kd-tree rectangle to the query point. This comes about from
// the fact that which each successive split, only one component
// (along the dimension that is split) of the squared distance to
// the child rectangle is different from the squared distance to
// the parent rectangle.
//----------------------------------------------------------------------
//----------------------------------------------------------------------
// To keep argument lists short, a number of global variables
// are maintained which are common to all the recursive calls.
// These are given below.
//----------------------------------------------------------------------
double ANNprEps; // the error bound
int ANNprDim; // dimension of space
ANNpoint ANNprQ; // query point
double ANNprMaxErr; // max tolerable squared error
ANNpointArray ANNprPts; // the points
ANNpr_queue *ANNprBoxPQ; // priority queue for boxes
ANNmin_k *ANNprPointMK; // set of k closest points
//----------------------------------------------------------------------
// annkPriSearch - priority search for k nearest neighbors
//----------------------------------------------------------------------
void ANNkd_tree::annkPriSearch(
ANNpoint q, // query point
int k, // number of near neighbors to return
ANNidxArray nn_idx, // nearest neighbor indices (returned)
ANNdistArray dd, // dist to near neighbors (returned)
double eps) // error bound (ignored)
{
// max tolerable squared error
ANNprMaxErr = ANN_POW(1.0 + eps);
ANN_FLOP(2) // increment floating ops
ANNprDim = dim; // copy arguments to static equivs
ANNprQ = q;
ANNprPts = pts;
ANNptsVisited = 0; // initialize count of points visited
ANNprPointMK = new ANNmin_k(k); // create set for closest k points
// distance to root box
ANNdist box_dist = annBoxDistance(q,
bnd_box_lo, bnd_box_hi, dim);
ANNprBoxPQ = new ANNpr_queue(n_pts);// create priority queue for boxes
ANNprBoxPQ->insert(box_dist, root); // insert root in priority queue
while (ANNprBoxPQ->non_empty() &&
(!(ANNmaxPtsVisited != 0 && ANNptsVisited > ANNmaxPtsVisited))) {
ANNkd_ptr np; // next box from prior queue
// extract closest box from queue
ANNprBoxPQ->extr_min(box_dist, (void *&) np);
ANN_FLOP(2) // increment floating ops
if (box_dist*ANNprMaxErr >= ANNprPointMK->max_key())
break;
np->ann_pri_search(box_dist); // search this subtree.
}
for (int i = 0; i < k; i++) { // extract the k-th closest points
dd[i] = ANNprPointMK->ith_smallest_key(i);
nn_idx[i] = ANNprPointMK->ith_smallest_info(i);
}
delete ANNprPointMK; // deallocate closest point set
delete ANNprBoxPQ; // deallocate priority queue
}
//----------------------------------------------------------------------
// kd_split::ann_pri_search - search a splitting node
//----------------------------------------------------------------------
void ANNkd_split::ann_pri_search(ANNdist box_dist)
{
ANNdist new_dist; // distance to child visited later
// distance to cutting plane
ANNcoord cut_diff = ANNprQ[cut_dim] - cut_val;
if (cut_diff < 0) { // left of cutting plane
ANNcoord box_diff = cd_bnds[ANN_LO] - ANNprQ[cut_dim];
if (box_diff < 0) // within bounds - ignore
box_diff = 0;
// distance to further box
new_dist = (ANNdist) ANN_SUM(box_dist,
ANN_DIFF(ANN_POW(box_diff), ANN_POW(cut_diff)));
if (child[ANN_HI] != KD_TRIVIAL)// enqueue if not trivial
ANNprBoxPQ->insert(new_dist, child[ANN_HI]);
// continue with closer child
child[ANN_LO]->ann_pri_search(box_dist);
}
else { // right of cutting plane
ANNcoord box_diff = ANNprQ[cut_dim] - cd_bnds[ANN_HI];
if (box_diff < 0) // within bounds - ignore
box_diff = 0;
// distance to further box
new_dist = (ANNdist) ANN_SUM(box_dist,
ANN_DIFF(ANN_POW(box_diff), ANN_POW(cut_diff)));
if (child[ANN_LO] != KD_TRIVIAL)// enqueue if not trivial
ANNprBoxPQ->insert(new_dist, child[ANN_LO]);
// continue with closer child
child[ANN_HI]->ann_pri_search(box_dist);
}
ANN_SPL(1) // one more splitting node visited
ANN_FLOP(8) // increment floating ops
}
//----------------------------------------------------------------------
// kd_leaf::ann_pri_search - search points in a leaf node
//
// This is virtually identical to the ann_search for standard search.
//----------------------------------------------------------------------
void ANNkd_leaf::ann_pri_search(ANNdist box_dist)
{
register ANNdist dist; // distance to data point
register ANNcoord* pp; // data coordinate pointer
register ANNcoord* qq; // query coordinate pointer
register ANNdist min_dist; // distance to k-th closest point
register ANNcoord t;
register int d;
min_dist = ANNprPointMK->max_key(); // k-th smallest distance so far
for (int i = 0; i < n_pts; i++) { // check points in bucket
pp = ANNprPts[bkt[i]]; // first coord of next data point
qq = ANNprQ; // first coord of query point
dist = 0;
for(d = 0; d < ANNprDim; d++) {
ANN_COORD(1) // one more coordinate hit
ANN_FLOP(4) // increment floating ops
t = *(qq++) - *(pp++); // compute length and adv coordinate
// exceeds dist to k-th smallest?
if( (dist = ANN_SUM(dist, ANN_POW(t))) > min_dist) {
break;
}
}
if (d >= ANNprDim && // among the k best?
(ANN_ALLOW_SELF_MATCH || dist!=0)) { // and no self-match problem
// add it to the list
ANNprPointMK->insert(dist, bkt[i]);
min_dist = ANNprPointMK->max_key();
}
}
ANN_LEAF(1) // one more leaf node visited
ANN_PTS(n_pts) // increment points visited
ANNptsVisited += n_pts; // increment number of points visited
}

View File

@@ -1,49 +0,0 @@
//----------------------------------------------------------------------
// File: kd_pr_search.h
// Programmer: Sunil Arya and David Mount
// Description: Priority kd-tree search
// Last modified: 01/04/05 (Version 1.0)
//----------------------------------------------------------------------
// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and
// David Mount. All Rights Reserved.
//
// This software and related documentation is part of the Approximate
// Nearest Neighbor Library (ANN). This software is provided under
// the provisions of the Lesser GNU Public License (LGPL). See the
// file ../ReadMe.txt for further information.
//
// The University of Maryland (U.M.) and the authors make no
// representations about the suitability or fitness of this software for
// any purpose. It is provided "as is" without express or implied
// warranty.
//----------------------------------------------------------------------
// History:
// Revision 0.1 03/04/98
// Initial release
//----------------------------------------------------------------------
#ifndef ANN_kd_pr_search_H
#define ANN_kd_pr_search_H
#include "kd_tree.h" // kd-tree declarations
#include "kd_util.h" // kd-tree utilities
#include "pr_queue.h" // priority queue declarations
#include "pr_queue_k.h" // k-element priority queue
#include <ANN/ANNperf.h> // performance evaluation
//----------------------------------------------------------------------
// Global variables
// Active for the life of each call to Appx_Near_Neigh() or
// Appx_k_Near_Neigh().
//----------------------------------------------------------------------
extern double ANNprEps; // the error bound
extern int ANNprDim; // dimension of space
extern ANNpoint ANNprQ; // query point
extern double ANNprMaxErr; // max tolerable squared error
extern ANNpointArray ANNprPts; // the points
extern ANNpr_queue *ANNprBoxPQ; // priority queue for boxes
extern ANNmin_k *ANNprPointMK; // set of k closest points
#endif

View File

@@ -1,210 +0,0 @@
//----------------------------------------------------------------------
// File: kd_search.cpp
// Programmer: Sunil Arya and David Mount
// Description: Standard kd-tree search
// Last modified: 01/04/05 (Version 1.0)
//----------------------------------------------------------------------
// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and
// David Mount. All Rights Reserved.
//
// This software and related documentation is part of the Approximate
// Nearest Neighbor Library (ANN). This software is provided under
// the provisions of the Lesser GNU Public License (LGPL). See the
// file ../ReadMe.txt for further information.
//
// The University of Maryland (U.M.) and the authors make no
// representations about the suitability or fitness of this software for
// any purpose. It is provided "as is" without express or implied
// warranty.
//----------------------------------------------------------------------
// History:
// Revision 0.1 03/04/98
// Initial release
// Revision 1.0 04/01/05
// Changed names LO, HI to ANN_LO, ANN_HI
//----------------------------------------------------------------------
#include "kd_search.h" // kd-search declarations
//----------------------------------------------------------------------
// Approximate nearest neighbor searching by kd-tree search
// The kd-tree is searched for an approximate nearest neighbor.
// The point is returned through one of the arguments, and the
// distance returned is the squared distance to this point.
//
// The method used for searching the kd-tree is an approximate
// adaptation of the search algorithm described by Friedman,
// Bentley, and Finkel, ``An algorithm for finding best matches
// in logarithmic expected time,'' ACM Transactions on Mathematical
// Software, 3(3):209-226, 1977).
//
// The algorithm operates recursively. When first encountering a
// node of the kd-tree we first visit the child which is closest to
// the query point. On return, we decide whether we want to visit
// the other child. If the box containing the other child exceeds
// 1/(1+eps) times the current best distance, then we skip it (since
// any point found in this child cannot be closer to the query point
// by more than this factor.) Otherwise, we visit it recursively.
// The distance between a box and the query point is computed exactly
// (not approximated as is often done in kd-tree), using incremental
// distance updates, as described by Arya and Mount in ``Algorithms
// for fast vector quantization,'' Proc. of DCC '93: Data Compression
// Conference, eds. J. A. Storer and M. Cohn, IEEE Press, 1993,
// 381-390.
//
// The main entry points is annkSearch() which sets things up and
// then call the recursive routine ann_search(). This is a recursive
// routine which performs the processing for one node in the kd-tree.
// There are two versions of this virtual procedure, one for splitting
// nodes and one for leaves. When a splitting node is visited, we
// determine which child to visit first (the closer one), and visit
// the other child on return. When a leaf is visited, we compute
// the distances to the points in the buckets, and update information
// on the closest points.
//
// Some trickery is used to incrementally update the distance from
// a kd-tree rectangle to the query point. This comes about from
// the fact that which each successive split, only one component
// (along the dimension that is split) of the squared distance to
// the child rectangle is different from the squared distance to
// the parent rectangle.
//----------------------------------------------------------------------
//----------------------------------------------------------------------
// To keep argument lists short, a number of global variables
// are maintained which are common to all the recursive calls.
// These are given below.
//----------------------------------------------------------------------
int ANNkdDim; // dimension of space
ANNpoint ANNkdQ; // query point
double ANNkdMaxErr; // max tolerable squared error
ANNpointArray ANNkdPts; // the points
ANNmin_k *ANNkdPointMK; // set of k closest points
//----------------------------------------------------------------------
// annkSearch - search for the k nearest neighbors
//----------------------------------------------------------------------
void ANNkd_tree::annkSearch(
ANNpoint q, // the query point
int k, // number of near neighbors to return
ANNidxArray nn_idx, // nearest neighbor indices (returned)
ANNdistArray dd, // the approximate nearest neighbor
double eps) // the error bound
{
ANNkdDim = dim; // copy arguments to static equivs
ANNkdQ = q;
ANNkdPts = pts;
ANNptsVisited = 0; // initialize count of points visited
if (k > n_pts) { // too many near neighbors?
annError("Requesting more near neighbors than data points", ANNabort);
}
ANNkdMaxErr = ANN_POW(1.0 + eps);
ANN_FLOP(2) // increment floating op count
ANNkdPointMK = new ANNmin_k(k); // create set for closest k points
// search starting at the root
root->ann_search(annBoxDistance(q, bnd_box_lo, bnd_box_hi, dim));
for (int i = 0; i < k; i++) { // extract the k-th closest points
dd[i] = ANNkdPointMK->ith_smallest_key(i);
nn_idx[i] = ANNkdPointMK->ith_smallest_info(i);
}
delete ANNkdPointMK; // deallocate closest point set
}
//----------------------------------------------------------------------
// kd_split::ann_search - search a splitting node
//----------------------------------------------------------------------
void ANNkd_split::ann_search(ANNdist box_dist)
{
// check dist calc term condition
if (ANNmaxPtsVisited != 0 && ANNptsVisited > ANNmaxPtsVisited) return;
// distance to cutting plane
ANNcoord cut_diff = ANNkdQ[cut_dim] - cut_val;
if (cut_diff < 0) { // left of cutting plane
child[ANN_LO]->ann_search(box_dist);// visit closer child first
ANNcoord box_diff = cd_bnds[ANN_LO] - ANNkdQ[cut_dim];
if (box_diff < 0) // within bounds - ignore
box_diff = 0;
// distance to further box
box_dist = (ANNdist) ANN_SUM(box_dist,
ANN_DIFF(ANN_POW(box_diff), ANN_POW(cut_diff)));
// visit further child if close enough
if (box_dist * ANNkdMaxErr < ANNkdPointMK->max_key())
child[ANN_HI]->ann_search(box_dist);
}
else { // right of cutting plane
child[ANN_HI]->ann_search(box_dist);// visit closer child first
ANNcoord box_diff = ANNkdQ[cut_dim] - cd_bnds[ANN_HI];
if (box_diff < 0) // within bounds - ignore
box_diff = 0;
// distance to further box
box_dist = (ANNdist) ANN_SUM(box_dist,
ANN_DIFF(ANN_POW(box_diff), ANN_POW(cut_diff)));
// visit further child if close enough
if (box_dist * ANNkdMaxErr < ANNkdPointMK->max_key())
child[ANN_LO]->ann_search(box_dist);
}
ANN_FLOP(10) // increment floating ops
ANN_SPL(1) // one more splitting node visited
}
//----------------------------------------------------------------------
// kd_leaf::ann_search - search points in a leaf node
// Note: The unreadability of this code is the result of
// some fine tuning to replace indexing by pointer operations.
//----------------------------------------------------------------------
void ANNkd_leaf::ann_search(ANNdist box_dist)
{
register ANNdist dist; // distance to data point
register ANNcoord* pp; // data coordinate pointer
register ANNcoord* qq; // query coordinate pointer
register ANNdist min_dist; // distance to k-th closest point
register ANNcoord t;
register int d;
min_dist = ANNkdPointMK->max_key(); // k-th smallest distance so far
for (int i = 0; i < n_pts; i++) { // check points in bucket
pp = ANNkdPts[bkt[i]]; // first coord of next data point
qq = ANNkdQ; // first coord of query point
dist = 0;
for(d = 0; d < ANNkdDim; d++) {
ANN_COORD(1) // one more coordinate hit
ANN_FLOP(4) // increment floating ops
t = *(qq++) - *(pp++); // compute length and adv coordinate
// exceeds dist to k-th smallest?
if( (dist = ANN_SUM(dist, ANN_POW(t))) > min_dist) {
break;
}
}
if (d >= ANNkdDim && // among the k best?
(ANN_ALLOW_SELF_MATCH || dist!=0)) { // and no self-match problem
// add it to the list
ANNkdPointMK->insert(dist, bkt[i]);
min_dist = ANNkdPointMK->max_key();
}
}
ANN_LEAF(1) // one more leaf node visited
ANN_PTS(n_pts) // increment points visited
ANNptsVisited += n_pts; // increment number of points visited
}

View File

@@ -1,48 +0,0 @@
//----------------------------------------------------------------------
// File: kd_search.h
// Programmer: Sunil Arya and David Mount
// Description: Standard kd-tree search
// Last modified: 01/04/05 (Version 1.0)
//----------------------------------------------------------------------
// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and
// David Mount. All Rights Reserved.
//
// This software and related documentation is part of the Approximate
// Nearest Neighbor Library (ANN). This software is provided under
// the provisions of the Lesser GNU Public License (LGPL). See the
// file ../ReadMe.txt for further information.
//
// The University of Maryland (U.M.) and the authors make no
// representations about the suitability or fitness of this software for
// any purpose. It is provided "as is" without express or implied
// warranty.
//----------------------------------------------------------------------
// History:
// Revision 0.1 03/04/98
// Initial release
//----------------------------------------------------------------------
#ifndef ANN_kd_search_H
#define ANN_kd_search_H
#include "kd_tree.h" // kd-tree declarations
#include "kd_util.h" // kd-tree utilities
#include "pr_queue_k.h" // k-element priority queue
#include <ANN/ANNperf.h> // performance evaluation
//----------------------------------------------------------------------
// More global variables
// These are active for the life of each call to annkSearch(). They
// are set to save the number of variables that need to be passed
// among the various search procedures.
//----------------------------------------------------------------------
extern int ANNkdDim; // dimension of space (static copy)
extern ANNpoint ANNkdQ; // query point (static copy)
extern double ANNkdMaxErr; // max tolerable squared error
extern ANNpointArray ANNkdPts; // the points (static copy)
extern ANNmin_k *ANNkdPointMK; // set of k closest points
extern int ANNptsVisited; // number of points visited
#endif

View File

@@ -1,428 +0,0 @@
//----------------------------------------------------------------------
// File: kd_split.cpp
// Programmer: Sunil Arya and David Mount
// Description: Methods for splitting kd-trees
// Last modified: 01/04/05 (Version 1.0)
//----------------------------------------------------------------------
// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and
// David Mount. All Rights Reserved.
//
// This software and related documentation is part of the Approximate
// Nearest Neighbor Library (ANN). This software is provided under
// the provisions of the Lesser GNU Public License (LGPL). See the
// file ../ReadMe.txt for further information.
//
// The University of Maryland (U.M.) and the authors make no
// representations about the suitability or fitness of this software for
// any purpose. It is provided "as is" without express or implied
// warranty.
//----------------------------------------------------------------------
// History:
// Revision 0.1 03/04/98
// Initial release
// Revision 1.0 04/01/05
//----------------------------------------------------------------------
#include "kd_tree.h" // kd-tree definitions
#include "kd_util.h" // kd-tree utilities
#include "kd_split.h" // splitting functions
//----------------------------------------------------------------------
// Constants
//----------------------------------------------------------------------
const double ERR = 0.001; // a small value
const double FS_ASPECT_RATIO = 3.0; // maximum allowed aspect ratio
// in fair split. Must be >= 2.
//----------------------------------------------------------------------
// kd_split - Bentley's standard splitting routine for kd-trees
// Find the dimension of the greatest spread, and split
// just before the median point along this dimension.
//----------------------------------------------------------------------
void kd_split(
ANNpointArray pa, // point array (permuted on return)
ANNidxArray pidx, // point indices
const ANNorthRect &bnds, // bounding rectangle for cell
int n, // number of points
int dim, // dimension of space
int &cut_dim, // cutting dimension (returned)
ANNcoord &cut_val, // cutting value (returned)
int &n_lo) // num of points on low side (returned)
{
// find dimension of maximum spread
cut_dim = annMaxSpread(pa, pidx, n, dim);
n_lo = n/2; // median rank
// split about median
annMedianSplit(pa, pidx, n, cut_dim, cut_val, n_lo);
}
//----------------------------------------------------------------------
// midpt_split - midpoint splitting rule for box-decomposition trees
//
// This is the simplest splitting rule that guarantees boxes
// of bounded aspect ratio. It simply cuts the box with the
// longest side through its midpoint. If there are ties, it
// selects the dimension with the maximum point spread.
//
// WARNING: This routine (while simple) doesn't seem to work
// well in practice in high dimensions, because it tends to
// generate a large number of trivial and/or unbalanced splits.
// Either kd_split(), sl_midpt_split(), or fair_split() are
// recommended, instead.
//----------------------------------------------------------------------
void midpt_split(
ANNpointArray pa, // point array
ANNidxArray pidx, // point indices (permuted on return)
const ANNorthRect &bnds, // bounding rectangle for cell
int n, // number of points
int dim, // dimension of space
int &cut_dim, // cutting dimension (returned)
ANNcoord &cut_val, // cutting value (returned)
int &n_lo) // num of points on low side (returned)
{
int d;
ANNcoord max_length = bnds.hi[0] - bnds.lo[0];
for (d = 1; d < dim; d++) { // find length of longest box side
ANNcoord length = bnds.hi[d] - bnds.lo[d];
if (length > max_length) {
max_length = length;
}
}
ANNcoord max_spread = -1; // find long side with most spread
for (d = 0; d < dim; d++) {
// is it among longest?
if (double(bnds.hi[d] - bnds.lo[d]) >= (1-ERR)*max_length) {
// compute its spread
ANNcoord spr = annSpread(pa, pidx, n, d);
if (spr > max_spread) { // is it max so far?
max_spread = spr;
cut_dim = d;
}
}
}
// split along cut_dim at midpoint
cut_val = (bnds.lo[cut_dim] + bnds.hi[cut_dim]) / 2;
// permute points accordingly
int br1, br2;
annPlaneSplit(pa, pidx, n, cut_dim, cut_val, br1, br2);
//------------------------------------------------------------------
// On return: pa[0..br1-1] < cut_val
// pa[br1..br2-1] == cut_val
// pa[br2..n-1] > cut_val
//
// We can set n_lo to any value in the range [br1..br2].
// We choose split so that points are most evenly divided.
//------------------------------------------------------------------
if (br1 > n/2) n_lo = br1;
else if (br2 < n/2) n_lo = br2;
else n_lo = n/2;
}
//----------------------------------------------------------------------
// sl_midpt_split - sliding midpoint splitting rule
//
// This is a modification of midpt_split, which has the nonsensical
// name "sliding midpoint". The idea is that we try to use the
// midpoint rule, by bisecting the longest side. If there are
// ties, the dimension with the maximum spread is selected. If,
// however, the midpoint split produces a trivial split (no points
// on one side of the splitting plane) then we slide the splitting
// (maintaining its orientation) until it produces a nontrivial
// split. For example, if the splitting plane is along the x-axis,
// and all the data points have x-coordinate less than the x-bisector,
// then the split is taken along the maximum x-coordinate of the
// data points.
//
// Intuitively, this rule cannot generate trivial splits, and
// hence avoids midpt_split's tendency to produce trees with
// a very large number of nodes.
//
//----------------------------------------------------------------------
void sl_midpt_split(
ANNpointArray pa, // point array
ANNidxArray pidx, // point indices (permuted on return)
const ANNorthRect &bnds, // bounding rectangle for cell
int n, // number of points
int dim, // dimension of space
int &cut_dim, // cutting dimension (returned)
ANNcoord &cut_val, // cutting value (returned)
int &n_lo) // num of points on low side (returned)
{
int d;
ANNcoord max_length = bnds.hi[0] - bnds.lo[0];
for (d = 1; d < dim; d++) { // find length of longest box side
ANNcoord length = bnds.hi[d] - bnds.lo[d];
if (length > max_length) {
max_length = length;
}
}
ANNcoord max_spread = -1; // find long side with most spread
for (d = 0; d < dim; d++) {
// is it among longest?
if ((bnds.hi[d] - bnds.lo[d]) >= (1-ERR)*max_length) {
// compute its spread
ANNcoord spr = annSpread(pa, pidx, n, d);
if (spr > max_spread) { // is it max so far?
max_spread = spr;
cut_dim = d;
}
}
}
// ideal split at midpoint
ANNcoord ideal_cut_val = (bnds.lo[cut_dim] + bnds.hi[cut_dim])/2;
ANNcoord min, max;
annMinMax(pa, pidx, n, cut_dim, min, max); // find min/max coordinates
if (ideal_cut_val < min) // slide to min or max as needed
cut_val = min;
else if (ideal_cut_val > max)
cut_val = max;
else
cut_val = ideal_cut_val;
// permute points accordingly
int br1, br2;
annPlaneSplit(pa, pidx, n, cut_dim, cut_val, br1, br2);
//------------------------------------------------------------------
// On return: pa[0..br1-1] < cut_val
// pa[br1..br2-1] == cut_val
// pa[br2..n-1] > cut_val
//
// We can set n_lo to any value in the range [br1..br2] to satisfy
// the exit conditions of the procedure.
//
// if ideal_cut_val < min (implying br2 >= 1),
// then we select n_lo = 1 (so there is one point on left) and
// if ideal_cut_val > max (implying br1 <= n-1),
// then we select n_lo = n-1 (so there is one point on right).
// Otherwise, we select n_lo as close to n/2 as possible within
// [br1..br2].
//------------------------------------------------------------------
if (ideal_cut_val < min) n_lo = 1;
else if (ideal_cut_val > max) n_lo = n-1;
else if (br1 > n/2) n_lo = br1;
else if (br2 < n/2) n_lo = br2;
else n_lo = n/2;
}
//----------------------------------------------------------------------
// fair_split - fair-split splitting rule
//
// This is a compromise between the kd-tree splitting rule (which
// always splits data points at their median) and the midpoint
// splitting rule (which always splits a box through its center.
// The goal of this procedure is to achieve both nicely balanced
// splits, and boxes of bounded aspect ratio.
//
// A constant FS_ASPECT_RATIO is defined. Given a box, those sides
// which can be split so that the ratio of the longest to shortest
// side does not exceed ASPECT_RATIO are identified. Among these
// sides, we select the one in which the points have the largest
// spread. We then split the points in a manner which most evenly
// distributes the points on either side of the splitting plane,
// subject to maintaining the bound on the ratio of long to short
// sides. To determine that the aspect ratio will be preserved,
// we determine the longest side (other than this side), and
// determine how narrowly we can cut this side, without causing the
// aspect ratio bound to be exceeded (small_piece).
//
// This procedure is more robust than either kd_split or midpt_split,
// but is more complicated as well. When point distribution is
// extremely skewed, this degenerates to midpt_split (actually
// 1/3 point split), and when the points are most evenly distributed,
// this degenerates to kd-split.
//----------------------------------------------------------------------
void fair_split(
ANNpointArray pa, // point array
ANNidxArray pidx, // point indices (permuted on return)
const ANNorthRect &bnds, // bounding rectangle for cell
int n, // number of points
int dim, // dimension of space
int &cut_dim, // cutting dimension (returned)
ANNcoord &cut_val, // cutting value (returned)
int &n_lo) // num of points on low side (returned)
{
int d;
ANNcoord max_length = bnds.hi[0] - bnds.lo[0];
cut_dim = 0;
for (d = 1; d < dim; d++) { // find length of longest box side
ANNcoord length = bnds.hi[d] - bnds.lo[d];
if (length > max_length) {
max_length = length;
cut_dim = d;
}
}
ANNcoord max_spread = 0; // find legal cut with max spread
cut_dim = 0;
for (d = 0; d < dim; d++) {
ANNcoord length = bnds.hi[d] - bnds.lo[d];
// is this side midpoint splitable
// without violating aspect ratio?
if (((double) max_length)*2.0/((double) length) <= FS_ASPECT_RATIO) {
// compute spread along this dim
ANNcoord spr = annSpread(pa, pidx, n, d);
if (spr > max_spread) { // best spread so far
max_spread = spr;
cut_dim = d; // this is dimension to cut
}
}
}
max_length = 0; // find longest side other than cut_dim
for (d = 0; d < dim; d++) {
ANNcoord length = bnds.hi[d] - bnds.lo[d];
if (d != cut_dim && length > max_length)
max_length = length;
}
// consider most extreme splits
ANNcoord small_piece = max_length / FS_ASPECT_RATIO;
ANNcoord lo_cut = bnds.lo[cut_dim] + small_piece;// lowest legal cut
ANNcoord hi_cut = bnds.hi[cut_dim] - small_piece;// highest legal cut
int br1, br2;
// is median below lo_cut ?
if (annSplitBalance(pa, pidx, n, cut_dim, lo_cut) >= 0) {
cut_val = lo_cut; // cut at lo_cut
annPlaneSplit(pa, pidx, n, cut_dim, cut_val, br1, br2);
n_lo = br1;
}
// is median above hi_cut?
else if (annSplitBalance(pa, pidx, n, cut_dim, hi_cut) <= 0) {
cut_val = hi_cut; // cut at hi_cut
annPlaneSplit(pa, pidx, n, cut_dim, cut_val, br1, br2);
n_lo = br2;
}
else { // median cut preserves asp ratio
n_lo = n/2; // split about median
annMedianSplit(pa, pidx, n, cut_dim, cut_val, n_lo);
}
}
//----------------------------------------------------------------------
// sl_fair_split - sliding fair split splitting rule
//
// Sliding fair split is a splitting rule that combines the
// strengths of both fair split with sliding midpoint split.
// Fair split tends to produce balanced splits when the points
// are roughly uniformly distributed, but it can produce many
// trivial splits when points are highly clustered. Sliding
// midpoint never produces trivial splits, and shrinks boxes
// nicely if points are highly clustered, but it may produce
// rather unbalanced splits when points are unclustered but not
// quite uniform.
//
// Sliding fair split is based on the theory that there are two
// types of splits that are "good": balanced splits that produce
// fat boxes, and unbalanced splits provided the cell with fewer
// points is fat.
//
// This splitting rule operates by first computing the longest
// side of the current bounding box. Then it asks which sides
// could be split (at the midpoint) and still satisfy the aspect
// ratio bound with respect to this side. Among these, it selects
// the side with the largest spread (as fair split would). It
// then considers the most extreme cuts that would be allowed by
// the aspect ratio bound. This is done by dividing the longest
// side of the box by the aspect ratio bound. If the median cut
// lies between these extreme cuts, then we use the median cut.
// If not, then consider the extreme cut that is closer to the
// median. If all the points lie to one side of this cut, then
// we slide the cut until it hits the first point. This may
// violate the aspect ratio bound, but will never generate empty
// cells. However the sibling of every such skinny cell is fat,
// and hence packing arguments still apply.
//
//----------------------------------------------------------------------
void sl_fair_split(
ANNpointArray pa, // point array
ANNidxArray pidx, // point indices (permuted on return)
const ANNorthRect &bnds, // bounding rectangle for cell
int n, // number of points
int dim, // dimension of space
int &cut_dim, // cutting dimension (returned)
ANNcoord &cut_val, // cutting value (returned)
int &n_lo) // num of points on low side (returned)
{
int d;
ANNcoord min, max; // min/max coordinates
int br1, br2; // split break points
ANNcoord max_length = bnds.hi[0] - bnds.lo[0];
cut_dim = 0;
for (d = 1; d < dim; d++) { // find length of longest box side
ANNcoord length = bnds.hi[d] - bnds.lo[d];
if (length > max_length) {
max_length = length;
cut_dim = d;
}
}
ANNcoord max_spread = 0; // find legal cut with max spread
cut_dim = 0;
for (d = 0; d < dim; d++) {
ANNcoord length = bnds.hi[d] - bnds.lo[d];
// is this side midpoint splitable
// without violating aspect ratio?
if (((double) max_length)*2.0/((double) length) <= FS_ASPECT_RATIO) {
// compute spread along this dim
ANNcoord spr = annSpread(pa, pidx, n, d);
if (spr > max_spread) { // best spread so far
max_spread = spr;
cut_dim = d; // this is dimension to cut
}
}
}
max_length = 0; // find longest side other than cut_dim
for (d = 0; d < dim; d++) {
ANNcoord length = bnds.hi[d] - bnds.lo[d];
if (d != cut_dim && length > max_length)
max_length = length;
}
// consider most extreme splits
ANNcoord small_piece = max_length / FS_ASPECT_RATIO;
ANNcoord lo_cut = bnds.lo[cut_dim] + small_piece;// lowest legal cut
ANNcoord hi_cut = bnds.hi[cut_dim] - small_piece;// highest legal cut
// find min and max along cut_dim
annMinMax(pa, pidx, n, cut_dim, min, max);
// is median below lo_cut?
if (annSplitBalance(pa, pidx, n, cut_dim, lo_cut) >= 0) {
if (max > lo_cut) { // are any points above lo_cut?
cut_val = lo_cut; // cut at lo_cut
annPlaneSplit(pa, pidx, n, cut_dim, cut_val, br1, br2);
n_lo = br1; // balance if there are ties
}
else { // all points below lo_cut
cut_val = max; // cut at max value
annPlaneSplit(pa, pidx, n, cut_dim, cut_val, br1, br2);
n_lo = n-1;
}
}
// is median above hi_cut?
else if (annSplitBalance(pa, pidx, n, cut_dim, hi_cut) <= 0) {
if (min < hi_cut) { // are any points below hi_cut?
cut_val = hi_cut; // cut at hi_cut
annPlaneSplit(pa, pidx, n, cut_dim, cut_val, br1, br2);
n_lo = br2; // balance if there are ties
}
else { // all points above hi_cut
cut_val = min; // cut at min value
annPlaneSplit(pa, pidx, n, cut_dim, cut_val, br1, br2);
n_lo = 1;
}
}
else { // median cut is good enough
n_lo = n/2; // split about median
annMedianSplit(pa, pidx, n, cut_dim, cut_val, n_lo);
}
}

View File

@@ -1,85 +0,0 @@
//----------------------------------------------------------------------
// File: kd_split.h
// Programmer: Sunil Arya and David Mount
// Description: Methods for splitting kd-trees
// Last modified: 01/04/05 (Version 1.0)
//----------------------------------------------------------------------
// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and
// David Mount. All Rights Reserved.
//
// This software and related documentation is part of the Approximate
// Nearest Neighbor Library (ANN). This software is provided under
// the provisions of the Lesser GNU Public License (LGPL). See the
// file ../ReadMe.txt for further information.
//
// The University of Maryland (U.M.) and the authors make no
// representations about the suitability or fitness of this software for
// any purpose. It is provided "as is" without express or implied
// warranty.
//----------------------------------------------------------------------
// History:
// Revision 0.1 03/04/98
// Initial release
//----------------------------------------------------------------------
#ifndef ANN_KD_SPLIT_H
#define ANN_KD_SPLIT_H
#include "kd_tree.h" // kd-tree definitions
//----------------------------------------------------------------------
// External entry points
// These are all splitting procedures for kd-trees.
//----------------------------------------------------------------------
void kd_split( // standard (optimized) kd-splitter
ANNpointArray pa, // point array (unaltered)
ANNidxArray pidx, // point indices (permuted on return)
const ANNorthRect &bnds, // bounding rectangle for cell
int n, // number of points
int dim, // dimension of space
int &cut_dim, // cutting dimension (returned)
ANNcoord &cut_val, // cutting value (returned)
int &n_lo); // num of points on low side (returned)
void midpt_split( // midpoint kd-splitter
ANNpointArray pa, // point array (unaltered)
ANNidxArray pidx, // point indices (permuted on return)
const ANNorthRect &bnds, // bounding rectangle for cell
int n, // number of points
int dim, // dimension of space
int &cut_dim, // cutting dimension (returned)
ANNcoord &cut_val, // cutting value (returned)
int &n_lo); // num of points on low side (returned)
void sl_midpt_split( // sliding midpoint kd-splitter
ANNpointArray pa, // point array (unaltered)
ANNidxArray pidx, // point indices (permuted on return)
const ANNorthRect &bnds, // bounding rectangle for cell
int n, // number of points
int dim, // dimension of space
int &cut_dim, // cutting dimension (returned)
ANNcoord &cut_val, // cutting value (returned)
int &n_lo); // num of points on low side (returned)
void fair_split( // fair-split kd-splitter
ANNpointArray pa, // point array (unaltered)
ANNidxArray pidx, // point indices (permuted on return)
const ANNorthRect &bnds, // bounding rectangle for cell
int n, // number of points
int dim, // dimension of space
int &cut_dim, // cutting dimension (returned)
ANNcoord &cut_val, // cutting value (returned)
int &n_lo); // num of points on low side (returned)
void sl_fair_split( // sliding fair-split kd-splitter
ANNpointArray pa, // point array (unaltered)
ANNidxArray pidx, // point indices (permuted on return)
const ANNorthRect &bnds, // bounding rectangle for cell
int n, // number of points
int dim, // dimension of space
int &cut_dim, // cutting dimension (returned)
ANNcoord &cut_val, // cutting value (returned)
int &n_lo); // num of points on low side (returned)
#endif

View File

@@ -1,405 +0,0 @@
//----------------------------------------------------------------------
// File: kd_tree.cpp
// Programmer: Sunil Arya and David Mount
// Description: Basic methods for kd-trees.
// Last modified: 01/04/05 (Version 1.0)
//----------------------------------------------------------------------
// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and
// David Mount. All Rights Reserved.
//
// This software and related documentation is part of the Approximate
// Nearest Neighbor Library (ANN). This software is provided under
// the provisions of the Lesser GNU Public License (LGPL). See the
// file ../ReadMe.txt for further information.
//
// The University of Maryland (U.M.) and the authors make no
// representations about the suitability or fitness of this software for
// any purpose. It is provided "as is" without express or implied
// warranty.
//----------------------------------------------------------------------
// History:
// Revision 0.1 03/04/98
// Initial release
// Revision 1.0 04/01/05
// Increased aspect ratio bound (ANN_AR_TOOBIG) from 100 to 1000.
// Fixed leaf counts to count trivial leaves.
// Added optional pa, pi arguments to Skeleton kd_tree constructor
// for use in load constructor.
// Added annClose() to eliminate KD_TRIVIAL memory leak.
//----------------------------------------------------------------------
#include "kd_tree.h" // kd-tree declarations
#include "kd_split.h" // kd-tree splitting rules
#include "kd_util.h" // kd-tree utilities
#include <ANN/ANNperf.h> // performance evaluation
//----------------------------------------------------------------------
// Global data
//
// For some splitting rules, especially with small bucket sizes,
// it is possible to generate a large number of empty leaf nodes.
// To save storage we allocate a single trivial leaf node which
// contains no points. For messy coding reasons it is convenient
// to have it reference a trivial point index.
//
// KD_TRIVIAL is allocated when the first kd-tree is created. It
// must *never* deallocated (since it may be shared by more than
// one tree).
//----------------------------------------------------------------------
static int IDX_TRIVIAL[] = {0}; // trivial point index
ANNkd_leaf *KD_TRIVIAL = NULL; // trivial leaf node
//----------------------------------------------------------------------
// Printing the kd-tree
// These routines print a kd-tree in reverse inorder (high then
// root then low). (This is so that if you look at the output
// from the right side it appear from left to right in standard
// inorder.) When outputting leaves we output only the point
// indices rather than the point coordinates. There is an option
// to print the point coordinates separately.
//
// The tree printing routine calls the printing routines on the
// individual nodes of the tree, passing in the level or depth
// in the tree. The level in the tree is used to print indentation
// for readability.
//----------------------------------------------------------------------
void ANNkd_split::print( // print splitting node
int level, // depth of node in tree
ostream &out) // output stream
{
child[ANN_HI]->print(level+1, out); // print high child
out << " ";
for (int i = 0; i < level; i++) // print indentation
out << "..";
out << "Split cd=" << cut_dim << " cv=" << cut_val;
out << " lbnd=" << cd_bnds[ANN_LO];
out << " hbnd=" << cd_bnds[ANN_HI];
out << "\n";
child[ANN_LO]->print(level+1, out); // print low child
}
void ANNkd_leaf::print( // print leaf node
int level, // depth of node in tree
ostream &out) // output stream
{
out << " ";
for (int i = 0; i < level; i++) // print indentation
out << "..";
if (this == KD_TRIVIAL) { // canonical trivial leaf node
out << "Leaf (trivial)\n";
}
else{
out << "Leaf n=" << n_pts << " <";
for (int j = 0; j < n_pts; j++) {
out << bkt[j];
if (j < n_pts-1) out << ",";
}
out << ">\n";
}
}
void ANNkd_tree::Print( // print entire tree
ANNbool with_pts, // print points as well?
ostream &out) // output stream
{
out << "ANN Version " << ANNversion << "\n";
if (with_pts) { // print point coordinates
out << " Points:\n";
for (int i = 0; i < n_pts; i++) {
out << "\t" << i << ": ";
annPrintPt(pts[i], dim, out);
out << "\n";
}
}
if (root == NULL) // empty tree?
out << " Null tree.\n";
else {
root->print(0, out); // invoke printing at root
}
}
//----------------------------------------------------------------------
// kd_tree statistics (for performance evaluation)
// This routine compute various statistics information for
// a kd-tree. It is used by the implementors for performance
// evaluation of the data structure.
//----------------------------------------------------------------------
#define MAX(a,b) ((a) > (b) ? (a) : (b))
void ANNkdStats::merge(const ANNkdStats &st) // merge stats from child
{
n_lf += st.n_lf; n_tl += st.n_tl;
n_spl += st.n_spl; n_shr += st.n_shr;
depth = MAX(depth, st.depth);
sum_ar += st.sum_ar;
}
//----------------------------------------------------------------------
// Update statistics for nodes
//----------------------------------------------------------------------
const double ANN_AR_TOOBIG = 1000; // too big an aspect ratio
void ANNkd_leaf::getStats( // get subtree statistics
int dim, // dimension of space
ANNkdStats &st, // stats (modified)
ANNorthRect &bnd_box) // bounding box
{
st.reset();
st.n_lf = 1; // count this leaf
if (this == KD_TRIVIAL) st.n_tl = 1; // count trivial leaf
double ar = annAspectRatio(dim, bnd_box); // aspect ratio of leaf
// incr sum (ignore outliers)
st.sum_ar += float(ar < ANN_AR_TOOBIG ? ar : ANN_AR_TOOBIG);
}
void ANNkd_split::getStats( // get subtree statistics
int dim, // dimension of space
ANNkdStats &st, // stats (modified)
ANNorthRect &bnd_box) // bounding box
{
ANNkdStats ch_stats; // stats for children
// get stats for low child
ANNcoord hv = bnd_box.hi[cut_dim]; // save box bounds
bnd_box.hi[cut_dim] = cut_val; // upper bound for low child
ch_stats.reset(); // reset
child[ANN_LO]->getStats(dim, ch_stats, bnd_box);
st.merge(ch_stats); // merge them
bnd_box.hi[cut_dim] = hv; // restore bound
// get stats for high child
ANNcoord lv = bnd_box.lo[cut_dim]; // save box bounds
bnd_box.lo[cut_dim] = cut_val; // lower bound for high child
ch_stats.reset(); // reset
child[ANN_HI]->getStats(dim, ch_stats, bnd_box);
st.merge(ch_stats); // merge them
bnd_box.lo[cut_dim] = lv; // restore bound
st.depth++; // increment depth
st.n_spl++; // increment number of splits
}
//----------------------------------------------------------------------
// getStats
// Collects a number of statistics related to kd_tree or
// bd_tree.
//----------------------------------------------------------------------
void ANNkd_tree::getStats( // get tree statistics
ANNkdStats &st) // stats (modified)
{
st.reset(dim, n_pts, bkt_size); // reset stats
// create bounding box
ANNorthRect bnd_box(dim, bnd_box_lo, bnd_box_hi);
if (root != NULL) { // if nonempty tree
root->getStats(dim, st, bnd_box); // get statistics
st.avg_ar = st.sum_ar / st.n_lf; // average leaf asp ratio
}
}
//----------------------------------------------------------------------
// kd_tree destructor
// The destructor just frees the various elements that were
// allocated in the construction process.
//----------------------------------------------------------------------
ANNkd_tree::~ANNkd_tree() // tree destructor
{
if (root != NULL) delete root;
if (pidx != NULL) delete [] pidx;
if (bnd_box_lo != NULL) annDeallocPt(bnd_box_lo);
if (bnd_box_hi != NULL) annDeallocPt(bnd_box_hi);
}
//----------------------------------------------------------------------
// This is called with all use of ANN is finished. It eliminates the
// minor memory leak caused by the allocation of KD_TRIVIAL.
//----------------------------------------------------------------------
void annClose() // close use of ANN
{
if (KD_TRIVIAL != NULL) {
delete KD_TRIVIAL;
KD_TRIVIAL = NULL;
}
}
//----------------------------------------------------------------------
// kd_tree constructors
// There is a skeleton kd-tree constructor which sets up a
// trivial empty tree. The last optional argument allows
// the routine to be passed a point index array which is
// assumed to be of the proper size (n). Otherwise, one is
// allocated and initialized to the identity. Warning: In
// either case the destructor will deallocate this array.
//
// As a kludge, we need to allocate KD_TRIVIAL if one has not
// already been allocated. (This is because I'm too dumb to
// figure out how to cause a pointer to be allocated at load
// time.)
//----------------------------------------------------------------------
void ANNkd_tree::SkeletonTree( // construct skeleton tree
int n, // number of points
int dd, // dimension
int bs, // bucket size
ANNpointArray pa, // point array
ANNidxArray pi) // point indices
{
dim = dd; // initialize basic elements
n_pts = n;
bkt_size = bs;
pts = pa; // initialize points array
root = NULL; // no associated tree yet
if (pi == NULL) { // point indices provided?
pidx = new ANNidx[n]; // no, allocate space for point indices
for (int i = 0; i < n; i++) {
pidx[i] = i; // initially identity
}
}
else {
pidx = pi; // yes, use them
}
bnd_box_lo = bnd_box_hi = NULL; // bounding box is nonexistent
if (KD_TRIVIAL == NULL) // no trivial leaf node yet?
KD_TRIVIAL = new ANNkd_leaf(0, IDX_TRIVIAL); // allocate it
}
ANNkd_tree::ANNkd_tree( // basic constructor
int n, // number of points
int dd, // dimension
int bs) // bucket size
{ SkeletonTree(n, dd, bs); } // construct skeleton tree
//----------------------------------------------------------------------
// rkd_tree - recursive procedure to build a kd-tree
//
// Builds a kd-tree for points in pa as indexed through the
// array pidx[0..n-1] (typically a subarray of the array used in
// the top-level call). This routine permutes the array pidx,
// but does not alter pa[].
//
// The construction is based on a standard algorithm for constructing
// the kd-tree (see Friedman, Bentley, and Finkel, ``An algorithm for
// finding best matches in logarithmic expected time,'' ACM Transactions
// on Mathematical Software, 3(3):209-226, 1977). The procedure
// operates by a simple divide-and-conquer strategy, which determines
// an appropriate orthogonal cutting plane (see below), and splits
// the points. When the number of points falls below the bucket size,
// we simply store the points in a leaf node's bucket.
//
// One of the arguments is a pointer to a splitting routine,
// whose prototype is:
//
// void split(
// ANNpointArray pa, // complete point array
// ANNidxArray pidx, // point array (permuted on return)
// ANNorthRect &bnds, // bounds of current cell
// int n, // number of points
// int dim, // dimension of space
// int &cut_dim, // cutting dimension
// ANNcoord &cut_val, // cutting value
// int &n_lo) // no. of points on low side of cut
//
// This procedure selects a cutting dimension and cutting value,
// partitions pa about these values, and returns the number of
// points on the low side of the cut.
//----------------------------------------------------------------------
ANNkd_ptr rkd_tree( // recursive construction of kd-tree
ANNpointArray pa, // point array
ANNidxArray pidx, // point indices to store in subtree
int n, // number of points
int dim, // dimension of space
int bsp, // bucket space
ANNorthRect &bnd_box, // bounding box for current node
ANNkd_splitter splitter) // splitting routine
{
if (n <= bsp) { // n small, make a leaf node
if (n == 0) // empty leaf node
return KD_TRIVIAL; // return (canonical) empty leaf
else // construct the node and return
return new ANNkd_leaf(n, pidx);
}
else { // n large, make a splitting node
int cd; // cutting dimension
ANNcoord cv; // cutting value
int n_lo; // number on low side of cut
ANNkd_node *lo, *hi; // low and high children
// invoke splitting procedure
(*splitter)(pa, pidx, bnd_box, n, dim, cd, cv, n_lo);
ANNcoord lv = bnd_box.lo[cd]; // save bounds for cutting dimension
ANNcoord hv = bnd_box.hi[cd];
bnd_box.hi[cd] = cv; // modify bounds for left subtree
lo = rkd_tree( // build left subtree
pa, pidx, n_lo, // ...from pidx[0..n_lo-1]
dim, bsp, bnd_box, splitter);
bnd_box.hi[cd] = hv; // restore bounds
bnd_box.lo[cd] = cv; // modify bounds for right subtree
hi = rkd_tree( // build right subtree
pa, pidx + n_lo, n-n_lo,// ...from pidx[n_lo..n-1]
dim, bsp, bnd_box, splitter);
bnd_box.lo[cd] = lv; // restore bounds
// create the splitting node
ANNkd_split *ptr = new ANNkd_split(cd, cv, lv, hv, lo, hi);
return ptr; // return pointer to this node
}
}
//----------------------------------------------------------------------
// kd-tree constructor
// This is the main constructor for kd-trees given a set of points.
// It first builds a skeleton tree, then computes the bounding box
// of the data points, and then invokes rkd_tree() to actually
// build the tree, passing it the appropriate splitting routine.
//----------------------------------------------------------------------
ANNkd_tree::ANNkd_tree( // construct from point array
ANNpointArray pa, // point array (with at least n pts)
int n, // number of points
int dd, // dimension
int bs, // bucket size
ANNsplitRule split) // splitting method
{
SkeletonTree(n, dd, bs); // set up the basic stuff
pts = pa; // where the points are
if (n == 0) return; // no points--no sweat
ANNorthRect bnd_box(dd); // bounding box for points
annEnclRect(pa, pidx, n, dd, bnd_box);// construct bounding rectangle
// copy to tree structure
bnd_box_lo = annCopyPt(dd, bnd_box.lo);
bnd_box_hi = annCopyPt(dd, bnd_box.hi);
switch (split) { // build by rule
case ANN_KD_STD: // standard kd-splitting rule
root = rkd_tree(pa, pidx, n, dd, bs, bnd_box, kd_split);
break;
case ANN_KD_MIDPT: // midpoint split
root = rkd_tree(pa, pidx, n, dd, bs, bnd_box, midpt_split);
break;
case ANN_KD_FAIR: // fair split
root = rkd_tree(pa, pidx, n, dd, bs, bnd_box, fair_split);
break;
case ANN_KD_SUGGEST: // best (in our opinion)
case ANN_KD_SL_MIDPT: // sliding midpoint split
root = rkd_tree(pa, pidx, n, dd, bs, bnd_box, sl_midpt_split);
break;
case ANN_KD_SL_FAIR: // sliding fair split
root = rkd_tree(pa, pidx, n, dd, bs, bnd_box, sl_fair_split);
break;
default:
annError("Illegal splitting method", ANNabort);
}
}

View File

@@ -1,197 +0,0 @@
//----------------------------------------------------------------------
// File: kd_tree.h
// Programmer: Sunil Arya and David Mount
// Description: Declarations for standard kd-tree routines
// Last modified: 05/03/05 (Version 1.1)
//----------------------------------------------------------------------
// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and
// David Mount. All Rights Reserved.
//
// This software and related documentation is part of the Approximate
// Nearest Neighbor Library (ANN). This software is provided under
// the provisions of the Lesser GNU Public License (LGPL). See the
// file ../ReadMe.txt for further information.
//
// The University of Maryland (U.M.) and the authors make no
// representations about the suitability or fitness of this software for
// any purpose. It is provided "as is" without express or implied
// warranty.
//----------------------------------------------------------------------
// History:
// Revision 0.1 03/04/98
// Initial release
// Revision 1.1 05/03/05
// Added fixed radius kNN search
//----------------------------------------------------------------------
#ifndef ANN_kd_tree_H
#define ANN_kd_tree_H
#include <ANN/ANNx.h> // all ANN includes
using namespace std; // make std:: available
//----------------------------------------------------------------------
// Generic kd-tree node
//
// Nodes in kd-trees are of two types, splitting nodes which contain
// splitting information (a splitting hyperplane orthogonal to one
// of the coordinate axes) and leaf nodes which contain point
// information (an array of points stored in a bucket). This is
// handled by making a generic class kd_node, which is essentially an
// empty shell, and then deriving the leaf and splitting nodes from
// this.
//----------------------------------------------------------------------
class ANNkd_node{ // generic kd-tree node (empty shell)
public:
virtual ~ANNkd_node() {} // virtual distroyer
virtual void ann_search(ANNdist) = 0; // tree search
virtual void ann_pri_search(ANNdist) = 0; // priority search
virtual void ann_FR_search(ANNdist) = 0; // fixed-radius search
virtual void getStats( // get tree statistics
int dim, // dimension of space
ANNkdStats &st, // statistics
ANNorthRect &bnd_box) = 0; // bounding box
// print node
virtual void print(int level, ostream &out) = 0;
virtual void dump(ostream &out) = 0; // dump node
friend class ANNkd_tree; // allow kd-tree to access us
};
//----------------------------------------------------------------------
// kd-splitting function:
// kd_splitter is a pointer to a splitting routine for preprocessing.
// Different splitting procedures result in different strategies
// for building the tree.
//----------------------------------------------------------------------
typedef void (*ANNkd_splitter)( // splitting routine for kd-trees
ANNpointArray pa, // point array (unaltered)
ANNidxArray pidx, // point indices (permuted on return)
const ANNorthRect &bnds, // bounding rectangle for cell
int n, // number of points
int dim, // dimension of space
int &cut_dim, // cutting dimension (returned)
ANNcoord &cut_val, // cutting value (returned)
int &n_lo); // num of points on low side (returned)
//----------------------------------------------------------------------
// Leaf kd-tree node
// Leaf nodes of the kd-tree store the set of points associated
// with this bucket, stored as an array of point indices. These
// are indices in the array points, which resides with the
// root of the kd-tree. We also store the number of points
// that reside in this bucket.
//----------------------------------------------------------------------
class ANNkd_leaf: public ANNkd_node // leaf node for kd-tree
{
int n_pts; // no. points in bucket
ANNidxArray bkt; // bucket of points
public:
ANNkd_leaf( // constructor
int n, // number of points
ANNidxArray b) // bucket
{
n_pts = n; // number of points in bucket
bkt = b; // the bucket
}
~ANNkd_leaf() { } // destructor (none)
virtual void getStats( // get tree statistics
int dim, // dimension of space
ANNkdStats &st, // statistics
ANNorthRect &bnd_box); // bounding box
virtual void print(int level, ostream &out);// print node
virtual void dump(ostream &out); // dump node
virtual void ann_search(ANNdist); // standard search
virtual void ann_pri_search(ANNdist); // priority search
virtual void ann_FR_search(ANNdist); // fixed-radius search
};
//----------------------------------------------------------------------
// KD_TRIVIAL is a special pointer to an empty leaf node. Since
// some splitting rules generate many (more than 50%) trivial
// leaves, we use this one shared node to save space.
//
// The pointer is initialized to NULL, but whenever a kd-tree is
// created, we allocate this node, if it has not already been
// allocated. This node is *never* deallocated, so it produces
// a small memory leak.
//----------------------------------------------------------------------
extern ANNkd_leaf *KD_TRIVIAL; // trivial (empty) leaf node
//----------------------------------------------------------------------
// kd-tree splitting node.
// Splitting nodes contain a cutting dimension and a cutting value.
// These indicate the axis-parellel plane which subdivide the
// box for this node. The extent of the bounding box along the
// cutting dimension is maintained (this is used to speed up point
// to box distance calculations) [we do not store the entire bounding
// box since this may be wasteful of space in high dimensions].
// We also store pointers to the 2 children.
//----------------------------------------------------------------------
class ANNkd_split : public ANNkd_node // splitting node of a kd-tree
{
int cut_dim; // dim orthogonal to cutting plane
ANNcoord cut_val; // location of cutting plane
ANNcoord cd_bnds[2]; // lower and upper bounds of
// rectangle along cut_dim
ANNkd_ptr child[2]; // left and right children
public:
ANNkd_split( // constructor
int cd, // cutting dimension
ANNcoord cv, // cutting value
ANNcoord lv, ANNcoord hv, // low and high values
ANNkd_ptr lc=NULL, ANNkd_ptr hc=NULL) // children
{
cut_dim = cd; // cutting dimension
cut_val = cv; // cutting value
cd_bnds[ANN_LO] = lv; // lower bound for rectangle
cd_bnds[ANN_HI] = hv; // upper bound for rectangle
child[ANN_LO] = lc; // left child
child[ANN_HI] = hc; // right child
}
~ANNkd_split() // destructor
{
if (child[ANN_LO]!= NULL && child[ANN_LO]!= KD_TRIVIAL)
delete child[ANN_LO];
if (child[ANN_HI]!= NULL && child[ANN_HI]!= KD_TRIVIAL)
delete child[ANN_HI];
}
virtual void getStats( // get tree statistics
int dim, // dimension of space
ANNkdStats &st, // statistics
ANNorthRect &bnd_box); // bounding box
virtual void print(int level, ostream &out);// print node
virtual void dump(ostream &out); // dump node
virtual void ann_search(ANNdist); // standard search
virtual void ann_pri_search(ANNdist); // priority search
virtual void ann_FR_search(ANNdist); // fixed-radius search
};
//----------------------------------------------------------------------
// External entry points
//----------------------------------------------------------------------
ANNkd_ptr rkd_tree( // recursive construction of kd-tree
ANNpointArray pa, // point array (unaltered)
ANNidxArray pidx, // point indices to store in subtree
int n, // number of points
int dim, // dimension of space
int bsp, // bucket space
ANNorthRect &bnd_box, // bounding box for current node
ANNkd_splitter splitter); // splitting routine
#endif

View File

@@ -1,439 +0,0 @@
//----------------------------------------------------------------------
// File: kd_util.cpp
// Programmer: Sunil Arya and David Mount
// Description: Common utilities for kd-trees
// Last modified: 01/04/05 (Version 1.0)
//----------------------------------------------------------------------
// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and
// David Mount. All Rights Reserved.
//
// This software and related documentation is part of the Approximate
// Nearest Neighbor Library (ANN). This software is provided under
// the provisions of the Lesser GNU Public License (LGPL). See the
// file ../ReadMe.txt for further information.
//
// The University of Maryland (U.M.) and the authors make no
// representations about the suitability or fitness of this software for
// any purpose. It is provided "as is" without express or implied
// warranty.
//----------------------------------------------------------------------
// History:
// Revision 0.1 03/04/98
// Initial release
//----------------------------------------------------------------------
#include "kd_util.h" // kd-utility declarations
#include <ANN/ANNperf.h> // performance evaluation
//----------------------------------------------------------------------
// The following routines are utility functions for manipulating
// points sets, used in determining splitting planes for kd-tree
// construction.
//----------------------------------------------------------------------
//----------------------------------------------------------------------
// NOTE: Virtually all point indexing is done through an index (i.e.
// permutation) array pidx. Consequently, a reference to the d-th
// coordinate of the i-th point is pa[pidx[i]][d]. The macro PA(i,d)
// is a shorthand for this.
//----------------------------------------------------------------------
// standard 2-d indirect indexing
#define PA(i,d) (pa[pidx[(i)]][(d)])
// accessing a single point
#define PP(i) (pa[pidx[(i)]])
//----------------------------------------------------------------------
// annAspectRatio
// Compute the aspect ratio (ratio of longest to shortest side)
// of a rectangle.
//----------------------------------------------------------------------
double annAspectRatio(
int dim, // dimension
const ANNorthRect &bnd_box) // bounding cube
{
ANNcoord length = bnd_box.hi[0] - bnd_box.lo[0];
ANNcoord min_length = length; // min side length
ANNcoord max_length = length; // max side length
for (int d = 0; d < dim; d++) {
length = bnd_box.hi[d] - bnd_box.lo[d];
if (length < min_length) min_length = length;
if (length > max_length) max_length = length;
}
return max_length/min_length;
}
//----------------------------------------------------------------------
// annEnclRect, annEnclCube
// These utilities compute the smallest rectangle and cube enclosing
// a set of points, respectively.
//----------------------------------------------------------------------
void annEnclRect(
ANNpointArray pa, // point array
ANNidxArray pidx, // point indices
int n, // number of points
int dim, // dimension
ANNorthRect &bnds) // bounding cube (returned)
{
for (int d = 0; d < dim; d++) { // find smallest enclosing rectangle
ANNcoord lo_bnd = PA(0,d); // lower bound on dimension d
ANNcoord hi_bnd = PA(0,d); // upper bound on dimension d
for (int i = 0; i < n; i++) {
if (PA(i,d) < lo_bnd) lo_bnd = PA(i,d);
else if (PA(i,d) > hi_bnd) hi_bnd = PA(i,d);
}
bnds.lo[d] = lo_bnd;
bnds.hi[d] = hi_bnd;
}
}
void annEnclCube( // compute smallest enclosing cube
ANNpointArray pa, // point array
ANNidxArray pidx, // point indices
int n, // number of points
int dim, // dimension
ANNorthRect &bnds) // bounding cube (returned)
{
int d;
// compute smallest enclosing rect
annEnclRect(pa, pidx, n, dim, bnds);
ANNcoord max_len = 0; // max length of any side
for (d = 0; d < dim; d++) { // determine max side length
ANNcoord len = bnds.hi[d] - bnds.lo[d];
if (len > max_len) { // update max_len if longest
max_len = len;
}
}
for (d = 0; d < dim; d++) { // grow sides to match max
ANNcoord len = bnds.hi[d] - bnds.lo[d];
ANNcoord half_diff = (max_len - len) / 2;
bnds.lo[d] -= half_diff;
bnds.hi[d] += half_diff;
}
}
//----------------------------------------------------------------------
// annBoxDistance - utility routine which computes distance from point to
// box (Note: most distances to boxes are computed using incremental
// distance updates, not this function.)
//----------------------------------------------------------------------
ANNdist annBoxDistance( // compute distance from point to box
const ANNpoint q, // the point
const ANNpoint lo, // low point of box
const ANNpoint hi, // high point of box
int dim) // dimension of space
{
register ANNdist dist = 0.0; // sum of squared distances
register ANNdist t;
for (register int d = 0; d < dim; d++) {
if (q[d] < lo[d]) { // q is left of box
t = ANNdist(lo[d]) - ANNdist(q[d]);
dist = ANN_SUM(dist, ANN_POW(t));
}
else if (q[d] > hi[d]) { // q is right of box
t = ANNdist(q[d]) - ANNdist(hi[d]);
dist = ANN_SUM(dist, ANN_POW(t));
}
}
ANN_FLOP(4*dim) // increment floating op count
return dist;
}
//----------------------------------------------------------------------
// annSpread - find spread along given dimension
// annMinMax - find min and max coordinates along given dimension
// annMaxSpread - find dimension of max spread
//----------------------------------------------------------------------
ANNcoord annSpread( // compute point spread along dimension
ANNpointArray pa, // point array
ANNidxArray pidx, // point indices
int n, // number of points
int d) // dimension to check
{
ANNcoord min = PA(0,d); // compute max and min coords
ANNcoord max = PA(0,d);
for (int i = 1; i < n; i++) {
ANNcoord c = PA(i,d);
if (c < min) min = c;
else if (c > max) max = c;
}
return (max - min); // total spread is difference
}
void annMinMax( // compute min and max coordinates along dim
ANNpointArray pa, // point array
ANNidxArray pidx, // point indices
int n, // number of points
int d, // dimension to check
ANNcoord &min, // minimum value (returned)
ANNcoord &max) // maximum value (returned)
{
min = PA(0,d); // compute max and min coords
max = PA(0,d);
for (int i = 1; i < n; i++) {
ANNcoord c = PA(i,d);
if (c < min) min = c;
else if (c > max) max = c;
}
}
int annMaxSpread( // compute dimension of max spread
ANNpointArray pa, // point array
ANNidxArray pidx, // point indices
int n, // number of points
int dim) // dimension of space
{
int max_dim = 0; // dimension of max spread
ANNcoord max_spr = 0; // amount of max spread
if (n == 0) return max_dim; // no points, who cares?
for (int d = 0; d < dim; d++) { // compute spread along each dim
ANNcoord spr = annSpread(pa, pidx, n, d);
if (spr > max_spr) { // bigger than current max
max_spr = spr;
max_dim = d;
}
}
return max_dim;
}
//----------------------------------------------------------------------
// annMedianSplit - split point array about its median
// Splits a subarray of points pa[0..n] about an element of given
// rank (median: n_lo = n/2) with respect to dimension d. It places
// the element of rank n_lo-1 correctly (because our splitting rule
// takes the mean of these two). On exit, the array is permuted so
// that:
//
// pa[0..n_lo-2][d] <= pa[n_lo-1][d] <= pa[n_lo][d] <= pa[n_lo+1..n-1][d].
//
// The mean of pa[n_lo-1][d] and pa[n_lo][d] is returned as the
// splitting value.
//
// All indexing is done indirectly through the index array pidx.
//
// This function uses the well known selection algorithm due to
// C.A.R. Hoare.
//----------------------------------------------------------------------
// swap two points in pa array
#define PASWAP(a,b) { int tmp = pidx[a]; pidx[a] = pidx[b]; pidx[b] = tmp; }
void annMedianSplit(
ANNpointArray pa, // points to split
ANNidxArray pidx, // point indices
int n, // number of points
int d, // dimension along which to split
ANNcoord &cv, // cutting value
int n_lo) // split into n_lo and n-n_lo
{
int l = 0; // left end of current subarray
int r = n-1; // right end of current subarray
while (l < r) {
register int i = (r+l)/2; // select middle as pivot
register int k;
if (PA(i,d) > PA(r,d)) // make sure last > pivot
PASWAP(i,r)
PASWAP(l,i); // move pivot to first position
ANNcoord c = PA(l,d); // pivot value
i = l;
k = r;
for(;;) { // pivot about c
while (PA(++i,d) < c) ;
while (PA(--k,d) > c) ;
if (i < k) PASWAP(i,k) else break;
}
PASWAP(l,k); // pivot winds up in location k
if (k > n_lo) r = k-1; // recurse on proper subarray
else if (k < n_lo) l = k+1;
else break; // got the median exactly
}
if (n_lo > 0) { // search for next smaller item
ANNcoord c = PA(0,d); // candidate for max
int k = 0; // candidate's index
for (int i = 1; i < n_lo; i++) {
if (PA(i,d) > c) {
c = PA(i,d);
k = i;
}
}
PASWAP(n_lo-1, k); // max among pa[0..n_lo-1] to pa[n_lo-1]
}
// cut value is midpoint value
cv = (PA(n_lo-1,d) + PA(n_lo,d))/2.0;
}
//----------------------------------------------------------------------
// annPlaneSplit - split point array about a cutting plane
// Split the points in an array about a given plane along a
// given cutting dimension. On exit, br1 and br2 are set so
// that:
//
// pa[ 0 ..br1-1] < cv
// pa[br1..br2-1] == cv
// pa[br2.. n -1] > cv
//
// All indexing is done indirectly through the index array pidx.
//
//----------------------------------------------------------------------
void annPlaneSplit( // split points by a plane
ANNpointArray pa, // points to split
ANNidxArray pidx, // point indices
int n, // number of points
int d, // dimension along which to split
ANNcoord cv, // cutting value
int &br1, // first break (values < cv)
int &br2) // second break (values == cv)
{
int l = 0;
int r = n-1;
for(;;) { // partition pa[0..n-1] about cv
while (l < n && PA(l,d) < cv) l++;
while (r >= 0 && PA(r,d) >= cv) r--;
if (l > r) break;
PASWAP(l,r);
l++; r--;
}
br1 = l; // now: pa[0..br1-1] < cv <= pa[br1..n-1]
r = n-1;
for(;;) { // partition pa[br1..n-1] about cv
while (l < n && PA(l,d) <= cv) l++;
while (r >= br1 && PA(r,d) > cv) r--;
if (l > r) break;
PASWAP(l,r);
l++; r--;
}
br2 = l; // now: pa[br1..br2-1] == cv < pa[br2..n-1]
}
//----------------------------------------------------------------------
// annBoxSplit - split point array about a orthogonal rectangle
// Split the points in an array about a given orthogonal
// rectangle. On exit, n_in is set to the number of points
// that are inside (or on the boundary of) the rectangle.
//
// All indexing is done indirectly through the index array pidx.
//
//----------------------------------------------------------------------
void annBoxSplit( // split points by a box
ANNpointArray pa, // points to split
ANNidxArray pidx, // point indices
int n, // number of points
int dim, // dimension of space
ANNorthRect &box, // the box
int &n_in) // number of points inside (returned)
{
int l = 0;
int r = n-1;
for(;;) { // partition pa[0..n-1] about box
while (l < n && box.inside(dim, PP(l))) l++;
while (r >= 0 && !box.inside(dim, PP(r))) r--;
if (l > r) break;
PASWAP(l,r);
l++; r--;
}
n_in = l; // now: pa[0..n_in-1] inside and rest outside
}
//----------------------------------------------------------------------
// annSplitBalance - compute balance factor for a given plane split
// Balance factor is defined as the number of points lying
// below the splitting value minus n/2 (median). Thus, a
// median split has balance 0, left of this is negative and
// right of this is positive. (The points are unchanged.)
//----------------------------------------------------------------------
int annSplitBalance( // determine balance factor of a split
ANNpointArray pa, // points to split
ANNidxArray pidx, // point indices
int n, // number of points
int d, // dimension along which to split
ANNcoord cv) // cutting value
{
int n_lo = 0;
for(int i = 0; i < n; i++) { // count number less than cv
if (PA(i,d) < cv) n_lo++;
}
return n_lo - n/2;
}
//----------------------------------------------------------------------
// annBox2Bnds - convert bounding box to list of bounds
// Given two boxes, an inner box enclosed within a bounding
// box, this routine determines all the sides for which the
// inner box is strictly contained with the bounding box,
// and adds an appropriate entry to a list of bounds. Then
// we allocate storage for the final list of bounds, and return
// the resulting list and its size.
//----------------------------------------------------------------------
void annBox2Bnds( // convert inner box to bounds
const ANNorthRect &inner_box, // inner box
const ANNorthRect &bnd_box, // enclosing box
int dim, // dimension of space
int &n_bnds, // number of bounds (returned)
ANNorthHSArray &bnds) // bounds array (returned)
{
int i;
n_bnds = 0; // count number of bounds
for (i = 0; i < dim; i++) {
if (inner_box.lo[i] > bnd_box.lo[i]) // low bound is inside
n_bnds++;
if (inner_box.hi[i] < bnd_box.hi[i]) // high bound is inside
n_bnds++;
}
bnds = new ANNorthHalfSpace[n_bnds]; // allocate appropriate size
int j = 0;
for (i = 0; i < dim; i++) { // fill the array
if (inner_box.lo[i] > bnd_box.lo[i]) {
bnds[j].cd = i;
bnds[j].cv = inner_box.lo[i];
bnds[j].sd = +1;
j++;
}
if (inner_box.hi[i] < bnd_box.hi[i]) {
bnds[j].cd = i;
bnds[j].cv = inner_box.hi[i];
bnds[j].sd = -1;
j++;
}
}
}
//----------------------------------------------------------------------
// annBnds2Box - convert list of bounds to bounding box
// Given an enclosing box and a list of bounds, this routine
// computes the corresponding inner box. It is assumed that
// the box points have been allocated already.
//----------------------------------------------------------------------
void annBnds2Box(
const ANNorthRect &bnd_box, // enclosing box
int dim, // dimension of space
int n_bnds, // number of bounds
ANNorthHSArray bnds, // bounds array
ANNorthRect &inner_box) // inner box (returned)
{
annAssignRect(dim, inner_box, bnd_box); // copy bounding box to inner
for (int i = 0; i < n_bnds; i++) {
bnds[i].project(inner_box.lo); // project each endpoint
bnds[i].project(inner_box.hi);
}
}

View File

@@ -1,124 +0,0 @@
//----------------------------------------------------------------------
// File: kd_util.h
// Programmer: Sunil Arya and David Mount
// Description: Common utilities for kd- trees
// Last modified: 01/04/05 (Version 1.0)
//----------------------------------------------------------------------
// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and
// David Mount. All Rights Reserved.
//
// This software and related documentation is part of the Approximate
// Nearest Neighbor Library (ANN). This software is provided under
// the provisions of the Lesser GNU Public License (LGPL). See the
// file ../ReadMe.txt for further information.
//
// The University of Maryland (U.M.) and the authors make no
// representations about the suitability or fitness of this software for
// any purpose. It is provided "as is" without express or implied
// warranty.
//----------------------------------------------------------------------
// History:
// Revision 0.1 03/04/98
// Initial release
//----------------------------------------------------------------------
#ifndef ANN_kd_util_H
#define ANN_kd_util_H
#include "kd_tree.h" // kd-tree declarations
//----------------------------------------------------------------------
// externally accessible functions
//----------------------------------------------------------------------
double annAspectRatio( // compute aspect ratio of box
int dim, // dimension
const ANNorthRect &bnd_box); // bounding cube
void annEnclRect( // compute smallest enclosing rectangle
ANNpointArray pa, // point array
ANNidxArray pidx, // point indices
int n, // number of points
int dim, // dimension
ANNorthRect &bnds); // bounding cube (returned)
void annEnclCube( // compute smallest enclosing cube
ANNpointArray pa, // point array
ANNidxArray pidx, // point indices
int n, // number of points
int dim, // dimension
ANNorthRect &bnds); // bounding cube (returned)
ANNdist annBoxDistance( // compute distance from point to box
const ANNpoint q, // the point
const ANNpoint lo, // low point of box
const ANNpoint hi, // high point of box
int dim); // dimension of space
ANNcoord annSpread( // compute point spread along dimension
ANNpointArray pa, // point array
ANNidxArray pidx, // point indices
int n, // number of points
int d); // dimension to check
void annMinMax( // compute min and max coordinates along dim
ANNpointArray pa, // point array
ANNidxArray pidx, // point indices
int n, // number of points
int d, // dimension to check
ANNcoord& min, // minimum value (returned)
ANNcoord& max); // maximum value (returned)
int annMaxSpread( // compute dimension of max spread
ANNpointArray pa, // point array
ANNidxArray pidx, // point indices
int n, // number of points
int dim); // dimension of space
void annMedianSplit( // split points along median value
ANNpointArray pa, // points to split
ANNidxArray pidx, // point indices
int n, // number of points
int d, // dimension along which to split
ANNcoord &cv, // cutting value
int n_lo); // split into n_lo and n-n_lo
void annPlaneSplit( // split points by a plane
ANNpointArray pa, // points to split
ANNidxArray pidx, // point indices
int n, // number of points
int d, // dimension along which to split
ANNcoord cv, // cutting value
int &br1, // first break (values < cv)
int &br2); // second break (values == cv)
void annBoxSplit( // split points by a box
ANNpointArray pa, // points to split
ANNidxArray pidx, // point indices
int n, // number of points
int dim, // dimension of space
ANNorthRect &box, // the box
int &n_in); // number of points inside (returned)
int annSplitBalance( // determine balance factor of a split
ANNpointArray pa, // points to split
ANNidxArray pidx, // point indices
int n, // number of points
int d, // dimension along which to split
ANNcoord cv); // cutting value
void annBox2Bnds( // convert inner box to bounds
const ANNorthRect &inner_box, // inner box
const ANNorthRect &bnd_box, // enclosing box
int dim, // dimension of space
int &n_bnds, // number of bounds (returned)
ANNorthHSArray &bnds); // bounds array (returned)
void annBnds2Box( // convert bounds to inner box
const ANNorthRect &bnd_box, // enclosing box
int dim, // dimension of space
int n_bnds, // number of bounds
ANNorthHSArray bnds, // bounds array
ANNorthRect &inner_box); // inner box (returned)
#endif

View File

@@ -1,134 +0,0 @@
//----------------------------------------------------------------------
// File: perf.cpp
// Programmer: Sunil Arya and David Mount
// Description: Methods for performance stats
// Last modified: 01/04/05 (Version 1.0)
//----------------------------------------------------------------------
// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and
// David Mount. All Rights Reserved.
//
// This software and related documentation is part of the Approximate
// Nearest Neighbor Library (ANN). This software is provided under
// the provisions of the Lesser GNU Public License (LGPL). See the
// file ../ReadMe.txt for further information.
//
// The University of Maryland (U.M.) and the authors make no
// representations about the suitability or fitness of this software for
// any purpose. It is provided "as is" without express or implied
// warranty.
//----------------------------------------------------------------------
// History:
// Revision 0.1 03/04/98
// Initial release
// Revision 1.0 04/01/05
// Changed names to avoid namespace conflicts.
// Added flush after printing performance stats to fix bug
// in Microsoft Windows version.
//----------------------------------------------------------------------
#include <ANN/ANN.h> // basic ANN includes
#include <ANN/ANNperf.h> // performance includes
using namespace std; // make std:: available
//----------------------------------------------------------------------
// Performance statistics
// The following data and routines are used for computing
// performance statistics for nearest neighbor searching.
// Because these routines can slow the code down, they can be
// activated and deactiviated by defining the PERF variable,
// by compiling with the option: -DPERF
//----------------------------------------------------------------------
//----------------------------------------------------------------------
// Global counters for performance measurement
//----------------------------------------------------------------------
int ann_Ndata_pts = 0; // number of data points
int ann_Nvisit_lfs = 0; // number of leaf nodes visited
int ann_Nvisit_spl = 0; // number of splitting nodes visited
int ann_Nvisit_shr = 0; // number of shrinking nodes visited
int ann_Nvisit_pts = 0; // visited points for one query
int ann_Ncoord_hts = 0; // coordinate hits for one query
int ann_Nfloat_ops = 0; // floating ops for one query
ANNsampStat ann_visit_lfs; // stats on leaf nodes visits
ANNsampStat ann_visit_spl; // stats on splitting nodes visits
ANNsampStat ann_visit_shr; // stats on shrinking nodes visits
ANNsampStat ann_visit_nds; // stats on total nodes visits
ANNsampStat ann_visit_pts; // stats on points visited
ANNsampStat ann_coord_hts; // stats on coordinate hits
ANNsampStat ann_float_ops; // stats on floating ops
//
ANNsampStat ann_average_err; // average error
ANNsampStat ann_rank_err; // rank error
//----------------------------------------------------------------------
// Routines for statistics.
//----------------------------------------------------------------------
DLL_API void annResetStats(int data_size) // reset stats for a set of queries
{
ann_Ndata_pts = data_size;
ann_visit_lfs.reset();
ann_visit_spl.reset();
ann_visit_shr.reset();
ann_visit_nds.reset();
ann_visit_pts.reset();
ann_coord_hts.reset();
ann_float_ops.reset();
ann_average_err.reset();
ann_rank_err.reset();
}
DLL_API void annResetCounts() // reset counts for one query
{
ann_Nvisit_lfs = 0;
ann_Nvisit_spl = 0;
ann_Nvisit_shr = 0;
ann_Nvisit_pts = 0;
ann_Ncoord_hts = 0;
ann_Nfloat_ops = 0;
}
DLL_API void annUpdateStats() // update stats with current counts
{
ann_visit_lfs += ann_Nvisit_lfs;
ann_visit_nds += ann_Nvisit_spl + ann_Nvisit_lfs;
ann_visit_spl += ann_Nvisit_spl;
ann_visit_shr += ann_Nvisit_shr;
ann_visit_pts += ann_Nvisit_pts;
ann_coord_hts += ann_Ncoord_hts;
ann_float_ops += ann_Nfloat_ops;
}
// print a single statistic
void print_one_stat(char *title, ANNsampStat s, double div)
{
cout << title << "= [ ";
cout.width(9); cout << s.mean()/div << " : ";
cout.width(9); cout << s.stdDev()/div << " ]<";
cout.width(9); cout << s.min()/div << " , ";
cout.width(9); cout << s.max()/div << " >\n";
}
DLL_API void annPrintStats( // print statistics for a run
ANNbool validate) // true if average errors desired
{
cout.precision(4); // set floating precision
cout << " (Performance stats: "
<< " [ mean : stddev ]< min , max >\n";
print_one_stat(" leaf_nodes ", ann_visit_lfs, 1);
print_one_stat(" splitting_nodes ", ann_visit_spl, 1);
print_one_stat(" shrinking_nodes ", ann_visit_shr, 1);
print_one_stat(" total_nodes ", ann_visit_nds, 1);
print_one_stat(" points_visited ", ann_visit_pts, 1);
print_one_stat(" coord_hits/pt ", ann_coord_hts, ann_Ndata_pts);
print_one_stat(" floating_ops_(K) ", ann_float_ops, 1000);
if (validate) {
print_one_stat(" average_error ", ann_average_err, 1);
print_one_stat(" rank_error ", ann_rank_err, 1);
}
cout.precision(0); // restore the default
cout << " )\n";
cout.flush();
}

View File

@@ -1,125 +0,0 @@
//----------------------------------------------------------------------
// File: pr_queue.h
// Programmer: Sunil Arya and David Mount
// Description: Include file for priority queue and related
// structures.
// Last modified: 01/04/05 (Version 1.0)
//----------------------------------------------------------------------
// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and
// David Mount. All Rights Reserved.
//
// This software and related documentation is part of the Approximate
// Nearest Neighbor Library (ANN). This software is provided under
// the provisions of the Lesser GNU Public License (LGPL). See the
// file ../ReadMe.txt for further information.
//
// The University of Maryland (U.M.) and the authors make no
// representations about the suitability or fitness of this software for
// any purpose. It is provided "as is" without express or implied
// warranty.
//----------------------------------------------------------------------
// History:
// Revision 0.1 03/04/98
// Initial release
//----------------------------------------------------------------------
#ifndef PR_QUEUE_H
#define PR_QUEUE_H
#include <ANN/ANNx.h> // all ANN includes
#include <ANN/ANNperf.h> // performance evaluation
//----------------------------------------------------------------------
// Basic types.
//----------------------------------------------------------------------
typedef void *PQinfo; // info field is generic pointer
typedef ANNdist PQkey; // key field is distance
//----------------------------------------------------------------------
// Priority queue
// A priority queue is a list of items, along with associated
// priorities. The basic operations are insert and extract_minimum.
//
// The priority queue is maintained using a standard binary heap.
// (Implementation note: Indexing is performed from [1..max] rather
// than the C standard of [0..max-1]. This simplifies parent/child
// computations.) User information consists of a void pointer,
// and the user is responsible for casting this quantity into whatever
// useful form is desired.
//
// Because the priority queue is so central to the efficiency of
// query processing, all the code is inline.
//----------------------------------------------------------------------
class ANNpr_queue {
struct pq_node { // node in priority queue
PQkey key; // key value
PQinfo info; // info field
};
int n; // number of items in queue
int max_size; // maximum queue size
pq_node *pq; // the priority queue (array of nodes)
public:
ANNpr_queue(int max) // constructor (given max size)
{
n = 0; // initially empty
max_size = max; // maximum number of items
pq = new pq_node[max+1]; // queue is array [1..max] of nodes
}
~ANNpr_queue() // destructor
{ delete [] pq; }
ANNbool empty() // is queue empty?
{ if (n==0) return ANNtrue; else return ANNfalse; }
ANNbool non_empty() // is queue nonempty?
{ if (n==0) return ANNfalse; else return ANNtrue; }
void reset() // make existing queue empty
{ n = 0; }
inline void insert( // insert item (inlined for speed)
PQkey kv, // key value
PQinfo inf) // item info
{
if (++n > max_size) annError("Priority queue overflow.", ANNabort);
register int r = n;
while (r > 1) { // sift up new item
register int p = r/2;
ANN_FLOP(1) // increment floating ops
if (pq[p].key <= kv) // in proper order
break;
pq[r] = pq[p]; // else swap with parent
r = p;
}
pq[r].key = kv; // insert new item at final location
pq[r].info = inf;
}
inline void extr_min( // extract minimum (inlined for speed)
PQkey &kv, // key (returned)
PQinfo &inf) // item info (returned)
{
kv = pq[1].key; // key of min item
inf = pq[1].info; // information of min item
register PQkey kn = pq[n--].key;// last item in queue
register int p = 1; // p points to item out of position
register int r = p<<1; // left child of p
while (r <= n) { // while r is still within the heap
ANN_FLOP(2) // increment floating ops
// set r to smaller child of p
if (r < n && pq[r].key > pq[r+1].key) r++;
if (kn <= pq[r].key) // in proper order
break;
pq[p] = pq[r]; // else swap with child
p = r; // advance pointers
r = p<<1;
}
pq[p] = pq[n+1]; // insert last item in proper place
}
};
#endif

View File

@@ -1,118 +0,0 @@
//----------------------------------------------------------------------
// File: pr_queue_k.h
// Programmer: Sunil Arya and David Mount
// Description: Include file for priority queue with k items.
// Last modified: 01/04/05 (Version 1.0)
//----------------------------------------------------------------------
// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and
// David Mount. All Rights Reserved.
//
// This software and related documentation is part of the Approximate
// Nearest Neighbor Library (ANN). This software is provided under
// the provisions of the Lesser GNU Public License (LGPL). See the
// file ../ReadMe.txt for further information.
//
// The University of Maryland (U.M.) and the authors make no
// representations about the suitability or fitness of this software for
// any purpose. It is provided "as is" without express or implied
// warranty.
//----------------------------------------------------------------------
// History:
// Revision 0.1 03/04/98
// Initial release
//----------------------------------------------------------------------
#ifndef PR_QUEUE_K_H
#define PR_QUEUE_K_H
#include <ANN/ANNx.h> // all ANN includes
#include <ANN/ANNperf.h> // performance evaluation
//----------------------------------------------------------------------
// Basic types
//----------------------------------------------------------------------
typedef ANNdist PQKkey; // key field is distance
typedef int PQKinfo; // info field is int
//----------------------------------------------------------------------
// Constants
// The NULL key value is used to initialize the priority queue, and
// so it should be larger than any valid distance, so that it will
// be replaced as legal distance values are inserted. The NULL
// info value must be a nonvalid array index, we use ANN_NULL_IDX,
// which is guaranteed to be negative.
//----------------------------------------------------------------------
const PQKkey PQ_NULL_KEY = ANN_DIST_INF; // nonexistent key value
const PQKinfo PQ_NULL_INFO = ANN_NULL_IDX; // nonexistent info value
//----------------------------------------------------------------------
// ANNmin_k
// An ANNmin_k structure is one which maintains the smallest
// k values (of type PQKkey) and associated information (of type
// PQKinfo). The special info and key values PQ_NULL_INFO and
// PQ_NULL_KEY means that thise entry is empty.
//
// It is currently implemented using an array with k items.
// Items are stored in increasing sorted order, and insertions
// are made through standard insertion sort. (This is quite
// inefficient, but current applications call for small values
// of k and relatively few insertions.)
//
// Note that the list contains k+1 entries, but the last entry
// is used as a simple placeholder and is otherwise ignored.
//----------------------------------------------------------------------
class ANNmin_k {
struct mk_node { // node in min_k structure
PQKkey key; // key value
PQKinfo info; // info field (user defined)
};
int k; // max number of keys to store
int n; // number of keys currently active
mk_node *mk; // the list itself
public:
ANNmin_k(int max) // constructor (given max size)
{
n = 0; // initially no items
k = max; // maximum number of items
mk = new mk_node[max+1]; // sorted array of keys
}
~ANNmin_k() // destructor
{ delete [] mk; }
PQKkey ANNmin_key() // return minimum key
{ return (n > 0 ? mk[0].key : PQ_NULL_KEY); }
PQKkey max_key() // return maximum key
{ return (n == k ? mk[k-1].key : PQ_NULL_KEY); }
PQKkey ith_smallest_key(int i) // ith smallest key (i in [0..n-1])
{ return (i < n ? mk[i].key : PQ_NULL_KEY); }
PQKinfo ith_smallest_info(int i) // info for ith smallest (i in [0..n-1])
{ return (i < n ? mk[i].info : PQ_NULL_INFO); }
inline void insert( // insert item (inlined for speed)
PQKkey kv, // key value
PQKinfo inf) // item info
{
register int i;
// slide larger values up
for (i = n; i > 0; i--) {
if (mk[i-1].key > kv)
mk[i] = mk[i-1];
else
break;
}
mk[i].key = kv; // store element here
mk[i].info = inf;
if (n < k) n++; // increment number of items
ANN_FLOP(k-i+1) // increment floating ops
}
};
#endif

View File

@@ -1,96 +0,0 @@
#-----------------------------------------------------------------------------
# Makefile for the test and evaluation program
#
# ANN: Approximate Nearest Neighbors
# Version: 1.1.1 08/04/06
#-----------------------------------------------------------------------------
# Copyright (c) 1997-2005 University of Maryland and Sunil Arya and
# David Mount. All Rights Reserved.
#
# This software and related documentation is part of the Approximate
# Nearest Neighbor Library (ANN). This software is provided under
# the provisions of the Lesser GNU Public License (LGPL). See the
# file ../ReadMe.txt for further information.
#
# The University of Maryland (U.M.) and the authors make no
# representations about the suitability or fitness of this software for
# any purpose. It is provided "as is" without express or implied
# warranty.
#-----------------------------------------------------------------------------
# Revision 0.1 03/04/98
# Initial release
# Revision 1.1.1 08/04/06
# Added copyright/license
#-----------------------------------------------------------------------------
# Note: For full performance measurements, it is assumed that the library
# and this program have both been compiled with the -DANN_PERF flag. See
# the Makefile in the ANN base directory for this flag.
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# Basic definitions
# BASEDIR where include, src, lib, ... are
# INCDIR include directory
# LIBDIR library directory
# BINDIR bin directory
# LDFLAGS loader flags
# ANNLIBS ANN library
# OTHERLIBS other libraries
#-----------------------------------------------------------------------------
BASEDIR = ..
INCDIR = $(BASEDIR)/include
LIBDIR = $(BASEDIR)/lib
BINDIR = $(BASEDIR)/bin
LDFLAGS = -L$(LIBDIR)
ANNLIBS = -lANN
OTHERLIBS = -lm
#-----------------------------------------------------------------------------
# Some more definitions
# ANNTEST name of test program
#-----------------------------------------------------------------------------
ANNTEST = ann_test
HEADERS = rand.h
TESTSOURCES = ann_test.cpp rand.cpp
TESTOBJECTS = $(TESTSOURCES:.cpp=.o)
#-----------------------------------------------------------------------------
# Make the program
#-----------------------------------------------------------------------------
default:
@echo "Specify a target configuration"
targets: $(BINDIR)/$(ANNTEST)
$(BINDIR)/$(ANNTEST): $(TESTOBJECTS) $(LIBDIR)/$(ANNLIB)
$(C++) $(TESTOBJECTS) -o $(ANNTEST) $(LDFLAGS) $(ANNLIBS) $(OTHERLIBS)
mv $(ANNTEST) $(BINDIR)
#-----------------------------------------------------------------------------
# configuration definitions
#-----------------------------------------------------------------------------
include ../Make-config
#-----------------------------------------------------------------------------
# Objects
#-----------------------------------------------------------------------------
ann_test.o: ann_test.cpp
$(C++) -c -I$(INCDIR) $(CFLAGS) ann_test.cpp
rand.o: rand.cpp
$(C++) -c -I$(INCDIR) $(CFLAGS) rand.cpp
#-----------------------------------------------------------------------------
# Cleaning
#-----------------------------------------------------------------------------
clean:
-rm -f *.o *.out core
realclean: clean

File diff suppressed because it is too large Load Diff

View File

@@ -1,594 +0,0 @@
//----------------------------------------------------------------------
// File: rand.cpp
// Programmer: Sunil Arya and David Mount
// Description: Routines for random point generation
// Last modified: 08/04/06 (Version 1.1.1)
//----------------------------------------------------------------------
// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and
// David Mount. All Rights Reserved.
//
// This software and related documentation is part of the Approximate
// Nearest Neighbor Library (ANN). This software is provided under
// the provisions of the Lesser GNU Public License (LGPL). See the
// file ../ReadMe.txt for further information.
//
// The University of Maryland (U.M.) and the authors make no
// representations about the suitability or fitness of this software for
// any purpose. It is provided "as is" without express or implied
// warranty.
//----------------------------------------------------------------------
// History:
// Revision 0.1 03/04/98
// Initial release
// Revision 0.2 03/26/98
// Changed random/srandom declarations for SGI's.
// Revision 1.0 04/01/05
// annClusGauss centers distributed over [-1,1] rather than [0,1]
// Added annClusOrthFlats distribution
// Changed procedure names to avoid namespace conflicts
// Added annClusFlats distribution
// Added rand/srand option and fixed annRan0() initialization.
// Revision 1.1.1 08/04/06
// Added planted distribution
//----------------------------------------------------------------------
#include "rand.h" // random generator declarations
using namespace std; // make std:: accessible
//----------------------------------------------------------------------
// Globals
//----------------------------------------------------------------------
int annIdum = 0; // used for random number generation
//------------------------------------------------------------------------
// annRan0 - (safer) uniform random number generator
//
// The code given here is taken from "Numerical Recipes in C" by
// William Press, Brian Flannery, Saul Teukolsky, and William
// Vetterling. The task of the code is to do an additional randomizing
// shuffle on the system-supplied random number generator to make it
// safer to use.
//
// Returns a uniform deviate between 0.0 and 1.0 using the
// system-supplied routine random() or rand(). Set the global
// annIdum to any negative value to initialise or reinitialise
// the sequence.
//------------------------------------------------------------------------
double annRan0()
{
const int TAB_SIZE = 97; // table size: any large number
int j;
static double y, v[TAB_SIZE];
static int iff = 0;
const double RAN_DIVISOR = double(ANN_RAND_MAX + 1UL);
if (RAN_DIVISOR < 0) {
cout << "RAN_DIVISOR " << RAN_DIVISOR << endl;
exit(0);
}
//--------------------------------------------------------------------
// As a precaution against misuse, we will always initialize on the
// first call, even if "annIdum" is not set negative. Determine
// "maxran", the next integer after the largest representable value
// of type int. We assume this is a factor of 2 smaller than the
// corresponding value of type unsigned int.
//--------------------------------------------------------------------
if (annIdum < 0 || iff == 0) { // initialize
iff = 1;
ANN_SRAND(annIdum); // (re)seed the generator
annIdum = 1;
for (j = 0; j < TAB_SIZE; j++) // exercise the system routine
ANN_RAND(); // (values intentionally ignored)
for (j = 0; j < TAB_SIZE; j++) // then save TAB_SIZE-1 values
v[j] = ANN_RAND();
y = ANN_RAND(); // generate starting value
}
//--------------------------------------------------------------------
// This is where we start if not initializing. Use the previously
// saved random number y to get an index j between 1 and TAB_SIZE-1.
// Then use the corresponding v[j] for both the next j and as the
// output number.
//--------------------------------------------------------------------
j = int(TAB_SIZE * (y / RAN_DIVISOR));
y = v[j];
v[j] = ANN_RAND(); // refill the table entry
return y / RAN_DIVISOR;
}
//------------------------------------------------------------------------
// annRanInt - generate a random integer from {0,1,...,n-1}
//
// If n == 0, then -1 is returned.
//------------------------------------------------------------------------
static int annRanInt(
int n)
{
int r = (int) (annRan0()*n);
if (r == n) r--; // (in case annRan0() == 1 or n == 0)
return r;
}
//------------------------------------------------------------------------
// annRanUnif - generate a random uniform in [lo,hi]
//------------------------------------------------------------------------
static double annRanUnif(
double lo,
double hi)
{
return annRan0()*(hi-lo) + lo;
}
//------------------------------------------------------------------------
// annRanGauss - Gaussian random number generator
// Returns a normally distributed deviate with zero mean and unit
// variance, using annRan0() as the source of uniform deviates.
//------------------------------------------------------------------------
static double annRanGauss()
{
static int iset=0;
static double gset;
if (iset == 0) { // we don't have a deviate handy
double v1, v2;
double r = 2.0;
while (r >= 1.0) {
//------------------------------------------------------------
// Pick two uniform numbers in the square extending from -1 to
// +1 in each direction, see if they are in the circle of radius
// 1. If not, try again
//------------------------------------------------------------
v1 = annRanUnif(-1, 1);
v2 = annRanUnif(-1, 1);
r = v1 * v1 + v2 * v2;
}
double fac = sqrt(-2.0 * log(r) / r);
//-----------------------------------------------------------------
// Now make the Box-Muller transformation to get two normal
// deviates. Return one and save the other for next time.
//-----------------------------------------------------------------
gset = v1 * fac;
iset = 1; // set flag
return v2 * fac;
}
else { // we have an extra deviate handy
iset = 0; // so unset the flag
return gset; // and return it
}
}
//------------------------------------------------------------------------
// annRanLaplace - Laplacian random number generator
// Returns a Laplacian distributed deviate with zero mean and
// unit variance, using annRan0() as the source of uniform deviates.
//
// prob(x) = b/2 * exp(-b * |x|).
//
// b is chosen to be sqrt(2.0) so that the variance of the Laplacian
// distribution [2/(b^2)] becomes 1.
//------------------------------------------------------------------------
static double annRanLaplace()
{
const double b = 1.4142136;
double laprand = -log(annRan0()) / b;
double sign = annRan0();
if (sign < 0.5) laprand = -laprand;
return(laprand);
}
//----------------------------------------------------------------------
// annUniformPts - Generate uniformly distributed points
// A uniform distribution over [-1,1].
//----------------------------------------------------------------------
void annUniformPts( // uniform distribution
ANNpointArray pa, // point array (modified)
int n, // number of points
int dim) // dimension
{
for (int i = 0; i < n; i++) {
for (int d = 0; d < dim; d++) {
pa[i][d] = (ANNcoord) (annRanUnif(-1,1));
}
}
}
//----------------------------------------------------------------------
// annGaussPts - Generate Gaussian distributed points
// A Gaussian distribution with zero mean and the given standard
// deviation.
//----------------------------------------------------------------------
void annGaussPts( // Gaussian distribution
ANNpointArray pa, // point array (modified)
int n, // number of points
int dim, // dimension
double std_dev) // standard deviation
{
for (int i = 0; i < n; i++) {
for (int d = 0; d < dim; d++) {
pa[i][d] = (ANNcoord) (annRanGauss() * std_dev);
}
}
}
//----------------------------------------------------------------------
// annLaplacePts - Generate Laplacian distributed points
// Generates a Laplacian distribution (zero mean and unit variance).
//----------------------------------------------------------------------
void annLaplacePts( // Laplacian distribution
ANNpointArray pa, // point array (modified)
int n, // number of points
int dim) // dimension
{
for (int i = 0; i < n; i++) {
for (int d = 0; d < dim; d++) {
pa[i][d] = (ANNcoord) annRanLaplace();
}
}
}
//----------------------------------------------------------------------
// annCoGaussPts - Generate correlated Gaussian distributed points
// Generates a Gauss-Markov distribution of zero mean and unit
// variance.
//----------------------------------------------------------------------
void annCoGaussPts( // correlated-Gaussian distribution
ANNpointArray pa, // point array (modified)
int n, // number of points
int dim, // dimension
double correlation) // correlation
{
double std_dev_w = sqrt(1.0 - correlation * correlation);
for (int i = 0; i < n; i++) {
double previous = annRanGauss();
pa[i][0] = (ANNcoord) previous;
for (int d = 1; d < dim; d++) {
previous = correlation*previous + std_dev_w*annRanGauss();
pa[i][d] = (ANNcoord) previous;
}
}
}
//----------------------------------------------------------------------
// annCoLaplacePts - Generate correlated Laplacian distributed points
// Generates a Laplacian-Markov distribution of zero mean and unit
// variance.
//----------------------------------------------------------------------
void annCoLaplacePts( // correlated-Laplacian distribution
ANNpointArray pa, // point array (modified)
int n, // number of points
int dim, // dimension
double correlation) // correlation
{
double wn;
double corr_sq = correlation * correlation;
for (int i = 0; i < n; i++) {
double previous = annRanLaplace();
pa[i][0] = (ANNcoord) previous;
for (int d = 1; d < dim; d++) {
double temp = annRan0();
if (temp < corr_sq)
wn = 0.0;
else
wn = annRanLaplace();
previous = correlation * previous + wn;
pa[i][d] = (ANNcoord) previous;
}
}
}
//----------------------------------------------------------------------
// annClusGaussPts - Generate clusters of Gaussian distributed points
// Cluster centers are uniformly distributed over [-1,1], and the
// standard deviation within each cluster is fixed.
//
// Note: Once cluster centers have been set, they are not changed,
// unless new_clust = true. This is so that subsequent calls generate
// points from the same distribution. It follows, of course, that any
// attempt to change the dimension or number of clusters without
// generating new clusters is asking for trouble.
//
// Note: Cluster centers are not generated by a call to uniformPts().
// Although this could be done, it has been omitted for
// compatibility with annClusGaussPts() in the colored version,
// rand_c.cc.
//----------------------------------------------------------------------
void annClusGaussPts( // clustered-Gaussian distribution
ANNpointArray pa, // point array (modified)
int n, // number of points
int dim, // dimension
int n_clus, // number of colors
ANNbool new_clust, // generate new clusters.
double std_dev) // standard deviation within clusters
{
static ANNpointArray clusters = NULL;// cluster storage
if (clusters == NULL || new_clust) {// need new cluster centers
if (clusters != NULL) // clusters already exist
annDeallocPts(clusters); // get rid of them
clusters = annAllocPts(n_clus, dim);
// generate cluster center coords
for (int i = 0; i < n_clus; i++) {
for (int d = 0; d < dim; d++) {
clusters[i][d] = (ANNcoord) annRanUnif(-1,1);
}
}
}
for (int i = 0; i < n; i++) {
int c = annRanInt(n_clus); // generate cluster index
for (int d = 0; d < dim; d++) {
pa[i][d] = (ANNcoord) (std_dev*annRanGauss() + clusters[c][d]);
}
}
}
//----------------------------------------------------------------------
// annClusOrthFlats - points clustered along orthogonal flats
//
// This distribution consists of a collection points clustered
// among a collection of axis-aligned low dimensional flats in
// the hypercube [-1,1]^d. A set of n_clus orthogonal flats are
// generated, each whose dimension is a random number between 1
// and max_dim. The points are evenly distributed among the clusters.
// For each cluster, we generate points uniformly distributed along
// the flat within the hypercube.
//
// This is done as follows. Each cluster is defined by a d-element
// control vector whose components are either:
//
// CO_FLAG indicating that this component is to be generated
// uniformly in [-1,1],
// x a value other than CO_FLAG in the range [-1,1],
// which indicates that this coordinate is to be
// generated as x plus a Gaussian random deviation
// with the given standard deviation.
//
// The number of zero components is the dimension of the flat, which
// is a random integer in the range from 1 to max_dim. The points
// are disributed between clusters in nearly equal sized groups.
//
// Note: Once cluster centers have been set, they are not changed,
// unless new_clust = true. This is so that subsequent calls generate
// points from the same distribution. It follows, of course, that any
// attempt to change the dimension or number of clusters without
// generating new clusters is asking for trouble.
//
// To make this a bad scenario at query time, query points should be
// selected from a different distribution, e.g. uniform or Gaussian.
//
// We use a little programming trick to generate groups of roughly
// equal size. If n is the total number of points, and n_clus is
// the number of clusters, then the c-th cluster (0 <= c < n_clus)
// is given floor((n+c)/n_clus) points. It can be shown that this
// will exactly consume all n points.
//
// This procedure makes use of the utility procedure, genOrthFlat
// which generates points in one orthogonal flat, according to
// the given control vector.
//
//----------------------------------------------------------------------
const double CO_FLAG = 999; // special flag value
static void genOrthFlat( // generate points on an orthog flat
ANNpointArray pa, // point array
int n, // number of points
int dim, // dimension
double *control, // control vector
double std_dev) // standard deviation
{
for (int i = 0; i < n; i++) { // generate each point
for (int d = 0; d < dim; d++) { // generate each coord
if (control[d] == CO_FLAG) // dimension on flat
pa[i][d] = (ANNcoord) annRanUnif(-1,1);
else // dimension off flat
pa[i][d] = (ANNcoord) (std_dev*annRanGauss() + control[d]);
}
}
}
void annClusOrthFlats( // clustered along orthogonal flats
ANNpointArray pa, // point array (modified)
int n, // number of points
int dim, // dimension
int n_clus, // number of colors
ANNbool new_clust, // generate new clusters.
double std_dev, // standard deviation within clusters
int max_dim) // maximum dimension of the flats
{
static ANNpointArray control = NULL; // control vectors
if (control == NULL || new_clust) { // need new cluster centers
if (control != NULL) { // clusters already exist
annDeallocPts(control); // get rid of them
}
control = annAllocPts(n_clus, dim);
for (int c = 0; c < n_clus; c++) { // generate clusters
int n_dim = 1 + annRanInt(max_dim); // number of dimensions in flat
for (int d = 0; d < dim; d++) { // generate side locations
// prob. of picking next dim
double Prob = ((double) n_dim)/((double) (dim-d));
if (annRan0() < Prob) { // add this one to flat
control[c][d] = CO_FLAG; // flag this entry
n_dim--; // one fewer dim to fill
}
else { // don't take this one
control[c][d] = annRanUnif(-1,1);// random value in [-1,1]
}
}
}
}
int offset = 0; // offset in pa array
for (int c = 0; c < n_clus; c++) { // generate clusters
int pick = (n+c)/n_clus; // number of points to pick
// generate the points
genOrthFlat(pa+offset, pick, dim, control[c], std_dev);
offset += pick; // increment offset
}
}
//----------------------------------------------------------------------
// annClusEllipsoids - points clustered around axis-aligned ellipsoids
//
// This distribution consists of a collection points clustered
// among a collection of low dimensional ellipsoids whose axes
// are alligned with the coordinate axes in the hypercube [-1,1]^d.
// The objective is to model distributions in which the points are
// distributed in lower dimensional subspaces, and within this
// lower dimensional space the points are distributed with a
// Gaussian distribution (with no correlation between the
// dimensions).
//
// The distribution is given the number of clusters or "colors"
// (n_clus), maximum number of dimensions (max_dim) of the lower
// dimensional subspace, a "small" standard deviation
// (std_dev_small), and a "large" standard deviation range
// (std_dev_lo, std_dev_hi).
//
// The algorithm generates n_clus cluster centers uniformly from
// the hypercube [-1,1]^d. For each cluster, it selects the
// dimension of the subspace as a random number r between 1 and
// max_dim. These are the dimensions of the ellipsoid. Then it
// generates a d-element std dev vector whose entries are the
// standard deviation for the coordinates of each cluster in the
// distribution. Among the d-element control vector, r randomly
// chosen values are chosen uniformly from the range [std_dev_lo,
// std_dev_hi]. The remaining values are set to std_dev_small.
//
// Note that annClusGaussPts is a special case of this in which
// max_dim = 0, and std_dev = std_dev_small.
//
// If the flag new_clust is set, then new cluster centers are
// generated.
//
// This procedure makes use of the utility procedure genGauss
// which generates points distributed according to a Gaussian
// distribution.
//
//----------------------------------------------------------------------
static void genGauss( // generate points on a general Gaussian
ANNpointArray pa, // point array
int n, // number of points
int dim, // dimension
double *center, // center vector
double *std_dev) // standard deviation vector
{
for (int i = 0; i < n; i++) {
for (int d = 0; d < dim; d++) {
pa[i][d] = (ANNcoord) (std_dev[d]*annRanGauss() + center[d]);
}
}
}
void annClusEllipsoids( // clustered around ellipsoids
ANNpointArray pa, // point array (modified)
int n, // number of points
int dim, // dimension
int n_clus, // number of colors
ANNbool new_clust, // generate new clusters.
double std_dev_small, // small standard deviation
double std_dev_lo, // low standard deviation for ellipses
double std_dev_hi, // high standard deviation for ellipses
int max_dim) // maximum dimension of the flats
{
static ANNpointArray centers = NULL; // cluster centers
static ANNpointArray std_dev = NULL; // standard deviations
if (centers == NULL || new_clust) { // need new cluster centers
if (centers != NULL) // clusters already exist
annDeallocPts(centers); // get rid of them
if (std_dev != NULL) // std deviations already exist
annDeallocPts(std_dev); // get rid of them
centers = annAllocPts(n_clus, dim); // alloc new clusters and devs
std_dev = annAllocPts(n_clus, dim);
for (int i = 0; i < n_clus; i++) { // gen cluster center coords
for (int d = 0; d < dim; d++) {
centers[i][d] = (ANNcoord) annRanUnif(-1,1);
}
}
for (int c = 0; c < n_clus; c++) { // generate cluster std dev
int n_dim = 1 + annRanInt(max_dim); // number of dimensions in flat
for (int d = 0; d < dim; d++) { // generate std dev's
// prob. of picking next dim
double Prob = ((double) n_dim)/((double) (dim-d));
if (annRan0() < Prob) { // add this one to ellipse
// generate random std dev
std_dev[c][d] = annRanUnif(std_dev_lo, std_dev_hi);
n_dim--; // one fewer dim to fill
}
else { // don't take this one
std_dev[c][d] = std_dev_small;// use small std dev
}
}
}
}
int offset = 0; // next slot to fill
for (int c = 0; c < n_clus; c++) { // generate clusters
int pick = (n+c)/n_clus; // number of points to pick
// generate the points
genGauss(pa+offset, pick, dim, centers[c], std_dev[c]);
offset += pick; // increment offset in array
}
}
//----------------------------------------------------------------------
// annPlanted - Generates points from a "planted" distribution
// In high dimensional spaces, interpoint distances tend to be
// highly clustered around the mean value. Approximate nearest
// neighbor searching makes little sense in this context, unless it
// is the case that each query point is significantly closer to its
// nearest neighbor than to other points. Thus, the query points
// should be planted close to the data points. Given a source data
// set, this procedure generates a set of query points having this
// property.
//
// We are given a source data array and a standard deviation. We
// generate points as follows. We select a random point from the
// source data set, and we generate a Gaussian point centered about
// this random point and perturbed by a normal distributed random
// variable with mean zero and the given standard deviation along
// each coordinate.
//
// Note that this essentially the same a clustered Gaussian
// distribution, but where the cluster centers are given by the
// source data set.
//----------------------------------------------------------------------
void annPlanted( // planted nearest neighbors
ANNpointArray pa, // point array (modified)
int n, // number of points
int dim, // dimension
ANNpointArray src, // source point array
int n_src, // source size
double std_dev) // standard deviation about source
{
for (int i = 0; i < n; i++) {
int c = annRanInt(n_src); // generate source index
for (int d = 0; d < dim; d++) {
pa[i][d] = (ANNcoord) (std_dev*annRanGauss() + src[c][d]);
}
}
}

View File

@@ -1,131 +0,0 @@
//----------------------------------------------------------------------
// File: rand.h
// Programmer: Sunil Arya and David Mount
// Description: Basic include file for random point generators
// Last modified: 08/04/06 (Version 1.1.1)
//----------------------------------------------------------------------
// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and
// David Mount. All Rights Reserved.
//
// This software and related documentation is part of the Approximate
// Nearest Neighbor Library (ANN). This software is provided under
// the provisions of the Lesser GNU Public License (LGPL). See the
// file ../ReadMe.txt for further information.
//
// The University of Maryland (U.M.) and the authors make no
// representations about the suitability or fitness of this software for
// any purpose. It is provided "as is" without express or implied
// warranty.
//----------------------------------------------------------------------
// History:
// Revision 0.1 03/04/98
// Initial release
// Revision 1.0 04/01/05
// Added annClusOrthFlats distribution
// Changed procedure names to avoid namespace conflicts
// Added annClusFlats distribution
// Revision 1.1.1 08/04/06
// Added planted distribution
//----------------------------------------------------------------------
#ifndef rand_H
#define rand_H
//----------------------------------------------------------------------
// Basic includes
//----------------------------------------------------------------------
#include <cstdlib> // standard includes (rand/random)
#include <cmath> // math routines
#include <ANN/ANN.h> // basic ANN includes
//----------------------------------------------------------------------
// Although random/srandom is a more reliable random number generator,
// many systems do not have it. If it is not available, set the
// preprocessor symbol ANN_NO_RANDOM, and this will substitute the use
// of rand/srand for them.
//----------------------------------------------------------------------
#ifdef ANN_NO_RANDOM // for systems not having random()
#define ANN_RAND rand
#define ANN_SRAND srand
#define ANN_RAND_MAX RAND_MAX
#else // otherwise use rand()
#define ANN_RAND random
#define ANN_SRAND srandom
#define ANN_RAND_MAX 2147483647UL // 2**{31} - 1
// #define ANN_RAND_MAX 1073741824UL // 2**{30}
#endif
//----------------------------------------------------------------------
// Globals
//----------------------------------------------------------------------
extern int annIdum; // random number seed
//----------------------------------------------------------------------
// External entry points
//----------------------------------------------------------------------
void annUniformPts( // uniform distribution
ANNpointArray pa, // point array (modified)
int n, // number of points
int dim); // dimension
void annGaussPts( // Gaussian distribution
ANNpointArray pa, // point array (modified)
int n, // number of points
int dim, // dimension
double std_dev); // standard deviation
void annCoGaussPts( // correlated-Gaussian distribution
ANNpointArray pa, // point array (modified)
int n, // number of points
int dim, // dimension
double correlation); // correlation
void annLaplacePts( // Laplacian distribution
ANNpointArray pa, // point array (modified)
int n, // number of points
int dim); // dimension
void annCoLaplacePts( // correlated-Laplacian distribution
ANNpointArray pa, // point array (modified)
int n, // number of points
int dim, // dimension
double correlation); // correlation
void annClusGaussPts( // clustered-Gaussian distribution
ANNpointArray pa, // point array (modified)
int n, // number of points
int dim, // dimension
int n_clus, // number of colors (clusters)
ANNbool new_clust, // generate new cluster centers
double std_dev); // standard deviation within clusters
void annClusOrthFlats( // clustered along orthogonal flats
ANNpointArray pa, // point array (modified)
int n, // number of points
int dim, // dimension
int n_clus, // number of colors
ANNbool new_clust, // generate new clusters.
double std_dev, // standard deviation within clusters
int max_dim); // maximum dimension of the flats
void annClusEllipsoids( // clustered around ellipsoids
ANNpointArray pa, // point array (modified)
int n, // number of points
int dim, // dimension
int n_clus, // number of colors
ANNbool new_clust, // generate new clusters.
double std_dev_small, // small standard deviation
double std_dev_lo, // low standard deviation for ellipses
double std_dev_hi, // high standard deviation for ellipses
int max_dim); // maximum dimension of the flats
void annPlanted( // planted nearest neighbors
ANNpointArray pa, // point array (modified)
int n, // number of points
int dim, // dimension
ANNpointArray src, // source point array
int n_src, // source size
double std_dev); // standard deviation about source
#endif

View File

@@ -1,20 +0,0 @@
-0.297462 0.176102
0.565538 -0.361496
0.909313 -0.182785
0.920712 0.478408
0.167682 0.0499836
0.305223 -0.0805835
0.114973 0.882453
0.742916 0.16376
0.0724605 -0.826775
0.690960 -0.559284
0.188485 -0.643934
0.749427 -0.942415
-0.970662 -0.223466
0.916110 0.879597
0.927417 -0.382593
-0.711327 0.278713
-0.519172 0.986146
0.135338 0.924588
-0.0837537 0.61687
0.0520465 0.896306

View File

@@ -1,10 +0,0 @@
0.0902484 -0.207129
-0.419567 0.485743
0.826225 -0.30962
0.694758 0.987088
-0.410807 -0.465182
-0.836501 0.490184
0.588289 0.656408
0.325807 0.38721
-0.532226 -0.727036
-0.52506 -0.853508

View File

@@ -1,15 +0,0 @@
validate on
stats query_stats
dim 2
data_size 20
query_size 10
read_data_pts test1-data.pts
read_query_pts test1-query.pts
bucket_size 1
near_neigh 3
split_rule suggest
shrink_rule none
build_ann
epsilon 0.0
run_queries standard
run_queries priority

View File

@@ -1,76 +0,0 @@
------------------------------------------------------------
ann_test: Version 1.0
Copyright: David M. Mount and Sunil Arya.
Latest Revision: Mar 1, 2005.
------------------------------------------------------------
validate = on (Warning: this may slow execution time.)
stats = query_stats
[Read Data Points:
data_size = 20
file_name = test1-data.pts
dim = 2
]
[Read Query Points:
query_size = 10
file_name = test1-query.pts
dim = 2
]
[Build ann-structure:
split_rule = suggest
shrink_rule = none
data_size = 20
dim = 2
bucket_size = 1
process_time = 0 sec
(Structure Statistics:
n_nodes = 39 (opt = 40, best if < 400)
n_leaves = 20 (0 contain no points)
n_splits = 19
n_shrinks = 0
empty_leaves = 0 percent (best if < 50 percent)
depth = 6 (opt = 4, best if < 17)
avg_aspect_ratio = 1.48847 (best if < 20)
)
]
(Computing true nearest neighbors for validation. This may take time.)
[Run Queries:
query_size = 10
dim = 2
search_method = standard
epsilon = 0
near_neigh = 3
true_nn = 13
query_time = 0 sec/query (biased by perf measurements)
(Performance stats: [ mean : stddev ]< min , max >
leaf_nodes = [ 6.3 : 2.751 ]< 4 , 11 >
splitting_nodes = [ 8.8 : 3.676 ]< 5 , 15 >
shrinking_nodes = [ 0 : 0 ]< 0 , 0 >
total_nodes = [ 15.1 : 6.35 ]< 9 , 26 >
points_visited = [ 6.3 : 2.751 ]< 4 , 11 >
coord_hits/pt = [ 0.57 : 0.2201 ]< 0.35 , 0.95 >
floating_ops_(K) = [ 0.156 : 0.0563 ]< 0.101 , 0.254 >
average_error = [ 0 : 0 ]< 0 , 0 >
rank_error = [ 0 : 0 ]< 0 , 0 >
)
]
[Run Queries:
query_size = 10
dim = 2
search_method = priority
epsilon = 0
near_neigh = 3
true_nn = 13
query_time = 0 sec/query (biased by perf measurements)
(Performance stats: [ mean : stddev ]< min , max >
leaf_nodes = [ 5.9 : 2.025 ]< 4 , 9 >
splitting_nodes = [ 8.7 : 3.498 ]< 5 , 15 >
shrinking_nodes = [ 0 : 0 ]< 0 , 0 >
total_nodes = [ 14.6 : 5.42 ]< 9 , 24 >
points_visited = [ 5.9 : 2.025 ]< 4 , 9 >
coord_hits/pt = [ 0.535 : 0.1667 ]< 0.35 , 0.8 >
floating_ops_(K) = [ 0.1719 : 0.05861 ]< 0.114 , 0.267 >
average_error = [ 0 : 0 ]< 0 , 0 >
rank_error = [ 0 : 0 ]< 0 , 0 >
)
]

File diff suppressed because it is too large Load Diff

View File

@@ -1,100 +0,0 @@
0.0902484 -0.207129 -0.419567 0.485743 0.826225 -0.30962 0.694758 0.987088
-0.410807 -0.465182 -0.836501 0.490184 0.588289 0.656408 0.325807 0.38721
-0.532226 -0.727036 -0.52506 -0.853508 0.28637 0.938617 -0.864754 0.622397
-0.408646 -0.522319 0.0388774 -0.893642 0.385806 0.890013 -0.38066 -0.524536
0.916427 -0.941696 0.219294 -0.971436 -0.706532 0.566439 -0.0591963 0.27756
0.692452 -0.210879 0.927987 0.587037 0.610211 0.895158 -0.228196 -0.314064
-0.13253 0.711121 0.605841 0.771335 -0.945103 0.356652 0.00215608 -0.54444
0.0611156 0.921316 0.245255 0.92896 0.562614 0.160313 -0.457179 -0.432326
-0.813199 -0.0630237 0.149021 0.0301869 0.669399 0.984082 -0.304983 0.480589
0.311004 0.515906 -0.667349 -0.464028 -0.554472 0.123471 -0.932191 0.153486
0.488214 -0.456547 0.695901 -0.693933 -0.775879 -0.940794 0.710796 -0.79388
-0.73914 -0.733084 0.300943 0.0726274 -0.722715 -0.414562 0.463033 -0.378469
-0.178166 -0.846243 -0.319029 0.186783 -0.364517 0.915747 -0.300208 -0.599272
-0.544192 0.173829 -0.0957917 0.889828 0.775796 0.148865 -0.430932 0.0342097
-0.969596 -0.545995 -0.98045 -0.57569 0.465756 -0.166752 0.622912 -0.580526
0.0918901 0.635361 -0.934228 -0.0273098 0.65055 0.227406 -0.628807 0.213824
0.216987 -0.653221 -0.789576 0.6252 0.124467 0.477613 -0.259097 0.913287
0.587512 0.377176 -0.393846 0.293478 0.275818 -0.298198 0.063539 -0.592623
0.867649 0.64842 -0.929959 0.677208 -0.302289 -0.230779 0.267189 -0.140577
-0.360362 0.910053 -0.26718 0.167234 -0.0203549 -0.190717 -0.291433 0.756657
0.637052 0.538531 0.200832 0.420082 0.688092 0.500134 0.78368 -0.542742
0.00257324 0.53221 -0.899835 0.503303 -0.46265 0.13425 -0.66756 0.125758
-0.28673 -0.255891 0.0805643 0.154396 -0.304337 0.942248 0.404729 -0.530016
0.330364 -0.469459 0.492101 0.923757 -0.0870035 0.114578 -0.321104 0.586945
0.104922 -0.620678 -0.27497 0.905927 0.219188 -0.495436 -0.762684 0.557364
-0.665582 -0.75013 -0.249321 0.667873 -0.288485 -0.765806 -0.45304 0.919665
-0.493835 0.239472 -0.917625 0.418003 0.273087 0.54198 -0.836992 -0.842215
-0.576808 -0.958153 0.73833 0.0770337 -0.82097 0.0731924 -0.192127 -0.369044
-0.204979 -0.564608 -0.792166 0.356056 -0.50905 -0.217096 -0.45753 -0.998959
0.735413 0.347442 -0.644887 0.178 0.935974 -0.630639 -0.624678 0.946812
0.72101 -0.881322 -0.0914539 0.80997 0.619855 0.299585 -0.0544264 -0.932907
-0.454196 0.903609 0.216595 -0.515838 0.650697 0.322145 -0.0598022 0.29879
0.56218 0.548496 0.116056 -0.109011 0.35975 0.375862 -0.473017 0.179013
0.790441 0.202804 0.370116 -0.299956 -0.789657 0.66881 -0.429629 -0.203547
0.870951 -0.240769 0.472253 -0.874723 -0.67061 -0.434253 0.661868 -0.515051
-0.45736 0.0815795 0.924138 0.0979838 -0.00884649 0.0643335 0.803118 -0.542487
-0.177146 -0.625442 -0.840198 -0.158722 -0.596283 -0.673887 -0.738309 0.439504
0.186587 -0.465294 0.81993 0.754213 -0.929469 0.5224 -0.567962 -0.0020964
-0.727445 0.654887 0.237451 -0.81993 0.461061 -0.330429 -0.423304 -0.11565
-0.638766 -0.623638 0.33871 -0.295169 -0.864833 0.715051 -0.443567 0.530583
0.81889 0.288548 -0.558678 -0.588774 -0.961246 0.46669 0.585559 0.566684
-0.336336 0.911721 -0.353767 -0.387489 -0.0397957 -0.544424 0.388611 -0.49438
0.389995 -0.989308 0.0531768 -0.119235 0.8707 0.190555 -0.829453 -0.0377095
-0.754985 0.722122 -0.486071 -0.0543854 -0.00514588 -0.0407811 -0.923871 0.768664
-0.257839 -0.963332 0.27127 0.90108 0.2946 0.295975 0.133463 -0.203565
0.128047 -0.0221978 0.565967 0.441817 -0.885341 -0.294394 0.752 0.655274
0.455767 -0.659883 0.40248 0.600338 -0.83844 -0.844635 -0.436961 -0.694439
0.494475 -0.85312 -0.703241 -0.0320226 -0.0312604 -0.804464 -0.967423 0.134369
-0.823558 0.72077 0.692424 -0.331696 0.28281 0.956438 -0.512021 0.343271
-0.120567 0.85007 -0.634148 0.479445 0.999095 -0.362764 -0.547786 0.0405272
-0.759062 -0.595061 0.891393 -0.772615 0.699682 0.433783 0.496053 0.989183
-0.830714 0.673363 -0.774558 -0.428386 -0.163786 -0.576139 0.870208 -0.403316
-0.358526 -0.816022 -0.40667 0.888208 0.0927729 0.567724 -0.993948 -0.315037
0.173889 0.324026 0.971654 0.445513 -0.836598 -0.335657 -0.193173 0.544429
-0.383334 0.0514736 -0.667312 -0.650427 -0.173149 -0.785155 -0.427284 -0.773588
-0.942451 -0.429928 -0.296064 0.478439 -0.21067 -0.583727 -0.172756 -0.867286
0.0722371 0.969577 -0.667728 -0.673244 0.975295 -0.468511 0.283715 -0.838649
-0.135551 0.0966441 -0.899046 -0.107455 -0.233247 -0.784231 -0.273956 -0.735285
-0.0414323 0.633082 0.756714 -0.941008 0.7334 -0.558333 0.515249 -0.0495845
0.151553 0.897797 0.535985 -0.435869 0.276652 0.950385 -0.588415 -0.908762
0.836871 -0.309154 0.542942 -0.555574 0.296423 -0.852823 0.0586046 0.907905
-0.037232 -0.50382 0.828129 0.852639 -0.187631 0.110954 -0.520551 0.2231
-0.669727 -0.670437 -0.395765 0.938759 -0.71912 -0.299401 -0.857412 0.136054
-0.426925 -0.323029 0.847521 -0.768077 -0.737279 -0.73427 0.409976 -0.424011
-0.485806 -0.842531 0.425504 0.928987 0.885911 0.193509 -0.786534 -0.0521742
0.477176 0.948246 -0.81151 -0.461006 0.140611 -0.0403634 0.904953 0.527849
0.278327 -0.960566 -0.745472 0.449632 -0.221733 -0.67303 0.0901394 -0.365342
0.350109 0.412389 0.22772 -0.743153 0.374894 -0.674853 -0.940435 0.284267
0.0780486 0.00241877 -0.793647 -0.801883 -0.931572 -0.906159 -0.325908 0.129096
0.251037 -0.32573 -0.0132674 0.16178 -0.391019 0.541115 0.186404 0.804935
-0.457725 0.0676978 -0.679403 -0.287371 -0.0475436 -0.433919 -0.777655 -0.648854
-0.0915583 -0.911684 -0.450737 0.330562 0.51434 -0.989688 -0.394102 0.621241
-0.475504 -0.0645391 0.836504 0.636607 -0.294769 0.747648 -0.23722 0.750184
-0.767895 -0.446372 0.758335 -0.407514 -0.304965 0.551426 0.467747 0.962403
-0.550376 0.261992 0.65622 -0.274081 0.87838 0.931551 -0.329732 0.0551602
0.911471 0.324545 0.0503461 -0.796273 0.150228 0.760694 -0.428716 -0.677338
0.320243 0.908401 -0.406211 -0.0914938 -0.0383119 0.971036 -0.996626 -0.420682
-0.632748 0.159697 0.350173 0.188661 -0.463423 -0.79209 -0.321071 -0.849934
-0.493952 0.59222 -0.239915 0.0675535 -0.209439 -0.896104 0.215966 -0.804748
0.470257 -0.814033 0.0936659 -0.279521 0.631632 -0.00510561 -0.694679 -0.554847
0.0193325 -0.515019 -0.502347 -0.0691725 0.0823693 0.218677 0.484909 0.230698
0.411173 -0.360974 -0.0687193 0.982974 -0.62282 -0.808528 0.391168 0.509953
-0.123533 0.573365 0.918135 -0.570049 0.0766659 0.916687 -0.189227 0.105294
-0.436078 0.565401 0.107861 -0.321394 -0.681098 0.372357 -0.911342 -0.836162
0.20572 0.550261 -0.578777 -0.236365 -0.582914 0.473617 -0.745445 -0.401362
-0.268776 -0.00963149 -0.870677 -0.315329 -0.327188 0.571639 -0.922104 -0.889744
-0.653846 0.42571 0.484338 0.786735 -0.924095 -0.777902 0.424617 -0.11099
0.314249 -0.488492 -0.09607 -0.285476 -0.257726 -0.803911 -0.806167 0.4756
-0.41036 -0.669857 -0.36997 0.551767 -0.906633 0.189437 -0.684472 -0.449454
-0.813612 -0.0906479 0.286132 0.680878 0.675851 0.0646878 -0.2403 -0.310925
-0.685114 0.0677462 -0.95481 -0.179017 0.857301 -0.87579 -0.329674 0.562246
0.0735071 -0.575949 0.50454 -0.686882 -0.0657996 0.874931 0.927272 -0.333088
-0.245092 -0.109308 -0.713837 -0.613438 -0.0236157 0.140357 -0.512282 -0.518118
0.184375 -0.865972 0.707001 -0.612003 0.67617 -0.709794 -0.885369 0.826005
-0.157901 0.836454 0.245372 0.589479 -0.930075 0.106183 0.420879 -0.510301
-0.466877 -0.115361 -0.736242 0.493482 -0.785855 -0.55306 0.617798 -0.904856
-0.830296 0.557992 -0.204564 -0.500123 0.153565 -0.773108 0.287265 0.823092
0.986858 -0.323913 -0.914362 0.535652 -0.535098 -0.945814 0.974316 0.434805
0.732686 0.221111 0.559403 0.584674 -0.447866 0.508206 0.907212 -0.782827
-0.970814 -0.13434 -0.550199 0.523038 -0.373701 -0.359454 0.0321578 0.840907

View File

@@ -1,21 +0,0 @@
validate on
stats query_stats
dim 8
data_size 5000
read_data_pts test2-data.pts
query_size 100
read_query_pts test2-query.pts
bucket_size 1
near_neigh 3
split_rule suggest
shrink_rule none
build_ann
epsilon 0.0
run_queries standard
run_queries priority
epsilon 0.10
run_queries standard
run_queries priority
epsilon 0.50
run_queries standard
run_queries priority

View File

@@ -1,156 +0,0 @@
------------------------------------------------------------
ann_test: Version 1.0
Copyright: David M. Mount and Sunil Arya.
Latest Revision: Mar 1, 2005.
------------------------------------------------------------
validate = on (Warning: this may slow execution time.)
stats = query_stats
[Read Data Points:
data_size = 5000
file_name = test2-data.pts
dim = 8
]
[Read Query Points:
query_size = 100
file_name = test2-query.pts
dim = 8
]
[Build ann-structure:
split_rule = suggest
shrink_rule = none
data_size = 5000
dim = 8
bucket_size = 1
process_time = 0.18 sec
(Structure Statistics:
n_nodes = 9999 (opt = 10000, best if < 100000)
n_leaves = 5000 (0 contain no points)
n_splits = 4999
n_shrinks = 0
empty_leaves = 0 percent (best if < 50 percent)
depth = 17 (opt = 12, best if < 196)
avg_aspect_ratio = 2.03396 (best if < 20)
)
]
(Computing true nearest neighbors for validation. This may take time.)
[Run Queries:
query_size = 100
dim = 8
search_method = standard
epsilon = 0
near_neigh = 3
true_nn = 13
query_time = 0.0008 sec/query (biased by perf measurements)
(Performance stats: [ mean : stddev ]< min , max >
leaf_nodes = [ 269.6 : 154.1 ]< 68 , 1046 >
splitting_nodes = [ 448.2 : 259.2 ]< 100 , 1858 >
shrinking_nodes = [ 0 : 0 ]< 0 , 0 >
total_nodes = [ 717.8 : 412.6 ]< 168 , 2904 >
points_visited = [ 269.6 : 154.1 ]< 68 , 1046 >
coord_hits/pt = [ 0.1975 : 0.1075 ]< 0.0446 , 0.6974 >
floating_ops_(K) = [ 8.492 : 4.716 ]< 1.939 , 32.61 >
average_error = [ 0 : 0 ]< 0 , 0 >
rank_error = [ 0 : 0 ]< 0 , 0 >
)
]
[Run Queries:
query_size = 100
dim = 8
search_method = priority
epsilon = 0
near_neigh = 3
true_nn = 13
query_time = 0.0011 sec/query (biased by perf measurements)
(Performance stats: [ mean : stddev ]< min , max >
leaf_nodes = [ 237.7 : 131.6 ]< 68 , 801 >
splitting_nodes = [ 408.1 : 227.7 ]< 100 , 1398 >
shrinking_nodes = [ 0 : 0 ]< 0 , 0 >
total_nodes = [ 645.8 : 358.5 ]< 168 , 2149 >
points_visited = [ 237.7 : 131.6 ]< 68 , 801 >
coord_hits/pt = [ 0.1679 : 0.08993 ]< 0.0472 , 0.5492 >
floating_ops_(K) = [ 10.83 : 6.344 ]< 2.638 , 38.3 >
average_error = [ 0 : 0 ]< 0 , 0 >
rank_error = [ 0 : 0 ]< 0 , 0 >
)
]
[Run Queries:
query_size = 100
dim = 8
search_method = standard
epsilon = 0.1
near_neigh = 3
true_nn = 13
query_time = 0.0006 sec/query (biased by perf measurements)
(Performance stats: [ mean : stddev ]< min , max >
leaf_nodes = [ 200.9 : 115.8 ]< 51 , 762 >
splitting_nodes = [ 344.9 : 202.4 ]< 77 , 1407 >
shrinking_nodes = [ 0 : 0 ]< 0 , 0 >
total_nodes = [ 545.9 : 317.4 ]< 128 , 2169 >
points_visited = [ 200.9 : 115.8 ]< 51 , 762 >
coord_hits/pt = [ 0.1548 : 0.08517 ]< 0.0348 , 0.5494 >
floating_ops_(K) = [ 6.606 : 3.703 ]< 1.513 , 25.14 >
average_error = [ 0 : 0 ]< 0 , 0 >
rank_error = [ 0 : 0 ]< 0 , 0 >
)
]
[Run Queries:
query_size = 100
dim = 8
search_method = priority
epsilon = 0.1
near_neigh = 3
true_nn = 13
query_time = 0.0007 sec/query (biased by perf measurements)
(Performance stats: [ mean : stddev ]< min , max >
leaf_nodes = [ 176.1 : 101.1 ]< 49 , 629 >
splitting_nodes = [ 314.3 : 186.9 ]< 77 , 1285 >
shrinking_nodes = [ 0 : 0 ]< 0 , 0 >
total_nodes = [ 490.4 : 286.6 ]< 128 , 1914 >
points_visited = [ 176.1 : 101.1 ]< 49 , 629 >
coord_hits/pt = [ 0.1309 : 0.07112 ]< 0.0374 , 0.4332 >
floating_ops_(K) = [ 8.205 : 4.999 ]< 2.032 , 33.27 >
average_error = [ 0 : 0 ]< 0 , 0 >
rank_error = [ 0 : 0 ]< 0 , 0 >
)
]
[Run Queries:
query_size = 100
dim = 8
search_method = standard
epsilon = 0.5
near_neigh = 3
true_nn = 13
query_time = 0.0002 sec/query (biased by perf measurements)
(Performance stats: [ mean : stddev ]< min , max >
leaf_nodes = [ 83.07 : 46.06 ]< 23 , 264 >
splitting_nodes = [ 163.4 : 94.86 ]< 42 , 512 >
shrinking_nodes = [ 0 : 0 ]< 0 , 0 >
total_nodes = [ 246.5 : 140.2 ]< 67 , 776 >
points_visited = [ 83.07 : 46.06 ]< 23 , 264 >
coord_hits/pt = [ 0.0765 : 0.03992 ]< 0.0182 , 0.2192 >
floating_ops_(K) = [ 3.224 : 1.734 ]< 0.891 , 9.572 >
average_error = [ 0.0009039 : 0.009619 ]< 0 , 0.1516 >
rank_error = [ 0 : 0 ]< 0 , 0 >
)
]
[Run Queries:
query_size = 100
dim = 8
search_method = priority
epsilon = 0.5
near_neigh = 3
true_nn = 13
query_time = 0.0004 sec/query (biased by perf measurements)
(Performance stats: [ mean : stddev ]< min , max >
leaf_nodes = [ 69.72 : 38.29 ]< 21 , 246 >
splitting_nodes = [ 146.8 : 81.69 ]< 40 , 475 >
shrinking_nodes = [ 0 : 0 ]< 0 , 0 >
total_nodes = [ 216.5 : 118.8 ]< 65 , 721 >
points_visited = [ 69.72 : 38.29 ]< 21 , 246 >
coord_hits/pt = [ 0.06206 : 0.03155 ]< 0.0182 , 0.194 >
floating_ops_(K) = [ 3.608 : 1.989 ]< 1.126 , 12.28 >
average_error = [ 0.001425 : 0.011 ]< 0 , 0.1516 >
rank_error = [ 0 : 0 ]< 0 , 0 >
)
]

View File

@@ -1,596 +0,0 @@
#ifndef CBLAS_H
#ifndef CBLAS_ENUM_DEFINED_H
#define CBLAS_ENUM_DEFINED_H
enum CBLAS_ORDER {CblasRowMajor=101, CblasColMajor=102 };
enum CBLAS_TRANSPOSE {CblasNoTrans=111, CblasTrans=112, CblasConjTrans=113,
AtlasConj=114};
enum CBLAS_UPLO {CblasUpper=121, CblasLower=122};
enum CBLAS_DIAG {CblasNonUnit=131, CblasUnit=132};
enum CBLAS_SIDE {CblasLeft=141, CblasRight=142};
#endif
#ifndef CBLAS_ENUM_ONLY
#define CBLAS_H
#define CBLAS_INDEX int
int cblas_errprn(int ierr, int info, char *form, ...);
/*
* ===========================================================================
* Prototypes for level 1 BLAS functions (complex are recast as routines)
* ===========================================================================
*/
float cblas_sdsdot(const int N, const float alpha, const float *X,
const int incX, const float *Y, const int incY);
double cblas_dsdot(const int N, const float *X, const int incX, const float *Y,
const int incY);
float cblas_sdot(const int N, const float *X, const int incX,
const float *Y, const int incY);
double cblas_ddot(const int N, const double *X, const int incX,
const double *Y, const int incY);
/*
* Functions having prefixes Z and C only
*/
void cblas_cdotu_sub(const int N, const void *X, const int incX,
const void *Y, const int incY, void *dotu);
void cblas_cdotc_sub(const int N, const void *X, const int incX,
const void *Y, const int incY, void *dotc);
void cblas_zdotu_sub(const int N, const void *X, const int incX,
const void *Y, const int incY, void *dotu);
void cblas_zdotc_sub(const int N, const void *X, const int incX,
const void *Y, const int incY, void *dotc);
/*
* Functions having prefixes S D SC DZ
*/
float cblas_snrm2(const int N, const float *X, const int incX);
float cblas_sasum(const int N, const float *X, const int incX);
double cblas_dnrm2(const int N, const double *X, const int incX);
double cblas_dasum(const int N, const double *X, const int incX);
float cblas_scnrm2(const int N, const void *X, const int incX);
float cblas_scasum(const int N, const void *X, const int incX);
double cblas_dznrm2(const int N, const void *X, const int incX);
double cblas_dzasum(const int N, const void *X, const int incX);
/*
* Functions having standard 4 prefixes (S D C Z)
*/
CBLAS_INDEX cblas_isamax(const int N, const float *X, const int incX);
CBLAS_INDEX cblas_idamax(const int N, const double *X, const int incX);
CBLAS_INDEX cblas_icamax(const int N, const void *X, const int incX);
CBLAS_INDEX cblas_izamax(const int N, const void *X, const int incX);
/*
* ===========================================================================
* Prototypes for level 1 BLAS routines
* ===========================================================================
*/
/*
* Routines with standard 4 prefixes (s, d, c, z)
*/
void cblas_sswap(const int N, float *X, const int incX,
float *Y, const int incY);
void cblas_scopy(const int N, const float *X, const int incX,
float *Y, const int incY);
void cblas_saxpy(const int N, const float alpha, const float *X,
const int incX, float *Y, const int incY);
void catlas_saxpby(const int N, const float alpha, const float *X,
const int incX, const float beta, float *Y, const int incY);
void catlas_sset
(const int N, const float alpha, float *X, const int incX);
void cblas_dswap(const int N, double *X, const int incX,
double *Y, const int incY);
void cblas_dcopy(const int N, const double *X, const int incX,
double *Y, const int incY);
void cblas_daxpy(const int N, const double alpha, const double *X,
const int incX, double *Y, const int incY);
void catlas_daxpby(const int N, const double alpha, const double *X,
const int incX, const double beta, double *Y, const int incY);
void catlas_dset
(const int N, const double alpha, double *X, const int incX);
void cblas_cswap(const int N, void *X, const int incX,
void *Y, const int incY);
void cblas_ccopy(const int N, const void *X, const int incX,
void *Y, const int incY);
void cblas_caxpy(const int N, const void *alpha, const void *X,
const int incX, void *Y, const int incY);
void catlas_caxpby(const int N, const void *alpha, const void *X,
const int incX, const void *beta, void *Y, const int incY);
void catlas_cset
(const int N, const void *alpha, void *X, const int incX);
void cblas_zswap(const int N, void *X, const int incX,
void *Y, const int incY);
void cblas_zcopy(const int N, const void *X, const int incX,
void *Y, const int incY);
void cblas_zaxpy(const int N, const void *alpha, const void *X,
const int incX, void *Y, const int incY);
void catlas_zaxpby(const int N, const void *alpha, const void *X,
const int incX, const void *beta, void *Y, const int incY);
void catlas_zset
(const int N, const void *alpha, void *X, const int incX);
/*
* Routines with S and D prefix only
*/
void cblas_srotg(float *a, float *b, float *c, float *s);
void cblas_srotmg(float *d1, float *d2, float *b1, const float b2, float *P);
void cblas_srot(const int N, float *X, const int incX,
float *Y, const int incY, const float c, const float s);
void cblas_srotm(const int N, float *X, const int incX,
float *Y, const int incY, const float *P);
void cblas_drotg(double *a, double *b, double *c, double *s);
void cblas_drotmg(double *d1, double *d2, double *b1, const double b2, double *P);
void cblas_drot(const int N, double *X, const int incX,
double *Y, const int incY, const double c, const double s);
void cblas_drotm(const int N, double *X, const int incX,
double *Y, const int incY, const double *P);
/*
* Routines with S D C Z CS and ZD prefixes
*/
void cblas_sscal(const int N, const float alpha, float *X, const int incX);
void cblas_dscal(const int N, const double alpha, double *X, const int incX);
void cblas_cscal(const int N, const void *alpha, void *X, const int incX);
void cblas_zscal(const int N, const void *alpha, void *X, const int incX);
void cblas_csscal(const int N, const float alpha, void *X, const int incX);
void cblas_zdscal(const int N, const double alpha, void *X, const int incX);
/*
* Extra reference routines provided by ATLAS, but not mandated by the standard
*/
void cblas_crotg(void *a, void *b, void *c, void *s);
void cblas_zrotg(void *a, void *b, void *c, void *s);
void cblas_csrot(const int N, void *X, const int incX, void *Y, const int incY,
const float c, const float s);
void cblas_zdrot(const int N, void *X, const int incX, void *Y, const int incY,
const double c, const double s);
/*
* ===========================================================================
* Prototypes for level 2 BLAS
* ===========================================================================
*/
/*
* Routines with standard 4 prefixes (S, D, C, Z)
*/
void cblas_sgemv(const enum CBLAS_ORDER Order,
const enum CBLAS_TRANSPOSE TransA, const int M, const int N,
const float alpha, const float *A, const int lda,
const float *X, const int incX, const float beta,
float *Y, const int incY);
void cblas_sgbmv(const enum CBLAS_ORDER Order,
const enum CBLAS_TRANSPOSE TransA, const int M, const int N,
const int KL, const int KU, const float alpha,
const float *A, const int lda, const float *X,
const int incX, const float beta, float *Y, const int incY);
void cblas_strmv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
const int N, const float *A, const int lda,
float *X, const int incX);
void cblas_stbmv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
const int N, const int K, const float *A, const int lda,
float *X, const int incX);
void cblas_stpmv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
const int N, const float *Ap, float *X, const int incX);
void cblas_strsv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
const int N, const float *A, const int lda, float *X,
const int incX);
void cblas_stbsv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
const int N, const int K, const float *A, const int lda,
float *X, const int incX);
void cblas_stpsv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
const int N, const float *Ap, float *X, const int incX);
void cblas_dgemv(const enum CBLAS_ORDER Order,
const enum CBLAS_TRANSPOSE TransA, const int M, const int N,
const double alpha, const double *A, const int lda,
const double *X, const int incX, const double beta,
double *Y, const int incY);
void cblas_dgbmv(const enum CBLAS_ORDER Order,
const enum CBLAS_TRANSPOSE TransA, const int M, const int N,
const int KL, const int KU, const double alpha,
const double *A, const int lda, const double *X,
const int incX, const double beta, double *Y, const int incY);
void cblas_dtrmv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
const int N, const double *A, const int lda,
double *X, const int incX);
void cblas_dtbmv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
const int N, const int K, const double *A, const int lda,
double *X, const int incX);
void cblas_dtpmv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
const int N, const double *Ap, double *X, const int incX);
void cblas_dtrsv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
const int N, const double *A, const int lda, double *X,
const int incX);
void cblas_dtbsv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
const int N, const int K, const double *A, const int lda,
double *X, const int incX);
void cblas_dtpsv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
const int N, const double *Ap, double *X, const int incX);
void cblas_cgemv(const enum CBLAS_ORDER Order,
const enum CBLAS_TRANSPOSE TransA, const int M, const int N,
const void *alpha, const void *A, const int lda,
const void *X, const int incX, const void *beta,
void *Y, const int incY);
void cblas_cgbmv(const enum CBLAS_ORDER Order,
const enum CBLAS_TRANSPOSE TransA, const int M, const int N,
const int KL, const int KU, const void *alpha,
const void *A, const int lda, const void *X,
const int incX, const void *beta, void *Y, const int incY);
void cblas_ctrmv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
const int N, const void *A, const int lda,
void *X, const int incX);
void cblas_ctbmv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
const int N, const int K, const void *A, const int lda,
void *X, const int incX);
void cblas_ctpmv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
const int N, const void *Ap, void *X, const int incX);
void cblas_ctrsv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
const int N, const void *A, const int lda, void *X,
const int incX);
void cblas_ctbsv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
const int N, const int K, const void *A, const int lda,
void *X, const int incX);
void cblas_ctpsv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
const int N, const void *Ap, void *X, const int incX);
void cblas_zgemv(const enum CBLAS_ORDER Order,
const enum CBLAS_TRANSPOSE TransA, const int M, const int N,
const void *alpha, const void *A, const int lda,
const void *X, const int incX, const void *beta,
void *Y, const int incY);
void cblas_zgbmv(const enum CBLAS_ORDER Order,
const enum CBLAS_TRANSPOSE TransA, const int M, const int N,
const int KL, const int KU, const void *alpha,
const void *A, const int lda, const void *X,
const int incX, const void *beta, void *Y, const int incY);
void cblas_ztrmv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
const int N, const void *A, const int lda,
void *X, const int incX);
void cblas_ztbmv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
const int N, const int K, const void *A, const int lda,
void *X, const int incX);
void cblas_ztpmv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
const int N, const void *Ap, void *X, const int incX);
void cblas_ztrsv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
const int N, const void *A, const int lda, void *X,
const int incX);
void cblas_ztbsv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
const int N, const int K, const void *A, const int lda,
void *X, const int incX);
void cblas_ztpsv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
const int N, const void *Ap, void *X, const int incX);
/*
* Routines with S and D prefixes only
*/
void cblas_ssymv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
const int N, const float alpha, const float *A,
const int lda, const float *X, const int incX,
const float beta, float *Y, const int incY);
void cblas_ssbmv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
const int N, const int K, const float alpha, const float *A,
const int lda, const float *X, const int incX,
const float beta, float *Y, const int incY);
void cblas_sspmv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
const int N, const float alpha, const float *Ap,
const float *X, const int incX,
const float beta, float *Y, const int incY);
void cblas_sger(const enum CBLAS_ORDER Order, const int M, const int N,
const float alpha, const float *X, const int incX,
const float *Y, const int incY, float *A, const int lda);
void cblas_ssyr(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
const int N, const float alpha, const float *X,
const int incX, float *A, const int lda);
void cblas_sspr(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
const int N, const float alpha, const float *X,
const int incX, float *Ap);
void cblas_ssyr2(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
const int N, const float alpha, const float *X,
const int incX, const float *Y, const int incY, float *A,
const int lda);
void cblas_sspr2(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
const int N, const float alpha, const float *X,
const int incX, const float *Y, const int incY, float *A);
void cblas_dsymv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
const int N, const double alpha, const double *A,
const int lda, const double *X, const int incX,
const double beta, double *Y, const int incY);
void cblas_dsbmv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
const int N, const int K, const double alpha, const double *A,
const int lda, const double *X, const int incX,
const double beta, double *Y, const int incY);
void cblas_dspmv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
const int N, const double alpha, const double *Ap,
const double *X, const int incX,
const double beta, double *Y, const int incY);
void cblas_dger(const enum CBLAS_ORDER Order, const int M, const int N,
const double alpha, const double *X, const int incX,
const double *Y, const int incY, double *A, const int lda);
void cblas_dsyr(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
const int N, const double alpha, const double *X,
const int incX, double *A, const int lda);
void cblas_dspr(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
const int N, const double alpha, const double *X,
const int incX, double *Ap);
void cblas_dsyr2(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
const int N, const double alpha, const double *X,
const int incX, const double *Y, const int incY, double *A,
const int lda);
void cblas_dspr2(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
const int N, const double alpha, const double *X,
const int incX, const double *Y, const int incY, double *A);
/*
* Routines with C and Z prefixes only
*/
void cblas_chemv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
const int N, const void *alpha, const void *A,
const int lda, const void *X, const int incX,
const void *beta, void *Y, const int incY);
void cblas_chbmv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
const int N, const int K, const void *alpha, const void *A,
const int lda, const void *X, const int incX,
const void *beta, void *Y, const int incY);
void cblas_chpmv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
const int N, const void *alpha, const void *Ap,
const void *X, const int incX,
const void *beta, void *Y, const int incY);
void cblas_cgeru(const enum CBLAS_ORDER Order, const int M, const int N,
const void *alpha, const void *X, const int incX,
const void *Y, const int incY, void *A, const int lda);
void cblas_cgerc(const enum CBLAS_ORDER Order, const int M, const int N,
const void *alpha, const void *X, const int incX,
const void *Y, const int incY, void *A, const int lda);
void cblas_cher(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
const int N, const float alpha, const void *X, const int incX,
void *A, const int lda);
void cblas_chpr(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
const int N, const float alpha, const void *X,
const int incX, void *A);
void cblas_cher2(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const int N,
const void *alpha, const void *X, const int incX,
const void *Y, const int incY, void *A, const int lda);
void cblas_chpr2(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const int N,
const void *alpha, const void *X, const int incX,
const void *Y, const int incY, void *Ap);
void cblas_zhemv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
const int N, const void *alpha, const void *A,
const int lda, const void *X, const int incX,
const void *beta, void *Y, const int incY);
void cblas_zhbmv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
const int N, const int K, const void *alpha, const void *A,
const int lda, const void *X, const int incX,
const void *beta, void *Y, const int incY);
void cblas_zhpmv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
const int N, const void *alpha, const void *Ap,
const void *X, const int incX,
const void *beta, void *Y, const int incY);
void cblas_zgeru(const enum CBLAS_ORDER Order, const int M, const int N,
const void *alpha, const void *X, const int incX,
const void *Y, const int incY, void *A, const int lda);
void cblas_zgerc(const enum CBLAS_ORDER Order, const int M, const int N,
const void *alpha, const void *X, const int incX,
const void *Y, const int incY, void *A, const int lda);
void cblas_zher(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
const int N, const double alpha, const void *X, const int incX,
void *A, const int lda);
void cblas_zhpr(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
const int N, const double alpha, const void *X,
const int incX, void *A);
void cblas_zher2(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const int N,
const void *alpha, const void *X, const int incX,
const void *Y, const int incY, void *A, const int lda);
void cblas_zhpr2(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const int N,
const void *alpha, const void *X, const int incX,
const void *Y, const int incY, void *Ap);
/*
* ===========================================================================
* Prototypes for level 3 BLAS
* ===========================================================================
*/
/*
* Routines with standard 4 prefixes (S, D, C, Z)
*/
void cblas_sgemm(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA,
const enum CBLAS_TRANSPOSE TransB, const int M, const int N,
const int K, const float alpha, const float *A,
const int lda, const float *B, const int ldb,
const float beta, float *C, const int ldc);
void cblas_ssymm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side,
const enum CBLAS_UPLO Uplo, const int M, const int N,
const float alpha, const float *A, const int lda,
const float *B, const int ldb, const float beta,
float *C, const int ldc);
void cblas_ssyrk(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
const enum CBLAS_TRANSPOSE Trans, const int N, const int K,
const float alpha, const float *A, const int lda,
const float beta, float *C, const int ldc);
void cblas_ssyr2k(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
const enum CBLAS_TRANSPOSE Trans, const int N, const int K,
const float alpha, const float *A, const int lda,
const float *B, const int ldb, const float beta,
float *C, const int ldc);
void cblas_strmm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side,
const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA,
const enum CBLAS_DIAG Diag, const int M, const int N,
const float alpha, const float *A, const int lda,
float *B, const int ldb);
void cblas_strsm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side,
const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA,
const enum CBLAS_DIAG Diag, const int M, const int N,
const float alpha, const float *A, const int lda,
float *B, const int ldb);
void cblas_dgemm(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA,
const enum CBLAS_TRANSPOSE TransB, const int M, const int N,
const int K, const double alpha, const double *A,
const int lda, const double *B, const int ldb,
const double beta, double *C, const int ldc);
void cblas_dsymm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side,
const enum CBLAS_UPLO Uplo, const int M, const int N,
const double alpha, const double *A, const int lda,
const double *B, const int ldb, const double beta,
double *C, const int ldc);
void cblas_dsyrk(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
const enum CBLAS_TRANSPOSE Trans, const int N, const int K,
const double alpha, const double *A, const int lda,
const double beta, double *C, const int ldc);
void cblas_dsyr2k(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
const enum CBLAS_TRANSPOSE Trans, const int N, const int K,
const double alpha, const double *A, const int lda,
const double *B, const int ldb, const double beta,
double *C, const int ldc);
void cblas_dtrmm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side,
const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA,
const enum CBLAS_DIAG Diag, const int M, const int N,
const double alpha, const double *A, const int lda,
double *B, const int ldb);
void cblas_dtrsm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side,
const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA,
const enum CBLAS_DIAG Diag, const int M, const int N,
const double alpha, const double *A, const int lda,
double *B, const int ldb);
void cblas_cgemm(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA,
const enum CBLAS_TRANSPOSE TransB, const int M, const int N,
const int K, const void *alpha, const void *A,
const int lda, const void *B, const int ldb,
const void *beta, void *C, const int ldc);
void cblas_csymm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side,
const enum CBLAS_UPLO Uplo, const int M, const int N,
const void *alpha, const void *A, const int lda,
const void *B, const int ldb, const void *beta,
void *C, const int ldc);
void cblas_csyrk(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
const enum CBLAS_TRANSPOSE Trans, const int N, const int K,
const void *alpha, const void *A, const int lda,
const void *beta, void *C, const int ldc);
void cblas_csyr2k(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
const enum CBLAS_TRANSPOSE Trans, const int N, const int K,
const void *alpha, const void *A, const int lda,
const void *B, const int ldb, const void *beta,
void *C, const int ldc);
void cblas_ctrmm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side,
const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA,
const enum CBLAS_DIAG Diag, const int M, const int N,
const void *alpha, const void *A, const int lda,
void *B, const int ldb);
void cblas_ctrsm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side,
const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA,
const enum CBLAS_DIAG Diag, const int M, const int N,
const void *alpha, const void *A, const int lda,
void *B, const int ldb);
void cblas_zgemm(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA,
const enum CBLAS_TRANSPOSE TransB, const int M, const int N,
const int K, const void *alpha, const void *A,
const int lda, const void *B, const int ldb,
const void *beta, void *C, const int ldc);
void cblas_zsymm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side,
const enum CBLAS_UPLO Uplo, const int M, const int N,
const void *alpha, const void *A, const int lda,
const void *B, const int ldb, const void *beta,
void *C, const int ldc);
void cblas_zsyrk(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
const enum CBLAS_TRANSPOSE Trans, const int N, const int K,
const void *alpha, const void *A, const int lda,
const void *beta, void *C, const int ldc);
void cblas_zsyr2k(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
const enum CBLAS_TRANSPOSE Trans, const int N, const int K,
const void *alpha, const void *A, const int lda,
const void *B, const int ldb, const void *beta,
void *C, const int ldc);
void cblas_ztrmm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side,
const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA,
const enum CBLAS_DIAG Diag, const int M, const int N,
const void *alpha, const void *A, const int lda,
void *B, const int ldb);
void cblas_ztrsm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side,
const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA,
const enum CBLAS_DIAG Diag, const int M, const int N,
const void *alpha, const void *A, const int lda,
void *B, const int ldb);
/*
* Routines with prefixes C and Z only
*/
void cblas_chemm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side,
const enum CBLAS_UPLO Uplo, const int M, const int N,
const void *alpha, const void *A, const int lda,
const void *B, const int ldb, const void *beta,
void *C, const int ldc);
void cblas_cherk(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
const enum CBLAS_TRANSPOSE Trans, const int N, const int K,
const float alpha, const void *A, const int lda,
const float beta, void *C, const int ldc);
void cblas_cher2k(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
const enum CBLAS_TRANSPOSE Trans, const int N, const int K,
const void *alpha, const void *A, const int lda,
const void *B, const int ldb, const float beta,
void *C, const int ldc);
void cblas_zhemm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side,
const enum CBLAS_UPLO Uplo, const int M, const int N,
const void *alpha, const void *A, const int lda,
const void *B, const int ldb, const void *beta,
void *C, const int ldc);
void cblas_zherk(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
const enum CBLAS_TRANSPOSE Trans, const int N, const int K,
const double alpha, const void *A, const int lda,
const double beta, void *C, const int ldc);
void cblas_zher2k(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
const enum CBLAS_TRANSPOSE Trans, const int N, const int K,
const void *alpha, const void *A, const int lda,
const void *B, const int ldb, const double beta,
void *C, const int ldc);
int cblas_errprn(int ierr, int info, char *form, ...);
#endif /* end #ifdef CBLAS_ENUM_ONLY */
#endif

View File

@@ -1,149 +0,0 @@
/*
* Automatically Tuned Linear Algebra Software v3.6.0
* (C) Copyright 1999 R. Clint Whaley
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions, and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the ATLAS group or the names of its contributers may
* not be used to endorse or promote products derived from this
* software without specific written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ATLAS GROUP OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef CLAPACK_H
#define CLAPACK_H
#include "cblas.h"
#ifndef ATLAS_ORDER
#define ATLAS_ORDER CBLAS_ORDER
#endif
#ifndef ATLAS_UPLO
#define ATLAS_UPLO CBLAS_UPLO
#endif
#ifndef ATLAS_DIAG
#define ATLAS_DIAG CBLAS_DIAG
#endif
int clapack_sgesv(const enum CBLAS_ORDER Order, const int N, const int NRHS,
float *A, const int lda, int *ipiv,
float *B, const int ldb);
int clapack_sgetrf(const enum CBLAS_ORDER Order, const int M, const int N,
float *A, const int lda, int *ipiv);
int clapack_sgetrs
(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE Trans,
const int N, const int NRHS, const float *A, const int lda,
const int *ipiv, float *B, const int ldb);
int clapack_sgetri(const enum CBLAS_ORDER Order, const int N, float *A,
const int lda, const int *ipiv);
int clapack_sposv(const enum ATLAS_ORDER Order, const enum ATLAS_UPLO Uplo,
const int N, const int NRHS, float *A, const int lda,
float *B, const int ldb);
int clapack_spotrf(const enum ATLAS_ORDER Order, const enum ATLAS_UPLO Uplo,
const int N, float *A, const int lda);
int clapack_spotrs(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
const int N, const int NRHS, const float *A, const int lda,
float *B, const int ldb);
int clapack_spotri(const enum ATLAS_ORDER Order, const enum ATLAS_UPLO Uplo,
const int N, float *A, const int lda);
int clapack_slauum(const enum ATLAS_ORDER Order, const enum ATLAS_UPLO Uplo,
const int N, float *A, const int lda);
int clapack_strtri(const enum ATLAS_ORDER Order,const enum ATLAS_UPLO Uplo,
const enum ATLAS_DIAG Diag,const int N, float *A, const int lda);
int clapack_dgesv(const enum CBLAS_ORDER Order, const int N, const int NRHS,
double *A, const int lda, int *ipiv,
double *B, const int ldb);
int clapack_dgetrf(const enum CBLAS_ORDER Order, const int M, const int N,
double *A, const int lda, int *ipiv);
int clapack_dgetrs
(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE Trans,
const int N, const int NRHS, const double *A, const int lda,
const int *ipiv, double *B, const int ldb);
int clapack_dgetri(const enum CBLAS_ORDER Order, const int N, double *A,
const int lda, const int *ipiv);
int clapack_dposv(const enum ATLAS_ORDER Order, const enum ATLAS_UPLO Uplo,
const int N, const int NRHS, double *A, const int lda,
double *B, const int ldb);
int clapack_dpotrf(const enum ATLAS_ORDER Order, const enum ATLAS_UPLO Uplo,
const int N, double *A, const int lda);
int clapack_dpotrs(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
const int N, const int NRHS, const double *A, const int lda,
double *B, const int ldb);
int clapack_dpotri(const enum ATLAS_ORDER Order, const enum ATLAS_UPLO Uplo,
const int N, double *A, const int lda);
int clapack_dlauum(const enum ATLAS_ORDER Order, const enum ATLAS_UPLO Uplo,
const int N, double *A, const int lda);
int clapack_dtrtri(const enum ATLAS_ORDER Order,const enum ATLAS_UPLO Uplo,
const enum ATLAS_DIAG Diag,const int N, double *A, const int lda);
int clapack_cgesv(const enum CBLAS_ORDER Order, const int N, const int NRHS,
void *A, const int lda, int *ipiv,
void *B, const int ldb);
int clapack_cgetrf(const enum CBLAS_ORDER Order, const int M, const int N,
void *A, const int lda, int *ipiv);
int clapack_cgetrs
(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE Trans,
const int N, const int NRHS, const void *A, const int lda,
const int *ipiv, void *B, const int ldb);
int clapack_cgetri(const enum CBLAS_ORDER Order, const int N, void *A,
const int lda, const int *ipiv);
int clapack_cposv(const enum ATLAS_ORDER Order, const enum ATLAS_UPLO Uplo,
const int N, const int NRHS, void *A, const int lda,
void *B, const int ldb);
int clapack_cpotrf(const enum ATLAS_ORDER Order, const enum ATLAS_UPLO Uplo,
const int N, void *A, const int lda);
int clapack_cpotrs(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
const int N, const int NRHS, const void *A, const int lda,
void *B, const int ldb);
int clapack_cpotri(const enum ATLAS_ORDER Order, const enum ATLAS_UPLO Uplo,
const int N, void *A, const int lda);
int clapack_clauum(const enum ATLAS_ORDER Order, const enum ATLAS_UPLO Uplo,
const int N, void *A, const int lda);
int clapack_ctrtri(const enum ATLAS_ORDER Order,const enum ATLAS_UPLO Uplo,
const enum ATLAS_DIAG Diag,const int N, void *A, const int lda);
int clapack_zgesv(const enum CBLAS_ORDER Order, const int N, const int NRHS,
void *A, const int lda, int *ipiv,
void *B, const int ldb);
int clapack_zgetrf(const enum CBLAS_ORDER Order, const int M, const int N,
void *A, const int lda, int *ipiv);
int clapack_zgetrs
(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE Trans,
const int N, const int NRHS, const void *A, const int lda,
const int *ipiv, void *B, const int ldb);
int clapack_zgetri(const enum CBLAS_ORDER Order, const int N, void *A,
const int lda, const int *ipiv);
int clapack_zposv(const enum ATLAS_ORDER Order, const enum ATLAS_UPLO Uplo,
const int N, const int NRHS, void *A, const int lda,
void *B, const int ldb);
int clapack_zpotrf(const enum ATLAS_ORDER Order, const enum ATLAS_UPLO Uplo,
const int N, void *A, const int lda);
int clapack_zpotrs(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
const int N, const int NRHS, const void *A, const int lda,
void *B, const int ldb);
int clapack_zpotri(const enum ATLAS_ORDER Order, const enum ATLAS_UPLO Uplo,
const int N, void *A, const int lda);
int clapack_zlauum(const enum ATLAS_ORDER Order, const enum ATLAS_UPLO Uplo,
const int N, void *A, const int lda);
int clapack_ztrtri(const enum ATLAS_ORDER Order,const enum ATLAS_UPLO Uplo,
const enum ATLAS_DIAG Diag,const int N, void *A, const int lda);
#endif

View File

@@ -1,23 +0,0 @@
Boost Software License - Version 1.0 - August 17th, 2003
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

View File

@@ -1,30 +0,0 @@
//
// Copyright Toon Knapen
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_NUMERIC_BINDINGS_AMOS_AMOS_H
#define BOOST_NUMERIC_BINDINGS_AMOS_AMOS_H
#include <boost/numeric/bindings/amos/amos_names.h>
#include <boost/numeric/bindings/traits/type.h>
extern "C"
{
void AMOS_DBESI(const double* z, const double* fnu, const int* kode, const int* n, double* cy, int* nz ) ;
void AMOS_CBESI(const fcomplex_t* z, const float* fnu, const int* kode, const int* n, fcomplex_t* cy, int* nz, int* ierr) ;
void AMOS_ZBESI(const double* zr, const double* zi, const double* fnu, const int* kode, const int* n, double* cyr, double* cyi, int* nz, int* ierr) ;
void AMOS_DBESJ(const double * z, const double* fnu, const int* n, double* cy, int* nz ) ;
void AMOS_CBESJ(const fcomplex_t* z, const float* fnu, const int* kode, const int* n, fcomplex_t* cy, int* nz, int* ierr) ;
void AMOS_ZBESJ(const double* zr, const double* zi, const double* fnu, const int* kode, const int* n, double* cyr, double* cyi, int* nz, int* ierr) ;
void AMOS_DBESY(const double * z, const double* fnu, const int* n, double* cy ) ;
void AMOS_CBESY(const fcomplex_t* z, const float* fnu, const int* kode, const int* n, fcomplex_t* cy, int* nz, fcomplex_t *cwrk, int* ierr) ;
void AMOS_ZBESY(const double* zr, const double* zi, const double* fnu, const int* kode, const int* n, double* cyr, double* cyi, int* nz, double *cwrkr, double *cwrki, int* ierr) ;
}
#endif // BOOST_NUMERIC_BINDINGS_AMOS_AMOS_HPP

View File

@@ -1,87 +0,0 @@
//
// Copyright Toon Knapen
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_NUMERIC_BINDINGS_AMOS_AMOS_HPP
#define BOOST_NUMERIC_BINDINGS_AMOS_AMOS_HPP
#include <boost/numeric/bindings/amos/amos_overloads.hpp>
#include <boost/numeric/bindings/traits/type_traits.hpp>
#include <boost/numeric/bindings/traits/vector_traits.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits.hpp>
namespace boost { namespace numeric { namespace bindings { namespace amos {
template < typename vector_type, typename value_type >
int besi(const value_type& z, // std::complex< float > or std::complex< double >
const typename traits::type_traits< value_type >::real_type fnu, // float or double
int kode,
vector_type& cy,
int& nz)
{
#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
BOOST_STATIC_ASSERT( ( boost::is_same< value_type, typename traits::vector_traits<vector_type>::value_type >::value ) ) ;
#else
BOOST_STATIC_ASSERT( ( boost::is_same< value_type, typename vector_type::value_type >::value ) ) ;
#endif
int n = traits::vector_size( cy ) ;
value_type * cy_ptr = traits::vector_storage( cy ) ;
int error = 0 ;
detail::besi( z, fnu, kode, n, cy_ptr, nz, error ) ;
return error ;
}
template < typename vector_type, typename value_type >
int besj(const value_type& z,
const typename traits::type_traits< value_type >::real_type fnu,
int kode,
vector_type& cy,
int& nz)
{
#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
BOOST_STATIC_ASSERT( ( boost::is_same< value_type, typename traits::vector_traits<vector_type>::value_type >::value ) ) ;
#else
BOOST_STATIC_ASSERT( ( boost::is_same< value_type, typename vector_type::value_type >::value ) ) ;
#endif
int n = traits::vector_size( cy ) ;
value_type * cy_ptr = traits::vector_storage( cy ) ;
int error = 0 ;
detail::besj( z, fnu, kode, n, cy_ptr, nz, error ) ;
return error ;
}
template < typename vector_type, typename value_type >
int besy(const value_type& z,
const typename traits::type_traits< value_type >::real_type fnu,
int kode,
vector_type& cy,
int& nz)
{
#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
BOOST_STATIC_ASSERT( ( boost::is_same< value_type, typename traits::vector_traits<vector_type>::value_type >::value ) ) ;
#else
BOOST_STATIC_ASSERT( ( boost::is_same< value_type, typename vector_type::value_type >::value ) ) ;
#endif
int n = traits::vector_size( cy ) ;
value_type * cy_ptr = traits::vector_storage( cy ) ;
int error = 0 ;
value_type * cwrk = new value_type[n];
detail::besy( z, fnu, kode, n, cy_ptr, nz, cwrk, error ) ;
delete[] cwrk ;
return error ;
}
}}}}
#endif // BOOST_NUMERIC_BINDINGS_AMOS_AMOS_HPP

View File

@@ -1,26 +0,0 @@
//
// Copyright Toon Knapen
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_NUMERIC_BINDINGS_AMOS_AMOS_NAMES_H
#define BOOST_NUMERIC_BINDINGS_AMOS_AMOS_NAMES_H
#include <boost/numeric/bindings/traits/fortran.h>
#define AMOS_DBESI FORTRAN_ID( dbesi )
#define AMOS_CBESI FORTRAN_ID( cbesi )
#define AMOS_ZBESI FORTRAN_ID( zbesi )
#define AMOS_DBESJ FORTRAN_ID( dbesj )
#define AMOS_CBESJ FORTRAN_ID( cbesj )
#define AMOS_ZBESJ FORTRAN_ID( zbesj )
#define AMOS_DBESY FORTRAN_ID( dbesy )
#define AMOS_CBESY FORTRAN_ID( cbesy )
#define AMOS_ZBESY FORTRAN_ID( zbesy )
#endif // BOOST_NUMERIC_BINDINGS_AMOS_AMOS_NAMES_HPP

View File

@@ -1,62 +0,0 @@
//
// Copyright Toon Knapen
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_NUMERIC_BINDINGS_AMOS_AMOS_OVERLOADS_HPP
#define BOOST_NUMERIC_BINDINGS_AMOS_AMOS_OVERLOADS_HPP
#include <boost/numeric/bindings/amos/amos.h>
#include <boost/numeric/bindings/traits/type.hpp>
#include <boost/numeric/bindings/traits/type_traits.hpp>
namespace boost { namespace numeric { namespace bindings { namespace amos { namespace detail {
using namespace ::boost::numeric::bindings::traits ;
//
// BESI
//
//inline
//void besi(const fcomplex * z, const fcomplex * fnu, const int * kode, const int * n, fcomplex* cy, int * nz, int * error) ;
inline
void besi(const double& z, const double& fnu, const int& kode, const int& n, double* cy, int& nz, int& error)
{ AMOS_DBESI( &z, &fnu, &kode, &n, cy, &nz ) ; }
inline
void besi(const complex_f& z, const float& fnu, const int& kode, const int& n, complex_f* cy, int & nz, int & error)
{ AMOS_CBESI( complex_ptr( &z ), &fnu, &kode, &n, complex_ptr( cy ), &nz, &error ) ; }
// inline
// void besi(const complex_d* z, const double* fnu, const int * kode, const int * n, complex_d* cy, int * nz, int * error) ;
//
// BESJ
//
inline
void besj(const double& z, const double& fnu, const int& kode, const int& n, double* cy, int& nz, int& error)
{ AMOS_DBESJ( &z, &fnu, &n, cy, &nz ) ; }
inline
void besj(const complex_f& z, const float& fnu, const int& kode, const int& n, complex_f* cy, int & nz, int & error)
{ AMOS_CBESJ( complex_ptr( &z ), &fnu, &kode, &n, complex_ptr( cy ), &nz, &error ) ; }
//
// BESY
//
inline
void besy(const double& z, const double& fnu, const int& kode, const int& n, double* cy, int& nz, double* wrk, int& error)
{ AMOS_DBESY( &z, &fnu, &n, cy ) ; }
}}}}}
#endif // BOOST_NUMERIC_BINDINGS_AMOS_AMOS_OVERLOADS_HPP

View File

@@ -1,21 +0,0 @@
/*
*
* Copyright (c) Kresimir Fresl 2002
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* Author acknowledges the support of the Faculty of Civil Engineering,
* University of Zagreb, Croatia.
*
*/
#ifndef BOOST_NUMERIC_BINDINGS_CBLAS_HPP
#define BOOST_NUMERIC_BINDINGS_CBLAS_HPP
#include <boost/numeric/bindings/atlas/cblas1.hpp>
#include <boost/numeric/bindings/atlas/cblas2.hpp>
#include <boost/numeric/bindings/atlas/cblas3.hpp>
#endif

View File

@@ -1,376 +0,0 @@
/*
*
* Copyright (c) Kresimir Fresl 2002
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* Author acknowledges the support of the Faculty of Civil Engineering,
* University of Zagreb, Croatia.
*
*/
#ifndef BOOST_NUMERIC_BINDINGS_CBLAS_LEVEL_1_HPP
#define BOOST_NUMERIC_BINDINGS_CBLAS_LEVEL_1_HPP
#include <cassert>
#include <boost/numeric/bindings/traits/type_traits.hpp>
#include <boost/numeric/bindings/traits/vector_traits.hpp>
#include <boost/numeric/bindings/atlas/cblas1_overloads.hpp>
#ifndef BOOST_NUMERIC_BINDINGS_NO_TYPE_CHECK
# include <boost/type_traits/same_traits.hpp>
# include <boost/static_assert.hpp>
#endif
namespace boost { namespace numeric { namespace bindings {
namespace atlas {
// x_i <- alpha for all i
template <typename T, typename Vct>
inline
void set (T const& alpha, Vct& x) {
detail::set (traits::vector_size (x), alpha,
traits::vector_storage (x), traits::vector_stride (x));
}
// y <- x
template <typename VctX, typename VctY>
inline
void copy (VctX const& x, VctY& y) {
assert (traits::vector_size (y) >= traits::vector_size (x));
detail::copy (traits::vector_size (x),
#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
traits::vector_storage (x),
#else
traits::vector_storage_const (x),
#endif
traits::vector_stride (x),
traits::vector_storage (y), traits::vector_stride (y));
}
// x <-> y
template <typename VctX, typename VctY>
inline
void swap (VctX& x, VctY& y) {
assert (traits::vector_size (y) >= traits::vector_size (x));
detail::swap (traits::vector_size (x),
traits::vector_storage (x), traits::vector_stride (x),
traits::vector_storage (y), traits::vector_stride (y));
}
// x <- alpha * x
template <typename T, typename Vct>
inline
void scal (T const& alpha, Vct& x) {
#ifndef BOOST_NUMERIC_BINDINGS_NO_TYPE_CHECK
typedef traits::vector_traits<Vct> vtraits;
BOOST_STATIC_ASSERT(
(boost::is_same<T, typename vtraits::value_type>::value
||
boost::is_same<T,
typename traits::type_traits<typename vtraits::value_type>::real_type
>::value
));
#endif
detail::scal (traits::vector_size (x), alpha,
traits::vector_storage (x), traits::vector_stride (x));
}
// y <- alpha * x + y
template <typename T, typename VctX, typename VctY>
inline
void axpy (T const& alpha, VctX const& x, VctY& y) {
assert (traits::vector_size (y) >= traits::vector_size (x));
detail::axpy (traits::vector_size (x), alpha,
#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
traits::vector_storage (x),
#else
traits::vector_storage_const (x),
#endif
traits::vector_stride (x),
traits::vector_storage (y), traits::vector_stride (y));
}
// y <- x + y
template <typename VctX, typename VctY>
inline
void xpy (VctX const& x, VctY& y) {
#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
typedef typename traits::vector_traits<VctX>::value_type val_t;
#else
typedef typename VctX::value_type val_t;
#endif
axpy ((val_t) 1, x, y);
}
// y <- alpha * x + beta * y
template <typename T, typename VctX, typename VctY>
inline
void axpby (T const& alpha, VctX const& x,
T const& beta, VctY& y) {
assert (traits::vector_size (y) >= traits::vector_size (x));
detail::axpby (traits::vector_size (x), alpha,
#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
traits::vector_storage (x),
#else
traits::vector_storage_const (x),
#endif
traits::vector_stride (x),
beta,
traits::vector_storage (y), traits::vector_stride (y));
}
///////////////////////////////////////////
// dot <- x^T * y
// .. real & complex types
template <typename VctX, typename VctY>
inline
#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
typename traits::vector_traits<VctX>::value_type
#else
typename VctX::value_type
#endif
dot (VctX const& x, VctY const& y) {
assert (traits::vector_size (y) >= traits::vector_size (x));
return detail::dot (traits::vector_size (x),
#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
traits::vector_storage (x),
#else
traits::vector_storage_const (x),
#endif
traits::vector_stride (x),
#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
traits::vector_storage (y),
#else
traits::vector_storage_const (y),
#endif
traits::vector_stride (y));
}
// dot <- x^T * y
// .. float only -- with double accumulation
template <typename VctX, typename VctY>
inline
double dsdot (VctX const& x, VctY const& y) {
assert (traits::vector_size (y) >= traits::vector_size (x));
return cblas_dsdot (traits::vector_size (x),
#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
traits::vector_storage (x),
#else
traits::vector_storage_const (x),
#endif
traits::vector_stride (x),
#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
traits::vector_storage (y),
#else
traits::vector_storage_const (y),
#endif
traits::vector_stride (y));
}
// apdot <- alpha + x^T * y
// .. float only -- computation uses double precision
template <typename VctX, typename VctY>
inline
float sdsdot (float const alpha, VctX const& x, VctY const& y) {
assert (traits::vector_size (y) >= traits::vector_size (x));
return cblas_sdsdot (traits::vector_size (x), alpha,
#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
traits::vector_storage (x),
#else
traits::vector_storage_const (x),
#endif
traits::vector_stride (x),
#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
traits::vector_storage (y),
#else
traits::vector_storage_const (y),
#endif
traits::vector_stride (y));
}
// dotu <- x^T * y
// .. complex types only
// .. function
template <typename VctX, typename VctY>
inline
#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
typename traits::vector_traits<VctX>::value_type
#else
typename VctX::value_type
#endif
dotu (VctX const& x, VctY const& y) {
assert (traits::vector_size (y) >= traits::vector_size (x));
#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
typename traits::vector_traits<VctX>::value_type val;
#else
typename VctX::value_type val;
#endif
detail::dotu (traits::vector_size (x),
#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
traits::vector_storage (x),
#else
traits::vector_storage_const (x),
#endif
traits::vector_stride (x),
#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
traits::vector_storage (y),
#else
traits::vector_storage_const (y),
#endif
traits::vector_stride (y),
&val);
return val;
}
// .. procedure
template <typename VctX, typename VctY>
inline
void dotu (VctX const& x, VctY const& y,
#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
typename traits::vector_traits<VctX>::value_type& val
#else
typename VctX::value_type& val
#endif
) {
assert (traits::vector_size (y) >= traits::vector_size (x));
detail::dotu (traits::vector_size (x),
#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
traits::vector_storage (x),
#else
traits::vector_storage_const (x),
#endif
traits::vector_stride (x),
#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
traits::vector_storage (y),
#else
traits::vector_storage_const (y),
#endif
traits::vector_stride (y),
&val);
}
// dotc <- x^H * y
// .. complex types only
// .. function
template <typename VctX, typename VctY>
inline
#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
typename traits::vector_traits<VctX>::value_type
#else
typename VctX::value_type
#endif
dotc (VctX const& x, VctY const& y) {
assert (traits::vector_size (y) >= traits::vector_size (x));
#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
typename traits::vector_traits<VctX>::value_type val;
#else
typename VctX::value_type val;
#endif
detail::dotc (traits::vector_size (x),
#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
traits::vector_storage (x),
#else
traits::vector_storage_const (x),
#endif
traits::vector_stride (x),
#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
traits::vector_storage (y),
#else
traits::vector_storage_const (y),
#endif
traits::vector_stride (y),
&val);
return val;
}
// .. procedure
template <typename VctX, typename VctY>
inline
void dotc (VctX const& x, VctY const& y,
#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
typename traits::vector_traits<VctX>::value_type& val
#else
typename VctX::value_type& val
#endif
) {
assert (traits::vector_size (y) >= traits::vector_size (x));
detail::dotc (traits::vector_size (x),
#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
traits::vector_storage (x),
#else
traits::vector_storage_const (x),
#endif
traits::vector_stride (x),
#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
traits::vector_storage (y),
#else
traits::vector_storage_const (y),
#endif
traits::vector_stride (y),
&val);
}
// nrm2 <- ||x||_2
template <typename Vct>
inline
typename traits::type_traits<
#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
typename traits::vector_traits<Vct>::value_type
#else
typename Vct::value_type
#endif
>::real_type
nrm2 (Vct const& x) {
return detail::nrm2 (traits::vector_size (x),
#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
traits::vector_storage (x),
#else
traits::vector_storage_const (x),
#endif
traits::vector_stride (x));
}
// asum <- ||re (x)|| + ||im (x)||
template <typename Vct>
inline
typename traits::type_traits<
#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
typename traits::vector_traits<Vct>::value_type
#else
typename Vct::value_type
#endif
>::real_type
asum (Vct const& x) {
return detail::asum (traits::vector_size (x),
#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
traits::vector_storage (x),
#else
traits::vector_storage_const (x),
#endif
traits::vector_stride (x));
}
// iamax <- 1st i: max (|re (x_i)| + |im (x_i)|)
template <typename Vct>
inline
CBLAS_INDEX iamax (Vct const& x) {
return detail::iamax (traits::vector_size (x),
#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
traits::vector_storage (x),
#else
traits::vector_storage_const (x),
#endif
traits::vector_stride (x));
}
// TO DO: plane rotations
} // namespace atlas
}}}
#endif // BOOST_NUMERIC_BINDINGS_CBLAS_LEVEL_1_HPP

View File

@@ -1,355 +0,0 @@
/*
*
* Copyright (c) Kresimir Fresl 2002
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* Author acknowledges the support of the Faculty of Civil Engineering,
* University of Zagreb, Croatia.
*
*/
#ifndef BOOST_NUMERIC_BINDINGS_CBLAS1_OVERLOADS_HPP
#define BOOST_NUMERIC_BINDINGS_CBLAS1_OVERLOADS_HPP
#include <complex>
#include <boost/numeric/bindings/atlas/cblas_inc.hpp>
#include <boost/numeric/bindings/traits/type.hpp>
namespace boost { namespace numeric { namespace bindings {
namespace atlas { namespace detail {
// dot <- x^T * y
// .. real types: calls cblas_xdot
// .. complex types: calls cblas_xdotu
inline
float dot (int const N, float const* X, int const incX,
float const* Y, int const incY) {
return cblas_sdot (N, X, incX, Y, incY);
}
inline
double dot (int const N, double const* X, int const incX,
double const* Y, int const incY) {
return cblas_ddot (N, X, incX, Y, incY);
}
inline
traits::complex_f
dot (int const N, traits::complex_f const* X, int const incX,
traits::complex_f const* Y, int const incY) {
traits::complex_f val;
cblas_cdotu_sub (N,
static_cast<void const*> (X), incX,
static_cast<void const*> (Y), incY,
static_cast<void*> (&val));
return val;
}
inline
traits::complex_d
dot (int const N, traits::complex_d const* X, int const incX,
traits::complex_d const* Y, int const incY) {
traits::complex_d val;
cblas_zdotu_sub (N,
static_cast<void const*> (X), incX,
static_cast<void const*> (Y), incY,
static_cast<void*> (&val));
return val;
}
// dotu <- x^T * y
// .. complex types only
inline
void dotu (int const N, traits::complex_f const* X, int const incX,
traits::complex_f const* Y, int const incY,
traits::complex_f* val)
{
cblas_cdotu_sub (N,
static_cast<void const*> (X), incX,
static_cast<void const*> (Y), incY,
static_cast<void*> (val));
}
inline
void dotu (int const N, traits::complex_d const* X, int const incX,
traits::complex_d const* Y, int const incY,
traits::complex_d* val)
{
cblas_zdotu_sub (N,
static_cast<void const*> (X), incX,
static_cast<void const*> (Y), incY,
static_cast<void*> (val));
}
// dotc <- x^H * y
// .. complex types only
inline
void dotc (int const N, traits::complex_f const* X, int const incX,
traits::complex_f const* Y, int const incY,
traits::complex_f* val)
{
cblas_cdotc_sub (N,
static_cast<void const*> (X), incX,
static_cast<void const*> (Y), incY,
static_cast<void*> (val));
}
inline
void dotc (int const N, traits::complex_d const* X, int const incX,
traits::complex_d const* Y, int const incY,
traits::complex_d* val)
{
cblas_zdotc_sub (N,
static_cast<void const*> (X), incX,
static_cast<void const*> (Y), incY,
static_cast<void*> (val));
}
// nrm2 <- ||x||_2
inline
float nrm2 (int const N, float const* X, int const incX) {
return cblas_snrm2 (N, X, incX);
}
inline
double nrm2 (int const N, double const* X, int const incX) {
return cblas_dnrm2 (N, X, incX);
}
inline
float nrm2 (int const N, traits::complex_f const* X, int const incX) {
return cblas_scnrm2 (N, static_cast<void const*> (X), incX);
}
inline
double nrm2 (int const N, traits::complex_d const* X, int const incX) {
return cblas_dznrm2 (N, static_cast<void const*> (X), incX);
}
// asum <- ||re (x)|| + ||im (x)||
inline
float asum (int const N, float const* X, int const incX) {
return cblas_sasum (N, X, incX);
}
inline
double asum (int const N, double const* X, int const incX) {
return cblas_dasum (N, X, incX);
}
inline
float asum (int const N, traits::complex_f const* X, int const incX) {
return cblas_scasum (N, static_cast<void const*> (X), incX);
}
inline
double asum (int const N, traits::complex_d const* X, int const incX) {
return cblas_dzasum (N, static_cast<void const*> (X), incX);
}
// iamax <- 1st i: max (|re (x_i)| + |im (x_i)|)
inline
CBLAS_INDEX iamax (int const N, float const* X, int const incX) {
return cblas_isamax (N, X, incX);
}
inline
CBLAS_INDEX iamax (int const N, double const* X, int const incX) {
return cblas_idamax (N, X, incX);
}
inline
CBLAS_INDEX
iamax (int const N, traits::complex_f const* X, int const incX) {
return cblas_icamax (N, static_cast<void const*> (X), incX);
}
inline
CBLAS_INDEX
iamax (int const N, traits::complex_d const* X, int const incX) {
return cblas_izamax (N, static_cast<void const*> (X), incX);
}
// x <-> y
inline
void swap (int const N, float* X, int const incX,
float* Y, int const incY) {
cblas_sswap (N, X, incX, Y, incY);
}
inline
void swap (int const N, double* X, int const incX,
double* Y, int const incY) {
cblas_dswap (N, X, incX, Y, incY);
}
inline
void swap (int const N, traits::complex_f* X, int const incX,
traits::complex_f* Y, int const incY) {
cblas_cswap (N,
static_cast<void*> (X), incX,
static_cast<void*> (Y), incY);
}
inline
void swap (int const N, traits::complex_d* X, int const incX,
traits::complex_d* Y, int const incY) {
cblas_zswap (N,
static_cast<void*> (X), incX,
static_cast<void*> (Y), incY);
}
// y <- x
inline
void copy (int const N, float const* X, int const incX,
float* Y, int const incY) {
cblas_scopy (N, X, incX, Y, incY);
}
inline
void copy (int const N, double const* X, int const incX,
double* Y, int const incY) {
cblas_dcopy (N, X, incX, Y, incY);
}
inline
void copy (int const N, traits::complex_f const* X, int const incX,
traits::complex_f* Y, int const incY) {
cblas_ccopy (N,
static_cast<void const*> (X), incX,
static_cast<void*> (Y), incY);
}
inline
void copy (int const N, traits::complex_d const* X, int const incX,
traits::complex_d* Y, int const incY) {
cblas_zcopy (N,
static_cast<void const*> (X), incX,
static_cast<void*> (Y), incY);
}
// y <- alpha * x + y
inline
void axpy (int const N,
float const alpha, float const* X, int const incX,
float* Y, int const incY)
{
cblas_saxpy (N, alpha, X, incX, Y, incY);
}
inline
void axpy (int const N,
double const alpha, double const* X, int const incX,
double* Y, int const incY)
{
cblas_daxpy (N, alpha, X, incX, Y, incY);
}
inline
void axpy (int const N,
traits::complex_f const& alpha,
traits::complex_f const* X, int const incX,
traits::complex_f* Y, int const incY)
{
cblas_caxpy (N,
static_cast<void const*> (&alpha),
static_cast<void const*> (X), incX,
static_cast<void*> (Y), incY);
}
inline
void axpy (int const N,
traits::complex_d const& alpha,
traits::complex_d const* X, int const incX,
traits::complex_d* Y, int const incY)
{
cblas_zaxpy (N,
static_cast<void const*> (&alpha),
static_cast<void const*> (X), incX,
static_cast<void*> (Y), incY);
}
// y <- alpha * x + beta * y
inline
void axpby (int const N,
float const alpha, float const* X, int const incX,
float const beta, float* Y, int const incY)
{
catlas_saxpby (N, alpha, X, incX, beta, Y, incY);
}
inline
void axpby (int const N,
double const alpha, double const* X, int const incX,
double const beta, double* Y, int const incY)
{
catlas_daxpby (N, alpha, X, incX, beta, Y, incY);
}
inline
void axpby (int const N,
traits::complex_f const& alpha,
traits::complex_f const* X, int const incX,
traits::complex_f const& beta,
traits::complex_f* Y, int const incY)
{
catlas_caxpby (N,
static_cast<void const*> (&alpha),
static_cast<void const*> (X), incX,
static_cast<void const*> (&beta),
static_cast<void*> (Y), incY);
}
inline
void axpby (int const N,
traits::complex_d const& alpha,
traits::complex_d const* X, int const incX,
traits::complex_d const& beta,
traits::complex_d* Y, int const incY)
{
catlas_zaxpby (N,
static_cast<void const*> (&alpha),
static_cast<void const*> (X), incX,
static_cast<void const*> (&beta),
static_cast<void*> (Y), incY);
}
// x_i <- alpha for all i
inline
void set (int const N, float const alpha, float* X, int const incX) {
catlas_sset (N, alpha, X, incX);
}
inline
void set (int const N, double const alpha, double* X, int const incX) {
catlas_dset (N, alpha, X, incX);
}
inline
void set (int const N, traits::complex_f const& alpha,
traits::complex_f* X, int const incX) {
catlas_cset (N, static_cast<void const*> (&alpha),
static_cast<void*> (X), incX);
}
inline
void set (int const N, traits::complex_d const& alpha,
traits::complex_d* X, int const incX) {
catlas_zset (N, static_cast<void const*> (&alpha),
static_cast<void*> (X), incX);
}
// x <- alpha * x
inline
void scal (int const N, float const alpha, float* X, int const incX) {
cblas_sscal (N, alpha, X, incX);
}
inline
void scal (int const N, double const alpha, double* X, int const incX) {
cblas_dscal (N, alpha, X, incX);
}
inline
void scal (int const N, traits::complex_f const& alpha,
traits::complex_f* X, int const incX) {
cblas_cscal (N, static_cast<void const*> (&alpha),
static_cast<void*> (X), incX);
}
inline
void scal (int const N, float const alpha,
traits::complex_f* X, int const incX) {
cblas_csscal (N, alpha, static_cast<void*> (X), incX);
}
inline
void scal (int const N, traits::complex_d const& alpha,
traits::complex_d* X, int const incX) {
cblas_zscal (N, static_cast<void const*> (&alpha),
static_cast<void*> (X), incX);
}
inline
void scal (int const N, double const alpha,
traits::complex_d* X, int const incX) {
cblas_zdscal (N, alpha, static_cast<void*> (X), incX);
}
}} // namepaces detail & atlas
}}}
#endif // BOOST_NUMERIC_BINDINGS_CBLAS1_OVERLOADS_HPP

File diff suppressed because it is too large Load Diff

View File

@@ -1,524 +0,0 @@
/*
*
* Copyright (c) Kresimir Fresl 2002, 2003
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* Author acknowledges the support of the Faculty of Civil Engineering,
* University of Zagreb, Croatia.
*
*/
#ifndef BOOST_NUMERIC_BINDINGS_CBLAS2_OVERLOADS_HPP
#define BOOST_NUMERIC_BINDINGS_CBLAS2_OVERLOADS_HPP
#include <complex>
#include <boost/numeric/bindings/atlas/cblas_inc.hpp>
#include <boost/numeric/bindings/traits/type.hpp>
namespace boost { namespace numeric { namespace bindings {
namespace atlas { namespace detail {
// y <- alpha * op (A) * x + beta * y
inline
void gemv (CBLAS_ORDER const Order,
CBLAS_TRANSPOSE const TransA, int const M, int const N,
float const alpha, float const* A, int const lda,
float const* X, int const incX,
float const beta, float* Y, int const incY)
{
cblas_sgemv (Order, TransA, M, N, alpha, A, lda,
X, incX,
beta, Y, incY);
}
inline
void gemv (CBLAS_ORDER const Order,
CBLAS_TRANSPOSE const TransA, int const M, int const N,
double const alpha, double const* A, int const lda,
double const* X, int const incX,
double const beta, double* Y, int const incY)
{
cblas_dgemv (Order, TransA, M, N, alpha, A, lda,
X, incX,
beta, Y, incY);
}
inline
void gemv (CBLAS_ORDER const Order,
CBLAS_TRANSPOSE const TransA, int const M, int const N,
traits::complex_f const& alpha,
traits::complex_f const* A, int const lda,
traits::complex_f const* X, int const incX,
traits::complex_f const& beta,
traits::complex_f* Y, int const incY)
{
cblas_cgemv (Order, TransA, M, N,
static_cast<void const*> (&alpha),
static_cast<void const*> (A), lda,
static_cast<void const*> (X), incX,
static_cast<void const*> (&beta),
static_cast<void*> (Y), incY);
}
inline
void gemv (CBLAS_ORDER const Order,
CBLAS_TRANSPOSE const TransA, int const M, int const N,
traits::complex_d const& alpha,
traits::complex_d const* A, int const lda,
traits::complex_d const* X, int const incX,
traits::complex_d const& beta,
traits::complex_d* Y, int const incY)
{
cblas_zgemv (Order, TransA, M, N,
static_cast<void const*> (&alpha),
static_cast<void const*> (A), lda,
static_cast<void const*> (X), incX,
static_cast<void const*> (&beta),
static_cast<void*> (Y), incY);
}
// y <- alpha * A * x + beta * y
// A real symmetric
inline
void symv (CBLAS_ORDER const Order, CBLAS_UPLO const Uplo,
int const N, float const alpha, float const* A,
int const lda, float const* X, int const incX,
float const beta, float* Y, int const incY)
{
cblas_ssymv (Order, Uplo, N, alpha, A, lda,
X, incX, beta, Y, incY);
}
inline
void symv (CBLAS_ORDER const Order, CBLAS_UPLO const Uplo,
int const N, double const alpha, double const* A,
int const lda, double const* X, int const incX,
double const beta, double* Y, int const incY)
{
cblas_dsymv (Order, Uplo, N, alpha, A, lda,
X, incX, beta, Y, incY);
}
// y <- alpha * A * x + beta * y
// A real symmetric in packed form
inline
void spmv (CBLAS_ORDER const Order, CBLAS_UPLO const Uplo,
int const N, float const alpha, float const* Ap,
float const* X, int const incX,
float const beta, float* Y, int const incY)
{
cblas_sspmv (Order, Uplo, N, alpha, Ap, X, incX, beta, Y, incY);
}
inline
void spmv (CBLAS_ORDER const Order, CBLAS_UPLO const Uplo,
int const N, double const alpha, double const* Ap,
double const* X, int const incX,
double const beta, double* Y, int const incY)
{
cblas_dspmv (Order, Uplo, N, alpha, Ap, X, incX, beta, Y, incY);
}
// y <- alpha * A * x + beta * y
// A complex hermitian
inline
void hemv (CBLAS_ORDER const Order, CBLAS_UPLO const Uplo,
int const N, traits::complex_f const& alpha,
traits::complex_f const* A, int const lda,
traits::complex_f const* X, int const incX,
traits::complex_f const& beta,
traits::complex_f* Y, int const incY)
{
cblas_chemv (Order, Uplo, N,
static_cast<void const*> (&alpha),
static_cast<void const*> (A), lda,
static_cast<void const*> (X), incX,
static_cast<void const*> (&beta),
static_cast<void*> (Y), incY);
}
inline
void hemv (CBLAS_ORDER const Order, CBLAS_UPLO const Uplo,
int const N, traits::complex_d const& alpha,
traits::complex_d const* A, int const lda,
traits::complex_d const* X, int const incX,
traits::complex_d const& beta,
traits::complex_d* Y, int const incY)
{
cblas_zhemv (Order, Uplo, N,
static_cast<void const*> (&alpha),
static_cast<void const*> (A), lda,
static_cast<void const*> (X), incX,
static_cast<void const*> (&beta),
static_cast<void*> (Y), incY);
}
// y <- alpha * A * x + beta * y
// A complex hermitian in packed form
inline
void hpmv (CBLAS_ORDER const Order, CBLAS_UPLO const Uplo,
int const N, traits::complex_f const& alpha,
traits::complex_f const* Ap,
traits::complex_f const* X, int const incX,
traits::complex_f const& beta,
traits::complex_f* Y, int const incY)
{
cblas_chpmv (Order, Uplo, N,
static_cast<void const*> (&alpha),
static_cast<void const*> (Ap),
static_cast<void const*> (X), incX,
static_cast<void const*> (&beta),
static_cast<void*> (Y), incY);
}
inline
void hpmv (CBLAS_ORDER const Order, CBLAS_UPLO const Uplo,
int const N, traits::complex_d const& alpha,
traits::complex_d const* Ap,
traits::complex_d const* X, int const incX,
traits::complex_d const& beta,
traits::complex_d* Y, int const incY)
{
cblas_zhpmv (Order, Uplo, N,
static_cast<void const*> (&alpha),
static_cast<void const*> (Ap),
static_cast<void const*> (X), incX,
static_cast<void const*> (&beta),
static_cast<void*> (Y), incY);
}
// A <- alpha * x * y^T + A
// .. real types: calls cblas_xger
// .. complex types: calls cblas_xgeru
inline
void ger (CBLAS_ORDER const Order, int const M, int const N,
float const alpha, float const* X, int const incX,
float const* Y, int const incY, float* A, int const lda)
{
cblas_sger (Order, M, N, alpha, X, incX, Y, incY, A, lda);
}
inline
void ger (CBLAS_ORDER const Order, int const M, int const N,
double const alpha, double const* X, int const incX,
double const* Y, int const incY, double* A, int const lda)
{
cblas_dger (Order, M, N, alpha, X, incX, Y, incY, A, lda);
}
inline
void ger (CBLAS_ORDER const Order, int const M, int const N,
traits::complex_f const& alpha,
traits::complex_f const* X, int const incX,
traits::complex_f const* Y, int const incY,
traits::complex_f* A, int const lda)
{
cblas_cgeru (Order, M, N,
static_cast<void const*> (&alpha),
static_cast<void const*> (X), incX,
static_cast<void const*> (Y), incY,
static_cast<void*> (A), lda);
}
inline
void ger (CBLAS_ORDER const Order, int const M, int const N,
traits::complex_d const& alpha,
traits::complex_d const* X, int const incX,
traits::complex_d const* Y, int const incY,
traits::complex_d* A, int const lda)
{
cblas_zgeru (Order, M, N,
static_cast<void const*> (&alpha),
static_cast<void const*> (X), incX,
static_cast<void const*> (Y), incY,
static_cast<void*> (A), lda);
}
// A <- alpha * x * y^T + A
// .. complex types only
inline
void geru (CBLAS_ORDER const Order, int const M, int const N,
traits::complex_f const& alpha,
traits::complex_f const* X, int const incX,
traits::complex_f const* Y, int const incY,
traits::complex_f* A, int const lda)
{
cblas_cgeru (Order, M, N,
static_cast<void const*> (&alpha),
static_cast<void const*> (X), incX,
static_cast<void const*> (Y), incY,
static_cast<void*> (A), lda);
}
inline
void geru (CBLAS_ORDER const Order, int const M, int const N,
traits::complex_d const& alpha,
traits::complex_d const* X, int const incX,
traits::complex_d const* Y, int const incY,
traits::complex_d* A, int const lda)
{
cblas_zgeru (Order, M, N,
static_cast<void const*> (&alpha),
static_cast<void const*> (X), incX,
static_cast<void const*> (Y), incY,
static_cast<void*> (A), lda);
}
// A <- alpha * x * y^H + A
// .. complex types only
inline
void gerc (CBLAS_ORDER const Order, int const M, int const N,
traits::complex_f const& alpha,
traits::complex_f const* X, int const incX,
traits::complex_f const* Y, int const incY,
traits::complex_f* A, int const lda)
{
cblas_cgerc (Order, M, N,
static_cast<void const*> (&alpha),
static_cast<void const*> (X), incX,
static_cast<void const*> (Y), incY,
static_cast<void*> (A), lda);
}
inline
void gerc (CBLAS_ORDER const Order, int const M, int const N,
traits::complex_d const& alpha,
traits::complex_d const* X, int const incX,
traits::complex_d const* Y, int const incY,
traits::complex_d* A, int const lda)
{
cblas_zgerc (Order, M, N,
static_cast<void const*> (&alpha),
static_cast<void const*> (X), incX,
static_cast<void const*> (Y), incY,
static_cast<void*> (A), lda);
}
// A <- alpha * x * x^T + A
// A real symmetric
inline
void syr (CBLAS_ORDER const Order, CBLAS_UPLO const Uplo,
int const N, float const alpha,
float const* X, int const incX, float* A, int const lda)
{
cblas_ssyr (Order, Uplo, N, alpha, X, incX, A, lda);
}
inline
void syr (CBLAS_ORDER const Order, CBLAS_UPLO const Uplo,
int const N, double const alpha,
double const* X, int const incX, double* A, int const lda)
{
cblas_dsyr (Order, Uplo, N, alpha, X, incX, A, lda);
}
// A <- alpha * x * x^T + A
// A real symmetric in packed form
inline
void spr (CBLAS_ORDER const Order, CBLAS_UPLO const Uplo,
int const N, float const alpha,
float const* X, int const incX, float* Ap)
{
cblas_sspr (Order, Uplo, N, alpha, X, incX, Ap);
}
inline
void spr (CBLAS_ORDER const Order, CBLAS_UPLO const Uplo,
int const N, double const alpha,
double const* X, int const incX, double* Ap)
{
cblas_dspr (Order, Uplo, N, alpha, X, incX, Ap);
}
// A <- alpha * x * y^T + alpha * y * x^T + A
// A real symmetric
inline
void syr2 (CBLAS_ORDER const Order, CBLAS_UPLO const Uplo,
int const N, float const alpha,
float const* X, int const incX,
float const* Y, int const incY,
float* A, int const lda)
{
cblas_ssyr2 (Order, Uplo, N, alpha, X, incX, Y, incY, A, lda);
}
inline
void syr2 (CBLAS_ORDER const Order, CBLAS_UPLO const Uplo,
int const N, double const alpha,
double const* X, int const incX,
double const* Y, int const incY,
double* A, int const lda)
{
cblas_dsyr2 (Order, Uplo, N, alpha, X, incX, Y, incY, A, lda);
}
// A <- alpha * x * y^T + alpha * y * x^T + A
// A real symmetric in packed form
inline
void spr2 (CBLAS_ORDER const Order, CBLAS_UPLO const Uplo,
int const N, float const alpha,
float const* X, int const incX,
float const* Y, int const incY, float* Ap)
{
cblas_sspr2 (Order, Uplo, N, alpha, X, incX, Y, incY, Ap);
}
inline
void spr2 (CBLAS_ORDER const Order, CBLAS_UPLO const Uplo,
int const N, double const alpha,
double const* X, int const incX,
double const* Y, int const incY, double* Ap)
{
cblas_dspr2 (Order, Uplo, N, alpha, X, incX, Y, incY, Ap);
}
// A <- alpha * x * x^H + A
// A hermitian
inline
void her (CBLAS_ORDER const Order, CBLAS_UPLO const Uplo,
int const N, float const alpha,
traits::complex_f const* X, int const incX,
traits::complex_f* A, int const lda)
{
cblas_cher (Order, Uplo, N, alpha,
static_cast<void const*> (X), incX,
static_cast<void*> (A), lda);
}
inline
void her (CBLAS_ORDER const Order, CBLAS_UPLO const Uplo,
int const N, double const alpha,
traits::complex_d const* X, int const incX,
traits::complex_d* A, int const lda)
{
cblas_zher (Order, Uplo, N, alpha,
static_cast<void const*> (X), incX,
static_cast<void*> (A), lda);
}
// A <- alpha * x * x^H + A
// A hermitian in packed form
inline
void hpr (CBLAS_ORDER const Order, CBLAS_UPLO const Uplo,
int const N, float const alpha,
traits::complex_f const* X, int const incX,
traits::complex_f* Ap)
{
cblas_chpr (Order, Uplo, N, alpha,
static_cast<void const*> (X), incX,
static_cast<void*> (Ap));
}
inline
void hpr (CBLAS_ORDER const Order, CBLAS_UPLO const Uplo,
int const N, double const alpha,
traits::complex_d const* X, int const incX,
traits::complex_d* Ap)
{
cblas_zhpr (Order, Uplo, N, alpha,
static_cast<void const*> (X), incX,
static_cast<void*> (Ap));
}
// A <- alpha * x * y^H + y * (alpha * x)^H + A
// A hermitian
inline
void her2 (CBLAS_ORDER const Order, CBLAS_UPLO const Uplo,
int const N, traits::complex_f const& alpha,
traits::complex_f const* X, int const incX,
traits::complex_f const* Y, int const incY,
traits::complex_f* A, int const lda)
{
cblas_cher2 (Order, Uplo, N,
static_cast<void const*> (&alpha),
static_cast<void const*> (X), incX,
static_cast<void const*> (Y), incY,
static_cast<void*> (A), lda);
}
inline
void her2 (CBLAS_ORDER const Order, CBLAS_UPLO const Uplo,
int const N, traits::complex_d const& alpha,
traits::complex_d const* X, int const incX,
traits::complex_d const* Y, int const incY,
traits::complex_d* A, int const lda)
{
cblas_zher2 (Order, Uplo, N,
static_cast<void const*> (&alpha),
static_cast<void const*> (X), incX,
static_cast<void const*> (Y), incY,
static_cast<void*> (A), lda);
}
// A <- alpha * x * y^H + y * (alpha * x)^H + A
// A hermitian in packed form
inline
void hpr2 (CBLAS_ORDER const Order, CBLAS_UPLO const Uplo,
int const N, traits::complex_f const& alpha,
traits::complex_f const* X, int const incX,
traits::complex_f const* Y, int const incY,
traits::complex_f* Ap)
{
cblas_chpr2 (Order, Uplo, N,
static_cast<void const*> (&alpha),
static_cast<void const*> (X), incX,
static_cast<void const*> (Y), incY,
static_cast<void*> (Ap));
}
inline
void hpr2 (CBLAS_ORDER const Order, CBLAS_UPLO const Uplo,
int const N, traits::complex_d const& alpha,
traits::complex_d const* X, int const incX,
traits::complex_d const* Y, int const incY,
traits::complex_d* Ap)
{
cblas_zhpr2 (Order, Uplo, N,
static_cast<void const*> (&alpha),
static_cast<void const*> (X), incX,
static_cast<void const*> (Y), incY,
static_cast<void*> (Ap));
}
}} // namepaces detail & atlas
}}}
#endif // BOOST_NUMERIC_BINDINGS_CBLAS2_OVERLOADS_HPP

File diff suppressed because it is too large Load Diff

View File

@@ -1,378 +0,0 @@
/*
*
* Copyright (c) Kresimir Fresl 2002
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* Author acknowledges the support of the Faculty of Civil Engineering,
* University of Zagreb, Croatia.
*
*/
#ifndef BOOST_NUMERIC_BINDINGS_CBLAS3_OVERLOADS_HPP
#define BOOST_NUMERIC_BINDINGS_CBLAS3_OVERLOADS_HPP
#include <complex>
#include <boost/numeric/bindings/atlas/cblas_inc.hpp>
#include <boost/numeric/bindings/traits/type.hpp>
namespace boost { namespace numeric { namespace bindings {
namespace atlas { namespace detail {
// C <- alpha * op (A) * op (B) + beta * C
inline
void gemm (CBLAS_ORDER const Order,
CBLAS_TRANSPOSE const TransA, CBLAS_TRANSPOSE const TransB,
int const M, int const N, int const K,
float const alpha, float const* A, int const lda,
float const* B, int const ldb,
float const beta, float* C, int const ldc)
{
cblas_sgemm (Order, TransA, TransB, M, N, K,
alpha, A, lda,
B, ldb,
beta, C, ldc);
}
inline
void gemm (CBLAS_ORDER const Order,
CBLAS_TRANSPOSE const TransA, CBLAS_TRANSPOSE const TransB,
int const M, int const N, int const K,
double const alpha, double const* A, int const lda,
double const* B, int const ldb,
double const beta, double* C, int const ldc)
{
cblas_dgemm (Order, TransA, TransB, M, N, K,
alpha, A, lda,
B, ldb,
beta, C, ldc);
}
inline
void gemm (CBLAS_ORDER const Order,
CBLAS_TRANSPOSE const TransA, CBLAS_TRANSPOSE const TransB,
int const M, int const N, int const K,
traits::complex_f const& alpha,
traits::complex_f const* A, int const lda,
traits::complex_f const* B, int const ldb,
traits::complex_f const& beta,
traits::complex_f* C, int const ldc)
{
cblas_cgemm (Order, TransA, TransB, M, N, K,
static_cast<void const*> (&alpha),
static_cast<void const*> (A), lda,
static_cast<void const*> (B), ldb,
static_cast<void const*> (&beta),
static_cast<void*> (C), ldc);
}
inline
void gemm (CBLAS_ORDER const Order,
CBLAS_TRANSPOSE const TransA, CBLAS_TRANSPOSE const TransB,
int const M, int const N, int const K,
traits::complex_d const& alpha,
traits::complex_d const* A, int const lda,
traits::complex_d const* B, int const ldb,
traits::complex_d const& beta,
traits::complex_d* C, int const ldc)
{
cblas_zgemm (Order, TransA, TransB, M, N, K,
static_cast<void const*> (&alpha),
static_cast<void const*> (A), lda,
static_cast<void const*> (B), ldb,
static_cast<void const*> (&beta),
static_cast<void*> (C), ldc);
}
// C <- alpha * A * B + beta * C
// C <- alpha * B * A + beta * C
// A == A^T
inline
void symm (CBLAS_ORDER const Order, CBLAS_SIDE const Side,
CBLAS_UPLO const Uplo, int const M, int const N,
float const alpha, float const* A, int const lda,
float const* B, int const ldb,
float const beta, float* C, int const ldc)
{
cblas_ssymm (Order, Side, Uplo, M, N,
alpha, A, lda,
B, ldb,
beta, C, ldc);
}
inline
void symm (CBLAS_ORDER const Order, CBLAS_SIDE const Side,
CBLAS_UPLO const Uplo, int const M, int const N,
double const alpha, double const* A, int const lda,
double const* B, int const ldb,
double const beta, double* C, int const ldc)
{
cblas_dsymm (Order, Side, Uplo, M, N,
alpha, A, lda,
B, ldb,
beta, C, ldc);
}
inline
void symm (CBLAS_ORDER const Order, CBLAS_SIDE const Side,
CBLAS_UPLO const Uplo, int const M, int const N,
traits::complex_f const& alpha,
traits::complex_f const* A, int const lda,
traits::complex_f const* B, int const ldb,
traits::complex_f const& beta,
traits::complex_f* C, int const ldc)
{
cblas_csymm (Order, Side, Uplo, M, N,
static_cast<void const*> (&alpha),
static_cast<void const*> (A), lda,
static_cast<void const*> (B), ldb,
static_cast<void const*> (&beta),
static_cast<void*> (C), ldc);
}
inline
void symm (CBLAS_ORDER const Order, CBLAS_SIDE const Side,
CBLAS_UPLO const Uplo, int const M, int const N,
traits::complex_d const& alpha,
traits::complex_d const* A, int const lda,
traits::complex_d const* B, int const ldb,
traits::complex_d const& beta,
traits::complex_d* C, int const ldc)
{
cblas_zsymm (Order, Side, Uplo, M, N,
static_cast<void const*> (&alpha),
static_cast<void const*> (A), lda,
static_cast<void const*> (B), ldb,
static_cast<void const*> (&beta),
static_cast<void*> (C), ldc);
}
// C <- alpha * A * B + beta * C
// C <- alpha * B * A + beta * C
// A == A^H
inline
void hemm (CBLAS_ORDER const Order, CBLAS_SIDE const Side,
CBLAS_UPLO const Uplo, int const M, int const N,
traits::complex_f const& alpha,
traits::complex_f const* A, int const lda,
traits::complex_f const* B, int const ldb,
traits::complex_f const& beta,
traits::complex_f* C, int const ldc)
{
cblas_chemm (Order, Side, Uplo, M, N,
static_cast<void const*> (&alpha),
static_cast<void const*> (A), lda,
static_cast<void const*> (B), ldb,
static_cast<void const*> (&beta),
static_cast<void*> (C), ldc);
}
inline
void hemm (CBLAS_ORDER const Order, CBLAS_SIDE const Side,
CBLAS_UPLO const Uplo, int const M, int const N,
traits::complex_d const& alpha,
traits::complex_d const* A, int const lda,
traits::complex_d const* B, int const ldb,
traits::complex_d const& beta,
traits::complex_d* C, int const ldc)
{
cblas_zhemm (Order, Side, Uplo, M, N,
static_cast<void const*> (&alpha),
static_cast<void const*> (A), lda,
static_cast<void const*> (B), ldb,
static_cast<void const*> (&beta),
static_cast<void*> (C), ldc);
}
// C <- alpha * A * A^T + beta * C
// C <- alpha * A^T * A + beta * C
// C == C^T
inline
void syrk (CBLAS_ORDER const Order, CBLAS_UPLO const Uplo,
CBLAS_TRANSPOSE const Trans, int const N, int const K,
float const alpha, float const* A, int const lda,
float const beta, float* C, int const ldc)
{
cblas_ssyrk (Order, Uplo, Trans, N, K, alpha, A, lda, beta, C, ldc);
}
inline
void syrk (CBLAS_ORDER const Order, CBLAS_UPLO const Uplo,
CBLAS_TRANSPOSE const Trans, int const N, int const K,
double const alpha, double const* A, int const lda,
double const beta, double* C, int const ldc)
{
cblas_dsyrk (Order, Uplo, Trans, N, K, alpha, A, lda, beta, C, ldc);
}
inline
void syrk (CBLAS_ORDER const Order, CBLAS_UPLO const Uplo,
CBLAS_TRANSPOSE const Trans, int const N, int const K,
traits::complex_f const& alpha,
traits::complex_f const* A, int const lda,
traits::complex_f const& beta,
traits::complex_f* C, int const ldc)
{
cblas_csyrk (Order, Uplo, Trans, N, K,
static_cast<void const*> (&alpha),
static_cast<void const*> (A), lda,
static_cast<void const*> (&beta),
static_cast<void*> (C), ldc);
}
inline
void syrk (CBLAS_ORDER const Order, CBLAS_UPLO const Uplo,
CBLAS_TRANSPOSE const Trans, int const N, int const K,
traits::complex_d const& alpha,
traits::complex_d const* A, int const lda,
traits::complex_d const& beta,
traits::complex_d* C, int const ldc)
{
cblas_zsyrk (Order, Uplo, Trans, N, K,
static_cast<void const*> (&alpha),
static_cast<void const*> (A), lda,
static_cast<void const*> (&beta),
static_cast<void*> (C), ldc);
}
// C <- alpha * A * B^T + conj(alpha) * B * A^T + beta * C
// C <- alpha * A^T * B + conj(alpha) * B^T * A + beta * C
// C == C^T
inline
void syr2k (CBLAS_ORDER const Order, CBLAS_UPLO const Uplo,
CBLAS_TRANSPOSE const Trans, int const N, int const K,
float const alpha, float const* A, int const lda,
float const* B, int const ldb,
float const beta, float* C, int const ldc)
{
cblas_ssyr2k (Order, Uplo, Trans, N, K,
alpha, A, lda, B, ldb, beta, C, ldc);
}
inline
void syr2k (CBLAS_ORDER const Order, CBLAS_UPLO const Uplo,
CBLAS_TRANSPOSE const Trans, int const N, int const K,
double const alpha, double const* A, int const lda,
double const* B, int const ldb,
double const beta, double* C, int const ldc)
{
cblas_dsyr2k (Order, Uplo, Trans, N, K,
alpha, A, lda, B, ldb, beta, C, ldc);
}
inline
void syr2k (CBLAS_ORDER const Order, CBLAS_UPLO const Uplo,
CBLAS_TRANSPOSE const Trans, int const N, int const K,
traits::complex_f const& alpha,
traits::complex_f const* A, int const lda,
traits::complex_f const* B, int const ldb,
traits::complex_f const& beta,
traits::complex_f* C, int const ldc)
{
cblas_csyr2k (Order, Uplo, Trans, N, K,
static_cast<void const*> (&alpha),
static_cast<void const*> (A), lda,
static_cast<void const*> (B), ldb,
static_cast<void const*> (&beta),
static_cast<void*> (C), ldc);
}
inline
void syr2k (CBLAS_ORDER const Order, CBLAS_UPLO const Uplo,
CBLAS_TRANSPOSE const Trans, int const N, int const K,
traits::complex_d const& alpha,
traits::complex_d const* A, int const lda,
traits::complex_d const* B, int const ldb,
traits::complex_d const& beta,
traits::complex_d* C, int const ldc)
{
cblas_zsyr2k (Order, Uplo, Trans, N, K,
static_cast<void const*> (&alpha),
static_cast<void const*> (A), lda,
static_cast<void const*> (B), ldb,
static_cast<void const*> (&beta),
static_cast<void*> (C), ldc);
}
// C <- alpha * A * A^H + beta * C
// C <- alpha * A^H * A + beta * C
// C == C^H
inline
void herk (CBLAS_ORDER const Order, CBLAS_UPLO const Uplo,
CBLAS_TRANSPOSE const Trans, int const N, int const K,
float alpha, traits::complex_f const* A, int const lda,
float beta, traits::complex_f* C, int const ldc)
{
cblas_cherk (Order, Uplo, Trans, N, K,
alpha, static_cast<void const*> (A), lda,
beta, static_cast<void*> (C), ldc);
}
inline
void herk (CBLAS_ORDER const Order, CBLAS_UPLO const Uplo,
CBLAS_TRANSPOSE const Trans, int const N, int const K,
double alpha, traits::complex_d const* A, int const lda,
double beta, traits::complex_d* C, int const ldc)
{
cblas_zherk (Order, Uplo, Trans, N, K,
alpha, static_cast<void const*> (A), lda,
beta, static_cast<void*> (C), ldc);
}
// C <- alpha * A * B^H + conj(alpha) * B * A^H + beta * C
// C <- alpha * A^H * B + conj(alpha) * B^H * A + beta * C
// C == C^H
inline
void her2k (CBLAS_ORDER const Order, CBLAS_UPLO const Uplo,
CBLAS_TRANSPOSE const Trans, int const N, int const K,
traits::complex_f const& alpha,
traits::complex_f const* A, int const lda,
traits::complex_f const* B, int const ldb,
float beta, traits::complex_f* C, int const ldc)
{
cblas_cher2k (Order, Uplo, Trans, N, K,
static_cast<void const*> (&alpha),
static_cast<void const*> (A), lda,
static_cast<void const*> (B), ldb,
beta, static_cast<void*> (C), ldc);
}
inline
void her2k (CBLAS_ORDER const Order, CBLAS_UPLO const Uplo,
CBLAS_TRANSPOSE const Trans, int const N, int const K,
traits::complex_d const& alpha,
traits::complex_d const* A, int const lda,
traits::complex_d const* B, int const ldb,
double beta, traits::complex_d* C, int const ldc)
{
cblas_zher2k (Order, Uplo, Trans, N, K,
static_cast<void const*> (&alpha),
static_cast<void const*> (A), lda,
static_cast<void const*> (B), ldb,
beta, static_cast<void*> (C), ldc);
}
}} // namepaces detail & atlas
}}}
#endif // BOOST_NUMERIC_BINDINGS_CBLAS3_OVERLOADS_HPP

View File

@@ -1,73 +0,0 @@
/*
*
* Copyright (c) Kresimir Fresl 2002
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* Author acknowledges the support of the Faculty of Civil Engineering,
* University of Zagreb, Croatia.
*
*/
#ifndef BOOST_NUMERIC_BINDINGS_CBLAS_ENUM_HPP
#define BOOST_NUMERIC_BINDINGS_CBLAS_ENUM_HPP
#include <boost/numeric/bindings/traits/traits.hpp>
#include <boost/numeric/bindings/atlas/cblas_inc.hpp>
#ifdef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
# include <boost/numeric/ublas/config.hpp>
#endif
namespace boost { namespace numeric { namespace bindings {
namespace atlas {
template <typename Ord> struct storage_order {};
#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
template<> struct storage_order<traits::row_major_t> {
// 'ename' - como (in enum_cast<>):
// a template argument may not reference an unnamed type
enum ename { value = CblasRowMajor };
};
template<> struct storage_order<traits::column_major_t> {
enum ename { value = CblasColMajor };
};
#else
template<> struct storage_order<boost::numeric::ublas::row_major_tag> {
enum ename { value = CblasRowMajor };
};
template<> struct storage_order<boost::numeric::ublas::column_major_tag> {
enum ename { value = CblasColMajor };
};
#endif
template <typename UpLo> struct uplo_triang {};
#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
template<> struct uplo_triang<traits::upper_t> {
enum ename { value = CblasUpper };
};
template<> struct uplo_triang<traits::lower_t> {
enum ename { value = CblasLower };
};
#else
template<> struct uplo_triang<boost::numeric::ublas::upper_tag> {
enum ename { value = CblasUpper };
};
template<> struct uplo_triang<boost::numeric::ublas::lower_tag> {
enum ename { value = CblasLower };
};
#endif
// g++ 3.0.4 rejects 'static_cast<E1> (e2)'
template <typename E1, typename E2>
E1 enum_cast (E2 e2) {
return static_cast<E1> (static_cast<int> (e2));
}
}
}}}
#endif

View File

@@ -1,32 +0,0 @@
/*
*
* Copyright (c) Kresimir Fresl 2002
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* Author acknowledges the support of the Faculty of Civil Engineering,
* University of Zagreb, Croatia.
*
*/
//////////////////////////////////////////////////////////////////////////
//
// ATLAS (Automatically Tuned Linear Algebra Software)
//
// ''At present, it provides C and Fortran77 interfaces to a portably
// efficient BLAS implementation, as well as a few routines from LAPACK.''
//
// see: http://math-atlas.sourceforge.net/
//
//////////////////////////////////////////////////////////////////////////
#ifndef BOOST_NUMERIC_BINDINGS_CBLAS_INC_H
#define BOOST_NUMERIC_BINDINGS_CBLAS_INC_H
extern "C" {
# include <atlas/cblas.h>
}
#endif

View File

@@ -1,784 +0,0 @@
/*
*
* Copyright (c) Kresimir Fresl 2002
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* Author acknowledges the support of the Faculty of Civil Engineering,
* University of Zagreb, Croatia.
*
*/
#ifndef BOOST_NUMERIC_BINDINGS_CLAPACK_HPP
#define BOOST_NUMERIC_BINDINGS_CLAPACK_HPP
#include <cassert>
#include <new>
#include <boost/numeric/bindings/traits/traits.hpp>
#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
# include <boost/numeric/bindings/traits/detail/symm_herm_traits.hpp>
#endif
#include <boost/numeric/bindings/atlas/cblas_enum.hpp>
// see libs/numeric/bindings/atlas/doc/index.html, section 2.5.2
//#define BOOST_NUMERIC_BINDINGS_ATLAS_POTRF_BUG
#include <boost/numeric/bindings/atlas/clapack_overloads.hpp>
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
# include <boost/static_assert.hpp>
# include <boost/type_traits/same_traits.hpp>
#endif
namespace boost { namespace numeric { namespace bindings {
namespace atlas {
/////////////////////////////////////////////////////////////////////
//
// general system of linear equations A * X = B
//
/////////////////////////////////////////////////////////////////////
// gesv(): 'driver' function
//
// [comments from 'clapack_dgesv.c':]
/* clapack_xgesv computes the solution to a system of linear equations
* A * X = B,
* where A is an N-by-N matrix and X and B are N-by-NRHS matrices.
*/
// [but ATLAS FAQ says:]
/* What's the deal with the RHS in the row-major factorization/solves?
* Most users are confused by the row major factorization and related
* solves. The right-hand side vectors are probably the biggest source
* of confusion. The RHS array does not represent a matrix in the
* mathematical sense, it is instead a pasting together of the various
* RHS into one array for calling convenience. As such, RHS vectors are
* always stored contiguously, regardless of the row/col major that is
* chosen. This means that ldb/ldx is always independent of NRHS, and
* dependant on N, regardless of the row/col major setting.
*/
// That is, it seems that, if B is row-major, it should be NRHS-by-N,
// and RHS vectors should be its rows, not columns.
//
// [comments from 'clapack_dgesv.c':]
/* The LU factorization used to factor A is dependent on the Order
* parameter, as detailed in the leading comments of clapack_dgetrf.
* The factored form of A is then used to solve the system of equations
* A * X = B.
* A is overwritten with the appropriate LU factorization, and B [...]
* is overwritten with the solution X on output.
*/
// If B is row-major, solution vectors are its rows.
template <typename MatrA, typename MatrB, typename IVec>
inline
int gesv (MatrA& a, IVec& ipiv, MatrB& b) {
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<MatrA>::matrix_structure,
traits::general_t
>::value));
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<MatrB>::matrix_structure,
traits::general_t
>::value));
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<MatrA>::ordering_type,
typename traits::matrix_traits<MatrB>::ordering_type
>::value));
#endif
CBLAS_ORDER const stor_ord
= enum_cast<CBLAS_ORDER const>
(storage_order<
#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
typename traits::matrix_traits<MatrA>::ordering_type
#else
typename MatrA::orientation_category
#endif
>::value);
int const n = traits::matrix_size1 (a);
int const nrhs = stor_ord == CblasColMajor
? traits::matrix_size2 (b)
: traits::matrix_size1 (b);
assert (n == traits::matrix_size2 (a));
assert (n == (stor_ord == CblasColMajor
? traits::matrix_size1 (b)
: traits::matrix_size2 (b)));
assert (n == traits::vector_size (ipiv));
return detail::gesv (stor_ord, n, nrhs,
traits::matrix_storage (a),
traits::leading_dimension (a),
traits::vector_storage (ipiv),
traits::matrix_storage (b),
traits::leading_dimension (b));
}
template <typename MatrA, typename MatrB>
inline
int gesv (MatrA& a, MatrB& b) {
// with 'internal' pivot vector
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<MatrA>::matrix_structure,
traits::general_t
>::value));
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<MatrB>::matrix_structure,
traits::general_t
>::value));
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<MatrA>::ordering_type,
typename traits::matrix_traits<MatrB>::ordering_type
>::value));
#endif
CBLAS_ORDER const stor_ord
= enum_cast<CBLAS_ORDER const>
(storage_order<
#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
typename traits::matrix_traits<MatrA>::ordering_type
#else
typename MatrA::orientation_category
#endif
>::value);
int const n = traits::matrix_size1 (a);
int const nrhs = stor_ord == CblasColMajor
? traits::matrix_size2 (b)
: traits::matrix_size1 (b);
assert (n == traits::matrix_size2 (a));
assert (n == (stor_ord == CblasColMajor
? traits::matrix_size1 (b)
: traits::matrix_size2 (b)));
int *ipiv = new (std::nothrow) int[n];
int ierr = -101;
// clapack_dgesv() errors:
// if (ierr == 0), successful
// if (ierr < 0), the -ierr argument had an illegal value
// -- we will use -101 if allocation fails
// if (ierr > 0), U(i-1,i-1) (or L(i-1,i-1)) is exactly zero
if (ipiv) {
ierr = detail::gesv (stor_ord, n, nrhs,
traits::matrix_storage (a),
traits::leading_dimension (a),
ipiv,
traits::matrix_storage (b),
traits::leading_dimension (b));
delete[] ipiv;
}
return ierr;
}
template <typename MatrA, typename MatrB>
inline
int lu_solve (MatrA& a, MatrB& b) {
return gesv (a, b);
}
// getrf(): LU factorization of A
// [comments from 'clapack_dgetrf.c':]
/* Computes one of two LU factorizations based on the setting of
* the Order parameter, as follows:
* ---------------------------------------------------------------
* Order == CblasColMajor
* Column-major factorization of form
* A = P * L * U
* where P is a row-permutation matrix, L is lower triangular with
* unit diagonal elements (lower trapezoidal if M > N), and U is
* upper triangular (upper trapezoidal if M < N).
* ---------------------------------------------------------------
* Order == CblasRowMajor
* Row-major factorization of form
* A = P * L * U
* where P is a column-permutation matrix, L is lower triangular
* (lower trapezoidal if M > N), and U is upper triangular with
* unit diagonals (upper trapezoidal if M < N).
*/
template <typename MatrA, typename IVec>
inline
int getrf (MatrA& a, IVec& ipiv) {
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<MatrA>::matrix_structure,
traits::general_t
>::value));
#endif
CBLAS_ORDER const stor_ord
= enum_cast<CBLAS_ORDER const>
(storage_order<
#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
typename traits::matrix_traits<MatrA>::ordering_type
#else
typename MatrA::orientation_category
#endif
>::value);
int const m = traits::matrix_size1 (a);
int const n = traits::matrix_size2 (a);
assert (traits::vector_size (ipiv) == (m < n ? m : n));
return detail::getrf (stor_ord, m, n,
traits::matrix_storage (a),
traits::leading_dimension (a),
traits::vector_storage (ipiv));
}
template <typename MatrA, typename IVec>
inline
int lu_factor (MatrA& a, IVec& ipiv) {
return getrf (a, ipiv);
}
// getrs(): solves a system of linear equations
// A * X = B or A' * X = B
// using the LU factorization previously computed by getrf()
template <typename MatrA, typename MatrB, typename IVec>
inline
int getrs (CBLAS_TRANSPOSE const Trans,
MatrA const& a, IVec const& ipiv, MatrB& b)
{
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<MatrA>::matrix_structure,
traits::general_t
>::value));
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<MatrB>::matrix_structure,
traits::general_t
>::value));
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<MatrA>::ordering_type,
typename traits::matrix_traits<MatrB>::ordering_type
>::value));
#endif
assert (Trans == CblasNoTrans
|| Trans == CblasTrans
|| Trans == CblasConjTrans);
CBLAS_ORDER const stor_ord
= enum_cast<CBLAS_ORDER const>
(storage_order<
#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
typename traits::matrix_traits<MatrA>::ordering_type
#else
typename MatrA::orientation_category
#endif
>::value);
int const n = traits::matrix_size1 (a);
int const nrhs = stor_ord == CblasColMajor
? traits::matrix_size2 (b)
: traits::matrix_size1 (b);
assert (n == traits::matrix_size2 (a));
assert (n == (stor_ord == CblasColMajor
? traits::matrix_size1 (b)
: traits::matrix_size2 (b)));
assert (n == traits::vector_size (ipiv));
return detail::getrs (stor_ord, Trans, n, nrhs,
#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
traits::matrix_storage (a),
#else
traits::matrix_storage_const (a),
#endif
traits::leading_dimension (a),
#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
traits::vector_storage (ipiv),
#else
traits::vector_storage_const (ipiv),
#endif
traits::matrix_storage (b),
traits::leading_dimension (b));
}
// getrs(): solves A * X = B (after getrf())
template <typename MatrA, typename MatrB, typename IVec>
inline
int getrs (MatrA const& a, IVec const& ipiv, MatrB& b) {
return getrs (CblasNoTrans, a, ipiv, b);
}
template <typename MatrA, typename MatrB, typename IVec>
inline
int lu_substitute (MatrA const& a, IVec const& ipiv, MatrB& b) {
return getrs (CblasNoTrans, a, ipiv, b);
}
// getri(): computes the inverse of a matrix A
// using the LU factorization previously computed by getrf()
template <typename MatrA, typename IVec>
inline
int getri (MatrA& a, IVec const& ipiv) {
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<MatrA>::matrix_structure,
traits::general_t
>::value));
#endif
CBLAS_ORDER const stor_ord
= enum_cast<CBLAS_ORDER const>
(storage_order<
#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
typename traits::matrix_traits<MatrA>::ordering_type
#else
typename MatrA::orientation_category
#endif
>::value);
int const n = traits::matrix_size1 (a);
assert (n == traits::matrix_size2 (a));
assert (traits::vector_size (ipiv) == n);
return detail::getri (stor_ord, n,
traits::matrix_storage (a),
traits::leading_dimension (a),
#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
traits::vector_storage (ipiv)
#else
traits::vector_storage_const (ipiv)
#endif
);
}
template <typename MatrA, typename IVec>
inline
int lu_invert (MatrA& a, IVec& ipiv) {
return getri (a, ipiv);
}
/////////////////////////////////////////////////////////////////////
//
// system of linear equations A * X = B
// with A symmetric or Hermitian positive definite matrix
//
/////////////////////////////////////////////////////////////////////
#ifndef BOOST_NUMERIC_BINDINGS_ATLAS_POTRF_BUG
// posv(): 'driver' function
//
// [from 'dposv.f' (slightly edited):]
/* XPOSV computes the solution to a system of linear equations
* A * X = B,
* where A is an N-by-N symmetric/Hermitian positive definite matrix
* and X and B are N-by-NRHS matrices. [See also comments of gesv().]
*
* A -- On entry, the symmetric/Hermitian matrix A.
* If UPLO = 'U', the leading N-by-N upper triangular part of A
* contains the upper triangular part of the matrix A, and the
* strictly lower triangular part of A is not referenced.
* If UPLO = 'L', the leading N-by-N lower triangular part of A
* contains the lower triangular part of the matrix A, and the
* strictly upper triangular part of A is not referenced.
*
* On exit, if INFO = 0, the factor U or L from the Cholesky
* factorization A = U**T*U or A = L*L**T
* [or A = U**H*U or A = L*L**H].
*
* B -- On entry, the right hand side matrix B.
* On exit, if INFO = 0, the solution matrix X.
*/
namespace detail {
template <typename SymmA, typename MatrB>
inline
int posv (CBLAS_UPLO const uplo, SymmA& a, MatrB& b) {
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<SymmA>::ordering_type,
typename traits::matrix_traits<MatrB>::ordering_type
>::value));
#endif
CBLAS_ORDER const stor_ord
= enum_cast<CBLAS_ORDER const>
(storage_order<
#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
typename traits::matrix_traits<SymmA>::ordering_type
#else
typename SymmA::orientation_category
#endif
>::value);
int const n = traits::matrix_size1 (a);
int const nrhs = stor_ord == CblasColMajor
? traits::matrix_size2 (b)
: traits::matrix_size1 (b);
assert (n == traits::matrix_size2 (a));
assert (n == (stor_ord == CblasColMajor
? traits::matrix_size1 (b)
: traits::matrix_size2 (b)));
return posv (stor_ord, uplo, n, nrhs,
traits::matrix_storage (a),
traits::leading_dimension (a),
traits::matrix_storage (b),
traits::leading_dimension (b));
}
} // detail
template <typename SymmA, typename MatrB>
inline
int posv (CBLAS_UPLO const uplo, SymmA& a, MatrB& b) {
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<SymmA>::matrix_structure,
traits::general_t
>::value));
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<MatrB>::matrix_structure,
traits::general_t
>::value));
#endif
assert (uplo == CblasUpper || uplo == CblasLower);
return detail::posv (uplo, a, b);
}
template <typename SymmA, typename MatrB>
inline
int posv (SymmA& a, MatrB& b) {
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
typedef typename traits::matrix_traits<SymmA>::value_type val_t;
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<SymmA>::matrix_structure,
typename traits::detail::symm_herm_t<val_t>::type
>::value));
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<MatrB>::matrix_structure,
traits::general_t
>::value));
#endif
CBLAS_UPLO const uplo
= enum_cast<CBLAS_UPLO const>
(uplo_triang<
#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
typename traits::matrix_traits<SymmA>::uplo_type
#else
typename SymmA::packed_category
#endif
>::value);
return detail::posv (uplo, a, b);
}
template <typename SymmA, typename MatrB>
inline
int cholesky_solve (SymmA& a, MatrB& b) { return posv (a, b); }
#endif // BOOST_NUMERIC_BINDINGS_ATLAS_POTRF_BUG
// potrf(): Cholesky factorization of A
namespace detail {
template <typename SymmA>
inline
int potrf (CBLAS_UPLO const uplo, SymmA& a) {
CBLAS_ORDER const stor_ord
= enum_cast<CBLAS_ORDER const>
(storage_order<
#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
typename traits::matrix_traits<SymmA>::ordering_type
#else
typename SymmA::orientation_category
#endif
>::value);
int const n = traits::matrix_size1 (a);
assert (n == traits::matrix_size2 (a));
return potrf (stor_ord, uplo, n,
traits::matrix_storage (a),
traits::leading_dimension (a));
}
} // detail
template <typename SymmA>
inline
int potrf (CBLAS_UPLO const uplo, SymmA& a) {
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<SymmA>::matrix_structure,
traits::general_t
>::value));
#endif
assert (uplo == CblasUpper || uplo == CblasLower);
return detail::potrf (uplo, a);
}
template <typename SymmA>
inline
int potrf (SymmA& a) {
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
typedef typename traits::matrix_traits<SymmA>::value_type val_t;
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<SymmA>::matrix_structure,
typename traits::detail::symm_herm_t<val_t>::type
>::value));
#endif
CBLAS_UPLO const uplo
= enum_cast<CBLAS_UPLO const>
(uplo_triang<
#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
typename traits::matrix_traits<SymmA>::uplo_type
#else
typename SymmA::packed_category
#endif
>::value);
return detail::potrf (uplo, a);
}
template <typename SymmA>
inline
int cholesky_factor (SymmA& a) { return potrf (a); }
// potrs(): solves a system of linear equations A * X = B
// using the Cholesky factorization computed by potrf()
namespace detail {
template <typename SymmA, typename MatrB>
inline
int potrs (CBLAS_UPLO const uplo, SymmA const& a, MatrB& b) {
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<SymmA>::ordering_type,
typename traits::matrix_traits<MatrB>::ordering_type
>::value));
#endif
CBLAS_ORDER const stor_ord
= enum_cast<CBLAS_ORDER const>
(storage_order<
#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
typename traits::matrix_traits<SymmA>::ordering_type
#else
typename SymmA::orientation_category
#endif
>::value);
int const n = traits::matrix_size1 (a);
int const nrhs = stor_ord == CblasColMajor
? traits::matrix_size2 (b)
: traits::matrix_size1 (b);
assert (n == traits::matrix_size2 (a));
assert (n == (stor_ord == CblasColMajor
? traits::matrix_size1 (b)
: traits::matrix_size2 (b)));
#ifndef BOOST_NUMERIC_BINDINGS_ATLAS_POTRF_BUG
return potrs (stor_ord, uplo, n, nrhs,
#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
traits::matrix_storage (a),
#else
traits::matrix_storage_const (a),
#endif
traits::leading_dimension (a),
traits::matrix_storage (b),
traits::leading_dimension (b));
#else // BOOST_NUMERIC_BINDINGS_ATLAS_POTRF_BUG
int ierr;
if (stor_ord == CblasColMajor)
ierr = potrs (stor_ord, uplo, n, nrhs,
#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
traits::matrix_storage (a),
#else
traits::matrix_storage_const (a),
#endif
traits::leading_dimension (a),
traits::matrix_storage (b),
traits::leading_dimension (b));
else // ATLAS bug with CblasRowMajor
ierr = potrs_bug (stor_ord, uplo, n, nrhs,
#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
traits::matrix_storage (a),
#else
traits::matrix_storage_const (a),
#endif
traits::leading_dimension (a),
traits::matrix_storage (b),
traits::leading_dimension (b));
return ierr;
#endif // BOOST_NUMERIC_BINDINGS_ATLAS_POTRF_BUG
}
} // detail
template <typename SymmA, typename MatrB>
inline
int potrs (CBLAS_UPLO const uplo, SymmA const& a, MatrB& b) {
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<SymmA>::matrix_structure,
traits::general_t
>::value));
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<MatrB>::matrix_structure,
traits::general_t
>::value));
#endif
assert (uplo == CblasUpper || uplo == CblasLower);
return detail::potrs (uplo, a, b);
}
template <typename SymmA, typename MatrB>
inline
int potrs (SymmA const& a, MatrB& b) {
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
typedef typename traits::matrix_traits<SymmA>::value_type val_t;
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<SymmA>::matrix_structure,
typename traits::detail::symm_herm_t<val_t>::type
>::value));
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<MatrB>::matrix_structure,
traits::general_t
>::value));
#endif
CBLAS_UPLO const uplo
= enum_cast<CBLAS_UPLO const>
(uplo_triang<
#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
typename traits::matrix_traits<SymmA>::uplo_type
#else
typename SymmA::packed_category
#endif
>::value);
return detail::potrs (uplo, a, b);
}
template <typename SymmA, typename MatrB>
inline
int cholesky_substitute (SymmA const& a, MatrB& b) { return potrs (a, b); }
#ifdef BOOST_NUMERIC_BINDINGS_ATLAS_POTRF_BUG
// posv(): 'driver' function
template <typename SymmA, typename MatrB>
inline
int posv (CBLAS_UPLO const uplo, SymmA& a, MatrB& b) {
int ierr = potrf (uplo, a);
if (ierr == 0)
ierr = potrs (uplo, a, b);
return ierr;
}
template <typename SymmA, typename MatrB>
inline
int posv (SymmA& a, MatrB& b) {
int ierr = potrf (a);
if (ierr == 0)
ierr = potrs (a, b);
return ierr;
}
template <typename SymmA, typename MatrB>
inline
int cholesky_solve (SymmA& a, MatrB& b) {
return posv (a, b);
}
#endif // BOOST_NUMERIC_BINDINGS_ATLAS_POTRF_BUG
// potri(): computes the inverse of a symmetric or Hermitian positive
// definite matrix A using the Cholesky factorization
// previously computed by potrf()
namespace detail {
template <typename SymmA>
inline
int potri (CBLAS_UPLO const uplo, SymmA& a) {
CBLAS_ORDER const stor_ord
= enum_cast<CBLAS_ORDER const>
(storage_order<
#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
typename traits::matrix_traits<SymmA>::ordering_type
#else
typename SymmA::orientation_category
#endif
>::value);
int const n = traits::matrix_size1 (a);
assert (n == traits::matrix_size2 (a));
return potri (stor_ord, uplo, n,
traits::matrix_storage (a),
traits::leading_dimension (a));
}
} // detail
template <typename SymmA>
inline
int potri (CBLAS_UPLO const uplo, SymmA& a) {
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<SymmA>::matrix_structure,
traits::general_t
>::value));
#endif
assert (uplo == CblasUpper || uplo == CblasLower);
return detail::potri (uplo, a);
}
template <typename SymmA>
inline
int potri (SymmA& a) {
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
typedef typename traits::matrix_traits<SymmA>::value_type val_t;
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<SymmA>::matrix_structure,
typename traits::detail::symm_herm_t<val_t>::type
>::value));
#endif
CBLAS_UPLO const uplo
= enum_cast<CBLAS_UPLO const>
(uplo_triang<
#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
typename traits::matrix_traits<SymmA>::uplo_type
#else
typename SymmA::packed_category
#endif
>::value);
return detail::potri (uplo, a);
}
template <typename SymmA>
inline
int cholesky_invert (SymmA& a) { return potri (a); }
} // namespace atlas
}}}
#endif // BOOST_NUMERIC_BINDINGS_CLAPACK_HPP

View File

@@ -1,34 +0,0 @@
/*
*
* Copyright (c) Kresimir Fresl 2002
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* Author acknowledges the support of the Faculty of Civil Engineering,
* University of Zagreb, Croatia.
*
*/
//////////////////////////////////////////////////////////////////////////
//
// ATLAS (Automatically Tuned Linear Algebra Software)
//
// ''At present, it provides C and Fortran77 interfaces to a portably
// efficient BLAS implementation, as well as a few routines from LAPACK.''
//
// see: http://math-atlas.sourceforge.net/
//
//////////////////////////////////////////////////////////////////////////
#ifndef BOOST_NUMERIC_BINDINGS_CLAPACK_INC_H
#define BOOST_NUMERIC_BINDINGS_CLAPACK_INC_H
extern "C" {
/* see footnote [2] in libs/numeric/bindings/lapack/doc/index.html */
/* #include <atlas/atlas_enum.h> */
#include <atlas/clapack.h>
}
#endif

View File

@@ -1,381 +0,0 @@
/*
*
* Copyright (c) Kresimir Fresl 2002
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* Author acknowledges the support of the Faculty of Civil Engineering,
* University of Zagreb, Croatia.
*
*/
#ifndef BOOST_NUMERIC_BINDINGS_CLAPACK_OVERLOADS_HPP
#define BOOST_NUMERIC_BINDINGS_CLAPACK_OVERLOADS_HPP
#include <boost/numeric/bindings/atlas/clapack_inc.hpp>
#include <boost/numeric/bindings/traits/type.hpp>
namespace boost { namespace numeric { namespace bindings {
namespace atlas { namespace detail {
//
// general system of linear equations A * X = B
//
// 'driver' function -- factor and solve
inline
int gesv (CBLAS_ORDER const Order,
int const N, int const NRHS,
float* A, int const lda, int* ipiv,
float* B, int const ldb)
{
return clapack_sgesv (Order, N, NRHS, A, lda, ipiv, B, ldb);
}
inline
int gesv (CBLAS_ORDER const Order,
int const N, int const NRHS,
double* A, int const lda, int* ipiv,
double* B, int const ldb)
{
return clapack_dgesv (Order, N, NRHS, A, lda, ipiv, B, ldb);
}
inline
int gesv (CBLAS_ORDER const Order,
int const N, int const NRHS,
traits::complex_f* A, int const lda, int* ipiv,
traits::complex_f* B, int const ldb)
{
return clapack_cgesv (Order, N, NRHS,
static_cast<void*> (A), lda, ipiv,
static_cast<void*> (B), ldb);
}
inline
int gesv (CBLAS_ORDER const Order,
int const N, int const NRHS,
traits::complex_d* A, int const lda, int* ipiv,
traits::complex_d* B, int const ldb)
{
return clapack_zgesv (Order, N, NRHS,
static_cast<void*> (A), lda, ipiv,
static_cast<void*> (B), ldb);
}
// LU factorization
inline
int getrf (CBLAS_ORDER const Order,
int const M, int const N,
float* A, int const lda, int* ipiv)
{
return clapack_sgetrf (Order, M, N, A, lda, ipiv);
}
inline
int getrf (CBLAS_ORDER const Order,
int const M, int const N,
double* A, int const lda, int* ipiv)
{
return clapack_dgetrf (Order, M, N, A, lda, ipiv);
}
inline
int getrf (CBLAS_ORDER const Order,
int const M, int const N,
traits::complex_f* A, int const lda, int* ipiv)
{
return clapack_cgetrf (Order, M, N, static_cast<void*> (A), lda, ipiv);
}
inline
int getrf (CBLAS_ORDER const Order,
int const M, int const N,
traits::complex_d* A, int const lda, int* ipiv)
{
return clapack_zgetrf (Order, M, N, static_cast<void*> (A), lda, ipiv);
}
// solve (using factorization computed by getrf())
inline
int getrs (CBLAS_ORDER const Order, CBLAS_TRANSPOSE const Trans,
int const N, int const NRHS,
float const* A, int const lda, int const* ipiv,
float* B, int const ldb)
{
return clapack_sgetrs (Order, Trans, N, NRHS, A, lda, ipiv, B, ldb);
}
inline
int getrs (CBLAS_ORDER const Order, CBLAS_TRANSPOSE const Trans,
int const N, int const NRHS,
double const* A, int const lda, int const* ipiv,
double* B, int const ldb)
{
return clapack_dgetrs (Order, Trans, N, NRHS, A, lda, ipiv, B, ldb);
}
inline
int getrs (CBLAS_ORDER const Order, CBLAS_TRANSPOSE const Trans,
int const N, int const NRHS,
traits::complex_f const* A, int const lda,
int const* ipiv,
traits::complex_f* B, int const ldb)
{
return clapack_cgetrs (Order, Trans, N, NRHS,
static_cast<void const*> (A), lda, ipiv,
static_cast<void*> (B), ldb);
}
inline
int getrs (CBLAS_ORDER const Order, CBLAS_TRANSPOSE const Trans,
int const N, int const NRHS,
traits::complex_d const* A, int const lda,
int const* ipiv,
traits::complex_d* B, int const ldb)
{
return clapack_zgetrs (Order, Trans, N, NRHS,
static_cast<void const*> (A), lda, ipiv,
static_cast<void*> (B), ldb);
}
// invert (using factorization computed by getrf())
inline
int getri (CBLAS_ORDER const Order,
int const N, float* A, int const lda,
int const* ipiv)
{
return clapack_sgetri (Order, N, A, lda, ipiv);
}
inline
int getri (CBLAS_ORDER const Order,
int const N, double* A, int const lda,
int const* ipiv)
{
return clapack_dgetri (Order, N, A, lda, ipiv);
}
inline
int getri (CBLAS_ORDER const Order,
int const N, traits::complex_f* A, int const lda,
int const* ipiv)
{
return clapack_cgetri (Order, N, static_cast<void*> (A), lda, ipiv);
}
inline
int getri (CBLAS_ORDER const Order,
int const N, traits::complex_d* A, int const lda,
int const* ipiv)
{
return clapack_zgetri (Order, N, static_cast<void*> (A), lda, ipiv);
}
//
// system of linear equations A * X = B
// with A symmetric positive definite matrix
//
// 'driver' function -- factor and solve
inline
int posv (CBLAS_ORDER const Order, CBLAS_UPLO const Uplo,
int const N, int const NRHS,
float* A, int const lda, float* B, int const ldb)
{
return clapack_sposv (Order, Uplo, N, NRHS, A, lda, B, ldb);
}
inline
int posv (CBLAS_ORDER const Order, CBLAS_UPLO const Uplo,
int const N, int const NRHS,
double* A, int const lda, double* B, int const ldb)
{
return clapack_dposv (Order, Uplo, N, NRHS, A, lda, B, ldb);
}
inline
int posv (CBLAS_ORDER const Order, CBLAS_UPLO const Uplo,
int const N, int const NRHS,
traits::complex_f* A, int const lda,
traits::complex_f* B, int const ldb)
{
return clapack_cposv (Order, Uplo, N, NRHS,
static_cast<void*> (A), lda,
static_cast<void*> (B), ldb);
}
inline
int posv (CBLAS_ORDER const Order, CBLAS_UPLO const Uplo,
int const N, int const NRHS,
traits::complex_d* A, int const lda,
traits::complex_d* B, int const ldb)
{
return clapack_zposv (Order, Uplo, N, NRHS,
static_cast<void*> (A), lda,
static_cast<void*> (B), ldb);
}
// Cholesky factorization
inline
int potrf (CBLAS_ORDER const Order, CBLAS_UPLO const Uplo,
int const N, float* A, int const lda)
{
return clapack_spotrf (Order, Uplo, N, A, lda);
}
inline
int potrf (CBLAS_ORDER const Order, CBLAS_UPLO const Uplo,
int const N, double* A, int const lda)
{
return clapack_dpotrf (Order, Uplo, N, A, lda);
}
inline
int potrf (CBLAS_ORDER const Order, CBLAS_UPLO const Uplo,
int const N, traits::complex_f* A, int const lda)
{
return clapack_cpotrf (Order, Uplo, N, static_cast<void*> (A), lda);
}
inline
int potrf (CBLAS_ORDER const Order, CBLAS_UPLO const Uplo,
int const N, traits::complex_d* A, int const lda)
{
return clapack_zpotrf (Order, Uplo, N, static_cast<void*> (A), lda);
}
// solve (using factorization computed by potrf())
inline
int potrs (CBLAS_ORDER const Order, CBLAS_UPLO const Uplo,
int const N, int const NRHS,
float const* A, int const lda, float* B, int const ldb)
{
return clapack_spotrs (Order, Uplo, N, NRHS, A, lda, B, ldb);
}
inline
int potrs (CBLAS_ORDER const Order, CBLAS_UPLO const Uplo,
int const N, int const NRHS,
double const* A, int const lda, double* B, int const ldb)
{
return clapack_dpotrs (Order, Uplo, N, NRHS, A, lda, B, ldb);
}
inline
int potrs (CBLAS_ORDER const Order, CBLAS_UPLO const Uplo,
int const N, int const NRHS,
traits::complex_f const* A, int const lda,
traits::complex_f* B, int const ldb)
{
return clapack_cpotrs (Order, Uplo, N, NRHS,
static_cast<void const*> (A), lda,
static_cast<void*> (B), ldb);
}
inline
int potrs (CBLAS_ORDER const Order, CBLAS_UPLO const Uplo,
int const N, int const NRHS,
traits::complex_d const* A, int const lda,
traits::complex_d* B, int const ldb)
{
return clapack_zpotrs (Order, Uplo, N, NRHS,
static_cast<void const*> (A), lda,
static_cast<void*> (B), ldb);
}
#ifdef BOOST_NUMERIC_BINDINGS_ATLAS_POTRF_BUG
// .. ATLAS bug with row major hermitian matrices
// .... symmetric matrices are OK, but to simplify generic potrs() ...
inline
int potrs_bug (CBLAS_ORDER const Order, CBLAS_UPLO const Uplo,
int const N, int const NRHS,
float const* A, int const lda, float* B, int const ldb)
{
return clapack_spotrs (Order, Uplo, N, NRHS, A, lda, B, ldb);
}
inline
int potrs_bug (CBLAS_ORDER const Order, CBLAS_UPLO const Uplo,
int const N, int const NRHS,
double const* A, int const lda, double* B, int const ldb)
{
return clapack_dpotrs (Order, Uplo, N, NRHS, A, lda, B, ldb);
}
inline
int potrs_bug (CBLAS_ORDER const Order, CBLAS_UPLO const Uplo,
int const N, int const NRHS,
traits::complex_f const* A, int const lda,
traits::complex_f* B, int const ldb)
{
int sz = N * lda;
traits::complex_f* A1 = new traits::complex_f[sz];
for (int i = 0; i < sz; ++i)
A1[i] = std::conj (A[i]);
int r = clapack_cpotrs (Order, Uplo, N, NRHS,
static_cast<void const*> (A1), lda,
static_cast<void*> (B), ldb);
delete[] A1;
return r;
}
inline
int potrs_bug (CBLAS_ORDER const Order, CBLAS_UPLO const Uplo,
int const N, int const NRHS,
traits::complex_d const* A, int const lda,
traits::complex_d* B, int const ldb)
{
int sz = N * lda;
traits::complex_d* A1 = new traits::complex_d[sz];
for (int i = 0; i < sz; ++i)
A1[i] = std::conj (A[i]);
int r = clapack_zpotrs (Order, Uplo, N, NRHS,
static_cast<void const*> (A1), lda,
static_cast<void*> (B), ldb);
delete[] A1;
return r;
}
#endif // BOOST_NUMERIC_BINDINGS_ATLAS_POTRF_BUG
// invert (using factorization computed by potrf())
inline
int potri (CBLAS_ORDER const Order, CBLAS_UPLO const Uplo,
int const N, float* A, int const lda)
{
return clapack_spotri (Order, Uplo, N, A, lda);
}
inline
int potri (CBLAS_ORDER const Order, CBLAS_UPLO const Uplo,
int const N, double* A, int const lda)
{
return clapack_dpotri (Order, Uplo, N, A, lda);
}
inline
int potri (CBLAS_ORDER const Order, CBLAS_UPLO const Uplo,
int const N, traits::complex_f* A, int const lda)
{
return clapack_cpotri (Order, Uplo, N, static_cast<void*> (A), lda);
}
inline
int potri (CBLAS_ORDER const Order, CBLAS_UPLO const Uplo,
int const N, traits::complex_d* A, int const lda)
{
return clapack_zpotri (Order, Uplo, N, static_cast<void*> (A), lda);
}
}} // namepaces detail & atlas
}}}
#endif // BOOST_NUMERIC_BINDINGS_CLAPACK_OVERLOADS_HPP

View File

@@ -1,110 +0,0 @@
//
// Copyright (C) 2002, 2003 Si-Lab b.v.b.a and Toon Knapen
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_NUMERIC_BINDINGS_BLAS_BLAS_H
#define BOOST_NUMERIC_BINDINGS_BLAS_BLAS_H
/*
* const-correct prototypes for BLAS functions
*
*/
#include <boost/numeric/bindings/blas/blas_names.h>
#include <boost/numeric/bindings/traits/type.h>
extern "C"
{
//
// Level 1
//
void BLAS_SSCAL(const int *n, const float* alpha, float* x, const int* incx);
void BLAS_DSCAL(const int *n, const double* alpha, double* x, const int* incx);
void BLAS_CSCAL(const int *n, const fcomplex_t* alpha, fcomplex_t* x, const int* incx);
void BLAS_ZSCAL(const int *n, const dcomplex_t* alpha, dcomplex_t* x, const int* incx);
void BLAS_SAXPY(const int *n, const float* alpha, const float* x, const int* incx, float* y, const int* incy);
void BLAS_DAXPY(const int *n, const double* alpha, const double* x, const int* incx, double* y, const int* incy);
void BLAS_CAXPY(const int *n, const fcomplex_t* alpha, const fcomplex_t* x, const int* incx, fcomplex_t* y, const int* incy);
void BLAS_ZAXPY(const int *n, const dcomplex_t* alpha, const dcomplex_t* x, const int* incx, dcomplex_t* y, const int* incy);
float BLAS_SDOT (const int *n, const float *x, const int *incx, const float *y, const int *incy);
double BLAS_DDOT (const int *n, const double *x, const int *incx, const double *y, const int *incy);
void BLAS_CDOTU(fcomplex_t* ret, const int *n, const fcomplex_t *x, const int *incx, const fcomplex_t *y, const int *incy);
void BLAS_ZDOTU(dcomplex_t* ret, const int *n, const dcomplex_t *x, const int *incx, const dcomplex_t *y, const int *incy);
void BLAS_CDOTC(fcomplex_t* ret, const int *n, const fcomplex_t *x, const int *incx, const fcomplex_t *y, const int *incy);
void BLAS_ZDOTC(dcomplex_t* ret, const int *n, const dcomplex_t *x, const int *incx, const dcomplex_t *y, const int *incy);
float BLAS_SNRM2(const int *n, const float *x, const int *incx);
double BLAS_DNRM2(const int *n, const double *x, const int *incx);
float BLAS_SCNRM2(const int *n, const fcomplex_t *x, const int *incx);
double BLAS_DZNRM2(const int *n, const dcomplex_t *x, const int *incx);
float BLAS_SASUM(const int *n, const float *x, const int *incx);
double BLAS_DASUM(const int *n, const double *x, const int *incx);
float BLAS_SCASUM(const int *n, const fcomplex_t *x, const int *incx);
double BLAS_DZASUM(const int *n, const dcomplex_t *x, const int *incx);
void BLAS_SCOPY( const int *n, const float *x, const int *incx, float *y, const int *incy);
void BLAS_DCOPY( const int *n, const double *x, const int *incx, double *y, const int *incy);
void BLAS_CCOPY( const int *n, const fcomplex_t *x, const int *incx, fcomplex_t *y, const int *incy);
void BLAS_ZCOPY( const int *n, const dcomplex_t *x, const int *incx, dcomplex_t *y, const int *incy);
//
// Level 2
//
void BLAS_SGEMV(const char *trans, const int *m, const int *n, const float *alpha, const float *a, const int *lda, const float *x, const int *incx, const float *beta, float *y, const int *incy) ;
void BLAS_DGEMV(const char *trans, const int *m, const int *n, const double *alpha, const double *a, const int *lda, const double *x, const int *incx, const double *beta, double *y, const int *incy) ;
void BLAS_CGEMV(const char *trans, const int *m, const int *n, const fcomplex_t *alpha, const fcomplex_t *a, const int *lda, const fcomplex_t *x, const int *incx, const fcomplex_t *beta, fcomplex_t *y, const int *incy) ;
void BLAS_ZGEMV(const char *trans, const int *m, const int *n, const dcomplex_t *alpha, const dcomplex_t *a, const int *lda, const dcomplex_t *x, const int *incx, const dcomplex_t *beta, dcomplex_t *y, const int *incy) ;
void BLAS_SGER (const int *m, const int *n, const float * alpha, const float * x, const int *incx, const float * y, const int *incy, float *a, const int *lda);
void BLAS_DGER (const int *m, const int *n, const double *alpha, const double *x, const int *incx, const double *y, const int *incy, double *a, const int *lda);
void BLAS_CGERU(const int *m, const int *n, const fcomplex_t *alpha, const fcomplex_t *x, const int *incx, const fcomplex_t *y, const int *incy, fcomplex_t *a, const int *lda);
void BLAS_ZGERU(const int *m, const int *n, const dcomplex_t *alpha, const dcomplex_t *x, const int *incx, const dcomplex_t *y, const int *incy, dcomplex_t *a, const int *lda);
void BLAS_CGERC(const int *m, const int *n, const fcomplex_t *alpha, const fcomplex_t *x, const int *incx, const fcomplex_t *y, const int *incy, fcomplex_t *a, const int *lda);
void BLAS_ZGERC(const int *m, const int *n, const dcomplex_t *alpha, const dcomplex_t *x, const int *incx, const dcomplex_t *y, const int *incy, dcomplex_t *a, const int *lda);
//
// Level 3
//
void BLAS_SGEMM(const char *transa, const char *transb, const int *m, const int *n, const int *k, const float *alpha, const float *a, const int *lda, const float *b, const int *ldb, const float *beta, float *c, const int *ldc);
void BLAS_DGEMM(const char *transa, const char *transb, const int *m, const int *n, const int *k, const double *alpha, const double *a, const int *lda, const double *b, const int *ldb, const double *beta, double *c, const int *ldc);
void BLAS_CGEMM(const char *transa, const char *transb, const int *m, const int *n, const int *k, const fcomplex_t *alpha, const fcomplex_t *a, const int *lda, const fcomplex_t *b, const int *ldb, const fcomplex_t *beta, fcomplex_t *c, const int *ldc);
void BLAS_ZGEMM(const char *transa, const char *transb, const int *m, const int *n, const int *k, const dcomplex_t *alpha, const dcomplex_t *a, const int *lda, const dcomplex_t *b, const int *ldb, const dcomplex_t *beta, dcomplex_t *c, const int *ldc);
void BLAS_SSYRK ( const char* uplo, const char* trans, const int* n, const int* k, const float* alpha,
const float* a, const int* lda, const float* beta, float* c, const int* ldc );
void BLAS_DSYRK ( const char* uplo, const char* trans, const int* n, const int* k, const double* alpha,
const double* a, const int* lda, const double* beta, double* c, const int* ldc );
void BLAS_CSYRK ( const char* uplo, const char* trans, const int* n, const int* k, const fcomplex_t* alpha,
const fcomplex_t* a, const int* lda, const fcomplex_t* beta, fcomplex_t* c, const int* ldc );
void BLAS_ZSYRK ( const char* uplo, const char* trans, const int* n, const int* k, const dcomplex_t* alpha,
const dcomplex_t* a, const int* lda, const dcomplex_t* beta, dcomplex_t* c, const int* ldc );
void BLAS_CHERK ( const char* uplo, const char* trans, const int* n, const int* k, const float* alpha,
const fcomplex_t* a, const int* lda, const float* beta, fcomplex_t* c, const int* ldc );
void BLAS_ZHERK ( const char* uplo, const char* trans, const int* n, const int* k, const double* alpha,
const dcomplex_t* a, const int* lda, const double* beta, dcomplex_t* c, const int* ldc );
void BLAS_STRSM( const char* side, const char* uplo, const char* transa, const char* diag, const int* m,
const int* n, float const* alpha, float const* a, int const* lda, float* b, int const* ldb );
void BLAS_DTRSM( const char* side, const char* uplo, const char* transa, const char* diag, const int* m,
const int* n, double const* alpha, double const* a, int const* lda, double* b, int const* ldb );
void BLAS_CTRSM( const char* side, const char* uplo, const char* transa, const char* diag, const int* m,
const int* n, fcomplex_t const* alpha, fcomplex_t const* a, int const* lda, fcomplex_t* b, int const* ldb );
void BLAS_ZTRSM( const char* side, const char* uplo, const char* transa, const char* diag, const int* m,
const int* n, dcomplex_t const* alpha, dcomplex_t const* a, int const* lda, dcomplex_t* b, int const* ldb );
}
#endif // BOOST_NUMERIC_BINDINGS_BLAS_BLAS_H

View File

@@ -1,9 +0,0 @@
#ifndef boost_blasbindings_blasbindings_hpp
#define boost_blasbindings_blasbindings_hpp
#include <boost/numeric/bindings/blas/blas1.hpp>
#include <boost/numeric/bindings/blas/blas2.hpp>
#include <boost/numeric/bindings/blas/blas3.hpp>
#endif // boost_blasbindings_blasbindings_hpp

View File

@@ -1,224 +0,0 @@
//
// Copyright Toon Knapen and Kresimir Fresl
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_NUMERIC_BINDINGS_BLAS_BLAS1_HPP
#define BOOST_NUMERIC_BINDINGS_BLAS_BLAS1_HPP
#include <boost/numeric/bindings/blas/blas1_overloads.hpp>
#include <boost/numeric/bindings/traits/vector_traits.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <cassert>
namespace boost { namespace numeric { namespace bindings { namespace blas {
// x <- y
template < typename vector_x_type, typename vector_y_type >
void copy(const vector_x_type &x, vector_y_type &y )
{
#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
BOOST_STATIC_ASSERT( ( boost::is_same< typename traits::vector_traits<vector_x_type>::value_type, typename traits::vector_traits<vector_y_type>::value_type >::value ) ) ;
#else
BOOST_STATIC_ASSERT( ( boost::is_same< typename vector_x_type::value_type, typename vector_y_type::value_type >::value ) ) ;
#endif
const int n = traits::vector_size( x ) ;
assert( n==traits::vector_size( y ) ) ;
const int stride_x = traits::vector_stride( x ) ;
const int stride_y = traits::vector_stride( y ) ;
typename traits::vector_traits<vector_x_type>::value_type const *x_ptr = traits::vector_storage( x ) ;
typename traits::vector_traits<vector_y_type>::value_type *y_ptr = traits::vector_storage( y ) ;
detail::copy( n, x_ptr, stride_x, y_ptr, stride_y ) ;
}
// x <- alpha * x
template < typename value_type, typename vector_type >
void scal(const value_type &alpha, vector_type &x )
{
#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
BOOST_STATIC_ASSERT( ( boost::is_same< value_type, typename traits::vector_traits<vector_type>::value_type >::value ) ) ;
#else
BOOST_STATIC_ASSERT( ( boost::is_same< value_type, typename vector_type::value_type >::value ) ) ;
#endif
const int n = traits::vector_size( x ) ;
const int stride = traits::vector_stride( x ) ;
value_type *x_ptr = traits::vector_storage( x ) ;
detail::scal( n, alpha, x_ptr, stride ) ;
}
// y <- alpha * x + y
template < typename value_type, typename vector_type_x, typename vector_type_y >
void axpy(const value_type& alpha, const vector_type_x &x, vector_type_y &y )
{
#ifdef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
BOOST_STATIC_ASSERT( ( is_same< value_type, typename vector_type_x::value_type >::value ) ) ;
BOOST_STATIC_ASSERT( ( is_same< value_type, typename vector_type_y::value_type >::value ) ) ;
#else
BOOST_STATIC_ASSERT( ( is_same< value_type, typename traits::vector_traits< vector_type_x >::value_type >::value ) ) ;
BOOST_STATIC_ASSERT( ( is_same< value_type, typename traits::vector_traits< vector_type_y >::value_type >::value ) ) ;
#endif
assert( traits::vector_size( x ) == traits::vector_size( y ) ) ;
const int n = traits::vector_size( x ) ;
const int stride_x = traits::vector_stride( x ) ;
const int stride_y = traits::vector_stride( y ) ;
const value_type *x_ptr = traits::vector_storage( x ) ;
value_type *y_ptr = traits::vector_storage( y ) ;
detail::axpy( n, alpha, x_ptr, stride_x, y_ptr, stride_y ) ;
}
// dot <- x^T * y (real vectors)
template < typename vector_type_x, typename vector_type_y >
#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
typename traits::vector_traits< vector_type_x >::value_type
#else
typename vector_type_x::value_type
#endif
dot(const vector_type_x &x, const vector_type_y &y)
{
#ifdef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
BOOST_STATIC_ASSERT( ( is_same< typename vector_type_y::value_type, typename vector_type_x::value_type >::value ) ) ;
#else
BOOST_STATIC_ASSERT( ( is_same< typename traits::vector_traits< vector_type_y >::value_type, typename traits::vector_traits< vector_type_x >::value_type >::value ) ) ;
#endif
assert( traits::vector_size( x ) == traits::vector_size( y ) ) ;
typedef
#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
typename traits::vector_traits< vector_type_x >::value_type
#else
typename vector_type_x::value_type
#endif
value_type ;
const int n = traits::vector_size( x ) ;
const int stride_x = traits::vector_stride( x ) ;
const int stride_y = traits::vector_stride( y ) ;
const value_type *x_ptr = traits::vector_storage( x ) ;
const value_type *y_ptr = traits::vector_storage( y ) ;
return detail::dot( n, x_ptr, stride_x, y_ptr, stride_y ) ;
}
// dotu <- x^T * y (complex vectors)
template < typename vector_type_x, typename vector_type_y >
#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
typename traits::vector_traits< vector_type_x >::value_type
#else
typename vector_type_x::value_type
#endif
dotu(const vector_type_x &x, const vector_type_y &y)
{
#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
BOOST_STATIC_ASSERT( ( is_same< typename traits::vector_traits< vector_type_y >::value_type, typename traits::vector_traits< vector_type_x >::value_type >::value ) ) ;
#else
BOOST_STATIC_ASSERT( ( is_same< typename vector_type_y::value_type, typename vector_type_x::value_type >::value ) ) ;
#endif
assert( traits::vector_size( x ) == traits::vector_size( y ) ) ;
typedef typename vector_type_x::value_type value_type ;
const int n = traits::vector_size( x ) ;
const int stride_x = traits::vector_stride( x ) ;
const int stride_y = traits::vector_stride( y ) ;
const value_type *x_ptr = traits::vector_storage( x ) ;
const value_type *y_ptr = traits::vector_storage( y ) ;
value_type ret ;
detail::dotu( ret, n, x_ptr, stride_x, y_ptr, stride_y ) ;
return ret;
}
// dotc <- x^H * y (complex vectors)
template < typename vector_type_x, typename vector_type_y >
#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
typename traits::vector_traits< vector_type_x >::value_type
#else
typename vector_type_x::value_type
#endif
dotc(const vector_type_x &x, const vector_type_y &y)
{
#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
BOOST_STATIC_ASSERT( ( is_same< typename traits::vector_traits< vector_type_y >::value_type, typename traits::vector_traits< vector_type_x >::value_type >::value ) ) ;
#else
BOOST_STATIC_ASSERT( ( is_same< typename vector_type_y::value_type, typename vector_type_x::value_type >::value ) ) ;
#endif
assert( traits::vector_size( x ) == traits::vector_size( y ) ) ;
typedef typename vector_type_x::value_type value_type ;
const int n = traits::vector_size( x ) ;
const int stride_x = traits::vector_stride( x ) ;
const int stride_y = traits::vector_stride( y ) ;
const value_type *x_ptr = traits::vector_storage( x ) ;
const value_type *y_ptr = traits::vector_storage( y ) ;
value_type ret ;
detail::dotc( ret, n, x_ptr, stride_x, y_ptr, stride_y ) ;
return ret;
}
// nrm2 <- ||x||_2
template < typename vector_type >
#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
typename traits::type_traits< typename traits::vector_traits< vector_type >::value_type >::real_type
#else
typename traits::type_traits< typename vector_type::value_type >::real_type
#endif
nrm2(const vector_type &x)
{
#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
typedef typename traits::vector_traits< vector_type >::value_type value_type;
#else
typedef vector_type::value_type value_type ;
#endif
const int n = traits::vector_size( x ) ;
const int stride_x = traits::vector_stride( x ) ;
const value_type *x_ptr = traits::vector_storage( x ) ;
return detail::nrm2( n, x_ptr, stride_x ) ;
}
// asum <- ||x||_1
// .. for now works only with real vectors
template < typename vector_type >
#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
typename traits::type_traits< typename traits::vector_traits< vector_type >::value_type >::real_type
#else
typename traits::type_traits< typename vector_type::value_type >::real_type
#endif
asum(const vector_type &x)
{
#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
typedef typename traits::vector_traits< vector_type >::value_type value_type;
#else
typedef vector_type::value_type value_type ;
#endif
const int n = traits::vector_size( x ) ;
const int stride_x = traits::vector_stride( x ) ;
const value_type *x_ptr = traits::vector_storage( x ) ;
return detail::asum( n, x_ptr, stride_x ) ;
}
}}}}
#endif // BOOST_NUMERIC_BINDINGS_BLAS_BLAS1_HPP

View File

@@ -1,64 +0,0 @@
//
// Copyright (C) Toon Knapen 2003
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_NUMERIC_BINDINGS_BLAS_BLAS1_OVERLOADS_HPP
#define BOOST_NUMERIC_BINDINGS_BLAS_BLAS1_OVERLOADS_HPP
#include <boost/numeric/bindings/blas/blas.h>
#include <boost/numeric/bindings/traits/type.hpp>
#include <boost/numeric/bindings/traits/type_traits.hpp>
namespace boost { namespace numeric { namespace bindings { namespace blas { namespace detail {
using namespace boost::numeric::bindings::traits ;
// x *= alpha
inline void scal(const int& n, const float& alpha, float* x, const int& incx) { BLAS_SSCAL( &n, &alpha, x , &incx ) ; }
inline void scal(const int& n, const double& alpha, double* x, const int& incx) { BLAS_DSCAL( &n, &alpha, x , &incx ) ; }
inline void scal(const int& n, const complex_f& alpha, complex_f* x, const int& incx) { BLAS_CSCAL( &n, complex_ptr( &alpha ), complex_ptr( x ), &incx ) ; }
inline void scal(const int& n, const complex_d& alpha, complex_d* x, const int& incx) { BLAS_ZSCAL( &n, complex_ptr( &alpha ), complex_ptr( x ), &incx ) ; }
// y += alpha * x
inline void axpy(const int& n, const float & alpha, const float * x, const int& incx, float * y, const int& incy) { BLAS_SAXPY( &n, &alpha , x , &incx, y , &incy ) ; }
inline void axpy(const int& n, const double & alpha, const double * x, const int& incx, double * y, const int& incy) { BLAS_DAXPY( &n, &alpha , x , &incx, y , &incy ) ; }
inline void axpy(const int& n, const complex_f& alpha, const complex_f* x, const int& incx, complex_f* y, const int& incy) { BLAS_CAXPY( &n, complex_ptr( &alpha ), complex_ptr( x ), &incx, complex_ptr( y ), &incy ) ; }
inline void axpy(const int& n, const complex_d& alpha, const complex_d* x, const int& incx, complex_d* y, const int& incy) { BLAS_ZAXPY( &n, complex_ptr( &alpha ), complex_ptr( x ), &incx, complex_ptr( y ), &incy ) ; }
// x^T . y
inline float dot(const int& n, const float * x, const int& incx, const float * y, const int& incy) { return BLAS_SDOT( &n, x, &incx, y, &incy ) ; }
inline double dot(const int& n, const double* x, const int& incx, const double* y, const int& incy) { return BLAS_DDOT( &n, x, &incx, y, &incy ) ; }
// x^T . y
inline void dotu(complex_f& ret, const int& n, const complex_f* x, const int& incx, const complex_f* y, const int& incy) { BLAS_CDOTU( complex_ptr( &ret ), &n, complex_ptr( x ), &incx, complex_ptr( y ), &incy ) ; }
inline void dotu(complex_d& ret, const int& n, const complex_d* x, const int& incx, const complex_d* y, const int& incy) { BLAS_ZDOTU( complex_ptr( &ret ), &n, complex_ptr( x ), &incx, complex_ptr( y ), &incy ) ; }
// x^H . y
inline void dotc(complex_f& ret, const int& n, const complex_f* x, const int& incx, const complex_f* y, const int& incy) { BLAS_CDOTC( complex_ptr( &ret ), &n, complex_ptr( x ), &incx, complex_ptr( y ), &incy ) ; }
inline void dotc(complex_d& ret, const int& n, const complex_d* x, const int& incx, const complex_d* y, const int& incy) { BLAS_ZDOTC( complex_ptr( &ret ), &n, complex_ptr( x ), &incx, complex_ptr( y ), &incy ) ; }
// euclidean norm
inline float nrm2(const int& n, const float* x, const int& incx) { return BLAS_SNRM2( &n, x, &incx ) ; }
inline double nrm2(const int& n, const double* x, const int& incx) { return BLAS_DNRM2( &n, x, &incx ) ; }
inline float nrm2(const int& n, const complex_f* x, const int& incx) { return BLAS_SCNRM2( &n, complex_ptr(x), &incx ) ; }
inline double nrm2(const int& n, const complex_d* x, const int& incx) { return BLAS_DZNRM2( &n, complex_ptr(x), &incx ) ; }
// 1-norm
inline float asum(const int& n, const float* x, const int& incx) { return BLAS_SASUM( &n, x, &incx ) ; }
inline double asum(const int& n, const double* x, const int& incx) { return BLAS_DASUM( &n, x, &incx ) ; }
inline float asum(const int& n, const complex_f* x, const int& incx) { return BLAS_SCASUM( &n, complex_ptr(x), &incx ) ; }
inline double asum(const int& n, const complex_d* x, const int& incx) { return BLAS_DZASUM( &n, complex_ptr(x), &incx ) ; }
// copy
inline void copy(const int& n, const float* x, const int& incx, float* y, const int& incy) { BLAS_SCOPY( &n, x, &incx, y, &incy ) ; }
inline void copy(const int& n, const double* x, const int& incx, double* y, const int& incy) { BLAS_DCOPY( &n, x, &incx, y, &incy ) ; }
inline void copy(const int& n, const complex_f* x, const int& incx, complex_f* y, const int& incy) { BLAS_CCOPY( &n, complex_ptr(x), &incx, complex_ptr(y), &incy ) ; }
inline void copy(const int& n, const complex_d* x, const int& incx, complex_d* y, const int& incy) { BLAS_ZCOPY( &n, complex_ptr(x), &incx, complex_ptr(y), &incy ) ; }
}}}}}
#endif // BOOST_NUMERIC_BINDINGS_BLAS_BLAS1_OVERLOADS_HPP

View File

@@ -1,147 +0,0 @@
//
// Copyright Toon Knapen and Kresimir Fresl 2003
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_BINDINGS_BLAS_BLAS2_HPP
#define BOOST_BINDINGS_BLAS_BLAS2_HPP
#include <boost/numeric/bindings/blas/blas2_overloads.hpp>
#include <boost/numeric/bindings/traits/traits.hpp>
#include <boost/numeric/bindings/traits/transpose.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits.hpp>
#include <cassert>
namespace boost { namespace numeric { namespace bindings { namespace blas {
// y <- alpha * op (A) * x + beta * y
// op (A) == A || A^T || A^H
// ! CAUTION this function assumes that all matrices involved are column-major matrices
template < typename matrix_type, typename vector_type_x, typename vector_type_y, typename value_type >
inline
void gemv(const char TRANS,
const value_type& alpha,
const matrix_type &a,
const vector_type_x &x,
const value_type& beta,
vector_type_y &y
)
{
// precondition: matrix_type must be dense or dense_proxy
/* not all compilers can handle the traits
BOOST_STATIC_ASSERT( ( boost::is_same< typename mtraits::matrix_structure,
boost::numeric::bindings::traits::general_t
>::value ) ) ;
*/
const int m = traits::matrix_size1( a ) ;
const int n = traits::matrix_size2( a ) ;
assert ( traits::vector_size( x ) >= (TRANS == traits::NO_TRANSPOSE ? n : m) ) ;
assert ( traits::vector_size( y ) >= (TRANS == traits::NO_TRANSPOSE ? m : n) ) ;
const int lda = traits::leading_dimension( a ) ;
const int stride_x = traits::vector_stride( x ) ;
const int stride_y = traits::vector_stride( y ) ;
const value_type *a_ptr = traits::matrix_storage( a ) ;
const value_type *x_ptr = traits::vector_storage( x ) ;
value_type *y_ptr = traits::vector_storage( y ) ;
detail::gemv( TRANS, m, n, alpha, a_ptr, lda, x_ptr, stride_x, beta, y_ptr, stride_y );
}
// A <- alpha * x * trans(y) ( outer product ), alpha, x and y are real-valued
// ! CAUTION this function assumes that all matrices involved are column-major matrices
template < typename vector_type_x, typename vector_type_y, typename value_type, typename matrix_type >
inline
void ger( const value_type& alpha,
const vector_type_x &x,
const vector_type_y &y,
matrix_type &a
)
{
// precondition: matrix_type must be dense or dense_proxy
/* not all compilers can handle the traits
BOOST_STATIC_ASSERT( ( boost::is_same< typename mtraits::matrix_structure,
boost::numeric::bindings::traits::general_t
>::value ) ) ;
*/
const int m = traits::matrix_size1( a ) ;
const int n = traits::matrix_size2( a ) ;
assert ( traits::vector_size( x ) <= m ) ;
assert ( traits::vector_size( y ) <= n ) ;
const int lda = traits::leading_dimension( a ) ;
const int stride_x = traits::vector_stride( x ) ;
const int stride_y = traits::vector_stride( y ) ;
const value_type *x_ptr = traits::vector_storage( x ) ;
const value_type *y_ptr = traits::vector_storage( y ) ;
value_type *a_ptr = traits::matrix_storage( a ) ;
detail::ger( m, n, alpha, x_ptr, stride_x, y_ptr, stride_y, a_ptr, lda );
}
/*
// A <- alpha * x * trans(y) ( outer product ), alpha, x and y are complex-valued
template < typename vector_type_x, typename vector_type_y, typename value_type, typename matrix_type >
inline
void geru( const value_type& alpha,
const vector_type_x &x,
const vector_type_y &y,
matrix_type &a
)
{
// precondition: matrix_type must be dense or dense_proxy
// not all compilers can handle the traits
// BOOST_STATIC_ASSERT( ( boost::is_same< typename mtraits::matrix_structure,
// boost::numeric::bindings::traits::general_t
// >::value ) ) ;
// BOOST_STATIC_ASSERT( ( boost::is_same< x.value_type(), FEMTown::Complex() >::value ) ) ;
const int m = traits::matrix_size1( a ) ;
const int n = traits::matrix_size2( a ) ;
assert ( traits::vector_size( x ) <= m ) ;
assert ( traits::vector_size( y ) <= n ) ;
const int lda = traits::leading_dimension( a ) ;
const int stride_x = traits::vector_stride( x ) ;
const int stride_y = traits::vector_stride( y ) ;
const value_type *x_ptr = traits::vector_storage( x ) ;
const value_type *y_ptr = traits::vector_storage( y ) ;
value_type *a_ptr = traits::matrix_storage( a ) ;
detail::geru( m, n, alpha, x_ptr, stride_x, y_ptr, stride_y, a_ptr, lda );
}
*/
/*
// y <- alpha * A * x + beta * y
template < typename matrix_type, typename vector_type_x, typename vector_type_y >
inline
void gemv(const typename traits::matrix_traits<matrix_type>::value_type &alpha,
const matrix_type &a,
const vector_type_x &x,
const typename traits::vector_traits<vector_type_y>::value_type &beta,
vector_type_y &y
)
{
gemv( traits::NO_TRANSPOSE, alpha, a, x, beta, y );
}
// y <- A * x
template < typename matrix_type, typename vector_type_x, typename vector_type_y >
inline
void gemv(const matrix_type &a, const vector_type_x &x, vector_type_y &y)
{
typedef typename traits::matrix_traits<matrix_type>::value_type val_t;
gemv( traits::NO_TRANSPOSE, (val_t) 1, a, x, (val_t) 0, y );
}
*/
}}}}
#endif // BOOST_BINDINGS_BLAS_BLAS2_HPP

View File

@@ -1,41 +0,0 @@
//
// Copyright (C) Toon Knapen 2003
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_NUMERIC_BINDINGS_BLAS_BLAS2_OVERLOADS_HPP
#define BOOST_NUMERIC_BINDINGS_BLAS_BLAS2_OVERLOADS_HPP
#include <boost/numeric/bindings/blas/blas.h>
#include <boost/numeric/bindings/traits/type_traits.hpp>
namespace boost { namespace numeric { namespace bindings { namespace blas { namespace detail {
using namespace boost::numeric::bindings::traits ;
inline
void gemv( char TRANS, const int& m, const int& n, const float & alpha, const float * a_ptr, const int& lda, const float * x_ptr, const int& incx, const float & beta, float * y_ptr, const int& incy ) { BLAS_SGEMV( &TRANS, &m, &n, ( &alpha ), ( a_ptr ), &lda, ( x_ptr ), &incx, ( &beta ), ( y_ptr ), &incy ) ; }
inline
void gemv( char TRANS, const int& m, const int& n, const double & alpha, const double * a_ptr, const int& lda, const double * x_ptr, const int& incx, const double & beta, double * y_ptr, const int& incy ) { BLAS_DGEMV( &TRANS, &m, &n, ( &alpha ), ( a_ptr ), &lda, ( x_ptr ), &incx, ( &beta ), ( y_ptr ), &incy ) ; }
inline
void gemv( char TRANS, const int& m, const int& n, const complex_f& alpha, const complex_f* a_ptr, const int& lda, const complex_f* x_ptr, const int& incx, const complex_f& beta, complex_f* y_ptr, const int& incy ) { BLAS_CGEMV( &TRANS, &m, &n, complex_ptr( &alpha ), complex_ptr( a_ptr ), &lda, complex_ptr( x_ptr ), &incx, complex_ptr( &beta ), complex_ptr( y_ptr ), &incy ) ; }
inline
void gemv( char TRANS, const int& m, const int& n, const complex_d& alpha, const complex_d* a_ptr, const int& lda, const complex_d* x_ptr, const int& incx, const complex_d& beta, complex_d* y_ptr, const int& incy ) { BLAS_ZGEMV( &TRANS, &m, &n, complex_ptr( &alpha ), complex_ptr( a_ptr ), &lda, complex_ptr( x_ptr ), &incx, complex_ptr( &beta ), complex_ptr( y_ptr ), &incy ) ; }
inline
void ger( const int& m, const int& n, const float & alpha, const float * x_ptr, const int& incx, const float * y_ptr, const int& incy, float * a_ptr, const int& lda ) { BLAS_SGER( &m, &n, &alpha, x_ptr, &incx, y_ptr, &incy, a_ptr, &lda ) ; }
inline
void ger( const int& m, const int& n, const double & alpha, const double * x_ptr, const int& incx, const double * y_ptr, const int& incy, double * a_ptr, const int& lda ) { BLAS_DGER( &m, &n, &alpha, x_ptr, &incx, y_ptr, &incy, a_ptr, &lda ) ; }
/*
inline
void geru( const int& m, const int& n, const complex_f & alpha, const complex_f * x_ptr, const int& incx, complex_f * y_ptr, const int& incy, complex_f * a_ptr, const int& lda ) { BLAS_CGERU( &m, &n, complex_ptr( &alpha ), complex_ptr( x_ptr ), &incx, complex_ptr( y_ptr ), &incy, complex_ptr( a_ptr ), &lda ) ; }
inline
void geru( const int& m, const int& n, const complex_d & alpha, const complex_d * x_ptr, const int& incx, complex_d * y_ptr, const int& incy, complex_d * a_ptr, const int& lda ) { BLAS_ZGERU( &m, &n, complex_ptr( &alpha ), complex_ptr( x_ptr ), &incx, complex_ptr( y_ptr ), &incy, complex_ptr( a_ptr ), &lda ) ; }
*/
}}}}}
#endif // BOOST_NUMERIC_BINDINGS_BLAS_BLAS2_OVERLOADS_HPP

View File

@@ -1,132 +0,0 @@
//
// Copyright Toon Knapen and Kresimir Fresl
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_BINDINGS_BLAS_BLAS3_HPP
#define BOOST_BINDINGS_BLAS_BLAS3_HPP
#include <boost/numeric/bindings/blas/blas3_overloads.hpp>
#include <boost/numeric/bindings/traits/traits.hpp>
#include <boost/numeric/bindings/traits/transpose.hpp>
namespace boost { namespace numeric { namespace bindings { namespace blas {
// C <- alpha * op (A) * op (B) + beta * C
// op (X) == X || X^T || X^H
template < typename value_type, typename matrix_type_a, typename matrix_type_b, typename matrix_type_c >
// ! CAUTION this function assumes that all matrices involved are column-major matrices
void gemm(const char TRANSA, const char TRANSB,
const value_type& alpha,
const matrix_type_a &a,
const matrix_type_b &b,
const value_type &beta,
matrix_type_c &c
)
{
const int m = TRANSA == traits::NO_TRANSPOSE ? traits::matrix_size1( a ) : traits::matrix_size2( a ) ;
const int n = TRANSB == traits::NO_TRANSPOSE ? traits::matrix_size2( b ) : traits::matrix_size1( b );
const int k = TRANSA == traits::NO_TRANSPOSE ? traits::matrix_size2( a ) : traits::matrix_size1( a ) ;
assert( k == ( TRANSB == traits::NO_TRANSPOSE ? traits::matrix_size1( b ) : traits::matrix_size2( b ) ) ) ;
assert( m == traits::matrix_size1( c ) );
assert( n == traits::matrix_size2( c ) );
const int lda = traits::leading_dimension( a );
const int ldb = traits::leading_dimension( b );
const int ldc = traits::leading_dimension( c );
const value_type *a_ptr = traits::matrix_storage( a ) ;
const value_type *b_ptr = traits::matrix_storage( b ) ;
value_type *c_ptr = traits::matrix_storage( c ) ;
detail::gemm( TRANSA, TRANSB, m, n, k, alpha, a_ptr, lda, b_ptr, ldb, beta, c_ptr, ldc ) ;
}
// C <- alpha * A * B + beta * C
template < typename value_type, typename matrix_type_a, typename matrix_type_b, typename matrix_type_c >
void gemm(const value_type& alpha,
const matrix_type_a &a,
const matrix_type_b &b,
const value_type &beta,
matrix_type_c &c
)
{
gemm( traits::NO_TRANSPOSE, traits::NO_TRANSPOSE, alpha, a, b, beta, c ) ;
}
// C <- A * B
// ! CAUTION this function assumes that all matrices involved are column-major matrices
template <
typename matrix_type_a, typename matrix_type_b, typename matrix_type_c
>
void gemm(const matrix_type_a &a, const matrix_type_b &b, matrix_type_c &c)
{
typedef typename traits::matrix_traits<matrix_type_c>::value_type val_t;
gemm( traits::NO_TRANSPOSE, traits::NO_TRANSPOSE, (val_t) 1, a, b, (val_t) 0, c ) ;
}
// C <- alpha * A * A^T + beta * C
// C <- alpha * A^T * A + beta * C
template < typename value_type, typename matrix_type_a, typename matrix_type_c >
void syrk( char uplo, char trans, const value_type& alpha, const matrix_type_a& a,
const value_type& beta, matrix_type_c& c) {
const int n = traits::matrix_size1( c );
assert( n == traits::matrix_size2( c ) );
const int k = trans == traits::NO_TRANSPOSE ? traits::matrix_size2( a ) : traits::matrix_size1( a ) ;
assert( n == traits::NO_TRANSPOSE ? traits::matrix_size1( a ) : traits::matrix_size2( a ) );
const int lda = traits::leading_dimension( a );
const int ldc = traits::leading_dimension( c );
const value_type *a_ptr = traits::matrix_storage( a ) ;
value_type *c_ptr = traits::matrix_storage( c ) ;
detail::syrk( uplo, trans, n, k, alpha, a_ptr, lda, beta, c_ptr, ldc );
} // syrk()
// C <- alpha * A * A^H + beta * C
// C <- alpha * A^H * A + beta * C
template < typename real_type, typename matrix_type_a, typename matrix_type_c >
void herk( char uplo, char trans, const real_type& alpha, const matrix_type_a& a,
const real_type& beta, matrix_type_c& c) {
typedef typename matrix_type_c::value_type value_type ;
const int n = traits::matrix_size1( c );
assert( n == traits::matrix_size2( c ) );
const int k = trans == traits::NO_TRANSPOSE ? traits::matrix_size2( a ) : traits::matrix_size1( a ) ;
assert( n == traits::NO_TRANSPOSE ? traits::matrix_size1( a ) : traits::matrix_size2( a ) );
const int lda = traits::leading_dimension( a );
const int ldc = traits::leading_dimension( c );
const value_type *a_ptr = traits::matrix_storage( a ) ;
value_type *c_ptr = traits::matrix_storage( c ) ;
detail::herk( uplo, trans, n, k, alpha, a_ptr, lda, beta, c_ptr, ldc );
} // herk()
// B <- alpha * op( A^-1 )
// B <- alpha * B op( A^-1 )
// op( A ) = A, A^T, A^H
template < class T, class A, class B >
void trsm( char side, char uplo, char transa, char diag, T const& alpha, A const& a, B& b ) {
const int m = traits::matrix_size1( b ) ;
const int n = traits::matrix_size2( b ) ;
assert( ( side=='L' && m==traits::matrix_size2( a ) && m==traits::matrix_size1( a ) ) ||
( side=='R' && n==traits::matrix_size2( a ) && n==traits::matrix_size1( a ) ) ) ;
assert( side=='R' || side=='L' ) ;
assert( uplo=='U' || uplo=='L' ) ;
assert( ( side=='L' && m==traits::matrix_size1( a ) ) || ( side=='R' && n==traits::matrix_size1( a ) ) ) ;
detail::trsm( side, uplo, transa, diag, m, n, alpha,
traits::matrix_storage( a ), traits::leading_dimension( a ),
traits::matrix_storage( b ), traits::leading_dimension( b )
) ;
}
}}}}
#endif // BOOST_BINDINGS_BLAS_BLAS3_HPP

View File

@@ -1,142 +0,0 @@
//
// Copyright (C) Toon Knapen 2003
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_NUMERIC_BINDINGS_BLAS_BLAS3_OVERLOADS_HPP
#define BOOST_NUMERIC_BINDINGS_BLAS_BLAS3_OVERLOADS_HPP
#include <boost/numeric/bindings/blas/blas.h>
#include <boost/numeric/bindings/traits/type_traits.hpp>
namespace boost { namespace numeric { namespace bindings { namespace blas { namespace detail {
using namespace boost::numeric::bindings::traits ;
inline
void gemm( char TRANSA, char TRANSB, const int& m, const int& n, const int& k, const float & alpha, const float * a_ptr, const int& lda, const float * b_ptr, const int& ldb, const float & beta, float * c_ptr, const int& ldc ) { BLAS_SGEMM( &TRANSA, &TRANSB, &m, &n, &k, ( &alpha ), ( a_ptr ), &lda, ( b_ptr ), &ldb, ( &beta ), ( c_ptr ), &ldc ) ; }
inline
void gemm( char TRANSA, char TRANSB, const int& m, const int& n, const int& k, const double & alpha, const double * a_ptr, const int& lda, const double * b_ptr, const int& ldb, const double & beta, double * c_ptr, const int& ldc ) { BLAS_DGEMM( &TRANSA, &TRANSB, &m, &n, &k, ( &alpha ), ( a_ptr ), &lda, ( b_ptr ), &ldb, ( &beta ), ( c_ptr ), &ldc ) ; }
inline
void gemm( char TRANSA, char TRANSB, const int& m, const int& n, const int& k, const complex_f& alpha, const complex_f* a_ptr, const int& lda, const complex_f* b_ptr, const int& ldb, const complex_f& beta, complex_f* c_ptr, const int& ldc ) { BLAS_CGEMM( &TRANSA, &TRANSB, &m, &n, &k, complex_ptr( &alpha ), complex_ptr( a_ptr ), &lda, complex_ptr( b_ptr ), &ldb, complex_ptr( &beta ), complex_ptr( c_ptr ), &ldc ) ; }
inline
void gemm( char TRANSA, char TRANSB, const int& m, const int& n, const int& k, const complex_d& alpha, const complex_d* a_ptr, const int& lda, const complex_d* b_ptr, const int& ldb, const complex_d& beta, complex_d* c_ptr, const int& ldc ) { BLAS_ZGEMM( &TRANSA, &TRANSB, &m, &n, &k, complex_ptr( &alpha ), complex_ptr( a_ptr ), &lda, complex_ptr( b_ptr ), &ldb, complex_ptr( &beta ), complex_ptr( c_ptr ), &ldc ) ; }
//
// SYRK
//
inline
void syrk( char uplo, char trans, const int& n, const int& k, const float& alpha,
const float* a_ptr, const int lda, const float& beta, float* c_ptr,
const int& ldc)
{
BLAS_SSYRK( &uplo, &trans, &n, &k, &alpha, a_ptr, &lda, &beta, c_ptr, &ldc);
}
inline
void syrk( char uplo, char trans, const int& n, const int& k, const double& alpha,
const double* a_ptr, const int lda, const double& beta, double* c_ptr,
const int& ldc)
{
BLAS_DSYRK( &uplo, &trans, &n, &k, &alpha, a_ptr, &lda, &beta, c_ptr, &ldc);
}
inline
void syrk( char uplo, char trans, const int& n, const int& k, const complex_f& alpha,
const complex_f* a_ptr, const int lda, const complex_f& beta, complex_f* c_ptr,
const int& ldc)
{
BLAS_CSYRK( &uplo, &trans, &n, &k, complex_ptr( &alpha ), complex_ptr( a_ptr ),
&lda, complex_ptr( &beta ), complex_ptr( c_ptr ), &ldc);
}
inline
void syrk( char uplo, char trans, const int& n, const int& k, const complex_d& alpha,
const complex_d* a_ptr, const int lda, const complex_d& beta, complex_d* c_ptr,
const int& ldc)
{
BLAS_ZSYRK( &uplo, &trans, &n, &k, complex_ptr( &alpha ), complex_ptr( a_ptr ),
&lda, complex_ptr( &beta ), complex_ptr( c_ptr ), &ldc);
}
//
// HERK
//
inline
void herk( char uplo, char trans, const int& n, const int& k, const float& alpha,
const float* a_ptr, const int lda, const float& beta, float* c_ptr,
const int& ldc)
{
BLAS_SSYRK( &uplo, &trans, &n, &k, &alpha, a_ptr, &lda, &beta, c_ptr, &ldc);
}
inline
void herk( char uplo, char trans, const int& n, const int& k, const double& alpha,
const double* a_ptr, const int lda, const double& beta, double* c_ptr,
const int& ldc)
{
BLAS_DSYRK( &uplo, &trans, &n, &k, &alpha, a_ptr, &lda, &beta, c_ptr, &ldc);
}
inline
void herk( char uplo, char trans, const int& n, const int& k, const float& alpha,
const complex_f* a_ptr, const int lda, const float& beta, complex_f* c_ptr,
const int& ldc)
{
BLAS_CHERK( &uplo, &trans, &n, &k, &alpha, complex_ptr( a_ptr ),
&lda, &beta, complex_ptr( c_ptr ), &ldc);
}
inline
void herk( char uplo, char trans, const int& n, const int& k, const double& alpha,
const complex_d* a_ptr, const int lda, const double& beta, complex_d* c_ptr,
const int& ldc)
{
BLAS_ZHERK( &uplo, &trans, &n, &k, &alpha, complex_ptr( a_ptr ),
&lda, &beta, complex_ptr( c_ptr ), &ldc);
}
//
// trsm
//
inline
void trsm( char side, char uplo, char transa, char diag, int m, int n,
float const& alpha, float const* a_ptr, int lda,
float* b_ptr, int ldb )
{
BLAS_STRSM( &side, &uplo, &transa, &diag, &m, &n, &alpha, a_ptr, &lda, b_ptr, &ldb ) ;
}
inline
void trsm( char side, char uplo, char transa, char diag, int m, int n,
double const& alpha, double const* a_ptr, int lda,
double* b_ptr, int ldb )
{
BLAS_DTRSM( &side, &uplo, &transa, &diag, &m, &n, &alpha, a_ptr, &lda, b_ptr, &ldb ) ;
}
inline
void trsm( char side, char uplo, char transa, char diag, int m, int n,
complex_f const& alpha, complex_f const* a_ptr, int lda,
complex_f* b_ptr, int ldb )
{
BLAS_CTRSM( &side, &uplo, &transa, &diag, &m, &n, complex_ptr( &alpha ), complex_ptr( a_ptr ), &lda, complex_ptr( b_ptr ), &ldb ) ;
}
inline
void trsm( char side, char uplo, char transa, char diag, int m, int n,
complex_d const& alpha, complex_d const* a_ptr, int lda,
complex_d* b_ptr, int ldb )
{
BLAS_ZTRSM( &side, &uplo, &transa, &diag, &m, &n, complex_ptr( &alpha ), complex_ptr( a_ptr ), &lda, complex_ptr( b_ptr ), &ldb ) ;
}
}}}}}
#endif // BOOST_NUMERIC_BINDINGS_BLAS_BLAS3_OVERLOADS_HPP

View File

@@ -1,88 +0,0 @@
//
// Copyright (C) 2002, 2003 Si-Lab b.v.b.a and Toon Knapen
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_NUMERIC_BINDINGS_BLAS_BLAS_NAMES_H
#define BOOST_NUMERIC_BINDINGS_BLAS_BLAS_NAMES_H
#include <boost/numeric/bindings/traits/fortran.h>
//
// level 1
//
#define BLAS_SSCAL FORTRAN_ID( sscal )
#define BLAS_DSCAL FORTRAN_ID( dscal )
#define BLAS_CSCAL FORTRAN_ID( cscal )
#define BLAS_ZSCAL FORTRAN_ID( zscal )
#define BLAS_SAXPY FORTRAN_ID( saxpy )
#define BLAS_DAXPY FORTRAN_ID( daxpy )
#define BLAS_CAXPY FORTRAN_ID( caxpy )
#define BLAS_ZAXPY FORTRAN_ID( zaxpy )
#define BLAS_SDOT FORTRAN_ID( sdot )
#define BLAS_DDOT FORTRAN_ID( ddot )
#define BLAS_CDOTU FORTRAN_ID( cdotu )
#define BLAS_ZDOTU FORTRAN_ID( zdotu )
#define BLAS_CDOTC FORTRAN_ID( cdotc )
#define BLAS_ZDOTC FORTRAN_ID( zdotc )
#define BLAS_SNRM2 FORTRAN_ID( snrm2 )
#define BLAS_DNRM2 FORTRAN_ID( dnrm2 )
#define BLAS_SCNRM2 FORTRAN_ID( scnrm2 )
#define BLAS_DZNRM2 FORTRAN_ID( dznrm2 )
#define BLAS_SASUM FORTRAN_ID( sasum )
#define BLAS_DASUM FORTRAN_ID( dasum )
#define BLAS_SCASUM FORTRAN_ID( scasum )
#define BLAS_DZASUM FORTRAN_ID( dzasum )
#define BLAS_SCOPY FORTRAN_ID( scopy )
#define BLAS_DCOPY FORTRAN_ID( dcopy )
#define BLAS_CCOPY FORTRAN_ID( ccopy )
#define BLAS_ZCOPY FORTRAN_ID( zcopy )
//
// level 2
//
#define BLAS_SGEMV FORTRAN_ID( sgemv )
#define BLAS_DGEMV FORTRAN_ID( dgemv )
#define BLAS_CGEMV FORTRAN_ID( cgemv )
#define BLAS_ZGEMV FORTRAN_ID( zgemv )
#define BLAS_SGER FORTRAN_ID( sger )
#define BLAS_DGER FORTRAN_ID( dger )
#define BLAS_CGERU FORTRAN_ID( cgeru )
#define BLAS_ZGERU FORTRAN_ID( zgeru )
#define BLAS_CGERC FORTRAN_ID( cgerc )
#define BLAS_ZGERC FORTRAN_ID( zgerc )
//
// level 3
//
#define BLAS_SGEMM FORTRAN_ID( sgemm )
#define BLAS_DGEMM FORTRAN_ID( dgemm )
#define BLAS_CGEMM FORTRAN_ID( cgemm )
#define BLAS_ZGEMM FORTRAN_ID( zgemm )
#define BLAS_SSYRK FORTRAN_ID( ssyrk )
#define BLAS_DSYRK FORTRAN_ID( dsyrk )
#define BLAS_CSYRK FORTRAN_ID( csyrk )
#define BLAS_ZSYRK FORTRAN_ID( zsyrk )
#define BLAS_CHERK FORTRAN_ID( cherk )
#define BLAS_ZHERK FORTRAN_ID( zherk )
#define BLAS_STRSM FORTRAN_ID( strsm )
#define BLAS_DTRSM FORTRAN_ID( dtrsm )
#define BLAS_CTRSM FORTRAN_ID( ctrsm )
#define BLAS_ZTRSM FORTRAN_ID( ztrsm )
#endif // BOOST_NUMERIC_BINDINGS_BLAS_BLAS_NAMES_H

View File

@@ -1,342 +0,0 @@
/*
*
* Copyright (c) Toon Knapen, Karl Meerbergen & Kresimir Fresl 2003
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* KF acknowledges the support of the Faculty of Civil Engineering,
* University of Zagreb, Croatia.
*
*/
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_GEES_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_GEES_HPP
#include <boost/numeric/bindings/traits/type.hpp>
#include <boost/numeric/bindings/traits/traits.hpp>
#include <boost/numeric/bindings/traits/type_traits.hpp>
#include <boost/numeric/bindings/lapack/lapack.h>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/traits/detail/array.hpp>
#include <boost/numeric/bindings/traits/detail/utils.hpp>
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
# include <boost/static_assert.hpp>
# include <boost/type_traits.hpp>
#endif
namespace boost { namespace numeric { namespace bindings {
namespace lapack {
///////////////////////////////////////////////////////////////////
//
// Schur factorization of general matrix.
//
///////////////////////////////////////////////////////////////////
/*
* gees() computes a Schur factorization of an N-by-N matrix A.
*
* The Schur decomposition is A = U S * herm(U) where U is a
* unitary matrix and S is upper triangular. The eigenvalues of A
* are on the main diagonal of S. If A is real, S is in pseudo
* upper triangular form.
*
* Workspace is organized following the arguments in the calling sequence.
* optimal_workspace() : for optimizing use of blas 3 kernels
* minimal_workspace() : minimum size of workarrays, but does not allow for optimization
* of blas 3 kernels
* workspace( work ) for real matrices where work is a real array with
* vector_size( work ) >= 3*matrix_size1( a )
* workspace( work, rwork ) for complex matrices where work is a complex
* array with vector_size( work ) >= 2*matrix_size1( a )
* and rwork is a real array with
* vector_size( rwork ) >= matrix_size1( a ).
*/
namespace detail {
inline
void gees (char const jobvs, char const sort, logical_t* select, int const n,
float* a, int const lda, int& sdim, traits::complex_f* w,
float* vs, int const ldvs, float* work, int const lwork,
bool* bwork, int& info)
{
traits::detail::array<float> wr(n);
traits::detail::array<float> wi(n);
LAPACK_SGEES (&jobvs, &sort, select, &n, a, &lda, &sdim,
traits::vector_storage(wr), traits::vector_storage(wi),
vs, &ldvs, work, &lwork, bwork, &info);
traits::detail::interlace(traits::vector_storage(wr),
traits::vector_storage(wr)+n,
traits::vector_storage(wi),
w);
}
inline
void gees (char const jobvs, char const sort, logical_t* select, int const n,
double* a, int const lda, int& sdim, traits::complex_d* w,
double* vs, int const ldvs, double* work, int const lwork,
bool* bwork, int& info)
{
traits::detail::array<double> wr(n);
traits::detail::array<double> wi(n);
LAPACK_DGEES (&jobvs, &sort, select, &n, a, &lda, &sdim,
traits::vector_storage(wr), traits::vector_storage(wi),
vs, &ldvs, work, &lwork, bwork, &info);
traits::detail::interlace(traits::vector_storage(wr),
traits::vector_storage(wr)+n,
traits::vector_storage(wi),
w);
}
inline
void gees (char const jobvs, char const sort, logical_t* select, int const n,
traits::complex_f* a, int const lda, int& sdim, traits::complex_f* w,
traits::complex_f* vs, int const ldvs,
traits::complex_f* work, int lwork, float* rwork, bool* bwork,
int& info)
{
LAPACK_CGEES (&jobvs, &sort, select, &n, traits::complex_ptr(a), &lda, &sdim,
traits::complex_ptr(w), traits::complex_ptr (vs), &ldvs,
traits::complex_ptr(work), &lwork, rwork, bwork, &info);
}
inline
void gees (char const jobvs, char const sort, logical_t* select, int const n,
traits::complex_d* a, int const lda, int& sdim, traits::complex_d* w,
traits::complex_d* vs, int const ldvs,
traits::complex_d* work, int lwork, double* rwork, bool* bwork,
int& info)
{
LAPACK_ZGEES (&jobvs, &sort, select, &n, traits::complex_ptr(a), &lda, &sdim,
traits::complex_ptr(w), traits::complex_ptr(vs), &ldvs,
traits::complex_ptr(work), &lwork, rwork, bwork, &info);
}
}
namespace detail {
/// Compute Schur factorization, passing one work array.
template <typename MatrA, typename SchVec, typename EigVal, typename Work>
inline
int gees (char jobvs, MatrA& a, EigVal& w, SchVec& vs, Work& work) {
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<MatrA>::matrix_structure,
traits::general_t
>::value));
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<SchVec>::matrix_structure,
traits::general_t
>::value));
#endif
typedef typename MatrA::value_type value_type ;
int const n = traits::matrix_size1 (a);
assert (n == traits::matrix_size2 (a));
assert (n == traits::matrix_size1 (vs));
assert (n == traits::matrix_size2 (vs));
assert (n == traits::vector_size (w));
assert (3*n <= traits::vector_size (work));
logical_t* select=0;
bool* bwork=0;
int info, sdim;
detail::gees (jobvs, 'N', select, n,
traits::matrix_storage (a),
traits::leading_dimension (a),
sdim,
traits::vector_storage (w),
traits::matrix_storage (vs),
traits::leading_dimension (vs),
traits::vector_storage( work ),
traits::vector_size( work ),
bwork, info);
return info ;
} // gees()
/// Compute Schur factorization, passing two work arrays.
template <typename MatrA, typename SchVec, typename EigVal,
typename Work, typename RWork>
inline
int gees (char jobvs, MatrA& a, EigVal& w, SchVec& vs,
Work& work, RWork& rwork) {
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<MatrA>::matrix_structure,
traits::general_t
>::value));
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<SchVec>::matrix_structure,
traits::general_t
>::value));
#endif
typedef typename MatrA::value_type value_type ;
int const n = traits::matrix_size1 (a);
assert (n == traits::matrix_size2 (a));
assert (n == traits::matrix_size1 (vs));
assert (n == traits::matrix_size2 (vs));
assert (n == traits::vector_size (w));
assert (2*n <= traits::vector_size (work));
assert (n <= traits::vector_size (rwork));
logical_t* select=0;
bool* bwork=0;
int info, sdim;
detail::gees (jobvs, 'N', select, n,
traits::matrix_storage (a),
traits::leading_dimension (a),
sdim,
traits::vector_storage (w),
traits::matrix_storage (vs),
traits::leading_dimension (vs),
traits::vector_storage( work ),
traits::vector_size( work ),
traits::vector_storage( rwork ),
bwork, info);
return info ;
} // gees()
/// Compute Schur factorization, depending on whether we have one or
/// two workspace arrays. N= the number of workspace arrays.
template <int N>
struct Gees {};
template <>
struct Gees< 2 > {
template <typename MatrA, typename SchVec, typename EigVal>
inline
int operator() (char jobvs, MatrA& a, EigVal& w, SchVec& vs, optimal_workspace ) const {
typedef typename MatrA::value_type value_type ;
typedef typename traits::type_traits< value_type >::real_type real_type ;
int n = traits::matrix_size1( a );
traits::detail::array<value_type> work( 2*n );
traits::detail::array<real_type> rwork( n );
return gees( jobvs, a, w, vs, work, rwork );
} // gees()
template <typename MatrA, typename SchVec, typename EigVal>
inline
int operator() (char jobvs, MatrA& a, EigVal& w, SchVec& vs, minimal_workspace ) const {
typedef typename MatrA::value_type value_type ;
typedef typename traits::type_traits< value_type >::real_type real_type ;
int n = traits::matrix_size1( a );
traits::detail::array<value_type> work( 2*n );
traits::detail::array<real_type> rwork( n );
return gees( jobvs, a, w, vs, work, rwork );
} // gees()
/// Compute Schur factorization, passing workspace2 as workspace
template <typename MatrA, typename SchVec, typename EigVal, typename RWork, typename Work>
inline
int operator() (char jobvs, MatrA& a, EigVal& w, SchVec& vs, workspace2<Work,RWork>& workspace ) const {
return gees( jobvs, a, w, vs, workspace.w_, workspace.wr_ );
} // gees()
}; // Gees<2>
template <>
struct Gees< 1 > {
template <typename MatrA, typename SchVec, typename EigVal>
inline
int operator() (char jobvs, MatrA& a, EigVal& w, SchVec& vs, optimal_workspace ) const {
typedef typename MatrA::value_type value_type ;
typedef typename traits::type_traits< value_type >::real_type real_type ;
int n = traits::matrix_size1( a );
traits::detail::array<value_type> work( 3*n );
return gees( jobvs, a, w, vs, work );
} // gees()
template <typename MatrA, typename SchVec, typename EigVal>
inline
int operator() (char jobvs, MatrA& a, EigVal& w, SchVec& vs, minimal_workspace ) const {
typedef typename MatrA::value_type value_type ;
typedef typename traits::type_traits< value_type >::real_type real_type ;
int n = traits::matrix_size1( a );
traits::detail::array<value_type> work( 3*n );
return gees( jobvs, a, w, vs, work );
} // gees()
/// Compute Schur factorization, passing workspace1 as workspace
template <typename MatrA, typename SchVec, typename EigVal, typename Work>
inline
int operator() (char jobvs, MatrA& a, EigVal& w, SchVec& vs, detail::workspace1<Work> workspace ) const {
return gees( jobvs, a, w, vs, workspace.w_ );
} // gees()
}; // Gees<1>
} // namespace detail
/// Compute Schur factorization with Schur vectors.
///
/// Workspace can be the following :
/// optimal_workspace() : for optimizing use of blas 3 kernels
/// minimal_workspace() : minimum size of workarrays, but does not allow for optimization
/// of blas 3 kernels
/// workspace( real_work ) for real matrices where
/// vector_size( real_work ) >= 3*matrix_size1( a )
/// workspace( complex_work, real_work ) for complex matrices where
/// vector_size( complex_work ) >= 2*matrix_size1( a )
/// and vector_size( real_work ) >= matrix_size1( a ).
template <typename MatrA, typename SchVec, typename EigVal, typename Workspace>
inline
int gees (MatrA& a, EigVal& e, SchVec& vs, Workspace workspace ) {
return detail::Gees< n_workspace_args<typename MatrA::value_type>::value>()
( 'V', a, e, vs, workspace );
} // gees()
// Compute Schur factorization without Schur vectors.
///
/// Workspace can be the following :
/// optimal_workspace() : for optimizing use of blas 3 kernels
/// minimal_workspace() : minimum size of workarrays, but does not allow for optimization
/// of blas 3 kernels
/// workspace( real_work ) for real matrices where
/// vector_size( real_work ) >= 3*matrix_size1( a )
/// workspace( complex_work, real_work ) for complex matrices where
/// vector_size( complex_work ) >= 2*matrix_size1( a )
/// and vector_size( real_work ) >= matrix_size1( a ).
template <typename MatrA, typename EigVal, typename Workspace>
inline
int gees (MatrA& a, EigVal& e, Workspace workspace) {
return detail::Gees< n_workspace_args<typename MatrA::value_type>::value>()
('N', a, e, a, workspace );
}
}
}}}
#endif

View File

@@ -1,355 +0,0 @@
/*
*
* Copyright (c) Andreas Kloeckner 2004
* Toon Knapen, Karl Meerbergen & Kresimir Fresl 2003
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* KF acknowledges the support of the Faculty of Civil Engineering,
* University of Zagreb, Croatia.
*
*/
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_GEEV_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_GEEV_HPP
#include <boost/numeric/bindings/traits/traits.hpp>
#include <boost/numeric/bindings/traits/type.hpp>
#include <boost/numeric/bindings/lapack/lapack.h>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/traits/detail/array.hpp>
// #include <boost/numeric/bindings/traits/std_vector.hpp>
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
# include <boost/static_assert.hpp>
# include <boost/type_traits.hpp>
#endif
namespace boost { namespace numeric { namespace bindings {
namespace lapack {
///////////////////////////////////////////////////////////////////
//
// Eigendecomposition of a general matrix A * V = V * D
//
///////////////////////////////////////////////////////////////////
/*
* geev() computes the eigendecomposition of a N x N matrix,
* where V is a N x N matrix and D is a diagonal matrix. The
* diagonal element D(i,i) is an eigenvalue of A and Q(:,i) is
* a corresponding eigenvector.
*
*
* int geev (char jobz, char uplo, A& a, W& w, V* vl, V* vr, optimal_workspace);
*
* a is the matrix whose eigendecomposition you're interested in. (input)
*
* w contains the diagonal of D, above. w must always be complex. (output)
*
* vl is an N x N matrix containing the left eigenvectors of a in its
* columns. See remark on complex vs. real below. May be left NULL to indicate
* that you do not want left eigenvectors.
*
* vr is an N x N matrix containing the right ("usual") eigenvectors of a in its
* columns. See remark on complex vs. real below. As a matrix, vr fulfills
* A * VR = VR * D. (except if real, see below). May be left NULL to indicate
* that you do not want right eigenvectors.
*
*
* For real A, vr and vl may be either complex or real, at your option.
* If you choose to leave them real, you have to pick apart the complex-conjugate
* eigenpairs as per the LAPACK documentation. If you choose them complex,
* the code will do the picking-apart on your behalf, at the expense of 4*N
* extra storage. Only if vr is complex, it will really fulfill its invariant
* on exit to the code in all cases, since complex pairs spoil that relation.
*/
namespace detail {
inline
int geev_backend(const char* jobvl, const char* jobvr, const int* n, float* a,
const int* lda, float* wr, float* wi, float* vl, const int* ldvl,
float* vr, const int* ldvr, float* work, const int* lwork)
{
int info;
LAPACK_SGEEV(jobvl, jobvr, n, a, lda, wr, wi, vl, ldvl, vr, ldvr, work, lwork, &info);
return info;
}
inline
int geev_backend(const char* jobvl, const char* jobvr, const int* n, double* a,
const int* lda, double* wr, double* wi, double* vl, const int* ldvl,
double* vr, const int* ldvr, double* work, const int* lwork)
{
int info;
LAPACK_DGEEV(jobvl, jobvr, n, a, lda, wr, wi, vl, ldvl, vr, ldvr, work, lwork, &info);
return info;
}
inline
int geev_backend(const char* jobvl, const char* jobvr, const int* n, traits::complex_f* a,
const int* lda, traits::complex_f* w, traits::complex_f* vl, const int* ldvl,
traits::complex_f* vr, const int* ldvr, traits::complex_f* work, const int* lwork,
float* rwork)
{
int info;
LAPACK_CGEEV(jobvl, jobvr, n,
traits::complex_ptr(a), lda,
traits::complex_ptr(w),
traits::complex_ptr(vl), ldvl,
traits::complex_ptr(vr), ldvr,
traits::complex_ptr(work), lwork,
rwork, &info);
return info;
}
inline
int geev_backend(const char* jobvl, const char* jobvr, const int* n, traits::complex_d* a,
const int* lda, traits::complex_d* w, traits::complex_d* vl, const int* ldvl,
traits::complex_d* vr, const int* ldvr, traits::complex_d* work, const int* lwork,
double* rwork)
{
int info;
LAPACK_ZGEEV(jobvl, jobvr, n,
traits::complex_ptr(a), lda,
traits::complex_ptr(w),
traits::complex_ptr(vl), ldvl,
traits::complex_ptr(vr), ldvr,
traits::complex_ptr(work), lwork,
rwork, &info);
return info;
}
struct real_case {};
struct mixed_case {};
struct complex_case {};
// real case
template <typename A, typename W, typename V>
int geev(real_case, const char jobvl, const char jobvr, A& a, W& w,
V* vl, V *vr)
{
int const n = traits::matrix_size1(a);
typedef typename A::value_type value_type;
traits::detail::array<value_type> wr(n);
traits::detail::array<value_type> wi(n);
traits::detail::array<value_type> vl2(vl ? 0 : n);
traits::detail::array<value_type> vr2(vr ? 0 : n);
value_type* vl_real = vl ? traits::matrix_storage(*vl) : vl2.storage();
const int ldvl = vl ? traits::matrix_size2(*vl) : 1;
value_type* vr_real = vr ? traits::matrix_storage(*vr) : vr2.storage();
const int ldvr = vr ? traits::matrix_size2(*vr) : 1;
// workspace query
int lwork = -1;
value_type work_temp;
int result = geev_backend(&jobvl, &jobvr, &n,
traits::matrix_storage(a), &n,
wr.storage(), wi.storage(),
vl_real, &ldvl, vr_real, &ldvr,
&work_temp, &lwork);
if (result != 0)
return result;
lwork = (int) work_temp;
traits::detail::array<value_type> work(lwork);
result = geev_backend(&jobvl, &jobvr, &n,
traits::matrix_storage(a), &n,
wr.storage(), wi.storage(),
vl_real, &ldvl, vr_real, &ldvr,
work.storage(), &lwork);
for (int i = 0; i < n; i++)
w[i] = std::complex<value_type>(wr[i], wi[i]);
return result;
}
// mixed (i.e. real with complex vectors) case
template <typename A, typename W, typename V>
int geev(mixed_case, const char jobvl, const char jobvr, A& a, W& w,
V* vl, V *vr)
{
int const n = traits::matrix_size1(a);
typedef typename A::value_type value_type;
traits::detail::array<value_type> wr(n);
traits::detail::array<value_type> wi(n);
traits::detail::array<value_type> vl2(vl ? n*n : n);
traits::detail::array<value_type> vr2(vr ? n*n : n);
const int ldvl2 = vl ? n : 1;
const int ldvr2 = vr ? n : 1;
// workspace query
int lwork = -1;
value_type work_temp;
int result = geev_backend(&jobvl, &jobvr, &n,
traits::matrix_storage(a), &n,
wr.storage(), wi.storage(),
vl2.storage(), &ldvl2, vr2.storage(), &ldvr2,
&work_temp, &lwork);
if (result != 0)
return result;
lwork = (int) work_temp;
traits::detail::array<value_type> work(lwork);
result = geev_backend(&jobvl, &jobvr, &n,
traits::matrix_storage(a), &n,
wr.storage(), wi.storage(),
vl2.storage(), &ldvl2, vr2.storage(), &ldvr2,
work.storage(), &lwork);
typedef typename V::value_type vec_value_type;
vec_value_type* vl_stor = NULL;
vec_value_type* vr_stor = NULL;
int ldvl = 0, ldvr = 0;
if (vl)
{
vl_stor = traits::matrix_storage(*vl);
ldvl = traits::matrix_size2(*vl);
}
if (vr)
{
vr_stor = traits::matrix_storage(*vr);
ldvr = traits::matrix_size2(*vr);
}
for (int i = 0; i < n; i++)
{
w[i] = std::complex<value_type>(wr[i], wi[i]);
if (wi[i] != 0)
{
assert(i+1 < n);
assert(wr[i+1] == wr[i]);
assert(wi[i+1] == -wi[i]);
w[i+1] = std::complex<value_type>(wr[i+1], wi[i+1]);
for (int j = 0; j < n; j++)
{
if (vl)
{
vl_stor[i*ldvl+j] = std::complex<value_type>(vl2[i*n+j], vl2[(i+1)*n+j]);
vl_stor[(i+1)*ldvl+j] = std::complex<value_type>(vl2[i*n+j], -vl2[(i+1)*n+j]);
}
if (vr)
{
vr_stor[i*ldvr+j] = std::complex<value_type>(vr2[i*n+j], vr2[(i+1)*n+j]);
vr_stor[(i+1)*ldvr+j] = std::complex<value_type>(vr2[i*n+j], -vr2[(i+1)*n+j]);
}
}
i++;
}
else
{
for (int j = 0; j < n; j++)
{
if (vl)
vl_stor[i*ldvl+j] = vl2[i*n+j];
if (vr)
vr_stor[i*ldvr+j] = vr2[i*n+j];
}
}
}
return result;
}
// complex case
template <typename A, typename W, typename V>
int geev(complex_case, const char jobvl, const char jobvr, A& a, W& w,
V* vl, V *vr)
{
typedef typename A::value_type value_type;
typedef typename traits::type_traits<value_type>::real_type real_type;
int const n = traits::matrix_size1(a);
traits::detail::array<real_type> rwork(2*n);
traits::detail::array<value_type> vl2(vl ? 0 : n);
traits::detail::array<value_type> vr2(vr ? 0 : n);
value_type* vl_real = vl ? traits::matrix_storage(*vl) : vl2.storage();
const int ldvl = vl ? traits::matrix_size2(*vl) : 1;
value_type* vr_real = vr ? traits::matrix_storage(*vr) : vr2.storage();
const int ldvr = vr ? traits::matrix_size2(*vr) : 1;
// workspace query
int lwork = -1;
value_type work_temp;
int result = geev_backend(&jobvl, &jobvr, &n,
traits::matrix_storage(a), &n,
traits::vector_storage(w),
vl_real, &ldvl, vr_real, &ldvr,
&work_temp, &lwork, rwork.storage());
if (result != 0)
return result;
lwork = (int) std::real(work_temp);
traits::detail::array<value_type> work(lwork);
result = geev_backend(&jobvl, &jobvr, &n,
traits::matrix_storage(a), &n,
traits::vector_storage(w),
vl_real, &ldvl, vr_real, &ldvr,
work.storage(), &lwork,
rwork.storage());
return result;
}
} // namespace detail
// gateway / dispatch routine
template <typename A, typename W, typename V>
int geev(A& a, W& w, V* vl, V* vr, optimal_workspace)
{
// input checking
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<A>::matrix_structure,
traits::general_t
>::value));
#endif
#ifndef NDEBUG
int const n = traits::matrix_size1(a);
#endif
assert(traits::matrix_size2(a)==n);
assert(traits::vector_size(w)==n);
assert(traits::vector_size(w)==n);
assert(!vr || traits::matrix_size1(*vr)==n);
assert(!vl || traits::matrix_size1(*vl)==n);
// preparation
typedef typename A::value_type value_type;
typedef typename V::value_type vec_value_type;
typedef typename traits::type_traits<value_type>::real_type real_type;
// dispatch
return detail::geev(typename boost::mpl::if_<
boost::is_same<value_type, real_type>,
typename boost::mpl::if_<
boost::is_same<vec_value_type, real_type>,
detail::real_case,
detail::mixed_case>::type,
detail::complex_case>::type(),
vl != 0 ? 'V' : 'N',
vr != 0 ? 'V' : 'N',
a, w, vl, vr);
}
}
}}}
#endif

View File

@@ -1,175 +0,0 @@
/*
*
* Copyright (c) Toon Knapen, Karl Meerbergen & Kresimir Fresl 2003
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* KF acknowledges the support of the Faculty of Civil Engineering,
* University of Zagreb, Croatia.
*
*/
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_GEQRF_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_GEQRF_HPP
#include <complex>
#include <boost/numeric/bindings/traits/traits.hpp>
#include <boost/numeric/bindings/lapack/lapack.h>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/traits/detail/array.hpp>
// #include <boost/numeric/bindings/traits/std_vector.hpp>
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
# include <boost/static_assert.hpp>
# include <boost/type_traits.hpp>
#endif
#include <cassert>
namespace boost { namespace numeric { namespace bindings {
namespace lapack {
///////////////////////////////////////////////////////////////////
//
// QR factorization of a general m x n matrix A = Q * R
//
///////////////////////////////////////////////////////////////////
/*
* geqrf() computes the QR factorization of a rectangular matrix
* A = Q * R, where Q is a M x min(M,N) matrix with orthogonal
* and normalized column (i.e. herm(Q) $ Q = I) and R is a
* min(M,N) x N upper triangular matrix.
*
* On return of geqrf, the elements on and above the diagonal of
* A contain the min(M,N) x N upper trapezoidal matrix R (R is
* upper triangular if m >= n); the elements below the diagonal,
* with the array TAU, represent the orthogonal matrix Q as a product
* of min(M,N) elementary reflectors.
*/
namespace detail {
inline
void geqrf (int const m, int const n,
float* a, int const lda,
float* tau, float* work, int const lwork, int& info)
{
LAPACK_SGEQRF (&m, &n, a, &lda, tau, work, &lwork, &info);
}
inline
void geqrf (int const m, int const n,
double* a, int const lda,
double* tau, double* work, int const lwork, int& info)
{
LAPACK_DGEQRF (&m, &n, a, &lda, tau, work, &lwork, &info);
}
inline
void geqrf (int const m, int const n,
traits::complex_f* a, int const lda,
traits::complex_f* tau, traits::complex_f* work,
int const lwork, int& info)
{
LAPACK_CGEQRF (&m, &n,
traits::complex_ptr (a), &lda,
traits::complex_ptr (tau),
traits::complex_ptr (work), &lwork, &info );
}
inline
void geqrf (int const m, int const n,
traits::complex_d* a, int const lda,
traits::complex_d* tau, traits::complex_d* work,
int const lwork, int& info)
{
LAPACK_ZGEQRF (&m, &n,
traits::complex_ptr (a), &lda,
traits::complex_ptr (tau),
traits::complex_ptr (work), &lwork, &info );
}
}
template <typename A, typename Tau, typename Work>
inline
int geqrf (A& a, Tau& tau, Work& work) {
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<A>::matrix_structure,
traits::general_t
>::value));
#endif
int const m = traits::matrix_size1 (a);
int const n = traits::matrix_size2 (a);
assert (std::min(m,n) <= traits::vector_size (tau));
assert (n <= traits::vector_size (work));
int info;
detail::geqrf (m, n,
traits::matrix_storage (a),
traits::leading_dimension (a),
traits::vector_storage (tau),
traits::vector_storage (work),
traits::vector_size (work),
info);
return info;
}
// Computation of the QR factorization.
// Workspace is allocated dynamically so that the optimization of
// blas 3 calls is optimal.
template <typename A, typename Tau>
inline
int geqrf (A& a, Tau& tau, optimal_workspace ) {
typedef typename A::value_type value_type ;
const int n = traits::matrix_size2 (a);
traits::detail::array<value_type> work(std::max(1, n*32));
return geqrf( a, tau, work );
}
// Computation of the QR factorization.
// Workspace is allocated dynamically to its minimum size.
// Blas 3 calls are not optimal.
template <typename A, typename Tau>
inline
int geqrf (A& a, Tau& tau, minimal_workspace ) {
typedef typename A::value_type value_type ;
const int n = traits::matrix_size2 (a);
traits::detail::array<value_type> work(std::max(1, n));
return geqrf( a, tau, work );
}
// Computation of the QR factorization.
// Workspace is taken from the array in workspace.
// The calling sequence is
// geqrf( a, tau, workspace( work ) ) where work is an array with the same value_type
// as a.
template <typename A, typename Tau, typename Work>
inline
int geqrf (A& a, Tau& tau, detail::workspace1<Work> workspace ) {
typedef typename A::value_type value_type ;
const int n = traits::matrix_size2 (a);
traits::detail::array<value_type> work(std::max(1, n));
return geqrf( a, tau, workspace.w_ );
}
// Function without workarray as argument
template <typename A, typename Tau>
inline
int geqrf (A& a, Tau& tau) {
return geqrf( a, tau, optimal_workspace() );
}
}
}}}
#endif

View File

@@ -1,708 +0,0 @@
/*
*
* Copyright (c) Toon Knapen & Kresimir Fresl 2003
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* KF acknowledges the support of the Faculty of Civil Engineering,
* University of Zagreb, Croatia.
*
*/
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_GESDD_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_GESDD_HPP
#include <boost/numeric/bindings/traits/type_traits.hpp>
#include <boost/numeric/bindings/traits/traits.hpp>
#include <boost/numeric/bindings/lapack/lapack.h>
#include <boost/numeric/bindings/traits/detail/array.hpp>
#include <boost/numeric/bindings/traits/detail/utils.hpp>
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
# include <boost/static_assert.hpp>
# include <boost/type_traits/is_same.hpp>
#endif
#include <cassert>
namespace boost { namespace numeric { namespace bindings {
namespace lapack {
///////////////////////////////////////////////////////////////////
//
// singular value decomposition
//
///////////////////////////////////////////////////////////////////
/*
* (divide and conquer driver)
* gesdd() computes the singular value decomposition (SVD) of
* M-by-N matrix A, optionally computing the left and/or right
* singular vectors, by using divide-and-conquer method.
* The SVD is written
*
* A = U * S * V^T or A = U * S * V^H
*
* where S is an M-by-N matrix which is zero except for its min(m,n)
* diagonal elements, U is an M-by-M orthogonal/unitary matrix, and V
* is an N-by-N orthogonal/unitary matrix. The diagonal elements of S
* are the singular values of A; they are real and non-negative, and
* are returnede in descending order. The first min(m,n) columns of
* U and V are the left and right singular vectors of A. (Note that
* the routine returns V^T or V^H, not V.
*/
namespace detail {
inline
void gesdd (char const jobz, int const m, int const n,
float* a, int const lda,
float* s, float* u, int const ldu,
float* vt, int const ldvt,
float* work, int const lwork, float* /* dummy */,
int* iwork, int* info)
{
LAPACK_SGESDD (&jobz, &m, &n, a, &lda, s,
u, &ldu, vt, &ldvt, work, &lwork, iwork, info);
}
inline
void gesdd (char const jobz, int const m, int const n,
double* a, int const lda,
double* s, double* u, int const ldu,
double* vt, int const ldvt,
double* work, int const lwork, double* /* dummy */,
int* iwork, int* info)
{
LAPACK_DGESDD (&jobz, &m, &n, a, &lda, s,
u, &ldu, vt, &ldvt, work, &lwork, iwork, info);
}
inline
void gesdd (char const jobz, int const m, int const n,
traits::complex_f* a, int const lda,
float* s, traits::complex_f* u, int const ldu,
traits::complex_f* vt, int const ldvt,
traits::complex_f* work, int const lwork,
float* rwork, int* iwork, int* info)
{
LAPACK_CGESDD (&jobz, &m, &n,
traits::complex_ptr (a), &lda, s,
traits::complex_ptr (u), &ldu,
traits::complex_ptr (vt), &ldvt,
traits::complex_ptr (work), &lwork,
rwork, iwork, info);
}
inline
void gesdd (char const jobz, int const m, int const n,
traits::complex_d* a, int const lda,
double* s, traits::complex_d* u, int const ldu,
traits::complex_d* vt, int const ldvt,
traits::complex_d* work, int const lwork,
double* rwork, int* iwork, int* info)
{
LAPACK_ZGESDD (&jobz, &m, &n,
traits::complex_ptr (a), &lda, s,
traits::complex_ptr (u), &ldu,
traits::complex_ptr (vt), &ldvt,
traits::complex_ptr (work), &lwork,
rwork, iwork, info);
}
inline
int gesdd_min_work (float, char jobz, int m, int n) {
int minmn = m < n ? m : n;
int maxmn = m < n ? n : m;
int m3 = 3 * minmn;
int m4 = 4 * minmn;
int minw;
if (jobz == 'N') {
// leading comments:
// LWORK >= 3*min(M,N) + max(max(M,N), 6*min(M,N))
// code:
// LWORK >= 3*min(M,N) + max(max(M,N), 7*min(M,N))
int m7 = 7 * minmn;
minw = maxmn < m7 ? m7 : maxmn;
minw += m3;
}
if (jobz == 'O') {
// LWORK >= 3*min(M,N)*min(M,N)
// + max(max(M,N), 5*min(M,N)*min(M,N)+4*min(M,N))
int m5 = 5 * minmn * minmn + m4;
minw = maxmn < m5 ? m5 : maxmn;
minw += m3 * minmn;
}
if (jobz == 'S' || jobz == 'A') {
// LWORK >= 3*min(M,N)*min(M,N)
// + max(max(M,N), 4*min(M,N)*min(M,N)+4*min(M,N)).
int m44 = m4 * minmn + m4;
minw = maxmn < m44 ? m44 : maxmn;
minw += m3 * minmn;
}
return minw;
}
inline
int gesdd_min_work (double, char jobz, int m, int n) {
int minmn = m < n ? m : n;
int maxmn = m < n ? n : m;
int m3 = 3 * minmn;
int m4 = 4 * minmn;
int minw;
if (jobz == 'N') {
// leading comments:
// LWORK >= 3*min(M,N) + max(max(M,N), 6*min(M,N))
// code:
// LWORK >= 3*min(M,N) + max(max(M,N), 7*min(M,N))
int m7 = 7 * minmn;
minw = maxmn < m7 ? m7 : maxmn;
minw += m3;
}
else if (jobz == 'O') {
// LWORK >= 3*min(M,N)*min(M,N)
// + max(max(M,N), 5*min(M,N)*min(M,N)+4*min(M,N))
int m5 = 5 * minmn * minmn + m4;
minw = maxmn < m5 ? m5 : maxmn;
minw += m3 * minmn;
}
else if (jobz == 'S' || jobz == 'A') {
// LWORK >= 3*min(M,N)*min(M,N)
// + max(max(M,N), 4*min(M,N)*min(M,N)+4*min(M,N)).
int m44 = m4 * minmn + m4;
minw = maxmn < m44 ? m44 : maxmn;
minw += m3 * minmn;
}
else {
std::cerr << "Invalid option passed to gesdd" << std::endl ;
return 0 ;
}
return minw;
}
inline
int gesdd_min_work (traits::complex_f, char jobz, int m, int n) {
int minmn = m < n ? m : n;
int maxmn = m < n ? n : m;
int m2 = 2 * minmn;
int minw = m2 + maxmn;
if (jobz == 'N')
// LWORK >= 2*min(M,N)+max(M,N)
;
if (jobz == 'O')
// LWORK >= 2*min(M,N)*min(M,N) + 2*min(M,N) + max(M,N)
minw += m2 * minmn;
if (jobz == 'S' || jobz == 'A')
// LWORK >= min(M,N)*min(M,N) + 2*min(M,N) + max(M,N)
minw += minmn * minmn;
return minw;
}
inline
int gesdd_min_work (traits::complex_d, char jobz, int m, int n) {
int minmn = m < n ? m : n;
int maxmn = m < n ? n : m;
int m2 = 2 * minmn;
int minw = m2 + maxmn;
if (jobz == 'N')
// LWORK >= 2*min(M,N)+max(M,N)
;
if (jobz == 'O')
// LWORK >= 2*min(M,N)*min(M,N) + 2*min(M,N) + max(M,N)
minw += m2 * minmn;
if (jobz == 'S' || jobz == 'A')
// LWORK >= min(M,N)*min(M,N) + 2*min(M,N) + max(M,N)
minw += minmn * minmn;
return minw;
}
inline
int gesdd_rwork (float, char, int, int) { return 1; }
inline
int gesdd_rwork (double, char, int, int) { return 1; }
inline
int gesdd_rwork (traits::complex_f, char jobz, int m, int n) {
int minmn = m < n ? m : n;
int minw;
if (jobz == 'N')
// LWORK >= 7*min(M,N)
minw = 7 * minmn;
else
// LRWORK >= 5*min(M,N)*min(M,N) + 5*min(M,N)
minw = 5 * (minmn * minmn + minmn);
return minw;
}
inline
int gesdd_rwork (traits::complex_d, char jobz, int m, int n) {
int minmn = m < n ? m : n;
int minw;
if (jobz == 'N')
// LWORK >= 7*min(M,N)
minw = 7 * minmn;
else
// LRWORK >= 5*min(M,N)*min(M,N) + 5*min(M,N)
minw = 5 * (minmn * minmn + minmn);
return minw;
}
inline
int gesdd_iwork (int m, int n) {
int minmn = m < n ? m : n;
return 8 * minmn;
}
} // detail
template <typename MatrA>
inline
int gesdd_work (char const q, char const jobz, MatrA const& a)
{
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<MatrA>::matrix_structure,
traits::general_t
>::value));
#endif
#ifdef BOOST_NUMERIC_BINDINGS_LAPACK_2
assert (q == 'M');
#else
assert (q == 'M' || q == 'O');
#endif
assert (jobz == 'N' || jobz == 'O' || jobz == 'A' || jobz == 'S');
int const m = traits::matrix_size1 (a);
int const n = traits::matrix_size2 (a);
int lw = -13;
#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
typedef typename traits::matrix_traits<MatrA>::value_type val_t;
#else
typedef typename MatrA::value_type val_t;
#endif
if (q == 'M')
lw = detail::gesdd_min_work (val_t(), jobz, m, n);
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_2
MatrA& a2 = const_cast<MatrA&> (a);
if (q == 'O') {
// traits::detail::array<val_t> w (1);
val_t w;
int info;
detail::gesdd (jobz, m, n,
traits::matrix_storage (a2),
traits::leading_dimension (a2),
0, // traits::vector_storage (s),
0, // traits::matrix_storage (u),
m, // traits::leading_dimension (u),
0, // traits::matrix_storage (vt),
n, // traits::leading_dimension (vt),
&w, // traits::vector_storage (w),
-1, // traits::vector_size (w),
0, // traits::vector_storage (rw),
0, // traits::vector_storage (iw),
&info);
assert (info == 0);
lw = traits::detail::to_int (w);
// // lw = traits::detail::to_int (w[0]);
/*
* is there a bug in LAPACK? or in Mandrake's .rpm?
* if m == 3, n == 4 and jobz == 'N' (real A),
* gesdd() returns optimal size == 1 while minimum size == 27
*/
// int lwo = traits::detail::to_int (w);
// int lwmin = detail::gesdd_min_work (val_t(), jobz, m, n);
// lw = lwo < lwmin ? lwmin : lwo;
}
#endif
return lw;
}
template <typename MatrA>
inline
int gesdd_rwork (char jobz, MatrA const& a) {
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<MatrA>::matrix_structure,
traits::general_t
>::value));
#endif
assert (jobz == 'N' || jobz == 'O' || jobz == 'A' || jobz == 'S');
#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
typedef typename traits::matrix_traits<MatrA>::value_type val_t;
#else
typedef typename MatrA::value_type val_t;
#endif
return detail::gesdd_rwork (val_t(), jobz,
traits::matrix_size1 (a),
traits::matrix_size2 (a));
}
template <typename MatrA>
inline
int gesdd_iwork (MatrA const& a) {
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<MatrA>::matrix_structure,
traits::general_t
>::value));
#endif
return detail::gesdd_iwork (traits::matrix_size1 (a),
traits::matrix_size2 (a));
}
template <typename MatrA, typename VecS,
typename MatrU, typename MatrV, typename VecW, typename VecIW>
inline
int gesdd (char const jobz, MatrA& a,
VecS& s, MatrU& u, MatrV& vt, VecW& w, VecIW& iw)
{
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<MatrA>::matrix_structure,
traits::general_t
>::value));
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<MatrU>::matrix_structure,
traits::general_t
>::value));
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<MatrV>::matrix_structure,
traits::general_t
>::value));
BOOST_STATIC_ASSERT(
(boost::is_same<
typename traits::matrix_traits<MatrA>::value_type, float
>::value
||
boost::is_same<
typename traits::matrix_traits<MatrA>::value_type, double
>::value));
#endif
int const m = traits::matrix_size1 (a);
int const n = traits::matrix_size2 (a);
int const minmn = m < n ? m : n;
assert (minmn == traits::vector_size (s));
assert ((jobz == 'N')
|| ((jobz == 'O' || jobz == 'A') && m >= n)
|| ((jobz == 'O' || jobz == 'A')
&& m < n
&& m == traits::matrix_size2 (u))
|| (jobz == 'S' && minmn == traits::matrix_size2 (u)));
assert ((jobz == 'N' && traits::leading_dimension (u) >= 1)
|| (jobz == 'O'
&& m >= n
&& traits::leading_dimension (u) >= 1)
|| (jobz == 'O'
&& m < n
&& traits::leading_dimension (u) >= m)
|| (jobz == 'A' && traits::leading_dimension (u) >= m)
|| (jobz == 'S' && traits::leading_dimension (u) >= m));
assert (n == traits::matrix_size2 (vt));
assert ((jobz == 'N' && traits::leading_dimension (vt) >= 1)
|| (jobz == 'O'
&& m < n
&& traits::leading_dimension (vt) >= 1)
|| (jobz == 'O'
&& m >= n
&& traits::leading_dimension (vt) >= n)
|| (jobz == 'A' && traits::leading_dimension (vt) >= n)
|| (jobz == 'S' && traits::leading_dimension (vt) >= minmn));
#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
typedef typename traits::matrix_traits<MatrA>::value_type val_t;
#else
typedef typename MatrA::value_type val_t;
#endif
assert (traits::vector_size (w)
>= detail::gesdd_min_work (val_t(), jobz, m, n));
assert (traits::vector_size (iw) >= detail::gesdd_iwork (m, n));
int info;
detail::gesdd (jobz, m, n,
traits::matrix_storage (a),
traits::leading_dimension (a),
traits::vector_storage (s),
traits::matrix_storage (u),
traits::leading_dimension (u),
traits::matrix_storage (vt),
traits::leading_dimension (vt),
traits::vector_storage (w),
traits::vector_size (w),
0, // dummy argument
traits::vector_storage (iw),
&info);
return info;
}
template <typename MatrA, typename VecS, typename MatrU,
typename MatrV, typename VecW, typename VecRW, typename VecIW>
inline
int gesdd (char const jobz, MatrA& a,
VecS& s, MatrU& u, MatrV& vt, VecW& w, VecRW& rw, VecIW& iw)
{
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<MatrA>::matrix_structure,
traits::general_t
>::value));
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<MatrU>::matrix_structure,
traits::general_t
>::value));
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<MatrV>::matrix_structure,
traits::general_t
>::value));
#endif
int const m = traits::matrix_size1 (a);
int const n = traits::matrix_size2 (a);
int const minmn = m < n ? m : n;
assert (minmn == traits::vector_size (s));
assert ((jobz == 'N')
|| ((jobz == 'O' || jobz == 'A') && m >= n)
|| ((jobz == 'O' || jobz == 'A')
&& m < n
&& m == traits::matrix_size2 (u))
|| (jobz == 'S' && minmn == traits::matrix_size2 (u)));
assert ((jobz == 'N' && traits::leading_dimension (u) >= 1)
|| (jobz == 'O'
&& m >= n
&& traits::leading_dimension (u) >= 1)
|| (jobz == 'O'
&& m < n
&& traits::leading_dimension (u) >= m)
|| (jobz == 'A' && traits::leading_dimension (u) >= m)
|| (jobz == 'S' && traits::leading_dimension (u) >= m));
assert (n == traits::matrix_size2 (vt));
assert ((jobz == 'N' && traits::leading_dimension (vt) >= 1)
|| (jobz == 'O'
&& m < n
&& traits::leading_dimension (vt) >= 1)
|| (jobz == 'O'
&& m >= n
&& traits::leading_dimension (vt) >= n)
|| (jobz == 'A' && traits::leading_dimension (vt) >= n)
|| (jobz == 'S' && traits::leading_dimension (vt) >= minmn));
#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
typedef typename traits::matrix_traits<MatrA>::value_type val_t;
#else
typedef typename MatrA::value_type val_t;
#endif
assert (traits::vector_size (w)
>= detail::gesdd_min_work (val_t(), jobz, m, n));
assert (traits::vector_size (rw)
>= detail::gesdd_rwork (val_t(), jobz, m, n));
assert (traits::vector_size (iw) >= detail::gesdd_iwork (m, n));
int info;
detail::gesdd (jobz, m, n,
traits::matrix_storage (a),
traits::leading_dimension (a),
traits::vector_storage (s),
traits::matrix_storage (u),
traits::leading_dimension (u),
traits::matrix_storage (vt),
traits::leading_dimension (vt),
traits::vector_storage (w),
traits::vector_size (w),
traits::vector_storage (rw),
traits::vector_storage (iw),
&info);
return info;
}
template <typename MatrA, typename VecS, typename MatrU, typename MatrV>
inline
int gesdd (char const opt, char const jobz,
MatrA& a, VecS& s, MatrU& u, MatrV& vt)
{
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<MatrA>::matrix_structure,
traits::general_t
>::value));
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<MatrU>::matrix_structure,
traits::general_t
>::value));
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<MatrV>::matrix_structure,
traits::general_t
>::value));
#endif
int const m = traits::matrix_size1 (a);
int const n = traits::matrix_size2 (a);
#ifndef NDEBUG
int const minmn = m < n ? m : n;
#endif // NDEBUG
assert (minmn == traits::vector_size (s));
assert ((jobz == 'N')
|| ((jobz == 'O' || jobz == 'A') && m >= n)
|| ((jobz == 'O' || jobz == 'A')
&& m < n
&& m == traits::matrix_size2 (u))
|| (jobz == 'S' && minmn == traits::matrix_size2 (u)));
assert ((jobz == 'N' && traits::leading_dimension (u) >= 1)
|| (jobz == 'O'
&& m >= n
&& traits::leading_dimension (u) >= 1)
|| (jobz == 'O'
&& m < n
&& traits::leading_dimension (u) >= m)
|| (jobz == 'A' && traits::leading_dimension (u) >= m)
|| (jobz == 'S' && traits::leading_dimension (u) >= m));
assert (n == traits::matrix_size2 (vt));
assert ((jobz == 'N' && traits::leading_dimension (vt) >= 1)
|| (jobz == 'O'
&& m < n
&& traits::leading_dimension (vt) >= 1)
|| (jobz == 'O'
&& m >= n
&& traits::leading_dimension (vt) >= n)
|| (jobz == 'A' && traits::leading_dimension (vt) >= n)
|| (jobz == 'S' && traits::leading_dimension (vt) >= minmn));
#ifdef BOOST_NUMERIC_BINDINGS_LAPACK_2
assert (opt == 'M');
#else
assert (opt == 'M' || opt == 'O');
#endif
#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
typedef typename traits::matrix_traits<MatrA>::value_type val_t;
#else
typedef typename MatrA::value_type val_t;
#endif
typedef typename traits::type_traits<val_t>::real_type real_t;
int const lw = gesdd_work (opt, jobz, a);
traits::detail::array<val_t> w (lw);
if (!w.valid()) return -101;
int const lrw = gesdd_rwork (jobz, a);
traits::detail::array<real_t> rw (lrw);
if (!rw.valid()) return -102;
int const liw = gesdd_iwork (a);
traits::detail::array<int> iw (liw);
if (!iw.valid()) return -103;
int info;
detail::gesdd (jobz, m, n,
traits::matrix_storage (a),
traits::leading_dimension (a),
traits::vector_storage (s),
traits::matrix_storage (u),
traits::leading_dimension (u),
traits::matrix_storage (vt),
traits::leading_dimension (vt),
traits::vector_storage (w),
lw, //traits::vector_size (w),
traits::vector_storage (rw),
traits::vector_storage (iw),
&info);
return info;
}
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_2
template <typename MatrA, typename VecS, typename MatrU, typename MatrV>
inline
int gesdd (char const jobz, MatrA& a, VecS& s, MatrU& u, MatrV& vt) {
return gesdd ('O', jobz, a, s, u, vt);
}
template <typename MatrA, typename VecS, typename MatrU, typename MatrV>
inline
int gesdd (MatrA& a, VecS& s, MatrU& u, MatrV& vt) {
return gesdd ('O', 'S', a, s, u, vt);
}
template <typename MatrA, typename VecS>
inline
int gesdd (MatrA& a, VecS& s) {
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<MatrA>::matrix_structure,
traits::general_t
>::value));
#endif
int const m = traits::matrix_size1 (a);
int const n = traits::matrix_size2 (a);
int const minmn = m < n ? m : n;
assert (minmn == traits::vector_size (s));
#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
typedef typename traits::matrix_traits<MatrA>::value_type val_t;
#else
typedef typename MatrA::value_type val_t;
#endif
typedef typename traits::type_traits<val_t>::real_type real_t;
int const lw = gesdd_work ('O', 'N', a);
traits::detail::array<val_t> w (lw);
if (!w.valid()) return -101;
int const lrw = gesdd_rwork ('N', a);
traits::detail::array<real_t> rw (lrw);
if (!rw.valid()) return -102;
int const liw = gesdd_iwork (a);
traits::detail::array<int> iw (liw);
if (!iw.valid()) return -103;
int info;
detail::gesdd ('N', m, n,
traits::matrix_storage (a),
traits::leading_dimension (a),
traits::vector_storage (s),
0, // traits::matrix_storage (u),
1, // traits::leading_dimension (u),
0, // traits::matrix_storage (vt),
1, // traits::leading_dimension (vt),
traits::vector_storage (w),
traits::vector_size (w),
traits::vector_storage (rw),
traits::vector_storage (iw),
&info);
return info;
}
#endif
} // namespace lapack
}}}
#endif

View File

@@ -1,311 +0,0 @@
/*
*
* Copyright (c) Toon Knapen & Kresimir Fresl 2003
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* KF acknowledges the support of the Faculty of Civil Engineering,
* University of Zagreb, Croatia.
*
*/
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_GESV_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_GESV_HPP
#include <boost/numeric/bindings/traits/type_traits.hpp>
#include <boost/numeric/bindings/traits/traits.hpp>
#include <boost/numeric/bindings/lapack/lapack.h>
#include <boost/numeric/bindings/traits/detail/array.hpp>
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
# include <boost/static_assert.hpp>
# include <boost/type_traits/is_same.hpp>
#endif
#include <cassert>
namespace boost { namespace numeric { namespace bindings {
namespace lapack {
///////////////////////////////////////////////////////////////////
//
// general system of linear equations A * X = B
//
///////////////////////////////////////////////////////////////////
/*
* gesv() computes the solution to a system of linear equations
* A * X = B, where A is an N-by-N matrix and X and B are N-by-NRHS
* matrices.
*
* The LU decomposition with partial pivoting and row interchanges
* is used to factor A as A = P * L * U, where P is a permutation
* matrix, L is unit lower triangular, and U is upper triangular.
* The factored form of A is then used to solve the system of
* equations A * X = B.
*/
namespace detail {
inline
void gesv (int const n, int const nrhs,
float* a, int const lda, int* ipiv,
float* b, int const ldb, int* info)
{
LAPACK_SGESV (&n, &nrhs, a, &lda, ipiv, b, &ldb, info);
}
inline
void gesv (int const n, int const nrhs,
double* a, int const lda, int* ipiv,
double* b, int const ldb, int* info)
{
LAPACK_DGESV (&n, &nrhs, a, &lda, ipiv, b, &ldb, info);
}
inline
void gesv (int const n, int const nrhs,
traits::complex_f* a, int const lda, int* ipiv,
traits::complex_f* b, int const ldb, int* info)
{
LAPACK_CGESV (&n, &nrhs,
traits::complex_ptr (a), &lda, ipiv,
traits::complex_ptr (b), &ldb, info);
}
inline
void gesv (int const n, int const nrhs,
traits::complex_d* a, int const lda, int* ipiv,
traits::complex_d* b, int const ldb, int* info)
{
LAPACK_ZGESV (&n, &nrhs,
traits::complex_ptr (a), &lda, ipiv,
traits::complex_ptr (b), &ldb, info);
}
}
template <typename MatrA, typename MatrB, typename IVec>
inline
int gesv (MatrA& a, IVec& ipiv, MatrB& b) {
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<MatrA>::matrix_structure,
traits::general_t
>::value));
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<MatrB>::matrix_structure,
traits::general_t
>::value));
#endif
int const n = traits::matrix_size1 (a);
assert (n == traits::matrix_size2 (a));
assert (n == traits::matrix_size1 (b));
assert (n == traits::vector_size (ipiv));
int info;
detail::gesv (n, traits::matrix_size2 (b),
traits::matrix_storage (a),
traits::leading_dimension (a),
traits::vector_storage (ipiv),
traits::matrix_storage (b),
traits::leading_dimension (b),
&info);
return info;
}
template <typename MatrA, typename MatrB>
inline
int gesv (MatrA& a, MatrB& b) {
// with 'internal' pivot vector
// gesv() errors:
// if (info == 0), successful
// if (info < 0), the -info argument had an illegal value
// -- we will use -101 if allocation fails
// if (info > 0), U(i-1,i-1) is exactly zero
int info = -101;
traits::detail::array<int> ipiv (traits::matrix_size1 (a));
if (ipiv.valid())
info = gesv (a, ipiv, b);
return info;
}
/*
* getrf() computes an LU factorization of a general M-by-N matrix A
* using partial pivoting with row interchanges. The factorization
* has the form A = P * L * U, where P is a permutation matrix,
* L is lower triangular with unit diagonal elements (lower
* trapezoidal if M > N), and U is upper triangular (upper
* trapezoidal if M < N).
*/
namespace detail {
inline
void getrf (int const n, int const m,
float* a, int const lda, int* ipiv, int* info)
{
LAPACK_SGETRF (&n, &m, a, &lda, ipiv, info);
}
inline
void getrf (int const n, int const m,
double* a, int const lda, int* ipiv, int* info)
{
LAPACK_DGETRF (&n, &m, a, &lda, ipiv, info);
}
inline
void getrf (int const n, int const m,
traits::complex_f* a, int const
lda, int* ipiv, int* info)
{
LAPACK_CGETRF (&n, &m, traits::complex_ptr (a), &lda, ipiv, info);
}
inline
void getrf (int const n, int const m,
traits::complex_d* a, int const lda,
int* ipiv, int* info)
{
LAPACK_ZGETRF (&n, &m, traits::complex_ptr (a), &lda, ipiv, info);
}
}
template <typename MatrA, typename IVec>
inline
int getrf (MatrA& a, IVec& ipiv) {
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<MatrA>::matrix_structure,
traits::general_t
>::value));
#endif
int const n = traits::matrix_size1 (a);
int const m = traits::matrix_size2 (a);
assert (traits::vector_size (ipiv) == (m < n ? m : n));
int info;
detail::getrf (n, m,
traits::matrix_storage (a),
traits::leading_dimension (a),
traits::vector_storage (ipiv),
&info);
return info;
}
/*
* getrs() solves a system of linear equations A * X = B
* or A^T * X = B with a general N-by-N matrix A using
* the LU factorization computed by getrf().
*/
namespace detail {
inline
void getrs (char const trans, int const n, int const nrhs,
float const* a, int const lda, int const* ipiv,
float* b, int const ldb, int* info)
{
LAPACK_SGETRS (&trans, &n, &nrhs, a, &lda, ipiv, b, &ldb, info);
}
inline
void getrs (char const trans, int const n, int const nrhs,
double const* a, int const lda, int const* ipiv,
double* b, int const ldb, int* info)
{
LAPACK_DGETRS (&trans, &n, &nrhs, a, &lda, ipiv, b, &ldb, info);
}
inline
void getrs (char const trans, int const n, int const nrhs,
traits::complex_f const* a, int const lda,
int const* ipiv,
traits::complex_f* b, int const ldb, int* info)
{
LAPACK_CGETRS (&trans, &n, &nrhs,
traits::complex_ptr (a), &lda, ipiv,
traits::complex_ptr (b), &ldb, info);
}
inline
void getrs (char const trans, int const n, int const nrhs,
traits::complex_d const* a, int const lda,
int const* ipiv,
traits::complex_d* b, int const ldb, int* info)
{
LAPACK_ZGETRS (&trans, &n, &nrhs,
traits::complex_ptr (a), &lda, ipiv,
traits::complex_ptr (b), &ldb, info);
}
}
template <typename MatrA, typename MatrB, typename IVec>
inline
int getrs (char const trans, MatrA const& a, IVec const& ipiv, MatrB& b)
{
assert (trans == 'N' || trans == 'T' || trans == 'C');
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<MatrA>::matrix_structure,
traits::general_t
>::value));
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<MatrB>::matrix_structure,
traits::general_t
>::value));
#endif
int const n = traits::matrix_size1 (a);
assert (n == traits::matrix_size2 (a));
assert (n == traits::matrix_size1 (b));
assert (n == traits::vector_size (ipiv));
int info;
detail::getrs (trans, n, traits::matrix_size2 (b),
#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
traits::matrix_storage (a),
#else
traits::matrix_storage_const (a),
#endif
traits::leading_dimension (a),
#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
traits::vector_storage (ipiv),
#else
traits::vector_storage_const (ipiv),
#endif
traits::matrix_storage (b),
traits::leading_dimension (b),
&info);
return info;
}
template <typename MatrA, typename MatrB, typename IVec>
inline
int getrs (MatrA const& a, IVec const& ipiv, MatrB& b) {
char const no_transpose = 'N';
return getrs (no_transpose, a, ipiv, b);
}
// TO DO: getri()
}
}}}
#endif

View File

@@ -1,534 +0,0 @@
/*
*
* Copyright (c) Toon Knapen & Kresimir Fresl 2003
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* KF acknowledges the support of the Faculty of Civil Engineering,
* University of Zagreb, Croatia.
*
*/
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_GESVD_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_GESVD_HPP
#include <boost/numeric/bindings/traits/type_traits.hpp>
#include <boost/numeric/bindings/traits/traits.hpp>
#include <boost/numeric/bindings/lapack/lapack.h>
#include <boost/numeric/bindings/traits/detail/array.hpp>
#include <boost/numeric/bindings/traits/detail/utils.hpp>
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
# include <boost/static_assert.hpp>
# include <boost/type_traits/is_same.hpp>
#endif
#include <cassert>
namespace boost { namespace numeric { namespace bindings {
namespace lapack {
///////////////////////////////////////////////////////////////////
//
// singular value decomposition
//
///////////////////////////////////////////////////////////////////
/*
* (simple driver)
* gesvd() computes the singular value decomposition (SVD) of
* M-by-N matrix A, optionally computing the left and/or right
* singular vectors. The SVD is written
*
* A = U * S * V^T or A = U * S * V^H
*
* where S is an M-by-N matrix which is zero except for its min(m,n)
* diagonal elements, U is an M-by-M orthogonal/unitary matrix, and V
* is an N-by-N orthogonal/unitary matrix. The diagonal elements of S
* are the singular values of A; they are real and non-negative, and
* are returnede in descending order. The first min(m,n) columns of
* U and V are the left and right singular vectors of A. (Note that
* the routine returns V^T or V^H, not V.
*/
namespace detail {
inline
void gesvd (char const jobu, char const jobvt,
int const m, int const n, float* a, int const lda,
float* s, float* u, int const ldu,
float* vt, int const ldvt,
float* work, int const lwork, float* /* dummy */,
int* info)
{
LAPACK_SGESVD (&jobu, &jobvt, &m, &n, a, &lda,
s, u, &ldu, vt, &ldvt, work, &lwork, info);
}
inline
void gesvd (char const jobu, char const jobvt,
int const m, int const n, double* a, int const lda,
double* s, double* u, int const ldu,
double* vt, int const ldvt,
double* work, int const lwork, double* /* dummy */,
int* info)
{
LAPACK_DGESVD (&jobu, &jobvt, &m, &n, a, &lda,
s, u, &ldu, vt, &ldvt, work, &lwork, info);
}
inline
void gesvd (char const jobu, char const jobvt,
int const m, int const n,
traits::complex_f* a, int const lda,
float* s, traits::complex_f* u, int const ldu,
traits::complex_f* vt, int const ldvt,
traits::complex_f* work, int const lwork,
float* rwork, int* info)
{
LAPACK_CGESVD (&jobu, &jobvt, &m, &n,
traits::complex_ptr (a), &lda, s,
traits::complex_ptr (u), &ldu,
traits::complex_ptr (vt), &ldvt,
traits::complex_ptr (work), &lwork, rwork, info);
}
inline
void gesvd (char const jobu, char const jobvt,
int const m, int const n,
traits::complex_d* a, int const lda,
double* s, traits::complex_d* u, int const ldu,
traits::complex_d* vt, int const ldvt,
traits::complex_d* work, int const lwork,
double* rwork, int* info)
{
LAPACK_ZGESVD (&jobu, &jobvt, &m, &n,
traits::complex_ptr (a), &lda, s,
traits::complex_ptr (u), &ldu,
traits::complex_ptr (vt), &ldvt,
traits::complex_ptr (work), &lwork, rwork, info);
}
inline
int gesvd_min_work (float, int m, int n) {
int minmn = m < n ? m : n;
int maxmn = m < n ? n : m;
int m3x = 3 * minmn + maxmn;
int m5 = 5 * minmn;
return m3x < m5 ? m5 : m3x;
}
inline
int gesvd_min_work (double, int m, int n) {
int minmn = m < n ? m : n;
int maxmn = m < n ? n : m;
int m3x = 3 * minmn + maxmn;
int m5 = 5 * minmn;
return m3x < m5 ? m5 : m3x;
}
inline
int gesvd_min_work (traits::complex_f, int m, int n) {
int minmn = m < n ? m : n;
int maxmn = m < n ? n : m;
return 2 * minmn + maxmn;
}
inline
int gesvd_min_work (traits::complex_d, int m, int n) {
int minmn = m < n ? m : n;
int maxmn = m < n ? n : m;
return 2 * minmn + maxmn;
}
inline
int gesvd_rwork (float, int, int) { return 1; }
inline
int gesvd_rwork (double, int, int) { return 1; }
inline
int gesvd_rwork (traits::complex_f, int m, int n) {
return 5 * (m < n ? m : n);
}
inline
int gesvd_rwork (traits::complex_d, int m, int n) {
return 5 * (m < n ? m : n);
}
} // detail
template <typename MatrA>
inline
int gesvd_work (char const q,
char const jobu, char const jobvt, MatrA const& a)
{
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<MatrA>::matrix_structure,
traits::general_t
>::value));
#endif
#ifdef BOOST_NUMERIC_BINDINGS_LAPACK_2
assert (q == 'M');
#else
assert (q == 'M' || q == 'O');
#endif
assert (jobu == 'N' || jobu == 'O' || jobu == 'A' || jobu == 'S');
assert (jobvt == 'N' || jobvt == 'O' || jobvt == 'A' || jobvt == 'S');
assert (!(jobu == 'O' && jobvt == 'O'));
int const m = traits::matrix_size1 (a);
int const n = traits::matrix_size2 (a);
int lw = -13;
#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
typedef typename traits::matrix_traits<MatrA>::value_type val_t;
#else
typedef typename MatrA::value_type val_t;
#endif
if (q == 'M')
lw = detail::gesvd_min_work (val_t(), m, n);
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_2
MatrA& a2 = const_cast<MatrA&> (a);
if (q == 'O') {
// traits::detail::array<val_t> w (0);
val_t w;
int info;
detail::gesvd (jobu, jobvt, m, n,
traits::matrix_storage (a2),
traits::leading_dimension (a2),
0, // traits::vector_storage (s),
0, // traits::matrix_storage (u),
m, // traits::leading_dimension (u),
0, // traits::matrix_storage (vt),
n, // traits::leading_dimension (vt),
&w, // traits::vector_storage (w),
-1, // traits::vector_size (w),
0, // traits::vector_storage (rw),
&info);
assert (info == 0);
lw = traits::detail::to_int (w); // (w[0]);
}
#endif
return lw;
}
template <typename MatrA>
inline
int gesvd_rwork (MatrA const& a) {
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<MatrA>::matrix_structure,
traits::general_t
>::value));
#endif
#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
typedef typename traits::matrix_traits<MatrA>::value_type val_t;
#else
typedef typename MatrA::value_type val_t;
#endif
return detail::gesvd_rwork (val_t(),
traits::matrix_size1 (a),
traits::matrix_size2 (a));
}
template <typename MatrA, typename VecS,
typename MatrU, typename MatrV, typename VecW>
inline
int gesvd (char const jobu, char const jobvt,
MatrA& a, VecS& s, MatrU& u, MatrV& vt, VecW& w)
{
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<MatrA>::matrix_structure,
traits::general_t
>::value));
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<MatrU>::matrix_structure,
traits::general_t
>::value));
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<MatrV>::matrix_structure,
traits::general_t
>::value));
BOOST_STATIC_ASSERT(
(boost::is_same<
typename traits::matrix_traits<MatrA>::value_type, float
>::value
||
boost::is_same<
typename traits::matrix_traits<MatrA>::value_type, double
>::value));
#endif
int const m = traits::matrix_size1 (a);
int const n = traits::matrix_size2 (a);
int const minmn = m < n ? m : n;
assert (minmn == traits::vector_size (s));
assert (!(jobu == 'O' && jobvt == 'O'));
assert ((jobu == 'N')
|| (jobu == 'O')
|| (jobu == 'A' && m == traits::matrix_size2 (u))
|| (jobu == 'S' && minmn == traits::matrix_size2 (u)));
assert ((jobu == 'N' && traits::leading_dimension (u) >= 1)
|| (jobu == 'O' && traits::leading_dimension (u) >= 1)
|| (jobu == 'A' && traits::leading_dimension (u) >= m)
|| (jobu == 'S' && traits::leading_dimension (u) >= m));
assert (n == traits::matrix_size2 (vt));
assert ((jobvt == 'N' && traits::leading_dimension (vt) >= 1)
|| (jobvt == 'O' && traits::leading_dimension (vt) >= 1)
|| (jobvt == 'A' && traits::leading_dimension (vt) >= n)
|| (jobvt == 'S' && traits::leading_dimension (vt) >= minmn));
#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
typedef typename traits::matrix_traits<MatrA>::value_type val_t;
#else
typedef typename MatrA::value_type val_t;
#endif
assert (traits::vector_size(w) >= detail::gesvd_min_work(val_t(),m,n));
int info;
detail::gesvd (jobu, jobvt, m, n,
traits::matrix_storage (a),
traits::leading_dimension (a),
traits::vector_storage (s),
traits::matrix_storage (u),
traits::leading_dimension (u),
traits::matrix_storage (vt),
traits::leading_dimension (vt),
traits::vector_storage (w),
traits::vector_size (w),
0, // dummy argument
&info);
return info;
}
template <typename MatrA, typename VecS,
typename MatrU, typename MatrV, typename VecW, typename VecRW>
inline
int gesvd (char const jobu, char const jobvt,
MatrA& a, VecS& s, MatrU& u, MatrV& vt, VecW& w, VecRW& rw)
{
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<MatrA>::matrix_structure,
traits::general_t
>::value));
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<MatrU>::matrix_structure,
traits::general_t
>::value));
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<MatrV>::matrix_structure,
traits::general_t
>::value));
#endif
int const m = traits::matrix_size1 (a);
int const n = traits::matrix_size2 (a);
int const minmn = m < n ? m : n;
assert (minmn == traits::vector_size (s));
assert (!(jobu == 'O' && jobvt == 'O'));
assert ((jobu == 'N')
|| (jobu == 'O')
|| (jobu == 'A' && m == traits::matrix_size2 (u))
|| (jobu == 'S' && minmn == traits::matrix_size2 (u)));
assert ((jobu == 'N' && traits::leading_dimension (u) >= 1)
|| (jobu == 'O' && traits::leading_dimension (u) >= 1)
|| (jobu == 'A' && traits::leading_dimension (u) >= m)
|| (jobu == 'S' && traits::leading_dimension (u) >= m));
assert (n == traits::matrix_size2 (vt));
assert ((jobvt == 'N' && traits::leading_dimension (vt) >= 1)
|| (jobvt == 'O' && traits::leading_dimension (vt) >= 1)
|| (jobvt == 'A' && traits::leading_dimension (vt) >= n)
|| (jobvt == 'S' && traits::leading_dimension (vt) >= minmn));
#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
typedef typename traits::matrix_traits<MatrA>::value_type val_t;
#else
typedef typename MatrA::value_type val_t;
#endif
assert (traits::vector_size(w) >= detail::gesvd_min_work(val_t(),m,n));
assert (traits::vector_size(rw) >= detail::gesvd_rwork(val_t(),m,n));
int info;
detail::gesvd (jobu, jobvt, m, n,
traits::matrix_storage (a),
traits::leading_dimension (a),
traits::vector_storage (s),
traits::matrix_storage (u),
traits::leading_dimension (u),
traits::matrix_storage (vt),
traits::leading_dimension (vt),
traits::vector_storage (w),
traits::vector_size (w),
traits::vector_storage (rw),
&info);
return info;
}
template <typename MatrA, typename VecS, typename MatrU, typename MatrV>
inline
int gesvd (char const opt, char const jobu, char const jobvt,
MatrA& a, VecS& s, MatrU& u, MatrV& vt)
{
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<MatrA>::matrix_structure,
traits::general_t
>::value));
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<MatrU>::matrix_structure,
traits::general_t
>::value));
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<MatrV>::matrix_structure,
traits::general_t
>::value));
#endif
int const m = traits::matrix_size1 (a);
int const n = traits::matrix_size2 (a);
int const minmn = m < n ? m : n;
assert (minmn == traits::vector_size (s));
assert (!(jobu == 'O' && jobvt == 'O'));
assert ((jobu == 'N')
|| (jobu == 'O')
|| (jobu == 'A' && m == traits::matrix_size2 (u))
|| (jobu == 'S' && minmn == traits::matrix_size2 (u)));
assert ((jobu == 'N' && traits::leading_dimension (u) >= 1)
|| (jobu == 'O' && traits::leading_dimension (u) >= 1)
|| (jobu == 'A' && traits::leading_dimension (u) >= m)
|| (jobu == 'S' && traits::leading_dimension (u) >= m));
assert ((jobvt == 'N' || traits::matrix_size2(vt) == n)) ;
assert ((jobvt == 'N' && traits::leading_dimension (vt) >= 1)
|| (jobvt == 'O' && traits::leading_dimension (vt) >= 1)
|| (jobvt == 'A' && traits::leading_dimension (vt) >= n)
|| (jobvt == 'S' && traits::leading_dimension (vt) >= minmn));
#ifdef BOOST_NUMERIC_BINDINGS_LAPACK_2
assert (opt == 'M');
#else
assert (opt == 'M' || opt == 'O');
#endif
#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
typedef typename traits::matrix_traits<MatrA>::value_type val_t;
#else
typedef typename MatrA::value_type val_t;
#endif
typedef typename traits::type_traits<val_t>::real_type real_t;
int const lw = gesvd_work (opt, jobu, jobvt, a);
traits::detail::array<val_t> w (lw);
if (!w.valid()) return -101;
int const lrw = gesvd_rwork (a);
traits::detail::array<real_t> rw (lrw);
if (!rw.valid()) return -102;
int info;
detail::gesvd (jobu, jobvt, m, n,
traits::matrix_storage (a),
traits::leading_dimension (a),
traits::vector_storage (s),
traits::matrix_storage (u),
traits::leading_dimension (u),
traits::matrix_storage (vt),
traits::leading_dimension (vt),
traits::vector_storage (w),
traits::vector_size (w),
traits::vector_storage (rw),
&info);
return info;
}
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_2
template <typename MatrA, typename VecS, typename MatrU, typename MatrV>
inline
int gesvd (char const jobu, char const jobvt,
MatrA& a, VecS& s, MatrU& u, MatrV& vt)
{
return gesvd ('O', jobu, jobvt, a, s, u, vt);
}
template <typename MatrA, typename VecS, typename MatrU, typename MatrV>
inline
int gesvd (MatrA& a, VecS& s, MatrU& u, MatrV& vt) {
return gesvd ('O', 'S', 'S', a, s, u, vt);
}
template <typename MatrA, typename VecS>
inline
int gesvd (MatrA& a, VecS& s) {
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<MatrA>::matrix_structure,
traits::general_t
>::value));
#endif
int const m = traits::matrix_size1 (a);
int const n = traits::matrix_size2 (a);
int const minmn = m < n ? m : n;
assert (minmn == traits::vector_size (s));
#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
typedef typename traits::matrix_traits<MatrA>::value_type val_t;
#else
typedef typename MatrA::value_type val_t;
#endif
typedef typename traits::type_traits<val_t>::real_type real_t;
int const lw = gesvd_work ('O', 'N', 'N', a);
traits::detail::array<val_t> w (lw);
if (!w.valid()) return -101;
int const lrw = gesvd_rwork (a);
traits::detail::array<real_t> rw (lrw);
if (!rw.valid()) return -102;
int info;
detail::gesvd ('N', 'N', m, n,
traits::matrix_storage (a),
traits::leading_dimension (a),
traits::vector_storage (s),
0, // traits::matrix_storage (u),
1, // traits::leading_dimension (u),
0, // traits::matrix_storage (vt),
1, // traits::leading_dimension (vt),
traits::vector_storage (w),
traits::vector_size (w),
traits::vector_storage (rw),
&info);
return info;
}
#endif
} // namespace lapack
}}}
#endif

View File

@@ -1,283 +0,0 @@
/*
*
* Copyright (c) Toon Knapen, Karl Meerbergen & Kresimir Fresl 2003
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* KF acknowledges the support of the Faculty of Civil Engineering,
* University of Zagreb, Croatia.
*
*/
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_HBEV_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_HBEV_HPP
#include <boost/numeric/bindings/traits/type.hpp>
#include <boost/numeric/bindings/traits/traits.hpp>
#include <boost/numeric/bindings/traits/type_traits.hpp>
#include <boost/numeric/bindings/lapack/lapack.h>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/traits/detail/array.hpp>
#include <boost/numeric/bindings/traits/detail/utils.hpp>
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
# include <boost/static_assert.hpp>
# include <boost/type_traits.hpp>
#endif
namespace boost { namespace numeric { namespace bindings {
namespace lapack {
///////////////////////////////////////////////////////////////////
//
// Eigendecomposition of a banded Hermitian matrix.
//
///////////////////////////////////////////////////////////////////
/*
* hbev() computes the eigenvalues and optionally the associated
* eigenvectors of a banded Hermitian matrix A. A matrix is Hermitian
* when herm( A ) == A. When A is real, a Hermitian matrix is also
* called symmetric.
*
* The eigen decomposition is A = U S * herm(U) where U is a
* unitary matrix and S is a diagonal matrix. The eigenvalues of A
* are on the main diagonal of S. The eigenvalues are real.
*
* Workspace is organized following the arguments in the calling sequence.
* optimal_workspace() : for optimizing use of blas 3 kernels
* minimal_workspace() : minimum size of workarrays, but does not allow for optimization
* of blas 3 kernels
* workspace( work ) for real matrices where work is a real array with
* vector_size( work ) >= 3*matrix_size1( a ) - 2
* workspace( work, rwork ) for complex matrices where work is a complex
* array with vector_size( work ) >= matrix_size1( a )
* and rwork is a real array with
* vector_size( rwork ) >= 3 * matrix_size1( a ) - 2.
*/
/*
* If uplo=='L' only the lower triangular part is stored.
* If uplo=='U' only the upper triangular part is stored.
*
* The matrix is assumed to be stored in LAPACK band format, i.e.
* matrices are stored columnwise, in a compressed format so that when e.g. uplo=='U'
* the (i,j) element with j>=i is in position (i-j) + j * (KD+1) + KD where KD is the
* half bandwidth of the matrix. For a triadiagonal matrix, KD=1, for a diagonal matrix
* KD=0.
* When uplo=='L', the (i,j) element with j>=i is in position (i-j) + j * (KD+1).
*
* The matrix A is thus a rectangular matrix with KD+1 rows and N columns.
*/
namespace detail {
inline
void hbev (char const jobz, char const uplo, int const n, int const kd,
float* ab, int const ldab, float* w, float* z, int const ldz,
float* work, int& info)
{
//for (int i=0; i<n*kd; ++i) std::cout << *(ab+i) << " " ;
//std::cout << "\n" ;
LAPACK_SSBEV (&jobz, &uplo, &n, &kd, ab, &ldab, w, z, &ldz,
work, &info);
}
inline
void hbev (char const jobz, char const uplo, int const n, int const kd,
double* ab, int const ldab, double* w, double* z, int const ldz,
double* work, int& info)
{
LAPACK_DSBEV (&jobz, &uplo, &n, &kd, ab, &ldab, w, z, &ldz,
work, &info);
}
inline
void hbev (char const jobz, char const uplo, int const n, int const kd,
traits::complex_f* ab, int const ldab, float* w,
traits::complex_f* z, int const ldz,
traits::complex_f* work, float* rwork, int& info)
{
LAPACK_CHBEV (&jobz, &uplo, &n, &kd, traits::complex_ptr(ab), &ldab,
w, traits::complex_ptr(z), &ldz,
traits::complex_ptr(work), rwork, &info);
}
inline
void hbev (char const jobz, char const uplo, int const n, int const kd,
traits::complex_d* ab, int const ldab, double* w,
traits::complex_d* z, int const ldz,
traits::complex_d* work, double* rwork, int& info)
{
LAPACK_ZHBEV (&jobz, &uplo, &n, &kd, traits::complex_ptr(ab), &ldab,
w, traits::complex_ptr(z), &ldz,
traits::complex_ptr(work), rwork, &info);
}
}
namespace detail {
template <int N>
struct Hbev{};
/// Handling of workspace in the case of one workarray.
template <>
struct Hbev< 1 > {
template <typename T, typename R>
void operator() (char const jobz, char const uplo, int const n,
int const kd, T* ab, int const ldab, R* w, T* z,
int const ldz, minimal_workspace , int& info ) const {
traits::detail::array<T> work( 3*n-2 );
hbev( jobz, uplo, n, kd, ab, ldab, w, z, ldz,
traits::vector_storage( work ),
info );
}
template <typename T, typename R>
void operator() (char const jobz, char const uplo, int const n,
int const kd, T* ab, int const ldab, R* w, T* z,
int const ldz, optimal_workspace , int& info ) const {
traits::detail::array<T> work( 3*n-2 );
hbev( jobz, uplo, n, kd, ab, ldab, w, z, ldz,
traits::vector_storage( work ),
info );
}
template <typename T, typename R, typename W>
void operator() (char const jobz, char const uplo, int const n,
int const kd, T* ab, int const ldab, R* w, T* z,
int const ldz, detail::workspace1<W> work,
int& info ) const {
assert( traits::vector_size( work.w_ ) >= 3*n-2 );
hbev( jobz, uplo, n, kd, ab, ldab, w, z, ldz,
traits::vector_storage( work.w_ ),
info );
}
}; // Hbev< 1 >
/// Handling of workspace in the case of two workarrays.
template <>
struct Hbev< 2 > {
template <typename T, typename R>
void operator() (char const jobz, char const uplo, int const n,
int const kd, T* ab, int const ldab, R* w, T* z,
int const ldz, minimal_workspace , int& info ) const {
traits::detail::array<T> work( n );
traits::detail::array<R> rwork( 3*n-2 );
hbev( jobz, uplo, n, kd, ab, ldab, w, z, ldz,
traits::vector_storage( work ),
traits::vector_storage( rwork ),
info );
}
template <typename T, typename R>
void operator() (char const jobz, char const uplo, int const n,
int const kd, T* ab, int const ldab, R* w, T* z,
int const ldz, optimal_workspace , int& info ) const {
traits::detail::array<T> work( n );
traits::detail::array<R> rwork( 3*n-2 );
hbev( jobz, uplo, n, kd, ab, ldab, w, z, ldz,
traits::vector_storage( work ),
traits::vector_storage( rwork ),
info );
}
template <typename T, typename R, typename W, typename RW>
void operator() (char const jobz, char const uplo, int const n,
int const kd, T* ab, int const ldab, R* w, T* z,
int const ldz, detail::workspace2<W,RW> work,
int& info ) const {
assert( traits::vector_size( work.wr_ ) >= 3*n-2 );
assert( traits::vector_size( work.w_ ) >= n );
hbev( jobz, uplo, n, kd, ab, ldab, w, z, ldz,
traits::vector_storage( work.w_ ),
traits::vector_storage( work.wr_ ),
info );
}
}; // Hbev< 2 >
/// Compute eigendecomposition of the banded Hermitian matrix ab.
/// if jobz=='N' only the eigenvalues are computed.
/// if jobz=='V' compute the eigenvalues a and the eigenvectors.
///
/// Workspace is organized following the arguments in the calling sequence.
/// optimal_workspace() : for optimizing use of blas 3 kernels
/// minimal_workspace() : minimum size of workarrays, but does not allow for optimization
/// of blas 3 kernels
/// workspace( work ) for real matrices where work is a real array with
/// vector_size( work ) >= 3*matrix_size1( a )-2
/// workspace( work, rwork ) for complex matrices where work is a complex
/// array with vector_size( work ) >= matrix_size1( a )
/// and rwork is a real array with
/// vector_size( rwork ) >= 3*matrix_size1( a )-2.
template <typename AB, typename Z, typename W, typename Work>
int hbev( char const jobz, AB& ab, W& w, Z& z, Work work ) {
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<AB>::matrix_structure,
traits::hermitian_t
>::value));
#endif
typedef typename AB::value_type value_type ;
int const n = traits::matrix_size2 (ab);
assert (n == traits::matrix_size1 (z));
assert (n == traits::vector_size (w));
assert ( jobz=='N' || jobz=='V' );
int info ;
detail::Hbev< n_workspace_args<value_type>::value >() (jobz,
traits::matrix_uplo_tag( ab ), n,
traits::matrix_upper_bandwidth(ab),
traits::matrix_storage (ab),
traits::leading_dimension (ab),
traits::vector_storage (w),
traits::matrix_storage (z),
traits::leading_dimension (z),
work, info);
return info ;
} // hbev()
} // namespace detail
/// Compute eigendecomposition without eigenvectors
template <typename AB, typename W, typename Work>
inline
int hbev (AB& ab, W& w, Work work) {
return detail::hbev( 'N', ab, w, ab, work );
} // hbev()
/// Compute eigendecomposition with eigenvectors
template <typename AB, typename W, typename Z, typename Work>
inline
int hbev (AB& ab, W& w, Z& z, Work work) {
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<Z>::matrix_structure,
traits::general_t
>::value));
int const n = traits::matrix_size2 (ab);
assert (n == traits::matrix_size1 (z));
assert (n == traits::matrix_size2 (z));
return detail::hbev( 'V', ab, w, z, work );
} // hbev()
}
}}}
#endif

View File

@@ -1,300 +0,0 @@
/*
*
* Copyright Toon Knapen, Karl Meerbergen & Kresimir Fresl 2003
* Copyright Thomas Klimpel 2008
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* KF acknowledges the support of the Faculty of Civil Engineering,
* University of Zagreb, Croatia.
*
*/
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_HBEVX_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_HBEVX_HPP
#include <boost/numeric/bindings/traits/type.hpp>
#include <boost/numeric/bindings/traits/traits.hpp>
#include <boost/numeric/bindings/traits/type_traits.hpp>
#include <boost/numeric/bindings/lapack/lapack.h>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/traits/detail/array.hpp>
#include <boost/numeric/bindings/traits/detail/utils.hpp>
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
# include <boost/static_assert.hpp>
# include <boost/type_traits.hpp>
#endif
namespace boost { namespace numeric { namespace bindings {
namespace lapack {
///////////////////////////////////////////////////////////////////
//
// Eigendecomposition of a banded Hermitian matrix.
//
///////////////////////////////////////////////////////////////////
/*
* hbevx() computes the eigenvalues and optionally the associated
* eigenvectors of a banded Hermitian matrix A. A matrix is Hermitian
* when herm( A ) == A. When A is real, a Hermitian matrix is also
* called symmetric.
*
* The eigen decomposition is A = U S * herm(U) where U is a
* unitary matrix and S is a diagonal matrix. The eigenvalues of A
* are on the main diagonal of S. The eigenvalues are real.
*/
/*
* If uplo=='L' only the lower triangular part is stored.
* If uplo=='U' only the upper triangular part is stored.
*
* The matrix is assumed to be stored in LAPACK band format, i.e.
* matrices are stored columnwise, in a compressed format so that when e.g. uplo=='U'
* the (i,j) element with j>=i is in position (i-j) + j * (KD+1) + KD where KD is the
* half bandwidth of the matrix. For a triadiagonal matrix, KD=1, for a diagonal matrix
* KD=0.
* When uplo=='L', the (i,j) element with j>=i is in position (i-j) + j * (KD+1).
*
* The matrix A is thus a rectangular matrix with KD+1 rows and N columns.
*/
namespace detail {
inline
void hbevx (
char const jobz, char const range, char const uplo, int const n, int const kd,
float* ab, int const ldab, float* q, int const ldq,
float const vl, float const vu, int const il, int const iu,
float const abstol, int& m,
float* w, float* z, int const ldz,
float* work, int* iwork, int* ifail, int& info)
{
LAPACK_SSBEVX (
&jobz, &range, &uplo, &n, &kd, ab, &ldab, q, &ldq,
&vl, &vu, &il, &iu, &abstol, &m,
w, z, &ldz,
work, iwork, ifail, &info);
}
inline
void hbevx (
char const jobz, char const range, char const uplo, int const n, int const kd,
double* ab, int const ldab, double* q, int const ldq,
double const vl, double const vu, int const il, int const iu,
double const abstol, int& m,
double* w, double* z, int const ldz,
double* work, int* iwork, int* ifail, int& info)
{
LAPACK_DSBEVX (
&jobz, &range, &uplo, &n, &kd, ab, &ldab, q, &ldq,
&vl, &vu, &il, &iu, &abstol, &m,
w, z, &ldz,
work, iwork, ifail, &info);
}
inline
void hbevx (
char const jobz, char const range, char const uplo, int const n, int const kd,
traits::complex_f* ab, int const ldab, traits::complex_f* q, int const ldq,
float const vl, float const vu, int const il, int const iu,
float const abstol, int& m,
float* w, traits::complex_f* z, int const ldz,
traits::complex_f* work, float* rwork, int* iwork, int* ifail, int& info)
{
LAPACK_CHBEVX (
&jobz, &range, &uplo, &n, &kd, traits::complex_ptr(ab), &ldab,
traits::complex_ptr(q), &ldq,
&vl, &vu, &il, &iu, &abstol, &m,
w, traits::complex_ptr(z), &ldz,
traits::complex_ptr(work), rwork, iwork, ifail, &info);
}
inline
void hbevx (
char const jobz, char const range, char const uplo, int const n, int const kd,
traits::complex_d* ab, int const ldab, traits::complex_d* q, int const ldq,
double const vl, double const vu, int const il, int const iu,
double const abstol, int& m,
double* w, traits::complex_d* z, int const ldz,
traits::complex_d* work, double* rwork, int* iwork, int* ifail, int& info)
{
LAPACK_ZHBEVX (
&jobz, &range, &uplo, &n, &kd, traits::complex_ptr(ab), &ldab,
traits::complex_ptr(q), &ldq,
&vl, &vu, &il, &iu, &abstol, &m,
w, traits::complex_ptr(z), &ldz,
traits::complex_ptr(work), rwork, iwork, ifail, &info);
}
}
namespace detail {
template <int N>
struct Hbevx{};
/// Handling of workspace in the case of one workarray.
template <>
struct Hbevx< 1 > {
template <typename T, typename R>
void operator() (char const jobz, char const range, char const uplo, int const n,
int const kd, T* ab, int const ldab, T* q, int const ldq,
R vl, R vu, int const il, int const iu, R abstol, int& m,
R* w, T* z, int const ldz,
minimal_workspace, int* ifail, int& info ) const {
traits::detail::array<T> work( 7*n );
traits::detail::array<int> iwork( 5*n );
hbevx( jobz, range, uplo, n, kd, ab, ldab, q, ldq,
vl, vu, il, iu, abstol, m,
w, z, ldz,
traits::vector_storage( work ),
traits::vector_storage (iwork),
ifail, info );
}
template <typename T, typename R>
void operator() (char const jobz, char const range, char const uplo, int const n,
int const kd, T* ab, int const ldab, T* q, int const ldq,
R vl, R vu, int const il, int const iu, R abstol, int& m,
R* w, T* z, int const ldz,
optimal_workspace, int* ifail, int& info ) const {
traits::detail::array<T> work( 7*n );
traits::detail::array<int> iwork( 5*n );
hbevx( jobz, range, uplo, n, kd, ab, ldab, q, ldq,
vl, vu, il, iu, abstol, m,
w, z, ldz,
traits::vector_storage( work ),
traits::vector_storage (iwork),
ifail, info );
}
template <typename T, typename R, typename W, typename WI>
void operator() (char const jobz, char const range, char const uplo, int const n,
int const kd, T* ab, int const ldab, T* q, int const ldq,
R vl, R vu, int const il, int const iu, R abstol, int& m,
R* w, T* z, int const ldz,
std::pair<detail::workspace1<W>, detail::workspace1<WI> > work,
int* ifail, int& info ) const {
assert( traits::vector_size( work.first.w_ ) >= 7*n );
assert( traits::vector_size( work.second.w_ ) >= 5*n );
hbevx( jobz, range, uplo, n, kd, ab, ldab, q, ldq,
vl, vu, il, iu, abstol, m,
w, z, ldz,
traits::vector_storage( work.first.w_ ),
traits::vector_storage( work.second.w_ ),
ifail, info );
}
}; // Hbevx< 1 >
/// Handling of workspace in the case of two workarrays.
template <>
struct Hbevx< 2 > {
template <typename T, typename R>
void operator() (char const jobz, char const range, char const uplo, int const n,
int const kd, T* ab, int const ldab, T* q, int const ldq,
R vl, R vu, int const il, int const iu, R abstol, int& m,
R* w, T* z, int const ldz,
minimal_workspace, int* ifail, int& info ) const {
traits::detail::array<T> work( n );
traits::detail::array<R> rwork( 7*n );
traits::detail::array<int> iwork( 5*n );
hbevx( jobz, range, uplo, n, kd, ab, ldab, q, ldq,
vl, vu, il, iu, abstol, m,
w, z, ldz,
traits::vector_storage( work ),
traits::vector_storage( rwork ),
traits::vector_storage (iwork),
ifail, info );
}
template <typename T, typename R>
void operator() (char const jobz, char const range, char const uplo, int const n,
int const kd, T* ab, int const ldab, T* q, int const ldq,
R vl, R vu, int const il, int const iu, R abstol, int& m,
R* w, T* z, int const ldz,
optimal_workspace, int* ifail, int& info ) const {
traits::detail::array<T> work( n );
traits::detail::array<R> rwork( 7*n );
traits::detail::array<int> iwork( 5*n );
hbevx( jobz, range, uplo, n, kd, ab, ldab, q, ldq,
vl, vu, il, iu, abstol, m,
w, z, ldz,
traits::vector_storage( work ),
traits::vector_storage( rwork ),
traits::vector_storage (iwork),
ifail, info );
}
template <typename T, typename R, typename W, typename RW, typename WI>
void operator() (char const jobz, char const range, char const uplo, int const n,
int const kd, T* ab, int const ldab, T* q, int const ldq,
R vl, R vu, int const il, int const iu, R abstol, int& m,
R* w, T* z, int const ldz,
std::pair<detail::workspace2<W,RW>, detail::workspace1<WI> > work,
int* ifail, int& info ) const {
assert( traits::vector_size( work.first.w_ ) >= n );
assert( traits::vector_size( work.first.wr_ ) >= 7*n );
assert( traits::vector_size( work.second.w_ ) >= 5*n );
hbevx( jobz, range, uplo, n, kd, ab, ldab, q, ldq,
vl, vu, il, iu, abstol, m,
w, z, ldz,
traits::vector_storage( work.first.w_ ),
traits::vector_storage( work.first.wr_ ),
traits::vector_storage( work.second.w_ ),
ifail, info );
}
}; // Hbevx< 2 >
} // namespace detail
template <typename AB, typename Q, typename R, typename Z, typename W, typename IFail, typename Work>
int hbevx( char const jobz, char const range, AB& ab, Q& q, R vl, R vu, int il, int iu, R abstol, int& m,
W& w, Z& z, IFail& ifail, Work work ) {
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<AB>::matrix_structure,
traits::hermitian_t
>::value));
#endif
typedef typename AB::value_type value_type ;
int const n = traits::matrix_size2 (ab);
assert (n == traits::matrix_size1 (z));
assert (n == traits::vector_size (w));
assert (n == traits::vector_size (ifail));
assert ( jobz=='N' || jobz=='V' );
int info ;
detail::Hbevx< n_workspace_args<value_type>::value >() (jobz, range,
traits::matrix_uplo_tag( ab ), n,
traits::matrix_upper_bandwidth(ab),
traits::matrix_storage (ab),
traits::leading_dimension (ab),
traits::matrix_storage (q),
traits::leading_dimension (q),
vl, vu, il, iu, abstol, m,
traits::vector_storage (w),
traits::matrix_storage (z),
traits::leading_dimension (z),
work,
traits::vector_storage (ifail),
info);
return info ;
} // hbevx()
}
}}}
#endif

View File

@@ -1,160 +0,0 @@
/*
*
* Copyright (c) Toon Knapen, Karl Meerbergen & Kresimir Fresl 2003
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* KF acknowledges the support of the Faculty of Civil Engineering,
* University of Zagreb, Croatia.
*
*/
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_HEEV_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_HEEV_HPP
#include <boost/numeric/bindings/traits/traits.hpp>
#include <boost/numeric/bindings/traits/type.hpp>
#include <boost/numeric/bindings/lapack/lapack.h>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/traits/detail/array.hpp>
// #include <boost/numeric/bindings/traits/std_vector.hpp>
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
# include <boost/static_assert.hpp>
# include <boost/type_traits.hpp>
#endif
namespace boost { namespace numeric { namespace bindings {
namespace lapack {
///////////////////////////////////////////////////////////////////
//
// Eigendecomposition of a complex Hermitian matrix A = Q * D * Q'
//
///////////////////////////////////////////////////////////////////
/*
* heev() computes the eigendecomposition of a N x N matrix
* A = Q * D * Q', where Q is a N x N unitary matrix and
* D is a diagonal matrix. The diagonal element D(i,i) is an
* eigenvalue of A and Q(:,i) is a corresponding eigenvector.
* The eigenvalues are stored in ascending order.
*
* On return of heev, A is overwritten by Q and w contains the main
* diagonal of D.
*
* int heev (char jobz, char uplo, A& a, W& w, minimal_workspace ) ;
* jobz : 'V' : compute eigenvectors
* 'N' : do not compute eigenvectors
* uplo : 'U' : only the upper triangular part of A is used on input.
* 'L' : only the lower triangular part of A is used on input.
*/
namespace detail {
inline
void heev (char const jobz, char const uplo, int const n,
traits::complex_f* a, int const lda,
float* w, traits::complex_f* work, int const lwork,
float* rwork, int& info)
{
LAPACK_CHEEV (&jobz, &uplo, &n,
traits::complex_ptr(a), &lda, w,
traits::complex_ptr(work), &lwork,
rwork, &info);
}
inline
void heev (char const jobz, char const uplo, int const n,
traits::complex_d* a, int const lda,
double* w, traits::complex_d* work, int const lwork,
double* rwork, int& info)
{
LAPACK_ZHEEV (&jobz, &uplo, &n,
traits::complex_ptr(a), &lda, w,
traits::complex_ptr(work), &lwork,
rwork, &info);
}
template <typename A, typename W, typename Work, typename RWork>
inline
int heev (char jobz, char uplo, A& a, W& w, Work& work, RWork& rwork) {
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<A>::matrix_structure,
traits::general_t
>::value));
#endif
int const n = traits::matrix_size1 (a);
assert (traits::matrix_size2 (a)==n);
assert (traits::vector_size (w)==n);
assert (2*n-1 <= traits::vector_size (work));
assert (3*n-2 <= traits::vector_size (rwork));
assert ( uplo=='U' || uplo=='L' );
assert ( jobz=='N' || jobz=='V' );
int info;
detail::heev (jobz, uplo, n,
traits::matrix_storage (a),
traits::leading_dimension (a),
traits::vector_storage (w),
traits::vector_storage (work),
traits::vector_size (work),
traits::vector_storage (rwork),
info);
return info;
}
} // namespace detail
// Function that allocates temporary arrays
template <typename A, typename W>
int heev (char jobz, char uplo, A& a, W& w, minimal_workspace ) {
typedef typename A::value_type value_type ;
typedef typename traits::type_traits<value_type>::real_type real_type ;
int const n = traits::matrix_size1 (a);
traits::detail::array<value_type> work( std::max(1,2*n-1) );
traits::detail::array<real_type> rwork( std::max(3*n-1,1) );
return detail::heev( jobz, uplo, a, w, work, rwork );
}
// Function that allocates temporary arrays
template <typename A, typename W>
int heev (char jobz, char uplo, A& a, W& w, optimal_workspace ) {
typedef typename A::value_type value_type ;
typedef typename traits::type_traits<value_type>::real_type real_type ;
int const n = traits::matrix_size1 (a);
traits::detail::array<value_type> work( std::max(1,33*n) );
traits::detail::array<real_type> rwork( std::max(3*n-1,1) );
return detail::heev( jobz, uplo, a, w, work, rwork );
}
// Function that uses given workarrays
template <typename A, typename W, typename WC, typename WR>
int heev (char jobz, char uplo, A& a, W& w, detail::workspace2<WC,WR> workspace ) {
typedef typename A::value_type value_type ;
typedef typename traits::type_traits<value_type>::real_type real_type ;
return detail::heev( jobz, uplo, a, w, workspace.w_, workspace.wr_ );
}
}
}}}
#endif

View File

@@ -1,277 +0,0 @@
/*
*
* Copyright Toon Knapen, Karl Meerbergen & Kresimir Fresl 2003
* Copyright Thomas Klimpel 2008
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* KF acknowledges the support of the Faculty of Civil Engineering,
* University of Zagreb, Croatia.
*
*/
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_HEEVD_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_HEEVD_HPP
#include <boost/numeric/bindings/traits/traits.hpp>
#include <boost/numeric/bindings/traits/type.hpp>
#include <boost/numeric/bindings/lapack/lapack.h>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/traits/detail/array.hpp>
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
# include <boost/static_assert.hpp>
# include <boost/type_traits.hpp>
#endif
namespace boost { namespace numeric { namespace bindings {
namespace lapack {
///////////////////////////////////////////////////////////////////
//
// Eigendecomposition of a complex Hermitian matrix A = Q * D * Q'
//
///////////////////////////////////////////////////////////////////
/*
* heevd() computes all eigenvalues and, optionally, eigenvectors of a
* complex Hermitian matrix A. If eigenvectors are desired, it uses a
* divide and conquer algorithm.
*
* heevd() computes the eigendecomposition of a N x N matrix
* A = Q * D * Q', where Q is a N x N unitary matrix and
* D is a diagonal matrix. The diagonal element D(i,i) is an
* eigenvalue of A and Q(:,i) is a corresponding eigenvector.
* The eigenvalues are stored in ascending order.
*
* On return of heevd, A is overwritten with the eigenvectors from Q
* and w contains the eigenvalues from the main diagonal of D.
*
* int heevd (char jobz, char uplo, A& a, W& w, Work work) {
* jobz : 'V' : compute eigenvectors
* 'N' : do not compute eigenvectors
* uplo : 'U' : only the upper triangular part of A is used on input.
* 'L' : only the lower triangular part of A is used on input.
*/
namespace detail {
inline void heevd (
char const jobz, char const uplo, int const n,
float* a, int const lda,
float* w, float* work, int const lwork,
int* iwork, int const liwork, int& info)
{
LAPACK_SSYEVD (
&jobz, &uplo, &n,
a, &lda,
w, work, &lwork,
iwork, &liwork, &info);
}
inline void heevd (
char const jobz, char const uplo, int const n,
double* a, int const lda,
double* w, double* work, int const lwork,
int* iwork, int const liwork, int& info)
{
LAPACK_DSYEVD (
&jobz, &uplo, &n,
a, &lda,
w, work, &lwork,
iwork, &liwork, &info);
}
inline void heevd (
char const jobz, char const uplo, int const n,
traits::complex_f* a, int const lda,
float* w, traits::complex_f* work, int const lwork,
float* rwork, int const lrwork, int* iwork, int const liwork, int& info)
{
LAPACK_CHEEVD (
&jobz, &uplo, &n,
traits::complex_ptr(a), &lda,
w,
traits::complex_ptr(work), &lwork,
rwork, &lrwork, iwork, &liwork, &info);
}
inline void heevd (
char const jobz, char const uplo, int const n,
traits::complex_d* a, int const lda,
double* w, traits::complex_d* work, int const lwork,
double* rwork, int const lrwork, int* iwork, int const liwork, int& info)
{
LAPACK_ZHEEVD (
&jobz, &uplo, &n,
traits::complex_ptr(a), &lda,
w,
traits::complex_ptr(work), &lwork,
rwork, &lrwork, iwork, &liwork, &info);
}
} // namespace detail
namespace detail {
template <int N>
struct Heevd{};
/// Handling of workspace in the case of one workarray.
template <>
struct Heevd< 1 > {
// Function that allocates temporary arrays
template <typename T, typename R>
void operator() (
char const jobz, char const uplo, int const n,
T* a, int const lda,
R* w, minimal_workspace, int& info) {
traits::detail::array<T> work( jobz=='N' ? 1+2*n : 1+6*n+2*n*n );
traits::detail::array<int> iwork( jobz=='N' ? 1 : 3+5*n );
heevd( jobz, uplo, n, a, lda, w,
traits::vector_storage (work), traits::vector_size (work),
traits::vector_storage (iwork), traits::vector_size (iwork),
info);
}
// Function that allocates temporary arrays
template <typename T, typename R>
void operator() (
char const jobz, char const uplo, int const n,
T* a, int const lda,
R* w, optimal_workspace, int& info) {
traits::detail::array<int> iwork( jobz=='N' ? 1 : 3+5*n );
T workspace_query;
heevd( jobz, uplo, n, a, lda, w,
&workspace_query, -1,
traits::vector_storage (iwork), traits::vector_size (iwork),
info);
traits::detail::array<T> work( static_cast<int>( workspace_query ) );
heevd( jobz, uplo, n, a, lda, w,
traits::vector_storage (work), traits::vector_size (work),
traits::vector_storage (iwork), traits::vector_size (iwork),
info);
}
// Function that uses given workarrays
template <typename T, typename R, typename W, typename WI>
void operator() (
char const jobz, char const uplo, int const n,
T* a, int const lda,
R* w, std::pair<detail::workspace1<W>, detail::workspace1<WI> > work, int& info) {
assert (traits::vector_size (work.first.w_) >= jobz=='N' ? 1+2*n : 1+6*n+2*n*n);
assert (traits::vector_size (work.second.w_) >= jobz=='N' ? 1 : 3+5*n);
heevd( jobz, uplo, n, a, lda, w,
traits::vector_storage (work.first.w_), traits::vector_size (work.first.w_),
traits::vector_storage (work.second.w_), traits::vector_size (work.second.w_),
info);
}
};
/// Handling of workspace in the case of two workarrays.
template <>
struct Heevd< 2 > {
// Function that allocates temporary arrays
template <typename T, typename R>
void operator() (
char const jobz, char const uplo, int const n,
T* a, int const lda,
R* w, minimal_workspace, int& info) {
traits::detail::array<T> work( jobz=='N' ? 1+n : 2*n+n*n );
traits::detail::array<R> rwork( jobz=='N' ? n : 1+5*n+2*n*n );
traits::detail::array<int> iwork( jobz=='N' ? 1 : 3+5*n );
heevd( jobz, uplo, n, a, lda, w,
traits::vector_storage (work), traits::vector_size (work),
traits::vector_storage (rwork), traits::vector_size (rwork),
traits::vector_storage (iwork), traits::vector_size (iwork),
info);
}
// Function that allocates temporary arrays
template <typename T, typename R>
void operator() (
char const jobz, char const uplo, int const n,
T* a, int const lda,
R* w, optimal_workspace, int& info) {
traits::detail::array<R> rwork( jobz=='N' ? n : 1+5*n+2*n*n );
traits::detail::array<int> iwork( jobz=='N' ? 1 : 3+5*n );
T workspace_query;
heevd( jobz, uplo, n, a, lda, w,
&workspace_query, -1,
traits::vector_storage (rwork), traits::vector_size (rwork),
traits::vector_storage (iwork), traits::vector_size (iwork),
info);
traits::detail::array<T> work( static_cast<int>( traits::real( workspace_query ) ) );
heevd( jobz, uplo, n, a, lda, w,
traits::vector_storage (work), traits::vector_size (work),
traits::vector_storage (rwork), traits::vector_size (rwork),
traits::vector_storage (iwork), traits::vector_size (iwork),
info);
}
// Function that uses given workarrays
template <typename T, typename R, typename WC, typename WR, typename WI>
void operator() (
char const jobz, char const uplo, int const n,
T* a, int const lda,
R* w, std::pair<detail::workspace2<WC,WR>, detail::workspace1<WI> > work, int& info) {
assert (traits::vector_size (work.first.w_) >= jobz=='N' ? 1+n : 2*n+n*n);
assert (traits::vector_size (work.first.wr_) >= jobz=='N' ? n : 1+5*n+2*n*n);
assert (traits::vector_size (work.second.w_) >= jobz=='N' ? 1 : 3+5*n);
heevd( jobz, uplo, n, a, lda, w,
traits::vector_storage (work.first.w_), traits::vector_size (work.first.w_),
traits::vector_storage (work.first.wr_), traits::vector_size (work.first.wr_),
traits::vector_storage (work.second.w_), traits::vector_size (work.second.w_),
info);
}
};
} // namespace detail
template <typename A, typename W, typename Work>
inline int heevd (
char jobz, char uplo, A& a,
W& w, Work work = optimal_workspace() ) {
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<A>::matrix_structure,
traits::general_t
>::value));
#endif
int const n = traits::matrix_size1 (a);
assert (traits::matrix_size2 (a) == n);
assert (traits::vector_size (w) == n);
assert ( uplo=='U' || uplo=='L' );
assert ( jobz=='N' || jobz=='V' );
int info;
detail::Heevd< n_workspace_args<typename A::value_type>::value >() (
jobz, uplo, n,
traits::matrix_storage (a),
traits::leading_dimension (a),
traits::vector_storage (w),
work,
info);
return info;
}
}
}}}
#endif

View File

@@ -1,320 +0,0 @@
/*
*
* Copyright Toon Knapen, Karl Meerbergen & Kresimir Fresl 2003
* Copyright Thomas Klimpel 2008
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* KF acknowledges the support of the Faculty of Civil Engineering,
* University of Zagreb, Croatia.
*
*/
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_HEEVX_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_HEEVX_HPP
#include <boost/numeric/bindings/traits/traits.hpp>
#include <boost/numeric/bindings/traits/type.hpp>
#include <boost/numeric/bindings/lapack/lapack.h>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/traits/detail/array.hpp>
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
# include <boost/static_assert.hpp>
# include <boost/type_traits.hpp>
#endif
namespace boost { namespace numeric { namespace bindings {
namespace lapack {
///////////////////////////////////////////////////////////////////
//
// Eigendecomposition of a complex Hermitian matrix A = Q * D * Q'
//
///////////////////////////////////////////////////////////////////
/*
* heevx() computes selected eigenvalues and, optionally, eigenvectors
* of a complex Hermitian matrix A. Eigenvalues and eigenvectors can
* be selected by specifying either a range of values or a range of
* indices for the desired eigenvalues.
*
* heevx() computes the eigendecomposition of a N x N matrix
* A = Q * D * Q', where Q is a N x N unitary matrix and
* D is a diagonal matrix. The diagonal element D(i,i) is an
* eigenvalue of A and Q(:,i) is a corresponding eigenvector.
* The eigenvalues are stored in ascending order.
*
* On return of heevx, A is overwritten, z contains selected eigenvectors from Q
* and w contains selected eigenvalues from the main diagonal of D.
*
* int heevx (char jobz, char range, char uplo, A& a, T vl, T vu, int il, int iu, T abstol, int& m,
* W& w, Z& z, IFail& ifail, Work work) {
* jobz : 'V' : compute eigenvectors
* 'N' : do not compute eigenvectors
* range : 'A': all eigenvalues will be found.
* 'V': all eigenvalues in the half-open interval (vl,vu] will be found.
* 'I': the il-th through iu-th eigenvalues will be found.
* uplo : 'U' : only the upper triangular part of A is used on input.
* 'L' : only the lower triangular part of A is used on input.
*/
namespace detail {
inline void heevx (
char const jobz, char const range, char const uplo, int const n,
float* a, int const lda,
float const vl, float const vu, int const il, int const iu,
float const abstol, int& m,
float* w, float* z, int const ldz, float* work, int const lwork,
int* iwork, int* ifail, int& info)
{
LAPACK_SSYEVX (
&jobz, &range, &uplo, &n,
a, &lda,
&vl, &vu, &il, &iu,
&abstol, &m,
w, z, &ldz, work, &lwork,
iwork, ifail, &info);
}
inline void heevx (
char const jobz, char const range, char const uplo, int const n,
double* a, int const lda,
double const vl, double const vu, int const il, int const iu,
double const abstol, int& m,
double* w, double* z, int const ldz, double* work, int const lwork,
int* iwork, int* ifail, int& info)
{
LAPACK_DSYEVX (
&jobz, &range, &uplo, &n,
a, &lda,
&vl, &vu, &il, &iu,
&abstol, &m,
w, z, &ldz, work, &lwork,
iwork, ifail, &info);
}
inline void heevx (
char const jobz, char const range, char const uplo, int const n,
traits::complex_f* a, int const lda,
float const vl, float const vu, int const il, int const iu,
float const abstol, int& m,
float* w, traits::complex_f* z, int const ldz, traits::complex_f* work, int const lwork,
float* rwork, int* iwork, int* ifail, int& info)
{
LAPACK_CHEEVX (
&jobz, &range, &uplo, &n,
traits::complex_ptr(a), &lda,
&vl, &vu, &il, &iu, &abstol, &m, w,
traits::complex_ptr(z), &ldz,
traits::complex_ptr(work), &lwork,
rwork, iwork, ifail, &info);
}
inline void heevx (
char const jobz, char const range, char const uplo, int const n,
traits::complex_d* a, int const lda,
double const vl, double const vu, int const il, int const iu,
double const abstol, int& m,
double* w, traits::complex_d* z, int const ldz, traits::complex_d* work, int const lwork,
double* rwork, int* iwork, int* ifail, int& info)
{
LAPACK_ZHEEVX (
&jobz, &range, &uplo, &n,
traits::complex_ptr(a), &lda,
&vl, &vu, &il, &iu, &abstol, &m, w,
traits::complex_ptr(z), &ldz,
traits::complex_ptr(work), &lwork,
rwork, iwork, ifail, &info);
}
} // namespace detail
namespace detail {
template <int N>
struct Heevx{};
/// Handling of workspace in the case of one workarray.
template <>
struct Heevx< 1 > {
// Function that allocates temporary arrays
template <typename T, typename R>
void operator() (
char const jobz, char const range, char const uplo, int const n,
T* a, int const lda,
R vl, R vu, int const il, int const iu,
R abstol, int& m,
R* w, T* z, int const ldz, minimal_workspace, int* ifail, int& info) {
traits::detail::array<T> work( 8*n );
traits::detail::array<int> iwork( 5*n );
heevx( jobz, range, uplo, n, a, lda, vl, vu, il, iu, abstol, m, w, z, ldz,
traits::vector_storage (work), traits::vector_size (work),
traits::vector_storage (iwork),
ifail, info);
}
// Function that allocates temporary arrays
template <typename T, typename R>
void operator() (
char const jobz, char const range, char const uplo, int const n,
T* a, int const lda,
R vl, R vu, int const il, int const iu,
R abstol, int& m,
R* w, T* z, int const ldz, optimal_workspace, int* ifail, int& info) {
traits::detail::array<int> iwork( 5*n );
T workspace_query;
heevx( jobz, range, uplo, n, a, lda, vl, vu, il, iu, abstol, m, w, z, ldz,
&workspace_query, -1,
traits::vector_storage (iwork),
ifail, info);
traits::detail::array<T> work( static_cast<int>( workspace_query ) );
heevx( jobz, range, uplo, n, a, lda, vl, vu, il, iu, abstol, m, w, z, ldz,
traits::vector_storage (work), traits::vector_size (work),
traits::vector_storage (iwork),
ifail, info);
}
// Function that uses given workarrays
template <typename T, typename R, typename W, typename WI>
void operator() (
char const jobz, char const range, char const uplo, int const n,
T* a, int const lda,
R vl, R vu, int const il, int const iu,
R abstol, int& m,
R* w, T* z, int const ldz, std::pair<detail::workspace1<W>, detail::workspace1<WI> > work, int* ifail, int& info) {
assert (traits::vector_size (work.first.w_) >= 8*n);
assert (traits::vector_size (work.second.w_) >= 5*n);
heevx( jobz, range, uplo, n, a, lda, vl, vu, il, iu, abstol, m, w, z, ldz,
traits::vector_storage (work.first.w_), traits::vector_size (work.first.w_),
traits::vector_storage (work.second.w_),
ifail, info);
}
};
/// Handling of workspace in the case of two workarrays.
template <>
struct Heevx< 2 > {
// Function that allocates temporary arrays
template <typename T, typename R>
void operator() (
char const jobz, char const range, char const uplo, int const n,
T* a, int const lda,
R vl, R vu, int const il, int const iu,
R abstol, int& m,
R* w, T* z, int const ldz, minimal_workspace, int* ifail, int& info) {
traits::detail::array<T> work( 2*n );
traits::detail::array<R> rwork( 7*n );
traits::detail::array<int> iwork( 5*n );
heevx( jobz, range, uplo, n, a, lda, vl, vu, il, iu, abstol, m, w, z, ldz,
traits::vector_storage (work), traits::vector_size (work),
traits::vector_storage (rwork),
traits::vector_storage (iwork),
ifail, info);
}
// Function that allocates temporary arrays
template <typename T, typename R>
void operator() (
char const jobz, char const range, char const uplo, int const n,
T* a, int const lda,
R vl, R vu, int const il, int const iu,
R abstol, int& m,
R* w, T* z, int const ldz, optimal_workspace, int* ifail, int& info) {
traits::detail::array<R> rwork( 7*n );
traits::detail::array<int> iwork( 5*n );
T workspace_query;
heevx( jobz, range, uplo, n, a, lda, vl, vu, il, iu, abstol, m, w, z, ldz,
&workspace_query, -1,
traits::vector_storage (rwork),
traits::vector_storage (iwork),
ifail, info);
traits::detail::array<T> work( static_cast<int>( traits::real( workspace_query ) ) );
heevx( jobz, range, uplo, n, a, lda, vl, vu, il, iu, abstol, m, w, z, ldz,
traits::vector_storage (work), traits::vector_size (work),
traits::vector_storage (rwork),
traits::vector_storage (iwork),
ifail, info);
}
// Function that uses given workarrays
template <typename T, typename R, typename WC, typename WR, typename WI>
void operator() (
char const jobz, char const range, char const uplo, int const n,
T* a, int const lda,
R vl, R vu, int const il, int const iu,
R abstol, int& m,
R* w, T* z, int const ldz, std::pair<detail::workspace2<WC,WR>, detail::workspace1<WI> > work, int* ifail, int& info) {
assert (traits::vector_size (work.first.w_) >= 2*n);
assert (traits::vector_size (work.first.wr_) >= 7*n);
assert (traits::vector_size (work.second.w_) >= 5*n);
heevx( jobz, range, uplo, n, a, lda, vl, vu, il, iu, abstol, m, w, z, ldz,
traits::vector_storage (work.first.w_), traits::vector_size (work.first.w_),
traits::vector_storage (work.first.wr_),
traits::vector_storage (work.second.w_),
ifail, info);
}
};
} // namespace detail
template <typename A, typename T, typename W, typename Z, typename IFail, typename Work>
inline int heevx (
char jobz, char range, A& a, T vl, T vu, int il, int iu, T abstol, int& m,
W& w, Z& z, IFail& ifail, Work work = optimal_workspace() ) {
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
typedef typename A::value_type value_type ;
typedef typename traits::type_traits< value_type >::real_type real_type ;
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<A>::matrix_structure,
traits::hermitian_t
>::value || (boost::is_same<
typename traits::matrix_traits<A>::matrix_structure,
traits::symmetric_t
>::value && boost::is_same<value_type, real_type>::value)));
#endif
int const n = traits::matrix_size1 (a);
assert (traits::matrix_size2 (a) == n);
assert (traits::vector_size (w) == n);
assert (traits::vector_size (ifail) == n);
assert ( range=='A' || range=='V' || range=='I' );
char uplo = traits::matrix_uplo_tag (a);
assert ( uplo=='U' || uplo=='L' );
assert ( jobz=='N' || jobz=='V' );
int info;
detail::Heevx< n_workspace_args<typename A::value_type>::value >() (
jobz, range, uplo, n,
traits::matrix_storage (a),
traits::leading_dimension (a),
vl, vu, il, iu, abstol, m,
traits::vector_storage (w),
traits::matrix_storage (z),
traits::leading_dimension (z),
work,
traits::vector_storage (ifail),
info);
return info;
}
}
}}}
#endif

View File

@@ -1,615 +0,0 @@
/*
*
* Copyright (c) Toon Knapen & Kresimir Fresl 2003
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* KF acknowledges the support of the Faculty of Civil Engineering,
* University of Zagreb, Croatia.
*
*/
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_HESV_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_HESV_HPP
#include <boost/numeric/bindings/traits/type_traits.hpp>
#include <boost/numeric/bindings/traits/traits.hpp>
#include <boost/numeric/bindings/lapack/lapack.h>
#include <boost/numeric/bindings/lapack/ilaenv.hpp>
#include <boost/numeric/bindings/traits/detail/array.hpp>
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
# include <boost/static_assert.hpp>
# include <boost/type_traits/is_same.hpp>
#endif
#include <cassert>
namespace boost { namespace numeric { namespace bindings {
namespace lapack {
/////////////////////////////////////////////////////////////////////
//
// system of linear equations A * X = B
// with A Hermitian indefinite matrix
//
/////////////////////////////////////////////////////////////////////
namespace detail {
inline
int hetrf_block (traits::complex_f,
int const ispec, char const ul, int const n)
{
char ul2[2] = "x"; ul2[0] = ul;
return ilaenv (ispec, "CHETRF", ul2, n);
}
inline
int hetrf_block (traits::complex_d,
int const ispec, char const ul, int const n)
{
char ul2[2] = "x"; ul2[0] = ul;
return ilaenv (ispec, "ZHETRF", ul2, n);
}
}
template <typename HermA>
inline
int hetrf_block (char const q, char const ul, HermA const& a) {
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<HermA>::matrix_structure,
traits::general_t
>::value));
#endif
assert (q == 'O' || q == 'M');
assert (ul == 'U' || ul == 'L');
int n = traits::matrix_size1 (a);
assert (n == traits::matrix_size2 (a));
#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
typedef typename traits::matrix_traits<HermA>::value_type val_t;
#else
typedef typename HermA::value_type val_t;
#endif
int ispec = (q == 'O' ? 1 : 2);
return detail::hetrf_block (val_t(), ispec, ul, n);
}
template <typename HermA>
inline
int hetrf_block (char const q, HermA const& a) {
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<HermA>::matrix_structure,
traits::hermitian_t
>::value));
#endif
assert (q == 'O' || q == 'M');
char ul = traits::matrix_uplo_tag (a);
int n = traits::matrix_size1 (a);
assert (n == traits::matrix_size2 (a));
#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
typedef typename traits::matrix_traits<HermA>::value_type val_t;
#else
typedef typename HermA::value_type val_t;
#endif
int ispec = (q == 'O' ? 1 : 2);
return detail::hetrf_block (val_t(), ispec, ul, n);
}
template <typename HermA>
inline
int hetrf_work (char const q, char const ul, HermA const& a) {
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<HermA>::matrix_structure,
traits::general_t
>::value));
#endif
assert (q == 'O' || q == 'M');
assert (ul == 'U' || ul == 'L');
int n = traits::matrix_size1 (a);
assert (n == traits::matrix_size2 (a));
#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
typedef typename traits::matrix_traits<HermA>::value_type val_t;
#else
typedef typename HermA::value_type val_t;
#endif
int lw = -13;
if (q == 'M')
lw = 1;
if (q == 'O')
lw = n * detail::hetrf_block (val_t(), 1, ul, n);
return lw;
}
template <typename HermA>
inline
int hetrf_work (char const q, HermA const& a) {
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<HermA>::matrix_structure,
traits::hermitian_t
>::value));
#endif
assert (q == 'O' || q == 'M');
char ul = traits::matrix_uplo_tag (a);
int n = traits::matrix_size1 (a);
assert (n == traits::matrix_size2 (a));
#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
typedef typename traits::matrix_traits<HermA>::value_type val_t;
#else
typedef typename HermA::value_type val_t;
#endif
int lw = -13;
if (q == 'M')
lw = 1;
if (q == 'O')
lw = n * detail::hetrf_block (val_t(), 1, ul, n);
return lw;
}
template <typename HermA>
inline
int hesv_work (char const q, char const ul, HermA const& a) {
return hetrf_work (q, ul, a);
}
template <typename HermA>
inline
int hesv_work (char const q, HermA const& a) { return hetrf_work (q, a); }
/*
* hesv() computes the solution to a system of linear equations
* A * X = B, where A is an N-by-N Hermitian matrix and X and B
* are N-by-NRHS matrices.
*
* The diagonal pivoting method is used to factor A as
* A = U * D * U^H, if UPLO = 'U',
* A = L * D * L^H, if UPLO = 'L',
* where U (or L) is a product of permutation and unit upper
* (lower) triangular matrices, and D is Hermitian and block
* diagonal with 1-by-1 and 2-by-2 diagonal blocks. The factored
* form of A is then used to solve the system of equations A * X = B.
*/
namespace detail {
inline
void hesv (char const uplo, int const n, int const nrhs,
traits::complex_f* a, int const lda, int* ipiv,
traits::complex_f* b, int const ldb,
traits::complex_f* w, int const lw, int* info)
{
LAPACK_CHESV (&uplo, &n, &nrhs,
traits::complex_ptr (a), &lda, ipiv,
traits::complex_ptr (b), &ldb,
traits::complex_ptr (w), &lw, info);
}
inline
void hesv (char const uplo, int const n, int const nrhs,
traits::complex_d* a, int const lda, int* ipiv,
traits::complex_d* b, int const ldb,
traits::complex_d* w, int const lw, int* info)
{
LAPACK_ZHESV (&uplo, &n, &nrhs,
traits::complex_ptr (a), &lda, ipiv,
traits::complex_ptr (b), &ldb,
traits::complex_ptr (w), &lw, info);
}
template <typename HermA, typename MatrB, typename IVec, typename Work>
inline
int hesv (char const ul, HermA& a, IVec& i, MatrB& b, Work& w) {
int const n = traits::matrix_size1 (a);
assert (n == traits::matrix_size2 (a));
assert (n == traits::matrix_size1 (b));
assert (n == traits::vector_size (i));
int info;
hesv (ul, n, traits::matrix_size2 (b),
traits::matrix_storage (a),
traits::leading_dimension (a),
traits::vector_storage (i),
traits::matrix_storage (b),
traits::leading_dimension (b),
traits::vector_storage (w),
traits::vector_size (w),
&info);
return info;
}
}
template <typename HermA, typename MatrB, typename IVec, typename Work>
inline
int hesv (char const ul, HermA& a, IVec& i, MatrB& b, Work& w) {
assert (ul == 'U' || ul == 'L');
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<HermA>::matrix_structure,
traits::general_t
>::value));
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<MatrB>::matrix_structure,
traits::general_t
>::value));
#endif
int const lw = traits::vector_size (w);
assert (lw >= 1);
return detail::hesv (ul, a, i, b, w);
}
template <typename HermA, typename MatrB, typename IVec, typename Work>
inline
int hesv (HermA& a, IVec& i, MatrB& b, Work& w) {
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<HermA>::matrix_structure,
traits::hermitian_t
>::value));
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<MatrB>::matrix_structure,
traits::general_t
>::value));
#endif
int const lw = traits::vector_size (w);
assert (lw >= 1);
char uplo = traits::matrix_uplo_tag (a);
return detail::hesv (uplo, a, i, b, w);
}
template <typename HermA, typename MatrB>
inline
int hesv (char const ul, HermA& a, MatrB& b) {
// with 'internal' pivot and work vectors
assert (ul == 'U' || ul == 'L');
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<HermA>::matrix_structure,
traits::general_t
>::value));
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<MatrB>::matrix_structure,
traits::general_t
>::value));
#endif
int const n = traits::matrix_size1 (a);
int info = -101;
traits::detail::array<int> i (n);
if (i.valid()) {
info = -102;
int lw = hetrf_work ('O', ul, a);
assert (lw >= 1); // paranoia ?
#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
typedef typename traits::matrix_traits<HermA>::value_type val_t;
#else
typedef typename HermA::value_type val_t;
#endif
traits::detail::array<val_t> w (lw);
if (w.valid())
info = detail::hesv (ul, a, i, b, w);
}
return info;
}
template <typename HermA, typename MatrB>
inline
int hesv (HermA& a, MatrB& b) {
// with 'internal' pivot and work vectors
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<HermA>::matrix_structure,
traits::hermitian_t
>::value));
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<MatrB>::matrix_structure,
traits::general_t
>::value));
#endif
int const n = traits::matrix_size1 (a);
char uplo = traits::matrix_uplo_tag (a);
int info = -101;
traits::detail::array<int> i (n);
if (i.valid()) {
info = -102;
int lw = hetrf_work ('O', a);
assert (lw >= 1); // paranoia ?
#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
typedef typename traits::matrix_traits<HermA>::value_type val_t;
#else
typedef typename HermA::value_type val_t;
#endif
traits::detail::array<val_t> w (lw);
w.resize (lw);
if (w.valid())
info = detail::hesv (uplo, a, i, b, w);
}
return info;
}
/*
* hetrf() computes the factorization of a Hermitian matrix A using
* the Bunch-Kaufman diagonal pivoting method. The form of the
* factorization is
* A = U * D * U^H or A = L * D * L^H
* where U (or L) is a product of permutation and unit upper (lower)
* triangular matrices, and D is Hermitian and block diagonal with
* 1-by-1 and 2-by-2 diagonal blocks.
*/
namespace detail {
inline
void hetrf (char const uplo, int const n,
traits::complex_f* a, int const lda, int* ipiv,
traits::complex_f* w, int const lw, int* info)
{
LAPACK_CHETRF (&uplo, &n,
traits::complex_ptr (a), &lda, ipiv,
traits::complex_ptr (w), &lw, info);
}
inline
void hetrf (char const uplo, int const n,
traits::complex_d* a, int const lda, int* ipiv,
traits::complex_d* w, int const lw, int* info)
{
LAPACK_ZHETRF (&uplo, &n,
traits::complex_ptr (a), &lda, ipiv,
traits::complex_ptr (w), &lw, info);
}
template <typename HermA, typename IVec, typename Work>
inline
int hetrf (char const ul, HermA& a, IVec& i, Work& w) {
int const n = traits::matrix_size1 (a);
assert (n == traits::matrix_size2 (a));
assert (n == traits::vector_size (i));
int info;
hetrf (ul, n, traits::matrix_storage (a),
traits::leading_dimension (a),
traits::vector_storage (i),
traits::vector_storage (w),
traits::vector_size (w),
&info);
return info;
}
}
template <typename HermA, typename IVec, typename Work>
inline
int hetrf (char const ul, HermA& a, IVec& i, Work& w) {
assert (ul == 'U' || ul == 'L');
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<HermA>::matrix_structure,
traits::general_t
>::value));
#endif
int const lw = traits::vector_size (w);
assert (lw >= 1);
return detail::hetrf (ul, a, i, w);
}
template <typename HermA, typename IVec, typename Work>
inline
int hetrf (HermA& a, IVec& i, Work& w) {
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<HermA>::matrix_structure,
traits::hermitian_t
>::value));
#endif
int const lw = traits::vector_size (w);
assert (lw >= 1);
char uplo = traits::matrix_uplo_tag (a);
return detail::hetrf (uplo, a, i, w);
}
template <typename HermA, typename Ivec>
inline
int hetrf (char const ul, HermA& a, Ivec& i) {
// with 'internal' work vector
assert (ul == 'U' || ul == 'L');
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<HermA>::matrix_structure,
traits::general_t
>::value));
#endif
int info = -101;
int lw = hetrf_work ('O', ul, a);
assert (lw >= 1); // paranoia ?
#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
typedef typename traits::matrix_traits<HermA>::value_type val_t;
#else
typedef typename HermA::value_type val_t;
#endif
traits::detail::array<val_t> w (lw);
if (w.valid())
info = detail::hetrf (ul, a, i, w);
return info;
}
template <typename HermA, typename Ivec>
inline
int hetrf (HermA& a, Ivec& i) {
// with 'internal' work vector
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<HermA>::matrix_structure,
traits::hermitian_t
>::value));
#endif
char uplo = traits::matrix_uplo_tag (a);
int info = -101;
int lw = hetrf_work ('O', a);
assert (lw >= 1); // paranoia ?
#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
typedef typename traits::matrix_traits<HermA>::value_type val_t;
#else
typedef typename HermA::value_type val_t;
#endif
traits::detail::array<val_t> w (lw);
if (w.valid())
info = detail::hetrf (uplo, a, i, w);
return info;
}
/*
* hetrs() solves a system of linear equations A*X = B with
* a Hermitian matrix A using the factorization
* A = U * D * U^H or A = L * D * L^H
* computed by hetrf().
*/
namespace detail {
inline
void hetrs (char const uplo, int const n, int const nrhs,
traits::complex_f const* a, int const lda,
int const* ipiv,
traits::complex_f* b, int const ldb, int* info)
{
LAPACK_CHETRS (&uplo, &n, &nrhs,
traits::complex_ptr (a), &lda, ipiv,
traits::complex_ptr (b), &ldb, info);
}
inline
void hetrs (char const uplo, int const n, int const nrhs,
traits::complex_d const* a, int const lda,
int const* ipiv,
traits::complex_d* b, int const ldb, int* info)
{
LAPACK_ZHETRS (&uplo, &n, &nrhs,
traits::complex_ptr (a), &lda, ipiv,
traits::complex_ptr (b), &ldb, info);
}
template <typename HermA, typename MatrB, typename IVec>
inline
int hetrs (char const ul, HermA const& a, IVec const& i, MatrB& b) {
int const n = traits::matrix_size1 (a);
assert (n == traits::matrix_size2 (a));
assert (n == traits::matrix_size1 (b));
assert (n == traits::vector_size (i));
int info;
hetrs (ul, n, traits::matrix_size2 (b),
#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
traits::matrix_storage (a),
#else
traits::matrix_storage_const (a),
#endif
traits::leading_dimension (a),
#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
traits::vector_storage (i),
#else
traits::vector_storage_const (i),
#endif
traits::matrix_storage (b),
traits::leading_dimension (b), &info);
return info;
}
}
template <typename HermA, typename MatrB, typename IVec>
inline
int hetrs (char const ul, HermA const& a, IVec const& i, MatrB& b) {
assert (ul == 'U' || ul == 'L');
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<HermA>::matrix_structure,
traits::general_t
>::value));
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<MatrB>::matrix_structure,
traits::general_t
>::value));
#endif
return detail::hetrs (ul, a, i, b);
}
template <typename HermA, typename MatrB, typename IVec>
inline
int hetrs (HermA const& a, IVec const& i, MatrB& b) {
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<HermA>::matrix_structure,
traits::hermitian_t
>::value));
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<MatrB>::matrix_structure,
traits::general_t
>::value));
#endif
char uplo = traits::matrix_uplo_tag (a);
return detail::hetrs (uplo, a, i, b);
}
// TO DO: hetri
}
}}}
#endif

View File

@@ -1,261 +0,0 @@
/*
*
* Copyright (c) Toon Knapen & Kresimir Fresl 2003
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* KF acknowledges the support of the Faculty of Civil Engineering,
* University of Zagreb, Croatia.
*
*/
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_HPSV_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_HPSV_HPP
#include <boost/numeric/bindings/traits/type_traits.hpp>
#include <boost/numeric/bindings/traits/traits.hpp>
#include <boost/numeric/bindings/lapack/lapack.h>
#include <boost/numeric/bindings/traits/detail/array.hpp>
#include <boost/numeric/bindings/traits/detail/utils.hpp>
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
# include <boost/static_assert.hpp>
# include <boost/type_traits/is_same.hpp>
#endif
#include <cassert>
namespace boost { namespace numeric { namespace bindings {
namespace lapack {
/////////////////////////////////////////////////////////////////////
//
// system of linear equations A * X = B
// with A Hermitian indefinite matrix stored in packed format
//
/////////////////////////////////////////////////////////////////////
/*
* hpsv() computes the solution to a system of linear equations
* A * X = B, where A is an N-by-N Hermitian matrix in packed
* storage and X and B are N-by-NRHS matrices.
*
* The diagonal pivoting method is used to factor A as
* A = U * D * U^H, if UPLO = 'U',
* A = L * D * L^H, if UPLO = 'L',
* where U (or L) is a product of permutation and unit upper
* (lower) triangular matrices, and D is Hermitian and block
* diagonal with 1-by-1 and 2-by-2 diagonal blocks. The factored
* form of A is then used to solve the system of equations A * X = B.
*/
namespace detail {
inline
void hpsv (char const uplo, int const n, int const nrhs,
traits::complex_f* ap, int* ipiv,
traits::complex_f* b, int const ldb, int* info)
{
LAPACK_CHPSV (&uplo, &n, &nrhs,
traits::complex_ptr (ap), ipiv,
traits::complex_ptr (b), &ldb, info);
}
inline
void hpsv (char const uplo, int const n, int const nrhs,
traits::complex_d* ap, int* ipiv,
traits::complex_d* b, int const ldb, int* info)
{
LAPACK_ZHPSV (&uplo, &n, &nrhs,
traits::complex_ptr (ap), ipiv,
traits::complex_ptr (b), &ldb, info);
}
template <typename HermA, typename MatrB, typename IVec>
inline
int hpsv (HermA& a, IVec& i, MatrB& b) {
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<HermA>::matrix_structure,
traits::hermitian_packed_t
>::value));
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<MatrB>::matrix_structure,
traits::general_t
>::value));
#endif
int const n = traits::matrix_size1 (a);
assert (n == traits::matrix_size2 (a));
assert (n == traits::matrix_size1 (b));
char uplo = traits::matrix_uplo_tag (a);
int info;
hpsv (uplo, n, traits::matrix_size2 (b),
traits::matrix_storage (a),
traits::vector_storage (i),
traits::matrix_storage (b),
traits::leading_dimension (b),
&info);
return info;
}
}
template <typename HermA, typename MatrB, typename IVec>
inline
int hpsv (HermA& a, IVec& i, MatrB& b) {
assert (traits::matrix_size1 (a) == traits::vector_size (i));
return detail::hpsv (a, i, b);
}
template <typename HermA, typename MatrB>
inline
int hpsv (HermA& a, MatrB& b) {
// with 'internal' pivot vector
int info = -101;
traits::detail::array<int> i (traits::matrix_size1 (a));
if (i.valid())
info = detail::hpsv (a, i, b);
return info;
}
/*
* hptrf() computes the factorization of a Hermitian matrix A
* in packed storage using the Bunch-Kaufman diagonal pivoting
* method. The form of the factorization is
* A = U * D * U^H or A = L * D * L^H
* where U (or L) is a product of permutation and unit upper (lower)
* triangular matrices, and D is Hermitian and block diagonal with
* 1-by-1 and 2-by-2 diagonal blocks.
*/
namespace detail {
inline
void hptrf (char const uplo, int const n,
traits::complex_f* ap, int* ipiv, int* info)
{
LAPACK_CHPTRF (&uplo, &n, traits::complex_ptr (ap), ipiv, info);
}
inline
void hptrf (char const uplo, int const n,
traits::complex_d* ap, int* ipiv, int* info)
{
LAPACK_ZHPTRF (&uplo, &n, traits::complex_ptr (ap), ipiv, info);
}
template <typename HermA, typename IVec, typename Work>
inline
int hptrf (char const ul, HermA& a, IVec& i, Work& w, int const lw) {
}
}
template <typename HermA, typename IVec>
inline
int hptrf (HermA& a, IVec& i) {
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<HermA>::matrix_structure,
traits::hermitian_packed_t
>::value));
#endif
int const n = traits::matrix_size1 (a);
assert (n == traits::matrix_size2 (a));
assert (n == traits::vector_size (i));
char uplo = traits::matrix_uplo_tag (a);
int info;
detail::hptrf (uplo, n, traits::matrix_storage (a),
traits::vector_storage (i), &info);
return info;
}
/*
* hptrs() solves a system of linear equations A*X = B with
* a Hermitian matrix A in packed storage using the factorization
* A = U * D * U^H or A = L * D * L^H
* computed by hptrf().
*/
namespace detail {
inline
void hptrs (char const uplo, int const n, int const nrhs,
traits::complex_f const* ap, int const* ipiv,
traits::complex_f* b, int const ldb, int* info)
{
LAPACK_CHPTRS (&uplo, &n, &nrhs,
traits::complex_ptr (ap), ipiv,
traits::complex_ptr (b), &ldb, info);
}
inline
void hptrs (char const uplo, int const n, int const nrhs,
traits::complex_d const* ap, int const* ipiv,
traits::complex_d* b, int const ldb, int* info)
{
LAPACK_ZHPTRS (&uplo, &n, &nrhs,
traits::complex_ptr (ap), ipiv,
traits::complex_ptr (b), &ldb, info);
}
}
template <typename HermA, typename MatrB, typename IVec>
inline
int hptrs (HermA const& a, IVec const& i, MatrB& b) {
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<HermA>::matrix_structure,
traits::hermitian_packed_t
>::value));
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<MatrB>::matrix_structure,
traits::general_t
>::value));
#endif
int const n = traits::matrix_size1 (a);
assert (n == traits::matrix_size2 (a));
assert (n == traits::matrix_size1 (b));
assert (n == traits::vector_size (i));
char uplo = traits::matrix_uplo_tag (a);
int info;
detail::hptrs (uplo, n, traits::matrix_size2 (b),
#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
traits::matrix_storage (a),
traits::vector_storage (i),
#else
traits::matrix_storage_const (a),
traits::vector_storage_const (i),
#endif
traits::matrix_storage (b),
traits::leading_dimension (b),
&info);
return info;
}
// TO DO: hptri
}
}}}
#endif

View File

@@ -1,302 +0,0 @@
/*
*
* Copyright Jeremy Conlin 2008
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
*/
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_HSEQR_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_HSEQR_HPP
#include <iostream>
#include <complex>
#include <boost/numeric/bindings/traits/traits.hpp>
#include <boost/numeric/bindings/traits/matrix_traits.hpp>
#include <boost/numeric/bindings/traits/type_traits.hpp>
#include <boost/numeric/bindings/lapack/lapack.h>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/traits/detail/array.hpp>
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
# include <boost/static_assert.hpp>
# include <boost/type_traits.hpp>
#endif
namespace boost { namespace numeric { namespace bindings {
namespace lapack {
///////////////////////////////////////////////////////////////////
//
// Compute eigenvalues of an Hessenberg matrix, H.
//
///////////////////////////////////////////////////////////////////
/*
* hseqr() computes the eigenvalues of a Hessenberg matrix H
* and, optionally, the matrices T and Z from the Schur decomposition
* H = Z U Z**T, where U is an upper quasi-triangular matrix (the
* Schur form), and Z is the orthogonal matrix of Schur vectors.
*
* Optionally Z may be postmultiplied into an input orthogonal
* matrix Q so that this routine can give the Schur factorization
* of a matrix A which has been reduced to the Hessenberg form H
* by the orthogonal matrix Q: A = Q*H*Q**T = (QZ)*U*(QZ)**T.
*
* There are two forms of the hseqr function:
*
* int hseqr( const char job, A& H, W& w)
* int hseqr( const char job, const char compz, A& H, W& w, Z& z)
*
* The first form does not compute Schur vectors and is equivelant to
* setting compz = 'N' in the second form. hseqr returns a '0' if the
* computation is successful.
*
* job.
* = 'E': compute eigenvalues only
* = 'S': compute eigenvalues and the Schur form U
*
* compz. (input)
* = 'N': no Schur vectors are computed; Equivalent to using the
* first form of the hseqr function.
* = 'I': Z is initialized to the unit matrix and the matrix Z
* of Schur vectors of H is returned;
* = 'V': Z must contain an orthogonal matrix Q on entry, and
* the product Q*Z is returned.
*
* H is the Hessenberg matrix whose eigenpairs you're interested
* in. (input/output) On exit, if computation is successful and
* job = 'S', then H contains the
* upper quasi-triangular matrix U from the Schur decomposition
* (the Schur form); 2-by-2 diagonal blocks (corresponding to
* complex conjugate pairs of eigenvalues) are returned in
* standard form, with H(i,i) = H(i+1,i+1) and
* H(i+1,i)*H(i,i+1) < 0. If computation is successful and
* job = 'E', the contents of H are unspecified on exit.
*
* w (output) contains the computed eigenvalues of H which is the diagonal
* of U. Must be a complex object.
*
* Z. (input/output)
* If compz = 'N', Z is not referenced.
* If compz = 'I', on entry Z need not be set and on exit,
* if computation is successful, Z contains the orthogonal matrix Z of the Schur
* vectors of H. If compz = 'V', on entry Z must contain an
* N-by-N matrix Q, which is assumed to be equal to the unit
* matrix . On exit, if computation is successful, Z contains Q*Z.
*
*/
namespace detail {
// float
inline
int hseqr_backend(const char* job, const char* compz, const int* n,
const int ilo, const int ihi, float* H, const int ldH,
float* wr, float* wi, float* Z, const int ldz, float* work,
const int* lwork){
int info;
// std::cout << "I'm inside lapack::detail::hseqr_backend for floats"
// << std::endl;
LAPACK_SHSEQR(job, compz, n, &ilo, &ihi, H, &ldH, wr, wi,
Z, &ldz, work, lwork, &info);
return info;
}
// double
inline
int hseqr_backend(const char* job, const char* compz, const int* n,
const int ilo, const int ihi, double* H, const int ldH,
double* wr, double* wi, double* Z, const int ldz, double* work,
const int* lwork){
int info;
// std::cout << "I'm inside lapack::detail::hseqr_backend for doubles"
// << std::endl;
LAPACK_DHSEQR(job, compz, n, &ilo, &ihi, H, &ldH, wr, wi,
Z, &ldz, work, lwork, &info);
return info;
}
// complex<float>
inline
int hseqr_backend(const char* job, const char* compz, int* n,
const int ilo, const int ihi, traits::complex_f* H, const int ldH,
traits::complex_f* w, traits::complex_f* Z, int ldz,
traits::complex_f* work, const int* lwork){
int info;
// std::cout << "I'm inside lapack::detail::hseqr_backend for complex<float>"
// << std::endl;
LAPACK_CHSEQR(job, compz, n, &ilo, &ihi,
traits::complex_ptr(H), &ldH,
traits::complex_ptr(w),
traits::complex_ptr(Z), &ldz,
traits::complex_ptr(work), lwork, &info);
return info;
}
// complex<double>
inline
int hseqr_backend(const char* job, const char* compz, int* n,
const int ilo, const int ihi, traits::complex_d* H, const int ldH,
traits::complex_d* w, traits::complex_d* Z, int ldz,
traits::complex_d* work, const int* lwork){
int info;
// std::cout << "I'm inside lapack::detail::hseqr_backend for complex<double>"
// << std::endl;
LAPACK_ZHSEQR(job, compz, n, &ilo, &ihi,
traits::complex_ptr(H), &ldH,
traits::complex_ptr(w),
traits::complex_ptr(Z), &ldz,
traits::complex_ptr(work), lwork, &info);
return info;
}
template <int N>
struct Hseqr{};
template <>
struct Hseqr< 1 >{
template < typename A, typename W, typename V>
int operator() ( const char job, const char compz, A& H, W& w, V& Z ){
// std::cout << "Inside Hseqr<1>." << std::endl;
int n = traits::matrix_size1(H);
typedef typename A::value_type value_type;
traits::detail::array<value_type> wr(n);
traits::detail::array<value_type> wi(n);
// workspace query
int lwork = -1;
value_type work_temp;
int result = detail::hseqr_backend(&job, &compz, &n, 1, n,
traits::matrix_storage(H),
traits::leading_dimension(H),
wr.storage(), wi.storage(),
traits::matrix_storage(Z),
traits::leading_dimension(Z),
&work_temp, &lwork);
if( result !=0 ) return result;
lwork = (int) work_temp;
traits::detail::array<value_type> work(lwork);
result = detail::hseqr_backend(&job, &compz, &n, 1, n,
traits::matrix_storage(H),
traits::leading_dimension(H),
wr.storage(), wi.storage(),
traits::matrix_storage(Z),
traits::leading_dimension(Z),
work.storage(), &lwork);
for (int i = 0; i < n; i++)
w[i] = std::complex<value_type>(wr[i], wi[i]);
return result;
}
};
template <>
struct Hseqr< 2 >{
template < typename A, typename W, typename V>
int operator() ( const char job, const char compz, A& H, W& w, V& Z ){
// std::cout << "Inside Hseqr<2>." << std::endl;
int n = traits::matrix_size1(H);
typedef typename A::value_type value_type;
// workspace query
int lwork = -1;
value_type work_temp;
int result = detail::hseqr_backend(&job, &compz, &n, 1, n,
traits::matrix_storage(H),
traits::leading_dimension(H),
traits::vector_storage(w),
traits::matrix_storage(Z), traits::leading_dimension(Z),
&work_temp, &lwork);
if( result !=0 ) return result;
lwork = (int) std::real(work_temp);
traits::detail::array<value_type> work(lwork);
result = detail::hseqr_backend(&job, &compz, &n, 1, n,
traits::matrix_storage(H),
traits::leading_dimension(H),
traits::vector_storage(w),
traits::matrix_storage(Z), traits::leading_dimension(Z),
work.storage(), &lwork);
return result;
}
};
template < typename A, typename W, typename V>
int hseqr( const char job, const char compz, A& H, W& w, V& Z ){
// std::cout << "I'm inside lapack::detail::hseqr." << std::endl;
assert ( job == 'E' || job == 'S' );
assert ( compz == 'N' || compz == 'I' || compz == 'V' );
typedef typename A::value_type value_type;
int result = detail::Hseqr< n_workspace_args<value_type>::value >()(
job, compz, H, w, Z);
return result;
}
} // namespace detail
// Compute eigenvalues without the Schur vectors
template < typename A, typename W>
int hseqr( const char job, A& H, W& w){
// input checking
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<A>::matrix_structure,
traits::general_t
>::value));
#endif
#ifndef NDEBUG
int const n = traits::matrix_size1(H);
#endif
typedef typename A::value_type value_type;
typedef typename W::value_type complex_value_type;
assert(traits::matrix_size2(H) == n); // Square matrix
assert(traits::vector_size(w) == n);
ublas::matrix<value_type, ublas::column_major> Z(1,1);
return detail::hseqr( job, 'N', H, w, Z );
}
// Compute eigenvalues and the Schur vectors
template < typename A, typename W, typename Z>
int hseqr( const char job, const char compz, A& H, W& w, Z& z){
// input checking
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
BOOST_STATIC_ASSERT((boost::is_same<
typename traits::matrix_traits<A>::matrix_structure,
traits::general_t
>::value));
#endif
#ifndef NDEBUG
int const n = traits::matrix_size1(H);
#endif
typedef typename A::value_type value_type;
assert(traits::matrix_size2(H) == n); // Square matrix
assert(traits::vector_size(w) == n);
assert(traits::matrix_size2(z) == n);
return detail::hseqr( job, compz, H, w, z );
}
}
}}}
#endif

Some files were not shown because too many files have changed in this diff Show More