overhauled physics engine
This commit is contained in:
+8
-1
@@ -28,7 +28,6 @@ set(TTFPARSER_ROOT ${EXTERNAL_ROOT}/ttf-parser)
|
||||
set(FREETYPE_ROOT ${EXTERNAL_ROOT}/freetype)
|
||||
set(SPIRV_ROOT ${EXTERNAL_ROOT}/SPIRV-Cross)
|
||||
set(ENTT_ROOT ${EXTERNAL_ROOT}/entt)
|
||||
set(NLOPT_ROOT ${EXTERNAL_ROOT}/nlopt)
|
||||
set(ODEINT_ROOT ${EXTERNAL_ROOT}/odeint)
|
||||
set(THREADPOOL_ROOT ${EXTERNAL_ROOT}/thread-pool)
|
||||
set(ZLIB_ROOT ${EXTERNAL_ROOT}/zlib)
|
||||
@@ -105,6 +104,7 @@ if(MSVC)
|
||||
target_compile_options(Engine PUBLIC /Zi /MP14 /W4 /DEBUG "/WX-")
|
||||
target_sources(Engine INTERFACE
|
||||
$<BUILD_INTERFACE:Seele.natvis>
|
||||
$<BUILD_INTERFACE:${Seele_DIR}/Seele.natvis>
|
||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_PREFIX}/Seele.natvis>
|
||||
)
|
||||
install(FILES
|
||||
@@ -174,3 +174,10 @@ install(
|
||||
DESTINATION
|
||||
${CMAKE_INSTALL_PREFIX}
|
||||
)
|
||||
|
||||
install(
|
||||
DIRECTORY
|
||||
${CMAKE_SOURCE_DIR}/res
|
||||
DESTINATION
|
||||
${CMAKE_INSTALL_PREFIX}
|
||||
)
|
||||
@@ -50,7 +50,7 @@ add_subdirectory(${ENTT_ROOT})
|
||||
#--------------thread-pool------------------------------
|
||||
add_subdirectory(${THREADPOOL_ROOT})
|
||||
|
||||
target_compile_options(ThreadPool INTERFACE "/WX-")
|
||||
target_compile_options(ThreadPool INTERFACE "/W0")
|
||||
|
||||
#--------------SLang------------------------------
|
||||
string(TOLOWER release_${CMAKE_PLATFORM} SLANG_CONFIG)
|
||||
|
||||
Vendored
+15
@@ -0,0 +1,15 @@
|
||||
--------------------------------------------------
|
||||
Copyright (C) 1995-2011 SDPA Project
|
||||
--------------------------------------------------
|
||||
|
||||
We appreciate your comments, suggestions, and questions about SDP
|
||||
and/or the SDPA software. We also consider questions such as "I can
|
||||
not install the SDPA on my computer," "I can not formulate my problem
|
||||
in SDPA format," "I found a bug in the software," etc.
|
||||
|
||||
|
||||
To contact SDPA project, refer the following Web page.
|
||||
https://sdpa.sourceforge.net/contact.html
|
||||
|
||||
The member list of SDPA project is available there.
|
||||
|
||||
Vendored
+340
@@ -0,0 +1,340 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, 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 or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
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 give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
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 Program or any portion
|
||||
of it, thus forming a work based on the Program, 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) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
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 Program, 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 Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) 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; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, 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 executable. However, as a
|
||||
special exception, the source code 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.
|
||||
|
||||
If distribution of executable or 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 counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program 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.
|
||||
|
||||
5. 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 Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program 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 to
|
||||
this License.
|
||||
|
||||
7. 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 Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program 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 Program.
|
||||
|
||||
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.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program 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.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the 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 Program
|
||||
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 Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, 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
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "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 PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. 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 PROGRAM 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 PROGRAM (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 PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
||||
Vendored
+10
@@ -0,0 +1,10 @@
|
||||
SDPA-C 7.3.8 from SDPA-C 6 / 2013-10-21 Makoto Yamashita
|
||||
* Based on SDPA 7.3.8
|
||||
* Employ CHOLMOD for sparse Cholesky factoization
|
||||
to the variable matrices
|
||||
* Efficient computation for the Schur complement matrix
|
||||
* New callable library
|
||||
* New Matlab/Octave interface
|
||||
* Multiple-threaded computation
|
||||
|
||||
|
||||
Vendored
+160
@@ -0,0 +1,160 @@
|
||||
|
||||
SDPA-C 7.3.X Install Manual
|
||||
|
||||
[Copyright (C) 2004-2013 SDPA Project]
|
||||
|
||||
This text explains how to install SDPA-C.
|
||||
If you have questions on the installation,
|
||||
please contact us from
|
||||
http://sdpa.sourceforge.net/contact.html
|
||||
|
||||
The user-manual of SDPA is available for SDPA-C, and can be downloaded at
|
||||
https://sourceforge.net/projects/sdpa/files/sdpa/sdpa.7.1.1.manual.20080618.pdf/download
|
||||
|
||||
--- index ------------------------------------
|
||||
|
||||
1. Install the SDPA-C
|
||||
2. Compile callable-library example [optional]
|
||||
3. Compile Matlab Interface [optional]
|
||||
4. Difference from SDPA
|
||||
5. If you have some trouble
|
||||
|
||||
----------------------------------------------
|
||||
|
||||
|
||||
1. Install the SDPA-C
|
||||
|
||||
(1) Check your environment
|
||||
|
||||
Requirement: wget, git
|
||||
Recommendation: gcc (>= 4.2), g++ (>= 4.2), gfortran (>=4.2)
|
||||
|
||||
We have checked the compilation on RedHat Linux (version 6)
|
||||
and Debian (wheezy).
|
||||
Other C/C++/Fortran compilers than gcc/g++/gfortran may be
|
||||
available, but we have not tested them.
|
||||
|
||||
(2) Download the SDPA from the SDPA Homepage
|
||||
|
||||
http://sdpa.sourceforge.net/download.html
|
||||
|
||||
You can get the sdpa-c_7.3.X.tar.gz, then unpack the file
|
||||
$ tar xzf sdpa-c_7.3.X.tar.gz
|
||||
You will find the directory 'sdpa-c'.
|
||||
$ cd sdpa-c
|
||||
|
||||
(3) Edit make.inc
|
||||
|
||||
At least you should check 'sdpac_dir'.
|
||||
In the default setting, sdpac_dir is $(HOME)/sdpa-c.
|
||||
In other words, the default setting assumes
|
||||
you unpacked the downloaded file in your home directory.
|
||||
|
||||
(4) Compile SDPA-C
|
||||
|
||||
$ make all
|
||||
will compile SuiteSparse, MUMPS, OpenBLAS, then SDPA-C.
|
||||
|
||||
If you want compile them step by step,
|
||||
$ make SuiteSparse
|
||||
$ make MUMPS
|
||||
$ make OpenBLAS
|
||||
$ make sdpa-c
|
||||
|
||||
|
||||
(5) Test SDPA-C
|
||||
Try the following command to execute sdpa
|
||||
$ cd $HOME/sdpa-c
|
||||
$ ./sdpa-c
|
||||
Then you will see message from SDPA and can check command line options.
|
||||
To solve input dat-s and write its result,
|
||||
$ ./sdpa example1.dat-s example1.result
|
||||
|
||||
If you specify the number of threads with the SDPA-C,
|
||||
set OMP_NUM_THREADS environment variable(ex. export OMP_NUM_THREADS=4).
|
||||
|
||||
----------------------------------------------
|
||||
2. Compile callable-library example (optional)
|
||||
|
||||
To compile callable-library example, use 'make' command
|
||||
in 'libexample' directory
|
||||
$ cd $HOME/sdpa-c/libexample
|
||||
$ make
|
||||
|
||||
The details of callable-library can be found in SDPA user manual.
|
||||
|
||||
----------------------------------------------
|
||||
3. Compile Matlab Interface (optional)
|
||||
|
||||
To compile the Matlab interface, use 'make matlab' command.
|
||||
$ cd $HOME/sdpa-c
|
||||
$ make matlab
|
||||
|
||||
If you use Octave instead of Matlab, then
|
||||
$ cd $HOME/sdpa-c
|
||||
$ make octave
|
||||
|
||||
Since the usage of this Matlab Interface as SDPA-M 6.2.0,
|
||||
SDPA-M 6.2.0 manual is very useful.
|
||||
(https://sourceforge.net/projects/sdpa/files/sdpa-m/sdpamManual.pdf/download)
|
||||
In addition, the file 'mex/CommandList.txt' summarizes
|
||||
each command.
|
||||
|
||||
|
||||
When you have trouble with SDPA-M(Matlab environment),
|
||||
the following command will display useful messages.
|
||||
|
||||
$ matlab -Dgdb
|
||||
[On gdb environment]
|
||||
(gdb) run -nodisplay
|
||||
[On Matlab environment]
|
||||
>> (Call SDPA-M by sdpam or sedumiwrap)
|
||||
If Matlab aborts, try the following command in gdb environment.
|
||||
(gdb) where
|
||||
The command 'where' will display what happened.
|
||||
To exit gdb environment,
|
||||
(gdb) quit
|
||||
|
||||
In some case, the segmentation fault may be avoided by
|
||||
$ export LD_PRELOAD=/usr/lib/gcc/x86_64-linux-gnu/4.4/libgfortran.so:$LD_PRELOAD
|
||||
$ export LD_PRELOAD=/usr/lib/gcc/x86_64-linux-gnu/4.4/libstdc++.so:$LD_PRELOAD
|
||||
$ export LD_PRELOAD=/usr/lib/gcc/x86_64-linux-gnu/4.4/libgcc_s.so:$LD_PRELOAD
|
||||
$ matlab
|
||||
In particular, when the gcc version is higher than the version Matlab
|
||||
assumes, Matlab sometimes can not load appropriate shared libraries.
|
||||
The command above load the libraries before Matlab launches.
|
||||
|
||||
-------------------------------------------------------
|
||||
4. Deference from SDPA
|
||||
|
||||
(1) Since SDPA-C employs the completion method, which extensively
|
||||
uses the structural sparsity, the SDPA dense format is not acceptable.
|
||||
More precisely, example1.dat-s is available while example1.dat is not.
|
||||
|
||||
(2) In the callable library, some function mainly related to the dense
|
||||
input file are not available.
|
||||
In addition, the function SDPA::terminate() is renamed as
|
||||
SDPA::finalize().
|
||||
In libexample directory, the difference in example1,2,5.cpp from SDPA
|
||||
is only terminate() to finalize().
|
||||
However, the example3,4,6.cpp in SDPA contained the functions
|
||||
which are not available in SDPA-C. We removed these examples
|
||||
from the SDPA-C package.
|
||||
|
||||
(3) param.sdpa is renamed as param.sdpaC.
|
||||
|
||||
(4) The matlab interface only contains the mex functions of SDPA-C.
|
||||
If you want to read the SDPA sparse format, you should employ
|
||||
such routines from SDPA. We suggest you add the paths of both SDPA
|
||||
and SDPA-C to the Matlab search path.
|
||||
|
||||
-------------------------------------------------------
|
||||
5. If you have some trouble
|
||||
|
||||
If some bugs are found or you encounter some trouble
|
||||
when you are compiling SDPA, please let us know from
|
||||
http://sdpa.sourceforge.net/contact.html
|
||||
|
||||
In particular, attaching error messages and/or 'config.log' file
|
||||
is very useful to let us understand your situation.
|
||||
|
||||
Vendored
+100
@@ -0,0 +1,100 @@
|
||||
|
||||
## This is Makefile for SDPA-C
|
||||
|
||||
## Requirement :: wget, git
|
||||
## Recommendation :: gcc (>= 4.2), g++ (>=4.2), gfortran (>= 4.2),
|
||||
|
||||
## Before the compilation, examine the file 'make.inc'
|
||||
|
||||
## To compile SDPA-C, 'make all'
|
||||
## This will compile SuiteSparse, MUMPS, OpenBLAS, then SDPA-C
|
||||
## To compile mex, 'make matlab' or 'make octave'
|
||||
|
||||
-include make.inc
|
||||
-include make.obj
|
||||
.PHONY: SuiteSparse MUMPS OpenBLAS
|
||||
|
||||
all: $(sdpac_exe)
|
||||
|
||||
matlab: all
|
||||
(cd mex; make DEVELOPEMENT_STAGE=1)
|
||||
@echo === Add "$(sdpac_dir)/mex" to your Matlab path. ===
|
||||
|
||||
octave: all
|
||||
(cd mex; make DEVELOPEMENT_STAGE=1 COMPILE_ENVIRONMENT=octave)
|
||||
@echo === Add "$(sdpac_dir)/mex" to your octave path. ===
|
||||
|
||||
$(sdpac_exe): SuiteSparse MUMPS OpenBLAS $(sdpac_lib) sdpa_exe.o
|
||||
$(CXX) $(CXXFLAGS) -o $@ sdpa_exe.o $(sdpac_lib) $(sdpac_all_lib)
|
||||
|
||||
$(sdpac_lib): $(OBJ)
|
||||
rm -f $@
|
||||
ar r $@ $(OBJ)
|
||||
ranlib $@
|
||||
|
||||
.cpp.o:
|
||||
$(CXX) $(CXXFLAGS) -c -o $@ -I. $(sdpac_all_include) \
|
||||
-DVERSION=$(SDPAC_VERSION) $<
|
||||
|
||||
SuiteSparse:$(suitesparse_lib)
|
||||
$(suitesparse_lib):
|
||||
(cd $(sdpac_dir); \
|
||||
rm -rf SuiteSparse; \
|
||||
wget http://faculty.cse.tamu.edu/davis/SuiteSparse/SuiteSparse-$(suitesparse_ver).tar.gz; \
|
||||
tar xzf SuiteSparse-$(suitesparse_ver).tar.gz; \
|
||||
rm -f SuiteSparse-$(suitesparse_ver).tar.gz; )
|
||||
(cd $(suitesparse_dir); \
|
||||
cd $(suitesparse_dir)/metis-5.1.0; \
|
||||
make config cc=$(CC); \
|
||||
make ; \
|
||||
cp build/*/libmetis/libmetis.a . )
|
||||
( cd $(suitesparse_dir); \
|
||||
echo CC = $(CC) >> $(suitesparse_dir)/SuiteSparse_config/SuiteSparse_config.mk; \
|
||||
echo CF = $(CFLAGS) -fexceptions >> $(suitesparse_dir)/SuiteSparse_config/SuiteSparse_config.mk; \
|
||||
echo CC = $(CC) >> $(suitesparse_dir)/CSparse/Lib/Makefile; \
|
||||
cd $(suitesparse_dir); \
|
||||
make)
|
||||
|
||||
MUMPS:$(mumps_lib)
|
||||
$(mumps_lib):
|
||||
(cd $(sdpac_dir); \
|
||||
rm -rf mumps; \
|
||||
wget wget http://ftp.de.debian.org/debian/pool/main/m/mumps/$(mumps_tar_file); \
|
||||
tar xzf $(mumps_tar_file); \
|
||||
rm -f $(mumps_tar_file); \
|
||||
mv -f MUMPS_$(mumps_ver)/ $(mumps_dir); \
|
||||
cd $(mumps_dir); \
|
||||
cp Make.inc/Makefile.inc.generic.SEQ Makefile.inc; \
|
||||
echo "CC = " $(CC) >> Makefile.inc; \
|
||||
echo "FC = " $(FC) >> Makefile.inc; \
|
||||
echo "FL = " $(FC) >> Makefile.inc; \
|
||||
echo "OPTC = " $(CFLAGS) >> Makefile.inc; \
|
||||
echo "OPTF = " $(FCFLAGS) >> Makefile.inc; \
|
||||
echo "OPTL = " $(FCFLAGS) >> Makefile.inc; \
|
||||
echo "LPORDDIR = "`pwd`"/PORD/lib/" >> Makefile.inc; \
|
||||
echo "IPORDDIR = "`pwd`"/PORD/include/" >> Makefile.inc; \
|
||||
make d;)
|
||||
|
||||
OpenBLAS:$(openblas_lib)
|
||||
$(openblas_lib):
|
||||
(cd $(sdpac_dir); \
|
||||
rm -rf OpenBLAS; \
|
||||
git clone git://github.com/xianyi/OpenBLAS; \
|
||||
mv -f OpenBLAS $(openblas_dir); \
|
||||
cd $(openblas_dir); \
|
||||
make NO_WARMUP=1 USE_THREAD=1 USE_OPENMP=1 FC=$(FC) CC=$(CC) libs netlib)
|
||||
|
||||
clean:
|
||||
rm -rf *~ *.o
|
||||
@echo "## If you want to clean SuiteSparse, MUMPS, OpenBLAS,"
|
||||
@echo "## then use 'make dist-clean'"
|
||||
|
||||
dist-clean: clean
|
||||
rm -f $(sdpac_lib) $(sdpac_exe)
|
||||
(cd $(sdpac_dir); \
|
||||
rm -rf SuiteSparse; rm -rf mumps; rm -rf OpenBLAS)
|
||||
(cd mex; make dist-clean)
|
||||
|
||||
# -include make.head must be the bottom
|
||||
# otherwise, you need to assign make 'all'.
|
||||
-include make.head
|
||||
Vendored
+24
@@ -0,0 +1,24 @@
|
||||
CC = gcc
|
||||
OPTFLAGS = -O3 -fPIC
|
||||
CC = gcc
|
||||
OPTFLAGS = -O3 -fPIC
|
||||
CC = gcc
|
||||
OPTFLAGS = -O3 -fPIC
|
||||
CC = gcc
|
||||
OPTFLAGS = -O3 -fPIC
|
||||
CC = gcc
|
||||
OPTFLAGS = -O3 -fPIC
|
||||
CC = gcc
|
||||
OPTFLAGS = -O3 -fPIC
|
||||
CC = gcc
|
||||
OPTFLAGS = -O3 -fPIC
|
||||
CC = gcc
|
||||
OPTFLAGS = -O3 -fPIC
|
||||
CC = gcc
|
||||
OPTFLAGS = -O3 -fPIC
|
||||
CC = gcc
|
||||
OPTFLAGS = -O3 -fPIC
|
||||
CC = gcc
|
||||
OPTFLAGS = -O3 -fPIC
|
||||
CC = gcc
|
||||
OPTFLAGS = -O3 -fPIC
|
||||
Vendored
+8
@@ -0,0 +1,8 @@
|
||||
CC = gcc
|
||||
FC = gfortran
|
||||
FL = gfortran
|
||||
OPTC = -O3 -fPIC
|
||||
OPTF = -O3 -fPIC
|
||||
OPTL = -O3 -fPIC
|
||||
LPORDDIR = /home/makoto/sdpa-c/PORD/lib/
|
||||
IPORDDIR = /home/makoto/sdpa-c/PORD/include/
|
||||
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
For the latest news on SDPA, please refer to
|
||||
http://sdpa.sourceforge.net/
|
||||
Vendored
+12
@@ -0,0 +1,12 @@
|
||||
"Example 1: mDim = 3, nBLOCK = 1, {2}"
|
||||
3 = mDIM
|
||||
1 = nBLOCK
|
||||
2 = bLOCKsTRUCT
|
||||
48, -8, 20
|
||||
0 1 1 1 -11
|
||||
0 1 2 2 23
|
||||
1 1 1 1 10
|
||||
1 1 1 2 4
|
||||
2 1 2 2 -8
|
||||
3 1 1 2 -8
|
||||
3 1 2 2 -2
|
||||
Vendored
+70
@@ -0,0 +1,70 @@
|
||||
5
|
||||
1
|
||||
7
|
||||
1.1 -10.0 6.6 19.0 4.1
|
||||
0 1 1 1 1.8
|
||||
0 1 2 2 -4.0
|
||||
0 1 3 3 -1.4
|
||||
0 1 3 4 -3.2
|
||||
0 1 4 4 -28.0
|
||||
0 1 5 5 15.0
|
||||
0 1 5 6 -12.0
|
||||
0 1 5 7 2.1
|
||||
0 1 6 6 16.0
|
||||
0 1 6 7 -3.8
|
||||
0 1 7 7 15.0
|
||||
1 1 1 1 -4.5
|
||||
1 1 2 2 -3.5
|
||||
1 1 3 3 0.5
|
||||
1 1 3 4 5.2
|
||||
1 1 4 4 -5.3
|
||||
1 1 5 5 7.8
|
||||
1 1 5 6 -2.4
|
||||
1 1 5 7 6.0
|
||||
1 1 6 6 4.2
|
||||
1 1 6 7 6.5
|
||||
1 1 7 7 2.1
|
||||
2 1 1 1 -0.2
|
||||
2 1 2 2 -3.7
|
||||
2 1 3 3 1.7
|
||||
2 1 3 4 7.0
|
||||
2 1 4 4 -9.3
|
||||
2 1 5 5 -1.9
|
||||
2 1 5 6 -0.9
|
||||
2 1 5 7 -1.3
|
||||
2 1 6 6 -0.8
|
||||
2 1 6 7 -2.1
|
||||
2 1 7 7 4.0
|
||||
3 1 1 1 -3.3
|
||||
3 1 2 2 -4.0
|
||||
3 1 3 3 6.3
|
||||
3 1 3 4 -7.5
|
||||
3 1 4 4 -3.3
|
||||
3 1 5 5 0.2
|
||||
3 1 5 6 8.8
|
||||
3 1 5 7 5.4
|
||||
3 1 6 6 3.4
|
||||
3 1 6 7 -0.4
|
||||
3 1 7 7 7.5
|
||||
4 1 1 1 4.8
|
||||
4 1 2 2 9.7
|
||||
4 1 3 3 -2.4
|
||||
4 1 3 4 -2.5
|
||||
4 1 4 4 -2.9
|
||||
4 1 5 5 3.4
|
||||
4 1 5 6 -3.2
|
||||
4 1 5 7 -4.5
|
||||
4 1 6 6 3.0
|
||||
4 1 6 7 -4.8
|
||||
4 1 7 7 3.6
|
||||
5 1 1 1 6.1
|
||||
5 1 2 2 -1.5
|
||||
5 1 3 3 -6.5
|
||||
5 1 3 4 -5.4
|
||||
5 1 4 4 -6.6
|
||||
5 1 5 5 6.7
|
||||
5 1 5 6 -7.2
|
||||
5 1 5 7 -3.6
|
||||
5 1 6 6 7.3
|
||||
5 1 6 7 -3.0
|
||||
5 1 7 7 -1.4
|
||||
Vendored
+54
@@ -0,0 +1,54 @@
|
||||
*Example 2:
|
||||
*mDim = 5, nBLOCK = 3, {2,3,-2}
|
||||
5 = mDIM
|
||||
3 = nBLOCK
|
||||
2 3 -2 = bLOCKsTRUCT
|
||||
{1.1, -10, 6.6 , 19 , 4.1}
|
||||
{
|
||||
{ { -1.4, -3.2 },
|
||||
{ -3.2,-28 } }
|
||||
{ { 15, -12, 2.1 },
|
||||
{-12, 16, -3.8 },
|
||||
{ 2.1, -3.8, 15 } }
|
||||
{ 1.8, -4.0 }
|
||||
}
|
||||
{
|
||||
{ { 0.5, 5.2 },
|
||||
{ 5.2, -5.3 } }
|
||||
{ { 7.8, -2.4, 6.0 },
|
||||
{ -2.4, 4.2, 6.5 },
|
||||
{ 6.0, 6.5, 2.1 } }
|
||||
{ -4.5, -3.5 }
|
||||
}
|
||||
{
|
||||
{ { 1.7, 7.0 },
|
||||
{ 7.0, -9.3 } }
|
||||
{ {-1.9, -0.9, -1.3 },
|
||||
{-0.9, -0.8, -2.1 },
|
||||
{-1.3, -2.1, 4.0 } }
|
||||
{-0.2, -3.7 }
|
||||
}
|
||||
{
|
||||
{ { 6.3, -7.5 },
|
||||
{-7.5, -3.3 } }
|
||||
{ { 0.2, 8.8, 5.4 },
|
||||
{ 8.8, 3.4, -0.4 },
|
||||
{ 5.4, -0.4, 7.5 } }
|
||||
{-3.3, -4.0 }
|
||||
}
|
||||
{
|
||||
{ { -2.4, -2.5 },
|
||||
{ -2.5, -2.9 } }
|
||||
{ { 3.4, -3.2, -4.5 },
|
||||
{ -3.2, 3.0, -4.8 },
|
||||
{ -4.5, -4.8, 3.6 } }
|
||||
{ 4.8 , 9.7 }
|
||||
}
|
||||
{
|
||||
{ { -6.5, -5.4 },
|
||||
{ -5.4, -6.6 } }
|
||||
{ { 6.7, -7.2, -3.6 },
|
||||
{ -7.2, 7.3, -3.0 },
|
||||
{ -3.6, -3.0, -1.4 } }
|
||||
{ 6.1, -1.5 }
|
||||
}
|
||||
Vendored
+72
@@ -0,0 +1,72 @@
|
||||
*Example 2:
|
||||
*mDim = 5, nBLOCK = 3, {2,3,-2}
|
||||
5 = mDIM
|
||||
3 = nBLOCK
|
||||
2 3 -2 = bLOCKsTRUCT
|
||||
1.1, -10, 6.6 , 19 , 4.1
|
||||
0 1 1 1 -1.4
|
||||
0 1 1 2 -3.2
|
||||
0 1 2 2 -28
|
||||
0 2 1 1 15
|
||||
0 2 1 2 -12
|
||||
0 2 1 3 2.1
|
||||
0 2 2 2 16
|
||||
0 2 2 3 -3.8
|
||||
0 2 3 3 15
|
||||
0 3 1 1 1.8
|
||||
0 3 2 2 -4.0
|
||||
1 1 1 1 0.5
|
||||
1 1 1 2 5.2
|
||||
1 1 2 2 -5.3
|
||||
1 2 1 1 7.8
|
||||
1 2 1 2 -2.4
|
||||
1 2 1 3 6.0
|
||||
1 2 2 2 4.2
|
||||
1 2 2 3 6.5
|
||||
1 2 3 3 2.1
|
||||
1 3 1 1 -4.5
|
||||
1 3 2 2 -3.5
|
||||
2 1 1 1 1.7
|
||||
2 1 1 2 7.0
|
||||
2 1 2 2 -9.3
|
||||
2 2 1 1 -1.9
|
||||
2 2 1 2 -0.9
|
||||
2 2 1 3 -1.3
|
||||
2 2 2 2 -0.8
|
||||
2 2 2 3 -2.1
|
||||
2 2 3 3 4.0
|
||||
2 3 1 1 -0.2
|
||||
2 3 2 2 -3.7
|
||||
3 1 1 1 6.3
|
||||
3 1 1 2 -7.5
|
||||
3 1 2 2 -3.3
|
||||
3 2 1 1 0.2
|
||||
3 2 1 2 8.8
|
||||
3 2 1 3 5.4
|
||||
3 2 2 2 3.4
|
||||
3 2 2 3 -0.4
|
||||
3 2 3 3 7.5
|
||||
3 3 1 1 -3.3
|
||||
3 3 2 2 -4.0
|
||||
4 1 1 1 -2.4
|
||||
4 1 1 2 -2.5
|
||||
4 1 2 2 -2.9
|
||||
4 2 1 1 3.4
|
||||
4 2 1 2 -3.2
|
||||
4 2 1 3 -4.5
|
||||
4 2 2 2 3.0
|
||||
4 2 2 3 -4.8
|
||||
4 2 3 3 3.6
|
||||
4 3 1 1 4.8
|
||||
4 3 2 2 9.7
|
||||
5 1 1 1 -6.5
|
||||
5 1 1 2 -5.4
|
||||
5 1 2 2 -6.6
|
||||
5 2 1 1 6.7
|
||||
5 2 1 2 -7.2
|
||||
5 2 1 3 -3.6
|
||||
5 2 2 2 7.3
|
||||
5 2 2 3 -3.0
|
||||
5 2 3 3 -1.4
|
||||
5 3 1 1 6.1
|
||||
5 3 2 2 -1.5
|
||||
Vendored
+46
@@ -0,0 +1,46 @@
|
||||
|
||||
#############################################################
|
||||
# List of examples for callable-library
|
||||
#
|
||||
# example1.cpp: Solve example1.dat-s using inputElements
|
||||
# example2.cpp: Solve example2.dat using inputElements
|
||||
# example5.cpp: Solve problems reading from file
|
||||
#
|
||||
#############################################################
|
||||
|
||||
.PHONY: all lib clean cleanall distclean
|
||||
.SUFFIXES: .exe
|
||||
|
||||
# after "make install", you can find
|
||||
# 'make.inc' in 'share/sdpa' sub-directory under the installed directory
|
||||
# For example
|
||||
# make MAKE_INCLUDE_DIR=/usr/share/sdpa
|
||||
# or
|
||||
# make MAKE_INCLUDE_DIR=/usr/local/share/sdpa
|
||||
|
||||
MAKE_INCLUDE_DIR=..
|
||||
-include ${MAKE_INCLUDE_DIR}/make.inc
|
||||
# after "make install", you can find
|
||||
# 'make.inc' in 'share/sdpa' sub-directory under the installed directory
|
||||
# For example
|
||||
# make MAKE_INCLUDE_DIR=/usr/share/sdpa
|
||||
# or
|
||||
# make MAKE_INCLUDE_DIR=/usr/local/share/sdpa
|
||||
|
||||
|
||||
SRC = $(wildcard example?.cpp)
|
||||
EXE = $(subst .cpp,.exe,$(SRC))
|
||||
|
||||
all: ${EXE}
|
||||
|
||||
%.exe: %.o
|
||||
${CXX} ${CXXFLAGS} -o $@ $< ${sdpac_dir}/${sdpac_lib} ${sdpac_all_lib}
|
||||
.cpp.o:
|
||||
${CXX} -c ${CXXFLAGS} \
|
||||
-I${sdpac_dir} ${sdpac_all_include} \
|
||||
-o $@ $<
|
||||
clean:
|
||||
rm -f *.o *~
|
||||
cleanall: clean
|
||||
rm -f *.exe
|
||||
dist-clean: cleanall
|
||||
+227
@@ -0,0 +1,227 @@
|
||||
/* -------------------------------------------------------------
|
||||
|
||||
This file is a component of SDPA
|
||||
Copyright (C) 2004-2013 SDPA Project
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
------------------------------------------------------------- */
|
||||
// Here is the start of ``example1.cpp''
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <sdpa_call.h>
|
||||
|
||||
/*
|
||||
example1.dat:
|
||||
|
||||
"Example 1: mDim = 3, nBLOCK = 1, {2}"
|
||||
3 = mDIM
|
||||
1 = nBLOCK
|
||||
2 = bLOCKsTRUCT
|
||||
{48, -8, 20}
|
||||
{ {-11, 0}, { 0, 23} }
|
||||
{ { 10, 4}, { 4, 0} }
|
||||
{ { 0, 0}, { 0, -8} }
|
||||
{ { 0, -8}, {-8, -2} }
|
||||
*/
|
||||
|
||||
void printVector(double* ele, int dim, char* printFormat,
|
||||
FILE* fpout);
|
||||
void printMatrix(double* ele, int dim, char* printFormat,
|
||||
FILE* fpout);
|
||||
void printDimacsError(double dimacs_error[7],char* printFormat,
|
||||
FILE* fpout);
|
||||
|
||||
int main ()
|
||||
{
|
||||
SDPA::printSDPAVersion(stdout);
|
||||
SDPA Problem1;
|
||||
Problem1.setDisplay(stdout);
|
||||
|
||||
// All parameteres are renewed
|
||||
Problem1.setParameterType(SDPA::PARAMETER_DEFAULT);
|
||||
|
||||
// If necessary, each parameter can be set independently
|
||||
|
||||
// Problem1.setParameterMaxIteration(100);
|
||||
// Problem1.setParameterEpsilonStar(1.0e-7);
|
||||
// Problem1.setParameterLambdaStar(1.0e+2);
|
||||
// Problem1.setParameterOmegaStar(2.0);
|
||||
// Problem1.setParameterLowerBound(-1.0e+5);
|
||||
// Problem1.setParameterUppwerBound(1.0e+5);
|
||||
// Problem1.setParameterBetaStar(0.1);
|
||||
// Problem1.setParameterBetaBar(0.2);
|
||||
// Problem1.setParameterGammaStar(0.9);
|
||||
// Problem1.setParameterEpsilonDash(1.0e-7);
|
||||
// Problem1.setParameterPrintXVec((char*)"%+8.3e" );
|
||||
// Problem1.setParameterPrintXMat((char*)"%+8.3e" );
|
||||
// Problem1.setParameterPrintYMat((char*)"%+8.3e" );
|
||||
// Problem1.setParameterPrintInformation((char*)"%+10.16e");
|
||||
|
||||
Problem1.printParameters(stdout);
|
||||
|
||||
int mDIM = 3;
|
||||
int nBlock = 1;
|
||||
Problem1.inputConstraintNumber(mDIM);
|
||||
Problem1.inputBlockNumber(nBlock);
|
||||
Problem1.inputBlockSize(1,2);
|
||||
Problem1.inputBlockType(1,SDPA::SDP);
|
||||
|
||||
Problem1.initializeUpperTriangleSpace();
|
||||
|
||||
Problem1.inputCVec(1,48);
|
||||
Problem1.inputCVec(2,-8);
|
||||
Problem1.inputCVec(3,20);
|
||||
|
||||
Problem1.inputElement(0, 1, 1, 1, -11);
|
||||
Problem1.inputElement(0, 1, 2, 2, 23);
|
||||
|
||||
Problem1.inputElement(1, 1, 1, 1, 10);
|
||||
Problem1.inputElement(1, 1, 1, 2, 4);
|
||||
|
||||
Problem1.inputElement(2, 1, 2, 2, -8);
|
||||
|
||||
Problem1.inputElement(3, 1, 1, 2, -8);
|
||||
Problem1.inputElement(3, 1, 2, 2, -2);
|
||||
|
||||
Problem1.initializeUpperTriangle();
|
||||
Problem1.initializeSolve();
|
||||
|
||||
// if necessary, dump input data and initial point
|
||||
// Problem1.writeInputSparse((char*)"tmp.dat-s",(char*)"%+8.3e");
|
||||
// Problem1.writeInitSparse((char*)"tmp.ini-s",(char*)"%+8.3e");
|
||||
|
||||
Problem1.solve();
|
||||
|
||||
fprintf(stdout, "\nStop iteration = %d\n",
|
||||
Problem1.getIteration());
|
||||
char phase_string[30];
|
||||
Problem1.getPhaseString(phase_string);
|
||||
fprintf(stdout, "Phase = %s\n", phase_string);
|
||||
fprintf(stdout, "objValPrimal = %+10.6e\n",
|
||||
Problem1.getPrimalObj());
|
||||
fprintf(stdout, "objValDual = %+10.6e\n",
|
||||
Problem1.getDualObj());
|
||||
fprintf(stdout, "p. feas. error = %+10.6e\n",
|
||||
Problem1.getPrimalError());
|
||||
fprintf(stdout, "d. feas. error = %+10.6e\n\n",
|
||||
Problem1.getDualError());
|
||||
|
||||
|
||||
fprintf(stdout, "xVec = \n");
|
||||
// Problem1.printResultXVec();
|
||||
printVector(Problem1.getResultXVec(),
|
||||
Problem1.getConstraintNumber(), (char*)"%+8.3e",
|
||||
stdout);
|
||||
|
||||
fprintf(stdout, "xMat = \n");
|
||||
// Problem1.printResultXMat();
|
||||
for (int l=0; l<Problem1.getBlockNumber(); ++l) {
|
||||
if (Problem1.getBlockType(l+1) == SDPA::SDP) {
|
||||
printMatrix(Problem1.getResultXMat(l+1),
|
||||
Problem1.getBlockSize(l+1), (char*)"%+8.3e",
|
||||
stdout);
|
||||
}
|
||||
else if (Problem1.getBlockType(l+1) == SDPA::SOCP) {
|
||||
printf("current version does not support SOCP\n");
|
||||
}
|
||||
if (Problem1.getBlockType(l+1) == SDPA::LP) {
|
||||
printVector(Problem1.getResultXMat(l+1),
|
||||
Problem1.getBlockSize(l+1), (char*)"%+8.3e",
|
||||
stdout);
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stdout, "yMat = \n");
|
||||
// Problem1.printResultYMat();
|
||||
for (int l=0; l<Problem1.getBlockNumber(); ++l) {
|
||||
if (Problem1.getBlockType(l+1) == SDPA::SDP) {
|
||||
printMatrix(Problem1.getResultYMat(l+1),
|
||||
Problem1.getBlockSize(l+1), (char*)"%+8.3e",
|
||||
stdout);
|
||||
}
|
||||
else if (Problem1.getBlockType(l+1) == SDPA::SOCP) {
|
||||
printf("current version does not support SOCP\n");
|
||||
}
|
||||
if (Problem1.getBlockType(l+1) == SDPA::LP) {
|
||||
printVector(Problem1.getResultYMat(l+1),
|
||||
Problem1.getBlockSize(l+1), (char*)"%+8.3e",
|
||||
stdout);
|
||||
}
|
||||
}
|
||||
|
||||
double dimacs_error[7];
|
||||
Problem1.getDimacsError(dimacs_error);
|
||||
printDimacsError(dimacs_error,(char*)"%+8.3e",stdout);
|
||||
|
||||
// Problem1.printComputationTime(stdout);
|
||||
|
||||
Problem1.finalize();
|
||||
exit(0);
|
||||
};
|
||||
|
||||
void printVector(double* ele, int dim, char* printFormat, FILE* fpout)
|
||||
{
|
||||
fprintf(fpout,"[ ");
|
||||
for (int k=0; k<dim-1; ++k) {
|
||||
fprintf(fpout,printFormat,ele[k]);
|
||||
fprintf(fpout," ");
|
||||
}
|
||||
fprintf(fpout,printFormat,ele[dim-1]);
|
||||
fprintf(fpout,"]; \n");
|
||||
}
|
||||
|
||||
void printMatrix(double* ele, int dim, char* printFormat, FILE* fpout)
|
||||
{
|
||||
fprintf(fpout,"[\n");
|
||||
for (int i=0; i<dim; ++i) {
|
||||
fprintf(fpout,"[ ");
|
||||
for (int j=0; j<dim-1; ++j) {
|
||||
fprintf(fpout,printFormat,ele[i+dim*j]);
|
||||
fprintf(fpout," ");
|
||||
}
|
||||
fprintf(fpout,printFormat,ele[i+dim*(dim-1)]);
|
||||
fprintf(fpout,"]; \n");
|
||||
}
|
||||
fprintf(fpout,"]; \n");
|
||||
}
|
||||
|
||||
void printDimacsError(double dimacs_error[7],char* printFormat,
|
||||
FILE* fpout)
|
||||
{
|
||||
fprintf(fpout, "\n");
|
||||
fprintf(fpout, "* DIMACS_ERRORS * \n");
|
||||
fprintf(fpout, "err1 = ");
|
||||
fprintf(fpout, printFormat, dimacs_error[1]);
|
||||
fprintf(fpout, " [||Ax-b|| / (1+||b||_1)]\n");
|
||||
fprintf(fpout, "err2 = ");
|
||||
fprintf(fpout, printFormat, dimacs_error[2]);
|
||||
fprintf(fpout, " [max(0, -lambda(x)/(1+||b||_1))]\n");
|
||||
fprintf(fpout, "err3 = ");
|
||||
fprintf(fpout, printFormat, dimacs_error[3]);
|
||||
fprintf(fpout, " [||A^Ty + z - c || / (1+||c||_1)]\n");
|
||||
fprintf(fpout, "err4 = ");
|
||||
fprintf(fpout, printFormat, dimacs_error[4]);
|
||||
fprintf(fpout, " [max(0, -lambda(z)/(1+||c||_1))]\n");
|
||||
fprintf(fpout, "err5 = ");
|
||||
fprintf(fpout, printFormat, dimacs_error[5]);
|
||||
fprintf(fpout, " [(<c,x> - <b,y>) / (1 + |<c,x>| + |<b,y>|)]\n");
|
||||
fprintf(fpout, "err6 = ");
|
||||
fprintf(fpout, printFormat, dimacs_error[6]);
|
||||
fprintf(fpout, " [<x,z> / (1 + |<c,x>| + |<b,y>|)]\n");
|
||||
fprintf(fpout, "\n");
|
||||
}
|
||||
|
||||
+411
@@ -0,0 +1,411 @@
|
||||
/* -------------------------------------------------------------
|
||||
|
||||
This file is a component of SDPA
|
||||
Copyright (C) 2004-2013 SDPA Project
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
------------------------------------------------------------- */
|
||||
// Here is the start of ``example1.cpp''
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <sdpa_call.h>
|
||||
|
||||
/*
|
||||
*Example 2:
|
||||
*mDim = 5, nBLOCK = 3, {2,3,-2}
|
||||
5 = mDIM
|
||||
3 = nBLOCK
|
||||
2 3 -2 = bLOCKsTRUCT
|
||||
{1.1, -10, 6.6 , 19 , 4.1}
|
||||
{
|
||||
{ { -1.4, -3.2 },
|
||||
{ -3.2,-28 } }
|
||||
{ { 15, -12, 2.1 },
|
||||
{-12, 16, -3.8 },
|
||||
{ 2.1, -3.8, 15 } }
|
||||
{ 1.8, -4.0 }
|
||||
}
|
||||
{
|
||||
{ { 0.5, 5.2 },
|
||||
{ 5.2, -5.3 } }
|
||||
{ { 7.8, -2.4, 6.0 },
|
||||
{ -2.4, 4.2, 6.5 },
|
||||
{ 6.0, 6.5, 2.1 } }
|
||||
{ -4.5, -3.5 }
|
||||
}
|
||||
{
|
||||
{ { 1.7, 7.0 },
|
||||
{ 7.0, -9.3 } }
|
||||
{ {-1.9, -0.9, -1.3 },
|
||||
{-0.9, -0.8, -2.1 },
|
||||
{-1.3, -2.1, 4.0 } }
|
||||
{-0.2, -3.7 }
|
||||
}
|
||||
{
|
||||
{ { 6.3, -7.5 },
|
||||
{-7.5, -3.3 } }
|
||||
{ { 0.2, 8.8, 5.4 },
|
||||
{ 8.8, 3.4, -0.4 },
|
||||
{ 5.4, -0.4, 7.5 } }
|
||||
{-3.3, -4.0 }
|
||||
}
|
||||
{
|
||||
{ { -2.4, -2.5 },
|
||||
{ -2.5, -2.9 } }
|
||||
{ { 3.4, -3.2, -4.5 },
|
||||
{ -3.2, 3.0, -4.8 },
|
||||
{ -4.5, -4.8, 3.6 } }
|
||||
{ 4.8 , 9.7 }
|
||||
}
|
||||
{
|
||||
{ { -6.5, -5.4 },
|
||||
{ -5.4, -6.6 } }
|
||||
{ { 6.7, -7.2, -3.6 },
|
||||
{ -7.2, 7.3, -3.0 },
|
||||
{ -3.6, -3.0, -1.4 } }
|
||||
{ 6.1, -1.5 }
|
||||
}
|
||||
*/
|
||||
|
||||
void printVector(double* ele, int dim, char* printFormat,
|
||||
FILE* fpout);
|
||||
void printMatrix(double* ele, int dim, char* printFormat,
|
||||
FILE* fpout);
|
||||
void printDimacsError(double dimacs_error[7],char* printFormat,
|
||||
FILE* fpout);
|
||||
|
||||
int main ()
|
||||
{
|
||||
SDPA::printSDPAVersion(stdout);
|
||||
SDPA Problem1;
|
||||
Problem1.setDisplay(stdout);
|
||||
|
||||
// All parameteres are renewed
|
||||
Problem1.setParameterType(SDPA::PARAMETER_DEFAULT);
|
||||
// Problem1.printParameters(stdout);
|
||||
|
||||
int mDIM = 5;
|
||||
int nBlock = 3;
|
||||
Problem1.inputConstraintNumber(mDIM);
|
||||
Problem1.inputBlockNumber(nBlock);
|
||||
// bLOCKsTRUCT :: 2(SDP) 3(SDP) -2(LP)
|
||||
Problem1.inputBlockSize(1,2);
|
||||
Problem1.inputBlockSize(2,3);
|
||||
Problem1.inputBlockSize(3,-2);
|
||||
Problem1.inputBlockType(1,SDPA::SDP);
|
||||
Problem1.inputBlockType(2,SDPA::SDP);
|
||||
Problem1.inputBlockType(3,SDPA::LP);
|
||||
|
||||
Problem1.initializeUpperTriangleSpace();
|
||||
|
||||
//cVECT = {1.1, -10, 6.6 , 19 , 4.1}
|
||||
Problem1.inputCVec(1,1.1);
|
||||
Problem1.inputCVec(2,-10);
|
||||
Problem1.inputCVec(3,6.6);
|
||||
Problem1.inputCVec(4,19);
|
||||
Problem1.inputCVec(5,4.1);
|
||||
|
||||
// --------- Input F_0 --------------------
|
||||
|
||||
// 1st block
|
||||
// { { -1.4, -3.2},
|
||||
// { -3.2, -28} }
|
||||
|
||||
Problem1.inputElement(0, 1, 1, 1, -1.4);
|
||||
Problem1.inputElement(0, 1, 1, 2, -3.2);
|
||||
Problem1.inputElement(0, 1, 2, 2, -28);
|
||||
|
||||
// 2nd block
|
||||
// { { 15, -12, 2.1 },
|
||||
// {-12, 16, -3.8 },
|
||||
// { 2.1, -3.8, 15 } }
|
||||
|
||||
Problem1.inputElement(0, 2, 1, 1, 15);
|
||||
Problem1.inputElement(0, 2, 1, 2, -12);
|
||||
Problem1.inputElement(0, 2, 1, 3, 2.1);
|
||||
Problem1.inputElement(0, 2, 2, 2, 16);
|
||||
Problem1.inputElement(0, 2, 2, 3,-3.8);
|
||||
Problem1.inputElement(0, 2, 3, 3, 15);
|
||||
|
||||
// 3rd block
|
||||
// { 1.8, -4.0 }
|
||||
Problem1.inputElement(0, 3, 1, 1, 1.8);
|
||||
Problem1.inputElement(0, 3, 2, 2,-4.0);
|
||||
|
||||
// --------- Input F_1 --------------------
|
||||
|
||||
// 1st block
|
||||
// { { 0.5, 5.2},
|
||||
// { 5.2, -5.3} }
|
||||
|
||||
Problem1.inputElement(1, 1, 1, 1, 0.5);
|
||||
Problem1.inputElement(1, 1, 1, 2, 5.2);
|
||||
Problem1.inputElement(1, 1, 2, 2,-5.3);
|
||||
|
||||
// 2nd block
|
||||
// { { 7.8, -2.4, 6.0 },
|
||||
// {-2.4, 4.2, 6.5 },
|
||||
// { 6.0, 6.5, 2.1 } }
|
||||
|
||||
Problem1.inputElement(1, 2, 1, 1, 7.8);
|
||||
Problem1.inputElement(1, 2, 1, 2,-2.4);
|
||||
Problem1.inputElement(1, 2, 1, 3, 6.0);
|
||||
Problem1.inputElement(1, 2, 2, 2, 4.2);
|
||||
Problem1.inputElement(1, 2, 2, 3, 6.5);
|
||||
Problem1.inputElement(1, 2, 3, 3, 2.1);
|
||||
|
||||
// 3rd block
|
||||
// { -4.5, -3.5 }
|
||||
Problem1.inputElement(1, 3, 1, 1, -4.5);
|
||||
Problem1.inputElement(1, 3, 2, 2, -3.5);
|
||||
|
||||
// --------- Input F_2 --------------------
|
||||
|
||||
// 1st block
|
||||
// { { 1.7, 7.0},
|
||||
// { 7.0,-9.3} }
|
||||
|
||||
Problem1.inputElement(2, 1, 1, 1, 1.7);
|
||||
Problem1.inputElement(2, 1, 1, 2, 7.0);
|
||||
Problem1.inputElement(2, 1, 2, 2, -9.3);
|
||||
|
||||
// 2nd block
|
||||
// { {-1.9, -0.9, -1.3 },
|
||||
// {-0.9, -0.8, -2.1 },
|
||||
// {-1.3, -2.1, 4.0 } }
|
||||
|
||||
Problem1.inputElement(2, 2, 1, 1, -1.9);
|
||||
Problem1.inputElement(2, 2, 1, 2, -0.9);
|
||||
Problem1.inputElement(2, 2, 1, 3, -1.3);
|
||||
Problem1.inputElement(2, 2, 2, 2, -0.8);
|
||||
Problem1.inputElement(2, 2, 2, 3, -2.1);
|
||||
Problem1.inputElement(2, 2, 3, 3, 4.0);
|
||||
|
||||
// 3rd block
|
||||
// { -0.2, -3.7 }
|
||||
Problem1.inputElement(2, 3, 1, 1, -0.2);
|
||||
Problem1.inputElement(2, 3, 2, 2, -3.7);
|
||||
|
||||
// --------- Input F_3 --------------------
|
||||
|
||||
// 1st block
|
||||
// { { 6.3, -7.5},
|
||||
// { -7.5, -3.3} }
|
||||
|
||||
Problem1.inputElement(3, 1, 1, 1, 6.3);
|
||||
Problem1.inputElement(3, 1, 1, 2, -7.5);
|
||||
Problem1.inputElement(3, 1, 2, 2, -3.3);
|
||||
|
||||
// 2nd block
|
||||
// { { 0.2, 8.8, 5.4 },
|
||||
// { 8.8, 3.4, -0.4 },
|
||||
// { 5.4, -0.4, 7.5 } }
|
||||
|
||||
Problem1.inputElement(3, 2, 1, 1, 0.2);
|
||||
Problem1.inputElement(3, 2, 1, 2, 8.8);
|
||||
Problem1.inputElement(3, 2, 1, 3, 5.4);
|
||||
Problem1.inputElement(3, 2, 2, 2, 3.4);
|
||||
Problem1.inputElement(3, 2, 2, 3, -0.4);
|
||||
Problem1.inputElement(3, 2, 3, 3, 7.5);
|
||||
|
||||
// 3rd block
|
||||
// { -3.3, -4.0 }
|
||||
Problem1.inputElement(3, 3, 1, 1, -3.3);
|
||||
Problem1.inputElement(3, 3, 2, 2, -4.0);
|
||||
|
||||
// --------- Input F_4 --------------------
|
||||
|
||||
// 1st block
|
||||
// { { -2.4, -2.5},
|
||||
// { -2.5, -2.9} }
|
||||
|
||||
Problem1.inputElement(4, 1, 1, 1, -2.4);
|
||||
Problem1.inputElement(4, 1, 1, 2, -2.5);
|
||||
Problem1.inputElement(4, 1, 2, 2, -2.9);
|
||||
|
||||
// 2nd block
|
||||
// { { 3.4, -3.2, -4.5 },
|
||||
// { -3.2, 3.0, -4.8 },
|
||||
// { -4.5, -4.8, 3.6 } }
|
||||
|
||||
Problem1.inputElement(4, 2, 1, 1, 3.4);
|
||||
Problem1.inputElement(4, 2, 1, 2, -3.2);
|
||||
Problem1.inputElement(4, 2, 1, 3, -4.5);
|
||||
Problem1.inputElement(4, 2, 2, 2, 3.0);
|
||||
Problem1.inputElement(4, 2, 2, 3, -4.8);
|
||||
Problem1.inputElement(4, 2, 3, 3, 3.6);
|
||||
|
||||
// 3rd block
|
||||
// { 4.8, 9.7 }
|
||||
Problem1.inputElement(4, 3, 1, 1, 4.8);
|
||||
Problem1.inputElement(4, 3, 2, 2, 9.7);
|
||||
|
||||
// --------- Input F_5 --------------------
|
||||
|
||||
// 1st block
|
||||
// { { -6.5, -5.4},
|
||||
// { -5.4, -6.6} }
|
||||
|
||||
Problem1.inputElement(5, 1, 1, 1, -6.5);
|
||||
Problem1.inputElement(5, 1, 1, 2, -5.4);
|
||||
Problem1.inputElement(5, 1, 2, 2, -6.6);
|
||||
|
||||
// 2nd block
|
||||
// { { 6.7, -7.2, -3.6 },
|
||||
// { -7.2, 7.3, -3.0 },
|
||||
// { -3.6, -3.0, -1.4 } }
|
||||
|
||||
Problem1.inputElement(5, 2, 1, 1, 6.7);
|
||||
Problem1.inputElement(5, 2, 1, 2, -7.2);
|
||||
Problem1.inputElement(5, 2, 1, 3, -3.6);
|
||||
Problem1.inputElement(5, 2, 2, 2, 7.3);
|
||||
Problem1.inputElement(5, 2, 2, 3, -3.0);
|
||||
Problem1.inputElement(5, 2, 3, 3, -1.4);
|
||||
|
||||
// 3rd block
|
||||
// { 6.1, -1.5 }
|
||||
Problem1.inputElement(5, 3, 1, 1, 6.1);
|
||||
Problem1.inputElement(5, 3, 2, 2,-1.5);
|
||||
|
||||
Problem1.initializeUpperTriangle();
|
||||
Problem1.initializeSolve();
|
||||
|
||||
// if necessary, dump input data and initial point
|
||||
// Problem1.writeInputSparse((char*)"tmp.dat-s",(char*)"%+8.3e");
|
||||
// Problem1.writeInitSparse((char*)"tmp.ini-s",(char*)"%+8.3e");
|
||||
|
||||
Problem1.solve();
|
||||
|
||||
fprintf(stdout, "\nStop iteration = %d\n",
|
||||
Problem1.getIteration());
|
||||
char phase_string[30];
|
||||
Problem1.getPhaseString(phase_string);
|
||||
fprintf(stdout, "Phase = %s\n", phase_string);
|
||||
fprintf(stdout, "objValPrimal = %+10.6e\n",
|
||||
Problem1.getPrimalObj());
|
||||
fprintf(stdout, "objValDual = %+10.6e\n",
|
||||
Problem1.getDualObj());
|
||||
fprintf(stdout, "p. feas. error = %+10.6e\n",
|
||||
Problem1.getPrimalError());
|
||||
fprintf(stdout, "d. feas. error = %+10.6e\n\n",
|
||||
Problem1.getDualError());
|
||||
|
||||
|
||||
fprintf(stdout, "xVec = \n");
|
||||
// Problem1.printResultXVec();
|
||||
printVector(Problem1.getResultXVec(),
|
||||
Problem1.getConstraintNumber(), (char*)"%+8.3e",
|
||||
stdout);
|
||||
|
||||
fprintf(stdout, "xMat = \n");
|
||||
// Problem1.printResultXMat();
|
||||
for (int l=0; l<Problem1.getBlockNumber(); ++l) {
|
||||
if (Problem1.getBlockType(l+1) == SDPA::SDP) {
|
||||
printMatrix(Problem1.getResultXMat(l+1),
|
||||
Problem1.getBlockSize(l+1), (char*)"%+8.3e",
|
||||
stdout);
|
||||
}
|
||||
else if (Problem1.getBlockType(l+1) == SDPA::SOCP) {
|
||||
printf("current version does not support SOCP\n");
|
||||
}
|
||||
if (Problem1.getBlockType(l+1) == SDPA::LP) {
|
||||
printVector(Problem1.getResultXMat(l+1),
|
||||
Problem1.getBlockSize(l+1), (char*)"%+8.3e",
|
||||
stdout);
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stdout, "yMat = \n");
|
||||
// Problem1.printResultYMat();
|
||||
for (int l=0; l<Problem1.getBlockNumber(); ++l) {
|
||||
if (Problem1.getBlockType(l+1) == SDPA::SDP) {
|
||||
printMatrix(Problem1.getResultYMat(l+1),
|
||||
Problem1.getBlockSize(l+1), (char*)"%+8.3e",
|
||||
stdout);
|
||||
}
|
||||
else if (Problem1.getBlockType(l+1) == SDPA::SOCP) {
|
||||
printf("current version does not support SOCP\n");
|
||||
}
|
||||
if (Problem1.getBlockType(l+1) == SDPA::LP) {
|
||||
printVector(Problem1.getResultYMat(l+1),
|
||||
Problem1.getBlockSize(l+1), (char*)"%+8.3e",
|
||||
stdout);
|
||||
}
|
||||
}
|
||||
|
||||
double dimacs_error[7];
|
||||
Problem1.getDimacsError(dimacs_error);
|
||||
printDimacsError(dimacs_error,(char*)"%+8.3e",stdout);
|
||||
|
||||
// Problem1.printComputationTime(stdout);
|
||||
|
||||
Problem1.finalize();
|
||||
exit(0);
|
||||
};
|
||||
|
||||
void printVector(double* ele, int dim, char* printFormat, FILE* fpout)
|
||||
{
|
||||
fprintf(fpout,"[ ");
|
||||
for (int k=0; k<dim-1; ++k) {
|
||||
fprintf(fpout,printFormat,ele[k]);
|
||||
fprintf(fpout," ");
|
||||
}
|
||||
fprintf(fpout,printFormat,ele[dim-1]);
|
||||
fprintf(fpout,"]; \n");
|
||||
}
|
||||
|
||||
void printMatrix(double* ele, int dim, char* printFormat, FILE* fpout)
|
||||
{
|
||||
fprintf(fpout,"[\n");
|
||||
for (int i=0; i<dim; ++i) {
|
||||
fprintf(fpout,"[ ");
|
||||
for (int j=0; j<dim-1; ++j) {
|
||||
fprintf(fpout,printFormat,ele[i+dim*j]);
|
||||
fprintf(fpout," ");
|
||||
}
|
||||
fprintf(fpout,printFormat,ele[i+dim*(dim-1)]);
|
||||
fprintf(fpout,"]; \n");
|
||||
}
|
||||
fprintf(fpout,"]; \n");
|
||||
}
|
||||
|
||||
void printDimacsError(double dimacs_error[7],char* printFormat,
|
||||
FILE* fpout)
|
||||
{
|
||||
fprintf(fpout, "\n");
|
||||
fprintf(fpout, "* DIMACS_ERRORS * \n");
|
||||
fprintf(fpout, "err1 = ");
|
||||
fprintf(fpout, printFormat, dimacs_error[1]);
|
||||
fprintf(fpout, " [||Ax-b|| / (1+||b||_1)]\n");
|
||||
fprintf(fpout, "err2 = ");
|
||||
fprintf(fpout, printFormat, dimacs_error[2]);
|
||||
fprintf(fpout, " [max(0, -lambda(x)/(1+||b||_1))]\n");
|
||||
fprintf(fpout, "err3 = ");
|
||||
fprintf(fpout, printFormat, dimacs_error[3]);
|
||||
fprintf(fpout, " [||A^Ty + z - c || / (1+||c||_1)]\n");
|
||||
fprintf(fpout, "err4 = ");
|
||||
fprintf(fpout, printFormat, dimacs_error[4]);
|
||||
fprintf(fpout, " [max(0, -lambda(z)/(1+||c||_1))]\n");
|
||||
fprintf(fpout, "err5 = ");
|
||||
fprintf(fpout, printFormat, dimacs_error[5]);
|
||||
fprintf(fpout, " [(<c,x> - <b,y>) / (1 + |<c,x>| + |<b,y>|)]\n");
|
||||
fprintf(fpout, "err6 = ");
|
||||
fprintf(fpout, printFormat, dimacs_error[6]);
|
||||
fprintf(fpout, " [<x,z> / (1 + |<c,x>| + |<b,y>|)]\n");
|
||||
fprintf(fpout, "\n");
|
||||
}
|
||||
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
/* -------------------------------------------------------------
|
||||
|
||||
This file is a component of SDPA
|
||||
Copyright (C) 2004-2013 SDPA Project
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
------------------------------------------------------------- */
|
||||
// Here is the start of ``example5.cpp''
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <sdpa_call.h>
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
if (argc != 4) {
|
||||
fprintf(stderr, "%s [Input] [Output] [Param] \n", argv[0]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
SDPA Problem1;
|
||||
FILE* fpresult;
|
||||
if ((fpresult = fopen(argv[2],"w")) == NULL) {
|
||||
fprintf(stderr, "Cannot Open %s \n", argv[2]);
|
||||
}
|
||||
Problem1.setResultFile(fpresult);
|
||||
|
||||
// fpresult records which file is read from argv[3]
|
||||
Problem1.readParameter(argv[3],fpresult);
|
||||
// Note that readParameter should be called before readInput
|
||||
// Otherwise initial point cannot be decided by lambdaStar
|
||||
Problem1.readInput(argv[1],fpresult);
|
||||
|
||||
Problem1.initializeSolve();
|
||||
|
||||
// All results and intermediate log are written into fpresult
|
||||
Problem1.solve();
|
||||
|
||||
fclose(fpresult);
|
||||
Problem1.finalize();
|
||||
exit(0);
|
||||
}
|
||||
Vendored
BIN
Binary file not shown.
Vendored
+15
@@ -0,0 +1,15 @@
|
||||
100 unsigned int maxIteration;
|
||||
1.0E-7 double 0.0 < epsilonStar;
|
||||
1.0E2 double 0.0 < lambdaStar;
|
||||
2.0 double 1.0 < omegaStar;
|
||||
-1.0E5 double lowerBound;
|
||||
1.0E5 double upperBound;
|
||||
0.1 double 0.0 <= betaStar < 1.0;
|
||||
0.3 double 0.0 <= betaBar < 1.0, betaStar <= betaBar;
|
||||
0.9 double 0.0 < gammaStar < 1.0;
|
||||
1.0E-7 double 0.0 < epsilonDash;
|
||||
%+8.3e char* xPrint (default %+8.3e, NOPRINT skips printout)
|
||||
%+8.3e char* XPrint (default %+8.3e, NOPRINT skips printout)
|
||||
%+8.3e char* YPrint (default %+8.3e, NOPRINT skips printout)
|
||||
%+10.16e char* infPrint (default %+10.16e, NOPRINT skips printout)
|
||||
|
||||
Vendored
+30
@@ -0,0 +1,30 @@
|
||||
sdpa_block.o: sdpa_block.cpp sdpa_block.h sdpa_include.h sdpa_right.h \
|
||||
sdpa_tool.h
|
||||
sdpa_call.o: sdpa_call.cpp sdpa_call.h sdpa_io.h sdpa_block.h \
|
||||
sdpa_include.h sdpa_right.h sdpa_tool.h sdpa_parts.h sdpa_dataset.h \
|
||||
sdpa_struct.h sdpa_linear.h
|
||||
sdpa_chordal.o: sdpa_chordal.cpp sdpa_chordal.h sdpa_dataset.h \
|
||||
sdpa_include.h sdpa_right.h sdpa_tool.h sdpa_struct.h sdpa_block.h
|
||||
sdpa_dataset.o: sdpa_dataset.cpp sdpa_dataset.h sdpa_include.h \
|
||||
sdpa_right.h sdpa_tool.h sdpa_struct.h sdpa_block.h sdpa_parts.h \
|
||||
sdpa_linear.h sdpa_newton.h sdpa_chordal.h
|
||||
sdpa_dpotrf.o: sdpa_dpotrf.cpp sdpa_include.h sdpa_right.h sdpa_tool.h \
|
||||
sdpa_algebra.h
|
||||
sdpa_exe.o: sdpa_exe.cpp
|
||||
sdpa_io.o: sdpa_io.cpp sdpa_io.h sdpa_block.h sdpa_include.h sdpa_right.h \
|
||||
sdpa_tool.h sdpa_parts.h sdpa_dataset.h sdpa_struct.h sdpa_linear.h
|
||||
sdpa_linear.o: sdpa_linear.cpp sdpa_linear.h sdpa_struct.h sdpa_include.h \
|
||||
sdpa_right.h sdpa_tool.h sdpa_block.h sdpa_dataset.h sdpa_dpotrf.h \
|
||||
sdpa_algebra.h
|
||||
sdpa_newton.o: sdpa_newton.cpp sdpa_newton.h sdpa_chordal.h \
|
||||
sdpa_dataset.h sdpa_include.h sdpa_right.h sdpa_tool.h sdpa_struct.h \
|
||||
sdpa_block.h sdpa_parts.h sdpa_linear.h sdpa_algebra.h
|
||||
sdpa_parts.o: sdpa_parts.cpp sdpa_parts.h sdpa_include.h sdpa_right.h \
|
||||
sdpa_tool.h sdpa_dataset.h sdpa_struct.h sdpa_block.h sdpa_linear.h \
|
||||
sdpa_newton.h sdpa_chordal.h
|
||||
sdpa_solve.o: sdpa_solve.cpp sdpa_call.h sdpa_linear.h sdpa_struct.h \
|
||||
sdpa_include.h sdpa_right.h sdpa_tool.h sdpa_block.h sdpa_io.h \
|
||||
sdpa_parts.h sdpa_dataset.h
|
||||
sdpa_struct.o: sdpa_struct.cpp sdpa_struct.h sdpa_include.h sdpa_right.h \
|
||||
sdpa_tool.h sdpa_block.h sdpa_algebra.h sdpa_linear.h sdpa_dataset.h
|
||||
sdpa_tool.o: sdpa_tool.cpp sdpa_tool.h sdpa_right.h
|
||||
Vendored
+62
@@ -0,0 +1,62 @@
|
||||
#########################################################
|
||||
# Edit below accordingly your environment
|
||||
#########################################################
|
||||
|
||||
# The base directory of SDPA-C
|
||||
sdpac_dir = $(HOME)/sdpa-c
|
||||
|
||||
# The compilers
|
||||
CC = gcc
|
||||
CXX = g++
|
||||
FC = gfortran
|
||||
|
||||
# The compiler options
|
||||
# To generate mex files, you should not remove '-fPIC' from FLAGS
|
||||
# When you use OpenBLAS, you should not remove '-DOPENBLAS' from CXXFLAGS
|
||||
CFLAGS = -O3 -fPIC
|
||||
CXXFLAGS = -O3 -fPIC -DOPENBLAS
|
||||
FCFLAGS = -O3 -fPIC
|
||||
|
||||
|
||||
#########################################################
|
||||
# Usually, you do not have to edit below
|
||||
#########################################################
|
||||
|
||||
SDPAC_VERSION = \"7.3.8\"
|
||||
sdpac_lib = libsdpa-c.a
|
||||
sdpac_exe = sdpa-c
|
||||
|
||||
## do not add '/' to the end of suitesparse_dir
|
||||
suitesparse_dir = $(sdpac_dir)/SuiteSparse
|
||||
suitesparse_include = -I$(suitesparse_dir)/CHOLMOD/Include \
|
||||
-I$(suitesparse_dir)/SuiteSparse_config
|
||||
suitesparse_lib = $(suitesparse_dir)/CHOLMOD/Lib/libcholmod.a \
|
||||
$(suitesparse_dir)/CCOLAMD/Lib/libccolamd.a \
|
||||
$(suitesparse_dir)/COLAMD/Lib/libcolamd.a \
|
||||
$(suitesparse_dir)/CAMD/Lib/libcamd.a \
|
||||
$(suitesparse_dir)/AMD/Lib/libamd.a \
|
||||
$(suitesparse_dir)/metis-5.1.0/libmetis.a \
|
||||
$(suitesparse_dir)/SuiteSparse_config/libsuitesparseconfig.a
|
||||
suitesparse_ver = 5.1.2
|
||||
|
||||
## do not add '/' to the end of mumps_dir
|
||||
mumps_dir = $(sdpac_dir)/mumps
|
||||
mumps_include = -I$(mumps_dir)/include
|
||||
mumps_lib = $(mumps_dir)/lib/libdmumps.a \
|
||||
$(mumps_dir)/lib/libmumps_common.a \
|
||||
$(mumps_dir)/lib/libpord.a \
|
||||
$(mumps_dir)/libseq/libmpiseq.a
|
||||
mumps_ver = 5.1.2
|
||||
mumps_tar_file = mumps_${mumps_ver}.orig.tar.gz
|
||||
|
||||
## do not add '/' to the end of openblas_dir
|
||||
openblas_dir = $(sdpac_dir)/OpenBLAS
|
||||
openblas_lib = $(openblas_dir)/libopenblas.a
|
||||
|
||||
openmp_lib = -lgomp -lpthread
|
||||
fortran_lib = -lgfortran
|
||||
realtime_lib = -lrt
|
||||
|
||||
sdpac_all_include = $(suitesparse_include) $(mumps_include)
|
||||
sdpac_all_lib = $(suitesparse_lib) $(mumps_lib) $(openblas_lib) \
|
||||
$(openmp_lib) $(fortran_lib) $(realtime_lib)
|
||||
Vendored
+60
@@ -0,0 +1,60 @@
|
||||
This is a short list for SDPA-M command.
|
||||
|
||||
(1) read_data.m
|
||||
>> [mDIM,nBLOCK,bLOCKsTRUCT,c,F] = read_data('example1.dat-s');
|
||||
will read 'example1.dat-s' into the SDPA-M structures.
|
||||
|
||||
(2) paramC.m
|
||||
>> OPTION=paramC;
|
||||
will prepare default parameter. You can change the parameter
|
||||
by this OPTION structure.
|
||||
|
||||
(3) sdpam.m
|
||||
>> [objVal,x,X,Y,INFO] = sdpam(mDIM,nBLOCK,bLOCKsTRUCT,c,F);
|
||||
or
|
||||
>> [objVal,x,X,Y,INFO] = sdpam(mDIM,nBLOCK,bLOCKsTRUCT,c,F,OPTION);
|
||||
will solve the SDP.
|
||||
|
||||
(4) gensdpafile.m
|
||||
>> gensdpafile('myexample.dat-s',mDIM,nBLOCK,bLOCKsTRUCT,c,F);
|
||||
will output the SDPA-M structure into 'myexample.dat-s'.
|
||||
|
||||
(5) initial_point.m
|
||||
>> [x0,X0,Y0] = initial_point('example1.ini-s', mDIM, nBLOCK, bLOCKsTRUCT);
|
||||
will read an initial point from 'example1.ini-s'.
|
||||
You need to prepare mDIM, nBLOCK, bLOCKsTRUCT by read_data.m
|
||||
|
||||
(6) SDPAToSedumi.m
|
||||
>> [At,b,c,K,blockStruct] = SDPAToSedumi('example1.dat-s');
|
||||
will read 'example1.dat-s' into SeDuMi structures with
|
||||
an additional structure 'blockStruct'.
|
||||
|
||||
(7) sedumiwrap.m
|
||||
>> [x,y,info]=sedumiwrap(A,b,c,K,pars,OPTION);
|
||||
will solve the SDP given in SeDuMi strucutres.
|
||||
The 5th argument 'pars' will be ignored
|
||||
and the 6th argument can be prepared by param.m
|
||||
|
||||
(8) SedumiToSDPA.m
|
||||
>> SedumiToSDPA('myexample.dat-s',A,b,c,K,'%8.16e');
|
||||
will output SeDuMi structures into 'myexample.dat-s'.
|
||||
'%8.16' determines the output style by printf-format.
|
||||
|
||||
(9) read_output.m
|
||||
>> [objVal,x,X,Y,INFO] = read_output('example1.result',mDIM,nBLOCK,bLOCKsTRUCT);
|
||||
will read the result file generated by SDPA.
|
||||
If you solve 'example1.dat-s' by
|
||||
$ ./sdpa example1.dat-s example1.result
|
||||
then this result can be read by
|
||||
>> [mDIM,nBLOCK,bLOCKsTRUCT,c,F] = read_data('example1.dat-s');
|
||||
>> [objVal,x,X,Y,INFO] = read_output('example1.result',mDIM,nBLOCK,bLOCKsTRUCT);
|
||||
|
||||
(10) read_outputSedumi.m
|
||||
>> [x,y,info] = read_outputSedumi('example1.result',m,K);
|
||||
will read the result file generated by SDPA.
|
||||
If you solve 'example1.dat-s' by
|
||||
$ ./sdpa example1.dat-s example1.result
|
||||
then this result can be read by
|
||||
>> [At,b,c,K,blockStruct] = SDPAToSedumi('example1.dat-s');
|
||||
>> [x,y,info] = read_outputSedumi('example1.result',m,K);
|
||||
|
||||
Vendored
+131
@@ -0,0 +1,131 @@
|
||||
#
|
||||
# SDPA-M: $Revision: 7.3 $
|
||||
#
|
||||
# For Matlab
|
||||
# $ make
|
||||
# For Octave
|
||||
# $ make COMPILE_ENVIRONMENT=octave
|
||||
|
||||
# after "make install", you can find
|
||||
# 'make.inc' in 'share/sdpa' sub-directory under the installed directory
|
||||
# For example
|
||||
# make MAKE_INCLUDE_DIR=/usr/share/sdpa
|
||||
# or
|
||||
# make MAKE_INCLUDE_DIR=/usr/local/share/sdpa
|
||||
# In addition, for Octave, you should try
|
||||
# make MAKE_INCLUDE_DIR=/usr/local/share/sdpa COMPILE_ENVIRONMENT=octave
|
||||
|
||||
|
||||
# To compile with mingw, the following command is a sample.
|
||||
# Your need to modify directory names and compiler names.
|
||||
# make MEX="i586-mingw32msvc-g++ -shared" COMPILE_ENVIRONMENT=octave \
|
||||
# PRINTF_INT_STYLE=-DPRINTF_INT_STYLE=\\\"%zd\\\" \
|
||||
# OUTPUT_FORMAT="-o \$@.mexw32" \
|
||||
# MATLAB_INCLUDE="-Imatlab-extern/include" \
|
||||
# MATLAB_LIBS="-I/matlab-extern/microsoft/libmx.lib -I/matlab-extern/microsoft/libmex.lib" \
|
||||
|
||||
|
||||
# for only SDPA-Project members
|
||||
# set DEVELOPEMENT_STAGE=1 to compile without 'make install'
|
||||
# For example
|
||||
# make MAKE_INCLUDE_DIR=../etc DEVELOPEMENT_STAGE=1
|
||||
# In addition, for Octave, you should try
|
||||
# make MAKE_INCLUDE_DIR=../etc DEVELOPEMENT_STAGE=1 COMPILE_ENVIRONMENT=octave
|
||||
|
||||
# This file is a component of SDPA
|
||||
# Copyright (C) 2004-2013 SDPA Project
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 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 General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
MAKE_INCLUDE_DIR=..
|
||||
-include ${MAKE_INCLUDE_DIR}/make.inc
|
||||
# after "make install", you can find
|
||||
# 'make.inc' in 'share/sdpa' sub-directory under the installed directory
|
||||
# For example
|
||||
# make MAKE_INCLUDE_DIR=/usr/share/sdpa
|
||||
# or
|
||||
# make MAKE_INCLUDE_DIR=/usr/local/share/sdpa
|
||||
|
||||
MEX = mex
|
||||
DEF_FPIC = -fPIC
|
||||
|
||||
CXXFLAGSOPTIONS = CXXFLAGS="-Wall -fPIC" -O -DNDEBUG CC=${CC} CXX=${CXX}
|
||||
LARGEARRAYOPTION = -largeArrayDims
|
||||
|
||||
SDPA_INCLUDE = -I${SDPA_DIR}/include
|
||||
ifeq ($(DEVELOPEMENT_STAGE),1)
|
||||
SDPA_INCLUDE = -I..
|
||||
SDPA_LIB = ../libsdpa-c.a
|
||||
endif
|
||||
|
||||
PRINTF_INT_STYLE = -DPRINTF_INT_STYLE=\\\"%zd\\\"
|
||||
# Output format is usually automatically set by mex command.
|
||||
OUTPUT_FORMAT =
|
||||
|
||||
ifeq ($(COMPILE_ENVIRONMENT),octave)
|
||||
MEX = CC=${CC} CXX=${CXX} mkoctfile --mex
|
||||
CXXFLAGSOPTIONS =
|
||||
LARGEARRAYOPTION =
|
||||
PRINTF_INT_STYLE = -DPRINTF_INT_STYLE=\\\"%d\\\"
|
||||
endif
|
||||
|
||||
ALL_OPTION = ${CXXFLAGSOPTIONS} ${LARGEARRAYOPTION} ${PRINTF_INT_STYLE}
|
||||
|
||||
all: mexsdpaC mexSedumiWrapC
|
||||
# all: mexSedumiWrap
|
||||
|
||||
mexBinaryCheck:
|
||||
@echo "---------------------------------------------"
|
||||
@echo "Mex Compilation Start "
|
||||
@echo "---------------------------------------------"
|
||||
@if [ -f $(MEX) ]; then \
|
||||
echo "---------------------------------------------" ;\
|
||||
echo " We use " ;\
|
||||
echo " " $(MEX) ;\
|
||||
echo " for Mex compilaton " ;\
|
||||
echo "---------------------------------------------" ;\
|
||||
else \
|
||||
echo "---------------------------------------------" ;\
|
||||
echo "Automatic search is failed, " ;\
|
||||
echo " Set the full path for mex command mannually " ;\
|
||||
echo " in "`pwd`"/Makekefile" ;\
|
||||
echo " and try 'make' in `pwd` " ;\
|
||||
echo "---------------------------------------------" ;\
|
||||
false ;\
|
||||
fi
|
||||
|
||||
mexsdpaC:
|
||||
${MEX} ${ALL_OPTION} \
|
||||
${OUTPUT_FORMAT} \
|
||||
${SDPA_INCLUDE} ${sdpac_all_include} \
|
||||
mexsdpaC.cpp mexFprintf.c \
|
||||
${SDPA_LIB} ${sdpac_all_lib}
|
||||
|
||||
mexSedumiWrapC:
|
||||
${MEX} ${ALL_OPTION} \
|
||||
${OUTPUT_FORMAT} \
|
||||
${SDPA_INCLUDE} ${sdpac_all_include} \
|
||||
mexSedumiWrapC.cpp mexFprintf.c \
|
||||
${SDPA_LIB} ${sdpac_all_lib}
|
||||
|
||||
# clean all generated files
|
||||
clean:
|
||||
rm -f *~ *.o
|
||||
dist-clean: clean
|
||||
rm -f mexsdpaC.mex* mexSedumiWrapC.mex*
|
||||
|
||||
#
|
||||
# End of File
|
||||
#
|
||||
Vendored
+116
@@ -0,0 +1,116 @@
|
||||
/* -------------------------------------------------------------
|
||||
|
||||
This file is a component of SDPA
|
||||
Copyright (C) 2004-2013 SDPA Project
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
------------------------------------------------------------- */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <mex.h>
|
||||
|
||||
|
||||
#define BUF_LENGTH 4096
|
||||
|
||||
int fprintf(FILE *stream, const char *format, ...)
|
||||
{
|
||||
va_list arg;
|
||||
va_start(arg,format);
|
||||
int return_size = 0;
|
||||
if (stream == stdout) {
|
||||
char tmp_buf[BUF_LENGTH];
|
||||
vsprintf(tmp_buf,format,arg);
|
||||
#if 0
|
||||
printf("tmp_buf = %s",tmp_buf);
|
||||
#endif
|
||||
mexPrintf(tmp_buf);
|
||||
mexEvalString("drawnow;"); /* to dump string.*/
|
||||
return_size = strlen(tmp_buf);
|
||||
if ( return_size >= BUF_LENGTH ) {
|
||||
mexPrintf("Too Long Message To PrintOut "
|
||||
"(some part might be truncated)");
|
||||
}
|
||||
}
|
||||
else {
|
||||
return_size = vfprintf(stream,format,arg);
|
||||
}
|
||||
va_end(arg);
|
||||
return return_size;
|
||||
}
|
||||
|
||||
static int internal_fprintf(FILE *stream, const char *format, ...)
|
||||
{
|
||||
va_list arg;
|
||||
va_start(arg,format);
|
||||
int return_size = 0;
|
||||
return_size = vfprintf(stream,format,arg);
|
||||
va_end(arg);
|
||||
return return_size;
|
||||
}
|
||||
|
||||
size_t fwrite(const void *ptr, size_t size, size_t nmemb,
|
||||
FILE *stream)
|
||||
{
|
||||
#if 1
|
||||
fprintf(stream,"%s",(const char*)ptr);
|
||||
#else
|
||||
// internal_fprintf does not work well here
|
||||
internal_fprintf(stream, (const char*) internal_fprintf);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
int fputc(int c, FILE* fp)
|
||||
{
|
||||
if (fp == stdout) {
|
||||
mexPrintf("%c",(unsigned char)c);
|
||||
}
|
||||
else {
|
||||
internal_fprintf(fp,"%c",c);
|
||||
/* fprintf(fp,"%c ",c);*/
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
#ifdef __GNUC__
|
||||
/*Only GNU, to avoid
|
||||
warning: 'noreturn' function does return
|
||||
*/
|
||||
static void internal_exit() __attribute__ ((noreturn));
|
||||
extern void mexErrMsgTxt(const char*) __attribute__ ((noreturn));
|
||||
void exit() __attribute__ ((noreturn));
|
||||
void abort() __attribute__ ((noreturn));
|
||||
#endif
|
||||
|
||||
static void internal_exit()
|
||||
{
|
||||
mexWarnMsgTxt("SDPA-C exits with some error.");
|
||||
mexWarnMsgTxt("Matlab should be reboot to clear up memory space.");
|
||||
mexErrMsgTxt("SDPA-C exits with some error.");
|
||||
}
|
||||
|
||||
void exit(int status)
|
||||
{
|
||||
internal_exit();
|
||||
}
|
||||
void abort(void)
|
||||
{
|
||||
internal_exit();
|
||||
}
|
||||
Vendored
+655
@@ -0,0 +1,655 @@
|
||||
/*
|
||||
* This file is a component of SDPA
|
||||
* Copyright (C) 2004-2013 SDPA Project
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* SDPA-M: 7.3
|
||||
* mexsdpa.cpp
|
||||
*/
|
||||
|
||||
#include <mex.h>
|
||||
/*
|
||||
* SDPA header files
|
||||
*/
|
||||
#include <sdpa_tool.h>
|
||||
#include <sdpa_call.h>
|
||||
using namespace sdpa;
|
||||
|
||||
extern void _main();
|
||||
|
||||
void sdpasolver(mxArray* At_ptr, mxArray* b_ptr, mxArray* c_ptr,
|
||||
mxArray* K_ptr, mxArray* OPTION_ptr,
|
||||
mxArray* x_ptr, mxArray* y_ptr,
|
||||
mxArray* info_ptr)
|
||||
{
|
||||
time_t ltime;
|
||||
time(<ime);
|
||||
char string_time[1024];
|
||||
strcpy(string_time,ctime(<ime));
|
||||
string_time[strlen(string_time)-1]='\0';
|
||||
|
||||
SDPA sdpa;
|
||||
|
||||
int maxIteration = 0;
|
||||
double param = 0.0;
|
||||
/* mxArray pointer */
|
||||
mxArray *field_ptr = NULL;
|
||||
int nSymmChk = 0;
|
||||
int nDimacs = 0;
|
||||
|
||||
/* strings for phase value */
|
||||
const char *szPhase[] = {
|
||||
"noINFO", "pFEAS", "dFEAS", "pdFEAS", "pdINF",
|
||||
"pFEAS_dINF", "pINF_dFEAS", "pdOPT", "pUNBD", "dUNBD"};
|
||||
|
||||
/* output file */
|
||||
char *outfile = NULL;
|
||||
FILE *fp = NULL;
|
||||
FILE *fpResult = NULL;
|
||||
int nOutfile = 0;
|
||||
|
||||
mwSize mDIM;
|
||||
mwSize nBLOCK;
|
||||
|
||||
/* temporary variables */
|
||||
mwIndex k;
|
||||
int size;
|
||||
mwSize mwsize;
|
||||
double *tmp_ptr = NULL;
|
||||
char* tmpPrint = NULL;
|
||||
|
||||
TimeStart(SDPA_START);
|
||||
TimeStart(SDPA_CONVERT_START);
|
||||
|
||||
/*** Set SDPA parameters by OPTIONS ***/
|
||||
/* Max Iteration */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "maxIteration");
|
||||
if( field_ptr != NULL ){
|
||||
maxIteration = (int)mxGetScalar(field_ptr);
|
||||
// mexPrintf("maxIteration = %d\n",maxIteration);
|
||||
sdpa.setParameterMaxIteration(maxIteration);
|
||||
}
|
||||
/* epsilonStar */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "epsilonStar");
|
||||
if( field_ptr != NULL ){
|
||||
param = *mxGetPr(field_ptr);
|
||||
sdpa.setParameterEpsilonStar(param);
|
||||
}
|
||||
/* lambdaStar */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "lambdaStar");
|
||||
if( field_ptr != NULL ){
|
||||
param = *mxGetPr(field_ptr);
|
||||
sdpa.setParameterLambdaStar(param);
|
||||
}
|
||||
/* omegaStar */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "omegaStar");
|
||||
if( field_ptr != NULL ){
|
||||
param = *mxGetPr(field_ptr);
|
||||
sdpa.setParameterOmegaStar(param);
|
||||
}
|
||||
/* lowerBound */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "lowerBound");
|
||||
if( field_ptr != NULL ){
|
||||
param = *mxGetPr(field_ptr);
|
||||
sdpa.setParameterLowerBound(param);
|
||||
}
|
||||
/* upperBound */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "upperBound");
|
||||
if( field_ptr != NULL ){
|
||||
param = *mxGetPr(field_ptr);
|
||||
sdpa.setParameterUpperBound(param);
|
||||
}
|
||||
/* betaStar */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "betaStar");
|
||||
if( field_ptr != NULL ){
|
||||
param = *mxGetPr(field_ptr);
|
||||
sdpa.setParameterBetaStar(param);
|
||||
}
|
||||
/* betaBar */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "betaBar");
|
||||
if( field_ptr != NULL ){
|
||||
param = *mxGetPr(field_ptr);
|
||||
sdpa.setParameterBetaBar(param);
|
||||
}
|
||||
/* gammaStar */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "gammaStar");
|
||||
if( field_ptr != NULL ){
|
||||
param = *mxGetPr(field_ptr);
|
||||
sdpa.setParameterGammaStar(param);
|
||||
}
|
||||
/* epsilonDash */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "epsilonDash");
|
||||
if( field_ptr != NULL ){
|
||||
param = *mxGetPr(field_ptr);
|
||||
sdpa.setParameterEpsilonDash(param);
|
||||
}
|
||||
/* xPrint */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "xPrint");
|
||||
if( field_ptr != NULL ){
|
||||
mwsize = mxGetM(field_ptr) * mxGetN(field_ptr) + 1;
|
||||
tmpPrint = (char*)mxCalloc(mwsize, sizeof(char));
|
||||
mxGetString(field_ptr, tmpPrint, mwsize);
|
||||
sdpa.setParameterPrintXVec(tmpPrint);
|
||||
mxFree(tmpPrint);
|
||||
}
|
||||
/* XPrint */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "XPrint");
|
||||
if( field_ptr != NULL ){
|
||||
mwsize = mxGetM(field_ptr) * mxGetN(field_ptr) + 1;
|
||||
tmpPrint = (char*)mxCalloc(mwsize, sizeof(char));
|
||||
mxGetString(field_ptr, tmpPrint, mwsize);
|
||||
sdpa.setParameterPrintXMat(tmpPrint);
|
||||
mxFree(tmpPrint);
|
||||
}
|
||||
/* YPrint */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "YPrint");
|
||||
if( field_ptr != NULL ){
|
||||
mwsize = mxGetM(field_ptr) * mxGetN(field_ptr) + 1;
|
||||
tmpPrint = (char*)mxCalloc(mwsize, sizeof(char));
|
||||
mxGetString(field_ptr, tmpPrint, mwsize);
|
||||
sdpa.setParameterPrintYMat(tmpPrint);
|
||||
mxFree(tmpPrint);
|
||||
}
|
||||
/* infPrint */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "infPrint");
|
||||
if( field_ptr != NULL ){
|
||||
mwsize = mxGetM(field_ptr) * mxGetN(field_ptr) + 1;
|
||||
tmpPrint = (char*)mxCalloc(mwsize, sizeof(char));
|
||||
mxGetString(field_ptr, tmpPrint, mwsize);
|
||||
sdpa.setParameterPrintInformation(tmpPrint);
|
||||
mxFree(tmpPrint);
|
||||
}
|
||||
|
||||
|
||||
/* isSymmetric */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "isSymmetric");
|
||||
if( field_ptr != NULL ){
|
||||
nSymmChk = (int)mxGetScalar(field_ptr);
|
||||
}
|
||||
/* isDimacs */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "isDimacs");
|
||||
if( field_ptr != NULL ){
|
||||
nDimacs = (int)mxGetScalar(field_ptr);
|
||||
}
|
||||
/* print */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "print");
|
||||
if( field_ptr != NULL ){
|
||||
mwsize = mxGetM(field_ptr) * mxGetN(field_ptr) + 1;
|
||||
if (mwsize == 1) {
|
||||
// mexPrintf("display is NULL\n");
|
||||
fp = NULL;
|
||||
}
|
||||
else {
|
||||
outfile = (char*)mxCalloc(mwsize, sizeof(char));
|
||||
mxGetString(field_ptr, outfile, mwsize);
|
||||
if( strncmp("display", outfile, mwsize - 1) == 0 ){
|
||||
fp = stdout;
|
||||
} else if( strncmp("no", outfile, mwsize - 1) == 0 ){
|
||||
fp = NULL;
|
||||
} else {
|
||||
fp = fopen(outfile, "at");
|
||||
if( fp == NULL ){
|
||||
mexPrintf("Failed to open %s\n", outfile);
|
||||
fp = stdout;
|
||||
} else {
|
||||
nOutfile = 1;
|
||||
}
|
||||
}
|
||||
mxFree(outfile);
|
||||
}
|
||||
} else {
|
||||
/* default setting is displaying information to stdout */
|
||||
fp = stdout;
|
||||
}
|
||||
sdpa.setDisplay(fp);
|
||||
|
||||
/* resultFile */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "resultFile");
|
||||
if( field_ptr != NULL ){
|
||||
mwsize = mxGetM(field_ptr) * mxGetN(field_ptr) + 1;
|
||||
if (mwsize == 1) {
|
||||
// mexPrintf("resultFile is NULL\n");
|
||||
}
|
||||
else {
|
||||
outfile = (char*)mxCalloc(mwsize, sizeof(char));
|
||||
mxGetString(field_ptr, outfile, mwsize);
|
||||
if ( strncmp("no", outfile, mwsize - 1) == 0 ) {
|
||||
mexPrintf("resultFile is NULL\n");
|
||||
}
|
||||
else {
|
||||
fpResult = fopen(outfile, "w");
|
||||
if ( fpResult == NULL ) {
|
||||
mexPrintf("Failed to open %s\n", outfile);
|
||||
mexPrintf("Skip the detail file\n");
|
||||
} else {
|
||||
sdpa.setResultFile(fpResult);
|
||||
}
|
||||
}
|
||||
mxFree(outfile);
|
||||
}
|
||||
}
|
||||
|
||||
if (fp) {
|
||||
fprintf(fp,"SDPA-C start at [%s]\n",string_time);
|
||||
}
|
||||
if (fpResult) {
|
||||
fprintf(fpResult,"SDPA-C start at [%s]\n",string_time);
|
||||
}
|
||||
|
||||
if (nDimacs != 0) {
|
||||
if (sdpa.judgeDimacsAvailability() == false) {
|
||||
if (fp) {
|
||||
fprintf(fp, "Dimacs will be skipped by XPrint and YPrint parameter.\n");
|
||||
}
|
||||
if (fpResult) {
|
||||
fprintf(fpResult, "Dimacs will be skipped by XPrint and YPrint parameter.\n");
|
||||
}
|
||||
nDimacs = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* NumThreads */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "NumThreads");
|
||||
if( field_ptr != NULL ){
|
||||
sdpa.setNumThreads((int)mxGetScalar(field_ptr));
|
||||
}
|
||||
|
||||
/*** initialize SDPA class members ***/
|
||||
/* mDIM */
|
||||
mDIM = mxGetN(At_ptr);
|
||||
sdpa.inputConstraintNumber(mDIM);
|
||||
/* nBLOCK */
|
||||
nBLOCK = 0;
|
||||
mwSize K_l = 0;
|
||||
int isK_l = 0; // 1 (K_l > 0) or 0 (K_l == 0)
|
||||
field_ptr = mxGetField(K_ptr, 0, "l");
|
||||
if (field_ptr != NULL) {
|
||||
K_l = (mwSize)((mxGetPr(field_ptr))[0]);
|
||||
#if 0
|
||||
mexPrintf("K_l = %zd\n", K_l);
|
||||
#endif
|
||||
if (K_l > 0) {
|
||||
isK_l = 1;
|
||||
nBLOCK++;
|
||||
}
|
||||
}
|
||||
mwSize* K_s = NULL;
|
||||
mwSize* K_sdpConeStart = NULL;
|
||||
int K_sdpNoCones = 0;
|
||||
field_ptr = mxGetField(K_ptr, 0, "s");
|
||||
if (field_ptr != NULL) {
|
||||
K_sdpNoCones = (int) mxGetM(field_ptr);
|
||||
K_s = (mwSize*) mxCalloc(K_sdpNoCones, sizeof(mwSize));
|
||||
K_sdpConeStart = (mwSize*) mxCalloc(K_sdpNoCones+1, sizeof(mwSize));
|
||||
K_sdpConeStart[0] = 0;
|
||||
for (int l=0; l<K_sdpNoCones; ++l) {
|
||||
K_s[l] = (mwSize)((mxGetPr(field_ptr))[l]);
|
||||
#if 0
|
||||
mexPrintf("K_s[%zd] = %zd\n", l+isK_l+1, K_s[l]);
|
||||
#endif
|
||||
K_sdpConeStart[l+1] = K_sdpConeStart[l] + K_s[l]*K_s[l];
|
||||
nBLOCK++;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
mexPrintf("isK_l = %d, nBlock = %d \n", isK_l, nBLOCK);
|
||||
#endif
|
||||
sdpa.inputBlockNumber(nBLOCK);
|
||||
if (isK_l > 0) {
|
||||
sdpa.inputBlockSize(1, K_l);
|
||||
sdpa.inputBlockType(1, SDPA::LP);
|
||||
}
|
||||
for (int l=0; l<K_sdpNoCones; ++l) {
|
||||
#if 0
|
||||
mexPrintf("l+isK_l+1 = %d, K_s = %d \n", l+isK_l+1, K_s[l]);
|
||||
#endif
|
||||
sdpa.inputBlockSize(l+isK_l+1, K_s[l]);
|
||||
sdpa.inputBlockType(l+isK_l+1, SDPA::SDP);
|
||||
}
|
||||
|
||||
/* Execute initializeUpperTriangleSpace() */
|
||||
sdpa.initializeUpperTriangleSpace();
|
||||
|
||||
/* cVECT = -b*/
|
||||
double* b = mxGetPr(b_ptr);
|
||||
for(mwSize i = 0; i < mDIM; i++){
|
||||
sdpa.inputCVec((int)i+1, -b[i]);
|
||||
}
|
||||
|
||||
/*** Count NonZeroNumber in coefficience matrices ***/
|
||||
// Do nothing for SDPA 7
|
||||
|
||||
/* F_0 = - C */
|
||||
if (mxIsEmpty(c_ptr) || mxGetNzmax(c_ptr) == 0
|
||||
|| (mxGetJc(c_ptr))[1] == 0) {
|
||||
mexPrintf("c = empty\n");
|
||||
}
|
||||
else {
|
||||
mwIndex* C_row = mxGetIr(c_ptr);
|
||||
mwIndex* C_column = mxGetJc(c_ptr);
|
||||
double* C_ele = mxGetPr(c_ptr);
|
||||
mwIndex C_length = C_column[1];
|
||||
int currentSdpCone = 0;
|
||||
for (mwSize index = 0; index<C_length; ++index) {
|
||||
mwSize C_j = C_row[index];
|
||||
/* A_0 = - C */
|
||||
double ele = -C_ele[index];
|
||||
// mexPrintf("C_j = %zd, ele = %e\n", C_j, ele);
|
||||
if (C_j < K_l) {
|
||||
sdpa.inputElement(0, 1, C_j+1, C_j+1, ele);
|
||||
}
|
||||
else {
|
||||
C_j -= K_l;
|
||||
while (K_sdpConeStart[currentSdpCone+1] <= C_j) {
|
||||
currentSdpCone++;
|
||||
}
|
||||
int index2, i,j;
|
||||
index2 = C_j - K_sdpConeStart[currentSdpCone];
|
||||
i = index2 / K_s[currentSdpCone];
|
||||
j = index2 % K_s[currentSdpCone];
|
||||
if (i <= j) {
|
||||
// Only upper triangular is input
|
||||
#if 0
|
||||
mexPrintf("input k=%d, l=%d, i=%d, j=%d, v=%e\n",
|
||||
0, isK_l + currentSdpCone+1,i+1, j+1, ele);
|
||||
#endif
|
||||
sdpa.inputElement(0, isK_l + currentSdpCone+1,i+1, j+1, ele);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* F_{k+1} = - A_k */
|
||||
mwIndex* At_row = mxGetIr(At_ptr);
|
||||
mwIndex* At_column = mxGetJc(At_ptr);
|
||||
double* At_ele = mxGetPr(At_ptr);
|
||||
for (k=0; k<mDIM; ++k) {
|
||||
mwIndex Ak_start = At_column[k ];
|
||||
mwIndex Ak_end = At_column[k+1];
|
||||
int currentSdpCone = 0;
|
||||
for (mwSize index = Ak_start; index<Ak_end; ++index) {
|
||||
mwSize Ak_j = At_row[index];
|
||||
/* F_{k+1} = - A_k */
|
||||
double ele = -At_ele[index];
|
||||
if (Ak_j < K_l) {
|
||||
sdpa.inputElement(k+1, 1, Ak_j+1, Ak_j+1, ele);
|
||||
}
|
||||
else {
|
||||
Ak_j -= K_l;
|
||||
while (K_sdpConeStart[currentSdpCone+1] <= Ak_j) {
|
||||
currentSdpCone++;
|
||||
}
|
||||
int index2, i,j;
|
||||
index2 = Ak_j - K_sdpConeStart[currentSdpCone];
|
||||
i = index2 / K_s[currentSdpCone];
|
||||
j = index2 % K_s[currentSdpCone];
|
||||
if (i <= j) {
|
||||
// Only upper triangular is input
|
||||
#if 0
|
||||
mexPrintf("input k=%d, l=%d, i=%d, j=%d, v=%e\n",
|
||||
k+1, isK_l + currentSdpCone+1,i+1, j+1, ele);
|
||||
#endif
|
||||
sdpa.inputElement(k+1, isK_l + currentSdpCone+1,i+1, j+1, ele);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*** Check the consistence of F, c ***/
|
||||
if( nSymmChk ){
|
||||
sdpa.initializeUpperTriangle(true);
|
||||
}
|
||||
else {
|
||||
sdpa.initializeUpperTriangle(false);
|
||||
}
|
||||
|
||||
// sdpa.writeInputSparse((char*)"b.dat-s",(char*)"%e");
|
||||
|
||||
/*** Solve SDP ***/
|
||||
sdpa.initializeSolve();
|
||||
mexPrintf("Converted to SDPA internal data / ");
|
||||
mexPrintf("Starting SDPA-C main loop\n");
|
||||
TimeEnd(SDPA_CONVERT_END);
|
||||
TimeStart(SDPA_SOLVE_START);
|
||||
sdpa.solve();
|
||||
TimeEnd(SDPA_SOLVE_END);
|
||||
TimeStart(SDPA_RETRIEVE_START);
|
||||
mexPrintf("Converting optimal solution to Sedumi format\n");
|
||||
/**** Set output values to arguments ****/
|
||||
|
||||
/* Optimal value for xVec */
|
||||
double* y = mxGetPr(y_ptr);
|
||||
tmp_ptr = sdpa.getResultXVec();
|
||||
if( tmp_ptr != NULL ){
|
||||
for(k = 0; k < mDIM; k++){
|
||||
y[k] = tmp_ptr[k];
|
||||
}
|
||||
}
|
||||
|
||||
/* Optimal value for YMat */
|
||||
double* x = mxGetPr(x_ptr);
|
||||
// if sdpa.getResultYMat(1) == NULL, YMat is not computed
|
||||
if (sdpa.getResultYMat(1) != NULL) {
|
||||
if (isK_l > 0) {
|
||||
size = sdpa.getBlockSize(1);
|
||||
tmp_ptr = sdpa.getResultYMat(1);
|
||||
for (int index = 0; index < size; ++index) {
|
||||
x[index] = tmp_ptr[index];
|
||||
}
|
||||
}
|
||||
for (int l=0; l<K_sdpNoCones; ++l) {
|
||||
size = sdpa.getBlockSize(l+isK_l+1);
|
||||
tmp_ptr = sdpa.getResultYMat(l+isK_l+1);
|
||||
for (int index = 0; index < size*size; ++index) {
|
||||
x[K_l + K_sdpConeStart[l] + index] = tmp_ptr[index];
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
rMessage("x is not computed by YPrint, and x will be empty matrix.");
|
||||
}
|
||||
TimeEnd(SDPA_RETRIEVE_END);
|
||||
|
||||
/* Dimacs Error Information */
|
||||
if (nDimacs != 0) {
|
||||
field_ptr = mxCreateNumericMatrix(6,1,mxDOUBLE_CLASS,mxREAL);
|
||||
double* dimacs_store = mxGetPr(field_ptr);
|
||||
double dimacs_error[7];
|
||||
if (sdpa.judgeDimacsAvailability() == false) {
|
||||
for (int i=0; i<=6; i++) {
|
||||
dimacs_store[i] = 0.0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
mexPrintf("Computing Dimacs Error\n");
|
||||
sdpa.getDimacsError(dimacs_error);
|
||||
for (int i=1; i<=6; i++) {
|
||||
dimacs_store[i-1] = dimacs_error[i];
|
||||
}
|
||||
}
|
||||
mxSetField(info_ptr, 0, "dimacs", field_ptr);
|
||||
}
|
||||
|
||||
|
||||
/* Phase information */
|
||||
field_ptr = mxCreateString(szPhase[sdpa.getPhaseValue()]);
|
||||
mxSetField(info_ptr, 0, "phasevalue", field_ptr);
|
||||
/* Iteration */
|
||||
field_ptr = mxCreateNumericMatrix(1,1,mxDOUBLE_CLASS,mxREAL);
|
||||
*mxGetPr(field_ptr) = (double)sdpa.getIteration();
|
||||
mxSetField(info_ptr, 0, "iteration", field_ptr);
|
||||
|
||||
/* primalObj */
|
||||
field_ptr = mxCreateNumericMatrix(1,1,mxDOUBLE_CLASS,mxREAL);
|
||||
*mxGetPr(field_ptr) = -sdpa.getDualObj();
|
||||
mxSetField(info_ptr, 0, "primalObj", field_ptr);
|
||||
/* dualObj */
|
||||
field_ptr = mxCreateNumericMatrix(1,1,mxDOUBLE_CLASS,mxREAL);
|
||||
*mxGetPr(field_ptr) = -sdpa.getPrimalObj();
|
||||
mxSetField(info_ptr, 0, "dualObj", field_ptr);
|
||||
/* primalError */
|
||||
field_ptr = mxCreateNumericMatrix(1,1,mxDOUBLE_CLASS,mxREAL);
|
||||
*mxGetPr(field_ptr) = sdpa.getDualError();
|
||||
mxSetField(info_ptr, 0, "primalError", field_ptr);
|
||||
/* dualError */
|
||||
field_ptr = mxCreateNumericMatrix(1,1,mxDOUBLE_CLASS,mxREAL);
|
||||
*mxGetPr(field_ptr) = sdpa.getPrimalError();
|
||||
mxSetField(info_ptr, 0, "dualError", field_ptr);
|
||||
/* digits */
|
||||
field_ptr = mxCreateNumericMatrix(1,1,mxDOUBLE_CLASS,mxREAL);
|
||||
*mxGetPr(field_ptr) = sdpa.getDigits();
|
||||
mxSetField(info_ptr, 0, "digits", field_ptr);
|
||||
/* dualityGap */
|
||||
field_ptr = mxCreateNumericMatrix(1,1,mxDOUBLE_CLASS,mxREAL);
|
||||
*mxGetPr(field_ptr) = sdpa.getDualityGap();
|
||||
mxSetField(info_ptr, 0, "dualityGap", field_ptr);
|
||||
/* mu */
|
||||
field_ptr = mxCreateNumericMatrix(1,1,mxDOUBLE_CLASS,mxREAL);
|
||||
*mxGetPr(field_ptr) = sdpa.getMu();
|
||||
mxSetField(info_ptr, 0, "mu", field_ptr);
|
||||
|
||||
/* solveTime */
|
||||
field_ptr = mxCreateNumericMatrix(1,1,mxDOUBLE_CLASS,mxREAL);
|
||||
*mxGetPr(field_ptr) = TimeCal(SDPA_SOLVE_START,SDPA_SOLVE_END);
|
||||
mxSetField(info_ptr, 0, "solveTime", field_ptr);
|
||||
/* convertingTime */
|
||||
field_ptr = mxCreateNumericMatrix(1,1,mxDOUBLE_CLASS,mxREAL);
|
||||
*mxGetPr(field_ptr) = TimeCal(SDPA_CONVERT_START,SDPA_CONVERT_END);
|
||||
mxSetField(info_ptr, 0, "convertingTime", field_ptr);
|
||||
/* retrivingTime */
|
||||
field_ptr = mxCreateNumericMatrix(1,1,mxDOUBLE_CLASS,mxREAL);
|
||||
*mxGetPr(field_ptr) = TimeCal(SDPA_RETRIEVE_START,SDPA_RETRIEVE_END);
|
||||
mxSetField(info_ptr, 0, "retrievingTime", field_ptr);
|
||||
/* retrivingTime */
|
||||
field_ptr = mxCreateNumericMatrix(1,1,mxDOUBLE_CLASS,mxREAL);
|
||||
TimeEnd(SDPA_END);
|
||||
*mxGetPr(field_ptr) = TimeCal(SDPA_START,SDPA_END);
|
||||
mxSetField(info_ptr, 0, "sdpaTime", field_ptr);
|
||||
|
||||
time(<ime);
|
||||
strcpy(string_time,ctime(<ime));
|
||||
string_time[strlen(string_time)-1]='\0';
|
||||
|
||||
if (fp) {
|
||||
fprintf(fp,"SDPA-C end at [%s]\n",string_time);
|
||||
}
|
||||
if (fpResult) {
|
||||
fprintf(fpResult,"SDPA-C end at [%s]\n",string_time);
|
||||
}
|
||||
/* close output file */
|
||||
if( nOutfile ){
|
||||
fclose(fp);
|
||||
}
|
||||
if (fpResult != NULL) {
|
||||
fclose(fpResult);
|
||||
}
|
||||
|
||||
/*** Free allocated memory ****/
|
||||
mxFree(K_s);
|
||||
mxFree(K_sdpConeStart);
|
||||
sdpa.finalize();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Matlab gateway function
|
||||
*/
|
||||
void mexFunction(int nlhs, mxArray *plhs[],
|
||||
int nrhs, const mxArray *prhs[])
|
||||
{
|
||||
/* Decleration of variables */
|
||||
|
||||
mxArray* At_ptr;
|
||||
mxArray* b_ptr;
|
||||
mxArray* c_ptr;
|
||||
mxArray* K_ptr;
|
||||
mxArray* OPTION_ptr;
|
||||
|
||||
mxArray* x_ptr;
|
||||
mxArray* y_ptr;
|
||||
mxArray* info_ptr;
|
||||
|
||||
const char *fnames[] = {
|
||||
"phasevalue",
|
||||
"iteration",
|
||||
"cpusec",
|
||||
"primalObj",
|
||||
"dualObj",
|
||||
"primalError",
|
||||
"dualError",
|
||||
"digits",
|
||||
"dualityGap",
|
||||
"mu",
|
||||
"dimacs",
|
||||
"solveTime",
|
||||
"convertingTime",
|
||||
"retrievingTime",
|
||||
"sdpaTime"
|
||||
};
|
||||
|
||||
/* Get the pointer of input variables */
|
||||
At_ptr = (mxArray*)prhs[0];
|
||||
b_ptr = (mxArray*)prhs[1];
|
||||
c_ptr = (mxArray*)prhs[2];
|
||||
K_ptr = (mxArray*)prhs[3];
|
||||
OPTION_ptr = (mxArray*)prhs[4];
|
||||
|
||||
mwSize m = mxGetM(b_ptr);
|
||||
mwSize n = mxGetM(c_ptr);
|
||||
|
||||
mxArray *field_ptr = NULL;
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "YPrint");
|
||||
bool x_ptr_empty = false;
|
||||
if( field_ptr != NULL ){
|
||||
mwSize mwsize = mxGetM(field_ptr) * mxGetN(field_ptr) + 1;
|
||||
char* tmpPrint = (char*)mxCalloc(mwsize, sizeof(char));
|
||||
mxGetString(field_ptr, tmpPrint, mwsize);
|
||||
#if 0
|
||||
rMessage("tmpPrint = " << tmpPrint
|
||||
<< " : NO_P_FORMAT " << NO_P_FORMAT);
|
||||
#endif
|
||||
if (strcmp(tmpPrint,NO_P_FORMAT) == 0) {
|
||||
x_ptr_empty = true;
|
||||
}
|
||||
mxFree(tmpPrint);
|
||||
}
|
||||
/* Create cellarrays for the output variables */
|
||||
if (x_ptr_empty == true) {
|
||||
rMessage("x is not computed by YPrint, and x will be empty matrix.");
|
||||
plhs[0] = mxCreateDoubleMatrix(0,0,mxREAL);
|
||||
}
|
||||
else {
|
||||
plhs[0] = mxCreateDoubleMatrix(n,1,mxREAL);
|
||||
}
|
||||
plhs[1] = mxCreateDoubleMatrix(m,1,mxREAL);
|
||||
plhs[2] = mxCreateStructMatrix(1,1,15,fnames);
|
||||
|
||||
//Get the pointer of output variables
|
||||
x_ptr = plhs[0];
|
||||
y_ptr = plhs[1];
|
||||
info_ptr = plhs[2];
|
||||
|
||||
/* Call sdpasolver here */
|
||||
sdpasolver(At_ptr,b_ptr,c_ptr,K_ptr,OPTION_ptr,
|
||||
x_ptr,y_ptr,info_ptr);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* End of File
|
||||
*/
|
||||
Vendored
+842
@@ -0,0 +1,842 @@
|
||||
/*
|
||||
* This file is a component of SDPA
|
||||
* Copyright (C) 2004-2013 SDPA Project
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* SDPA-M: 7.3
|
||||
* mexsdpa.cpp
|
||||
*/
|
||||
|
||||
#include <mex.h>
|
||||
/*
|
||||
* SDPA header files
|
||||
*/
|
||||
#include <sdpa_call.h>
|
||||
|
||||
extern void _main();
|
||||
|
||||
void sdpasolver(double *mDIM_ptr,
|
||||
double *nBLOCK_ptr,
|
||||
double *bLOCKsTRUCT_ptr,
|
||||
double *c_ptr,
|
||||
mxArray *F_ptr,
|
||||
double *x0_ptr,
|
||||
mxArray *X0_ptr,
|
||||
mxArray *Y0_ptr,
|
||||
mxArray *OPTION_ptr,
|
||||
int IniPt,
|
||||
double *objVal_ptr,
|
||||
double *x_ptr,
|
||||
mxArray *X_ptr,
|
||||
mxArray *Y_ptr,
|
||||
mxArray *INFO_ptr)
|
||||
{
|
||||
time_t ltime;
|
||||
time(<ime);
|
||||
char string_time[1024];
|
||||
strcpy(string_time,ctime(<ime));
|
||||
string_time[strlen(string_time)-1]='\0';
|
||||
|
||||
SDPA sdpa;
|
||||
|
||||
int maxIteration = 0;
|
||||
double param = 0.0;
|
||||
/* mxArray pointer */
|
||||
mxArray *field_ptr = NULL;
|
||||
mxArray *cell_ptr = NULL;
|
||||
|
||||
int nSymmChk = 0;
|
||||
int nDimacs = 0;
|
||||
|
||||
/* strings for phase value */
|
||||
const char *szPhase[] = {
|
||||
"noINFO", "pFEAS", "dFEAS", "pdFEAS", "pdINF",
|
||||
"pFEAS_dINF", "pINF_dFEAS", "pdOPT", "pUNBD", "dUNBD"};
|
||||
|
||||
/* output file */
|
||||
char *outfile = NULL;
|
||||
FILE *fp = NULL;
|
||||
FILE *fpResult = NULL;
|
||||
int nOutfile = 0;
|
||||
|
||||
mwSize mDIM;
|
||||
mwSize nBLOCK;
|
||||
|
||||
/* temporary variables */
|
||||
mwIndex i,j,k,l;
|
||||
int size;
|
||||
mwSize mwsize;
|
||||
mwIndex idx, startidx, endidx;
|
||||
mwSize sizeM, sizeN;
|
||||
mwIndex *subscript = NULL;
|
||||
mwIndex *dims = NULL;
|
||||
int cell_index = 0;
|
||||
mwIndex *ir_ptr = NULL;
|
||||
mwIndex *jc_ptr = NULL;
|
||||
double *tmp_ptr = NULL;
|
||||
double *result_ptr = NULL;
|
||||
char* tmpPrint = NULL;
|
||||
|
||||
/*** Set SDPA parameters by OPTIONS ***/
|
||||
/* Max Iteration */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "maxIteration");
|
||||
if( field_ptr != NULL ){
|
||||
maxIteration = (int)mxGetScalar(field_ptr);
|
||||
sdpa.setParameterMaxIteration(maxIteration);
|
||||
}
|
||||
/* epsilonStar */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "epsilonStar");
|
||||
if( field_ptr != NULL ){
|
||||
param = *mxGetPr(field_ptr);
|
||||
sdpa.setParameterEpsilonStar(param);
|
||||
}
|
||||
/* lambdaStar */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "lambdaStar");
|
||||
if( field_ptr != NULL ){
|
||||
param = *mxGetPr(field_ptr);
|
||||
sdpa.setParameterLambdaStar(param);
|
||||
}
|
||||
/* omegaStar */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "omegaStar");
|
||||
if( field_ptr != NULL ){
|
||||
param = *mxGetPr(field_ptr);
|
||||
sdpa.setParameterOmegaStar(param);
|
||||
}
|
||||
/* lowerBound */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "lowerBound");
|
||||
if( field_ptr != NULL ){
|
||||
param = *mxGetPr(field_ptr);
|
||||
sdpa.setParameterLowerBound(param);
|
||||
}
|
||||
/* upperBound */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "upperBound");
|
||||
if( field_ptr != NULL ){
|
||||
param = *mxGetPr(field_ptr);
|
||||
sdpa.setParameterUpperBound(param);
|
||||
}
|
||||
/* betaStar */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "betaStar");
|
||||
if( field_ptr != NULL ){
|
||||
param = *mxGetPr(field_ptr);
|
||||
sdpa.setParameterBetaStar(param);
|
||||
}
|
||||
/* betaBar */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "betaBar");
|
||||
if( field_ptr != NULL ){
|
||||
param = *mxGetPr(field_ptr);
|
||||
sdpa.setParameterBetaBar(param);
|
||||
}
|
||||
/* gammaStar */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "gammaStar");
|
||||
if( field_ptr != NULL ){
|
||||
param = *mxGetPr(field_ptr);
|
||||
sdpa.setParameterGammaStar(param);
|
||||
}
|
||||
/* epsilonDash */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "epsilonDash");
|
||||
if( field_ptr != NULL ){
|
||||
param = *mxGetPr(field_ptr);
|
||||
sdpa.setParameterEpsilonDash(param);
|
||||
}
|
||||
/* xPrint */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "xPrint");
|
||||
if( field_ptr != NULL ){
|
||||
mwsize = mxGetM(field_ptr) * mxGetN(field_ptr) + 1;
|
||||
tmpPrint = (char*)mxCalloc(mwsize, sizeof(char));
|
||||
mxGetString(field_ptr, tmpPrint, mwsize);
|
||||
sdpa.setParameterPrintXVec(tmpPrint);
|
||||
mxFree(tmpPrint);
|
||||
}
|
||||
/* XPrint */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "XPrint");
|
||||
if( field_ptr != NULL ){
|
||||
mwsize = mxGetM(field_ptr) * mxGetN(field_ptr) + 1;
|
||||
tmpPrint = (char*)mxCalloc(mwsize, sizeof(char));
|
||||
mxGetString(field_ptr, tmpPrint, mwsize);
|
||||
sdpa.setParameterPrintXMat(tmpPrint);
|
||||
mxFree(tmpPrint);
|
||||
}
|
||||
/* YPrint */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "YPrint");
|
||||
if( field_ptr != NULL ){
|
||||
mwsize = mxGetM(field_ptr) * mxGetN(field_ptr) + 1;
|
||||
tmpPrint = (char*)mxCalloc(mwsize, sizeof(char));
|
||||
mxGetString(field_ptr, tmpPrint, mwsize);
|
||||
sdpa.setParameterPrintYMat(tmpPrint);
|
||||
mxFree(tmpPrint);
|
||||
}
|
||||
/* infPrint */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "infPrint");
|
||||
if( field_ptr != NULL ){
|
||||
mwsize = mxGetM(field_ptr) * mxGetN(field_ptr) + 1;
|
||||
tmpPrint = (char*)mxCalloc(mwsize, sizeof(char));
|
||||
mxGetString(field_ptr, tmpPrint, mwsize);
|
||||
sdpa.setParameterPrintInformation(tmpPrint);
|
||||
mxFree(tmpPrint);
|
||||
}
|
||||
|
||||
/* isSymmetric */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "isSymmetric");
|
||||
if( field_ptr != NULL ){
|
||||
nSymmChk = (int)mxGetScalar(field_ptr);
|
||||
}
|
||||
/* isDimacs */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "isDimacs");
|
||||
if( field_ptr != NULL ){
|
||||
nDimacs = (int)mxGetScalar(field_ptr);
|
||||
}
|
||||
/* print */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "print");
|
||||
if( field_ptr != NULL ){
|
||||
mwsize = mxGetM(field_ptr) * mxGetN(field_ptr) + 1;
|
||||
if (mwsize == 1) {
|
||||
// mexPrintf("display is NULL\n");
|
||||
fp = NULL;
|
||||
}
|
||||
else {
|
||||
outfile = (char*)mxCalloc(mwsize, sizeof(char));
|
||||
mxGetString(field_ptr, outfile, mwsize);
|
||||
if( strncmp("display", outfile, mwsize - 1) == 0 ){
|
||||
fp = stdout;
|
||||
} else if( strncmp("no", outfile, mwsize - 1) == 0 ){
|
||||
fp = NULL;
|
||||
} else {
|
||||
fp = fopen(outfile, "at");
|
||||
if( fp == NULL ){
|
||||
mexPrintf("Failed to open %s\n", outfile);
|
||||
fp = stdout;
|
||||
} else {
|
||||
nOutfile = 1;
|
||||
}
|
||||
}
|
||||
mxFree(outfile);
|
||||
}
|
||||
} else {
|
||||
/* default setting is displaying information to stdout */
|
||||
fp = stdout;
|
||||
}
|
||||
sdpa.setDisplay(fp);
|
||||
|
||||
/* resultFile */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "resultFile");
|
||||
if( field_ptr != NULL ){
|
||||
mwsize = mxGetM(field_ptr) * mxGetN(field_ptr) + 1;
|
||||
if (mwsize == 1) {
|
||||
// mexPrintf("resultFile is NULL\n");
|
||||
}
|
||||
else {
|
||||
outfile = (char*)mxCalloc(mwsize, sizeof(char));
|
||||
mxGetString(field_ptr, outfile, mwsize);
|
||||
fpResult = fopen(outfile, "w");
|
||||
if( fpResult == NULL ){
|
||||
mexPrintf("Failed to open %s\n", outfile);
|
||||
mexPrintf("Skip the detail file\n");
|
||||
} else {
|
||||
sdpa.setResultFile(fpResult);
|
||||
}
|
||||
mxFree(outfile);
|
||||
}
|
||||
}
|
||||
|
||||
if (fp) {
|
||||
fprintf(fp,"SDPA-C start at [%s]\n",string_time);
|
||||
}
|
||||
if (fpResult) {
|
||||
fprintf(fpResult,"SDPA-C start at [%s]\n",string_time);
|
||||
}
|
||||
|
||||
if (nDimacs) {
|
||||
if (sdpa.judgeDimacsAvailability() == false) {
|
||||
if (fp) {
|
||||
fprintf(fp, "Dimacs will be skipped by XPrint and YPrint parameter.\n");
|
||||
}
|
||||
if (fpResult) {
|
||||
fprintf(fpResult, "Dimacs will be skipped by XPrint and YPrint parameter.\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* NumThreads */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "NumThreads");
|
||||
if( field_ptr != NULL ){
|
||||
sdpa.setNumThreads((int)mxGetScalar(field_ptr));
|
||||
}
|
||||
|
||||
/*** initialize SDPA class members ***/
|
||||
/* mDIM */
|
||||
mDIM = (mwSize)(*mDIM_ptr);
|
||||
sdpa.inputConstraintNumber(mDIM);
|
||||
/* nBLOCK */
|
||||
nBLOCK = (mwSize)(*nBLOCK_ptr);
|
||||
sdpa.inputBlockNumber(nBLOCK);
|
||||
/* bLOCKsTRUCT */
|
||||
for(i = 0; i < nBLOCK; i++){
|
||||
int bs = (int)(bLOCKsTRUCT_ptr[i]);
|
||||
sdpa.inputBlockSize(i+1,bs);
|
||||
if (bs < 0 || bs == 1) {
|
||||
sdpa.inputBlockType(i+1,SDPA::LP);
|
||||
}
|
||||
else {
|
||||
sdpa.inputBlockType(i+1,SDPA::SDP);
|
||||
}
|
||||
}
|
||||
/* Execute initializeUpperTriangleSpace() */
|
||||
sdpa.initializeUpperTriangleSpace();
|
||||
/* cVECT */
|
||||
for(i = 0; i < mDIM; i++){
|
||||
sdpa.inputCVec(i+1, c_ptr[i]);
|
||||
}
|
||||
|
||||
/*** Count NonZeroNumber in coefficience matrices ***/
|
||||
// Do nothing for SDPA 7
|
||||
|
||||
/*** Set coefficience matrices value ***/
|
||||
subscript = (mwIndex*)mxCalloc(2,sizeof(mwIndex));
|
||||
dims = (mwIndex*)mxGetDimensions(F_ptr);
|
||||
for(l = 0; l < dims[0]; l++){
|
||||
for(k = 0; k < dims[1]; k++){
|
||||
subscript[0]=l; subscript[1]=k;
|
||||
cell_index = mxCalcSingleSubscript(F_ptr, 2, subscript);
|
||||
cell_ptr = mxGetCell(F_ptr, cell_index);
|
||||
// mxGetDimensions at the next line is redundant,
|
||||
// but this is necessary to octave
|
||||
dims = (mwIndex*)mxGetDimensions(F_ptr);
|
||||
if( cell_ptr == NULL || mxIsEmpty(cell_ptr) ){
|
||||
/* If the cell is empty, we assume this cell as zero matrix */
|
||||
continue;
|
||||
}
|
||||
sizeM = mxGetM(cell_ptr);
|
||||
sizeN = mxGetN(cell_ptr);
|
||||
tmp_ptr = mxGetPr(cell_ptr);
|
||||
if( mxIsSparse(cell_ptr) ){
|
||||
/* Sparse Matrix */
|
||||
ir_ptr = mxGetIr(cell_ptr);
|
||||
jc_ptr = mxGetJc(cell_ptr);
|
||||
if( sizeM == 1 && sizeN != 1 ){
|
||||
/* Row Vector Case */
|
||||
for(j = 0; j < sizeN; j++){
|
||||
startidx = jc_ptr[j];
|
||||
endidx = jc_ptr[j+1];
|
||||
if( startidx == endidx ){ continue; }
|
||||
sdpa.inputElement( k, l+1, j+1, j+1, tmp_ptr[startidx]);
|
||||
}
|
||||
} else if( sizeM != 1 && sizeN == 1 ){
|
||||
/* Column Vector Case */
|
||||
endidx = jc_ptr[sizeN];
|
||||
for(idx = 0; idx < endidx; idx++){
|
||||
i = ir_ptr[idx];
|
||||
sdpa.inputElement( k, l+1, i+1, i+1, tmp_ptr[idx]);
|
||||
}
|
||||
} else {
|
||||
/* Matrix Case */
|
||||
for(j = 0; j < sizeN; j++){
|
||||
startidx = jc_ptr[j];
|
||||
endidx = jc_ptr[j+1];
|
||||
if( startidx == endidx ){ continue; }
|
||||
for(idx = startidx; idx < endidx; idx++){
|
||||
i = ir_ptr[idx];
|
||||
if( i <= j ){
|
||||
sdpa.inputElement( k, l+1, i+1, j+1, tmp_ptr[idx]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Dense Matrix */
|
||||
if( sdpa.getBlockType(l+1)==SDPA::SDP ){
|
||||
/* Full Matrix */
|
||||
for(j = 0; j < sizeN; j++){
|
||||
for(i = 0; i < sizeM; i++){
|
||||
if( i <= j ){
|
||||
if( tmp_ptr[j * sizeN + i] != 0 ){
|
||||
sdpa.inputElement(k, l+1, i+1, j+1,
|
||||
tmp_ptr[j * sizeN + i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Diagonal Matrix */
|
||||
if( sizeM == 1 && sizeN != 1 ){
|
||||
/* Row Vector Case */
|
||||
for(j = 0; j < sizeN; j++){
|
||||
if( tmp_ptr[j] != 0 ){
|
||||
sdpa.inputElement( k, l+1, j+1, j+1, tmp_ptr[j]);
|
||||
}
|
||||
}
|
||||
} else if( sizeM != 1 && sizeN == 1 ){
|
||||
/* Column Vector Case */
|
||||
for(i = 0; i < sizeM; i++){
|
||||
if( tmp_ptr[i] != 0 ){
|
||||
sdpa.inputElement( k, l+1, i+1, i+1, tmp_ptr[i]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Matrix Case */
|
||||
for(j = 0; j < sizeN; j++){
|
||||
if( tmp_ptr[j * sizeN + j] != 0 ){
|
||||
sdpa.inputElement( k, l+1, j+1, j+1,
|
||||
tmp_ptr[j * sizeN + j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*** Check the consistence of F, c ***/
|
||||
if( nSymmChk ){
|
||||
sdpa.initializeUpperTriangle(true);
|
||||
}
|
||||
else {
|
||||
sdpa.initializeUpperTriangle(false);
|
||||
}
|
||||
|
||||
/*** Check initial point ***/
|
||||
if( IniPt == 1 ){
|
||||
rMessage("Initial point is ignored in SDPA-C.");
|
||||
#if 0
|
||||
sdpa.setInitPoint(true);
|
||||
/* initial value for xVec */
|
||||
for(k = 0; k < mDIM; k++){
|
||||
sdpa.inputInitXVec( k+1, x0_ptr[k]);
|
||||
}
|
||||
/* initial value for XMat */
|
||||
cell_index = 0;
|
||||
for(l = 0; l < nBLOCK; l++){
|
||||
cell_ptr = mxGetCell(X0_ptr, cell_index);
|
||||
if( cell_ptr == NULL || mxIsEmpty(cell_ptr) ){
|
||||
/* If the cell is empty, we assume this cell as zero matrix */
|
||||
continue;
|
||||
}
|
||||
sizeM = mxGetM(cell_ptr);
|
||||
sizeN = mxGetN(cell_ptr);
|
||||
tmp_ptr = mxGetPr(cell_ptr);
|
||||
if( mxIsSparse(cell_ptr) ){
|
||||
/* Sparse Matrix */
|
||||
ir_ptr = mxGetIr(cell_ptr);
|
||||
jc_ptr = mxGetJc(cell_ptr);
|
||||
if( sizeM == 1 && sizeN != 1 ){
|
||||
/* Row Vector Case */
|
||||
for(j = 0; j < sizeN; j++){
|
||||
startidx = jc_ptr[j];
|
||||
endidx = jc_ptr[j+1];
|
||||
if( startidx == endidx ){ continue; }
|
||||
sdpa.inputInitXMat(l+1, j+1, j+1, tmp_ptr[startidx]);
|
||||
}
|
||||
} else if( sizeM != 1 && sizeN == 1 ){
|
||||
/* Column Vector Case */
|
||||
endidx = jc_ptr[sizeN];
|
||||
for(idx = 0; idx < endidx; idx++){
|
||||
i = ir_ptr[idx];
|
||||
sdpa.inputInitXMat(l+1, i+1, i+1, tmp_ptr[idx]);
|
||||
}
|
||||
} else {
|
||||
/* Matrix Case */
|
||||
for(j = 0; j < sizeN; j++){
|
||||
startidx = jc_ptr[j];
|
||||
endidx = jc_ptr[j+1];
|
||||
if( startidx == endidx ){ continue; }
|
||||
for(idx = startidx; idx < endidx; idx++){
|
||||
i = ir_ptr[idx];
|
||||
if( i <= j ){
|
||||
sdpa.inputInitXMat( l+1, i+1, j+1, tmp_ptr[idx]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Dense Matrix */
|
||||
if( sdpa.getBlockType(l+1) == SDPA::SDP ){
|
||||
/* Full Matrix */
|
||||
for(j = 0; j < sizeN; j++){
|
||||
for(i = 0; i < sizeM; i++){
|
||||
if( i <= j ){
|
||||
if( tmp_ptr[j * sizeN + i] != 0 ){
|
||||
sdpa.inputInitXMat( l+1, i+1, j+1,
|
||||
tmp_ptr[j * sizeN + i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Diagonal Matrix */
|
||||
if( sizeM == 1 && sizeN != 1 ){
|
||||
/* Row Vector Case */
|
||||
for(j = 0; j < sizeN; j++){
|
||||
if( tmp_ptr[j] != 0 ){
|
||||
sdpa.inputInitXMat( l+1, j+1, j+1, tmp_ptr[j]);
|
||||
}
|
||||
}
|
||||
} else if( sizeM != 1 && sizeN == 1 ){
|
||||
/* Column Vector Case */
|
||||
for(i = 0; i < sizeM; i++){
|
||||
if( tmp_ptr[i] != 0 ){
|
||||
sdpa.inputInitXMat( l+1, i+1, i+1, tmp_ptr[i]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Matrix Case */
|
||||
for(j = 0; j < sizeN; j++){
|
||||
if( tmp_ptr[j * sizeN + j] != 0 ){
|
||||
sdpa.inputInitXMat( l+1, j+1, j+1,
|
||||
tmp_ptr[j * sizeN + j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
cell_index++;
|
||||
}
|
||||
/* initial value for YMat */
|
||||
cell_index = 0;
|
||||
for(l = 0; l < nBLOCK; l++){
|
||||
cell_ptr = mxGetCell(Y0_ptr, cell_index);
|
||||
if( cell_ptr == NULL || mxIsEmpty(cell_ptr) ){
|
||||
/* If the cell is empty, we assume this cell as zero matrix */
|
||||
continue;
|
||||
}
|
||||
sizeM = mxGetM(cell_ptr);
|
||||
sizeN = mxGetN(cell_ptr);
|
||||
tmp_ptr = mxGetPr(cell_ptr);
|
||||
if( mxIsSparse(cell_ptr) ){
|
||||
/* Sparse Matrix */
|
||||
ir_ptr = mxGetIr(cell_ptr);
|
||||
jc_ptr = mxGetJc(cell_ptr);
|
||||
if( sizeM == 1 && sizeN != 1 ){
|
||||
/* Row Vector Case */
|
||||
for(j = 0; j < sizeN; j++){
|
||||
startidx = jc_ptr[j];
|
||||
endidx = jc_ptr[j+1];
|
||||
if( startidx == endidx ){ continue; }
|
||||
sdpa.inputInitYMat( l+1, j+1, j+1, tmp_ptr[startidx]);
|
||||
}
|
||||
} else if( sizeM != 1 && sizeN == 1 ){
|
||||
/* Column Vector Case */
|
||||
endidx = jc_ptr[sizeN];
|
||||
for(idx = 0; idx < endidx; idx++){
|
||||
i = ir_ptr[idx];
|
||||
sdpa.inputInitYMat( l+1, i+1, i+1, tmp_ptr[idx]);
|
||||
}
|
||||
} else {
|
||||
/* Matrix Case */
|
||||
for(j = 0; j < sizeN; j++){
|
||||
startidx = jc_ptr[j];
|
||||
endidx = jc_ptr[j+1];
|
||||
if( startidx == endidx ){ continue; }
|
||||
for(idx = startidx; idx < endidx; idx++){
|
||||
i = ir_ptr[idx];
|
||||
if( i <= j ){
|
||||
sdpa.inputInitYMat( l+1, i+1, j+1, tmp_ptr[idx]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Dense Matrix */
|
||||
if( sdpa.getBlockType(l+1) == SDPA::SDP ){
|
||||
/* Full Matrix */
|
||||
for(j = 0; j < sizeN; j++){
|
||||
for(i = 0; i < sizeM; i++){
|
||||
if( i <= j ){
|
||||
if( tmp_ptr[j * sizeN + i] != 0 ){
|
||||
sdpa.inputInitYMat( l+1, i+1, j+1,
|
||||
tmp_ptr[j * sizeN + i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Diagonal Matrix */
|
||||
if( sizeM == 1 && sizeN != 1 ){
|
||||
/* Row Vector Case */
|
||||
for(j = 0; j < sizeN; j++){
|
||||
if( tmp_ptr[j] != 0 ){
|
||||
sdpa.inputInitYMat( l+1, j+1, j+1, tmp_ptr[j]);
|
||||
}
|
||||
}
|
||||
} else if( sizeM != 1 && sizeN == 1 ){
|
||||
/* Column Vector Case */
|
||||
for(i = 0; i < sizeM; i++){
|
||||
if( tmp_ptr[i] != 0 ){
|
||||
sdpa.inputInitYMat( l+1, i+1, i+1, tmp_ptr[i]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Matrix Case */
|
||||
for(j = 0; j < sizeN; j++){
|
||||
if( tmp_ptr[j * sizeN + j] != 0 ){
|
||||
sdpa.inputInitYMat( l+1, j+1, j+1,
|
||||
tmp_ptr[j * sizeN + j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
cell_index++;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
/*** Solve SDP ***/
|
||||
sdpa.initializeSolve();
|
||||
sdpa.solve();
|
||||
/*** Dimacs Error Information ****/
|
||||
if (nDimacs != 0) {
|
||||
field_ptr = mxCreateNumericMatrix(6,1,mxDOUBLE_CLASS,mxREAL);
|
||||
double dimacs_error[7];
|
||||
sdpa.getDimacsError(dimacs_error);
|
||||
double* dimacs_store = mxGetPr(field_ptr);
|
||||
if (sdpa.judgeDimacsAvailability() == false) {
|
||||
for (int i=0; i<=6; i++) {
|
||||
dimacs_store[i] = 0.0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (int i=1; i<=6; i++) {
|
||||
dimacs_store[i-1] = dimacs_error[i];
|
||||
}
|
||||
}
|
||||
mxSetField(INFO_ptr, 0, "dimacs", field_ptr);
|
||||
}
|
||||
/**** Set output values to arguments ****/
|
||||
/* Optimal value of Primal objective */
|
||||
objVal_ptr[0] = sdpa.getPrimalObj();
|
||||
/* Optimal value of Dual objective */
|
||||
objVal_ptr[1] = sdpa.getDualObj();
|
||||
/* Optimal value for xVec */
|
||||
tmp_ptr = sdpa.getResultXVec();
|
||||
if( tmp_ptr != NULL ){
|
||||
for(k = 0; k < mDIM; k++){
|
||||
x_ptr[k] = tmp_ptr[k];
|
||||
}
|
||||
}
|
||||
/* Optimal value for XMat */
|
||||
cell_index = 0;
|
||||
result_ptr = sdpa.getResultXMat(1);
|
||||
if (result_ptr == NULL) {
|
||||
rMessage("XMat is not computed by XPrint, and XMat will be empty matrix.");
|
||||
}
|
||||
for(l = 0; l < nBLOCK; l++){
|
||||
result_ptr = sdpa.getResultXMat(l+1);
|
||||
if (result_ptr == NULL) {
|
||||
cell_ptr = mxCreateDoubleMatrix(0, 0, mxREAL);
|
||||
mxSetCell(X_ptr, cell_index++, mxDuplicateArray(cell_ptr));
|
||||
continue;
|
||||
}
|
||||
size = sdpa.getBlockSize(l+1);
|
||||
if( sdpa.getBlockType(l+1) == SDPA:: SDP){
|
||||
sizeM = size;
|
||||
sizeN = size;
|
||||
} else {
|
||||
sizeM = 1;
|
||||
sizeN = abs(size);
|
||||
}
|
||||
cell_ptr = mxCreateDoubleMatrix(sizeM, sizeN, mxREAL);
|
||||
tmp_ptr = mxGetPr(cell_ptr);
|
||||
idx = 0;
|
||||
result_ptr = sdpa.getResultXMat(l+1);
|
||||
if( size >= 0 ){
|
||||
for(j = 0; j < sizeN; j++){
|
||||
for(i = 0; i < sizeM; i++){
|
||||
tmp_ptr[idx++] = result_ptr[j + sizeN * i];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for(idx = 0; idx < sizeN; idx++){
|
||||
tmp_ptr[idx] = result_ptr[idx];
|
||||
}
|
||||
}
|
||||
mxSetCell(X_ptr, cell_index++, mxDuplicateArray(cell_ptr));
|
||||
}
|
||||
/* Optimal value for YMat */
|
||||
result_ptr = sdpa.getResultYMat(1);
|
||||
if (result_ptr == NULL) {
|
||||
rMessage("YMat is not computed by YPrint, and YMat will be empty matrix.");
|
||||
}
|
||||
cell_index = 0;
|
||||
for(l = 0; l < nBLOCK; l++){
|
||||
result_ptr = sdpa.getResultYMat(l+1);
|
||||
if (result_ptr == NULL) {
|
||||
cell_ptr = mxCreateDoubleMatrix(0, 0, mxREAL);
|
||||
mxSetCell(Y_ptr, cell_index++, mxDuplicateArray(cell_ptr));
|
||||
continue;
|
||||
}
|
||||
size = sdpa.getBlockSize(l+1);
|
||||
if( sdpa.getBlockType(l+1) == SDPA:: SDP){
|
||||
sizeM = size;
|
||||
sizeN = size;
|
||||
} else {
|
||||
sizeM = 1;
|
||||
sizeN = abs(size);
|
||||
}
|
||||
cell_ptr = mxCreateDoubleMatrix(sizeM, sizeN, mxREAL);
|
||||
tmp_ptr = mxGetPr(cell_ptr);
|
||||
idx = 0;
|
||||
result_ptr = sdpa.getResultYMat(l+1);
|
||||
if( size >= 0 ){
|
||||
for(j = 0; j < sizeN; j++){
|
||||
for(i = 0; i < sizeM; i++){
|
||||
tmp_ptr[idx++] = result_ptr[j + sizeN * i];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for(idx = 0; idx < sizeN; idx++){
|
||||
tmp_ptr[idx] = result_ptr[idx];
|
||||
}
|
||||
}
|
||||
mxSetCell(Y_ptr, cell_index++, mxDuplicateArray(cell_ptr));
|
||||
}
|
||||
/* Phase information */
|
||||
field_ptr = mxCreateString(szPhase[sdpa.getPhaseValue()]);
|
||||
mxSetField(INFO_ptr, 0, "phasevalue", field_ptr);
|
||||
/* Iteration */
|
||||
field_ptr = mxCreateNumericMatrix(1,1,mxDOUBLE_CLASS,mxREAL);
|
||||
*mxGetPr(field_ptr) = (double)sdpa.getIteration();
|
||||
mxSetField(INFO_ptr, 0, "iteration", field_ptr);
|
||||
/* close output file */
|
||||
time(<ime);
|
||||
strcpy(string_time,ctime(<ime));
|
||||
string_time[strlen(string_time)-1]='\0';
|
||||
if (fp) {
|
||||
fprintf(fp,"SDPA-C end at [%s]\n",string_time);
|
||||
}
|
||||
if (fpResult) {
|
||||
fprintf(fpResult,"SDPA-C end at [%s]\n",string_time);
|
||||
}
|
||||
|
||||
if( nOutfile ){
|
||||
fclose(fp);
|
||||
}
|
||||
if (fpResult != NULL) {
|
||||
fclose(fpResult);
|
||||
}
|
||||
/*** Free allocated memory ****/
|
||||
mxFree(subscript);
|
||||
sdpa.finalize();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Matlab gateway function
|
||||
*/
|
||||
void mexFunction(int nlhs, mxArray *plhs[],
|
||||
int nrhs, const mxArray *prhs[])
|
||||
{
|
||||
/* Decleration of variables */
|
||||
|
||||
double
|
||||
*mDIM_ptr,
|
||||
*nBLOCK_ptr,
|
||||
*bLOCKsTRUCT_ptr,
|
||||
*c_ptr,
|
||||
*x_ptr,
|
||||
*objVal_ptr,
|
||||
*x0_ptr;
|
||||
|
||||
mxArray
|
||||
*F_ptr,
|
||||
*X_ptr,
|
||||
*Y_ptr,
|
||||
*X0_ptr,
|
||||
*Y0_ptr,
|
||||
*OPTION_ptr,
|
||||
*INFO_ptr;
|
||||
|
||||
int IniPt;
|
||||
|
||||
const char *fnames[] = {
|
||||
"phasevalue",
|
||||
"iteration",
|
||||
"dimacs",
|
||||
"cpusec"
|
||||
};
|
||||
|
||||
/*
|
||||
* check arguments
|
||||
*/
|
||||
if( nrhs != 9 ){
|
||||
mexErrMsgTxt("Input arguments must be 9.");
|
||||
}
|
||||
|
||||
/* Get the pointer of input variables */
|
||||
mDIM_ptr = mxGetPr(prhs[0]);
|
||||
nBLOCK_ptr = mxGetPr(prhs[1]);
|
||||
bLOCKsTRUCT_ptr = mxGetPr(prhs[2]);
|
||||
c_ptr = mxGetPr(prhs[3]);
|
||||
F_ptr = (mxArray*)prhs[4];
|
||||
x0_ptr = mxGetPr(prhs[5]);
|
||||
X0_ptr = (mxArray*)prhs[6];
|
||||
Y0_ptr = (mxArray*)prhs[7];
|
||||
OPTION_ptr = (mxArray*)prhs[8];
|
||||
|
||||
if( mxIsEmpty(prhs[5]) /* x0 */
|
||||
|| mxIsEmpty(prhs[6]) /* X0 */
|
||||
|| mxIsEmpty(prhs[7]) /* Y0 */
|
||||
){
|
||||
/* nouse of Initial Point*/
|
||||
IniPt = 0;
|
||||
} else {
|
||||
/* use of Initial Point */
|
||||
IniPt = 1;
|
||||
/* check of argument dimensions */
|
||||
/* if(*mDIM_ptr != mxGetM(prhs[5]) || !mxIsDouble(prhs[5]))
|
||||
mexErrMsgTxt("x0 must be (mDIM x 1) column vector of double");
|
||||
if( *nBLOCK_ptr != sizeM_X0 || 1 != sizeN_X0 || !mxIsCell(prhs[6]))
|
||||
mexErrMsgTxt("X0 must be (nBLOCK x 1) cell array");
|
||||
if( *nBLOCK_ptr != sizeM_Y0 || 1 != sizeN_Y0 || !mxIsCell(prhs[7]))
|
||||
|
||||
mexErrMsgTxt("Y0 must be (nBLOCK x 1) cell array");*/
|
||||
}
|
||||
/* Create cellarrays for the output variables */
|
||||
plhs[0] = mxCreateDoubleMatrix(1,2,mxREAL);
|
||||
plhs[1] = mxCreateDoubleMatrix((int) *mDIM_ptr,1,mxREAL);
|
||||
plhs[2] = mxCreateCellMatrix((int) *nBLOCK_ptr,1);
|
||||
plhs[3] = mxCreateCellMatrix((int) *nBLOCK_ptr,1);
|
||||
plhs[4] = mxCreateStructMatrix(1,1,4,fnames);
|
||||
|
||||
//Get the pointer of output variables
|
||||
objVal_ptr = mxGetPr(plhs[0]);
|
||||
x_ptr = mxGetPr(plhs[1]);
|
||||
X_ptr = plhs[2];
|
||||
Y_ptr = plhs[3];
|
||||
INFO_ptr = plhs[4];
|
||||
|
||||
/* Call sdpasolver here */
|
||||
sdpasolver(mDIM_ptr,
|
||||
nBLOCK_ptr,
|
||||
bLOCKsTRUCT_ptr,
|
||||
c_ptr,
|
||||
F_ptr,
|
||||
x0_ptr,
|
||||
X0_ptr,
|
||||
Y0_ptr,
|
||||
OPTION_ptr,
|
||||
IniPt,
|
||||
objVal_ptr,
|
||||
x_ptr,
|
||||
X_ptr,
|
||||
Y_ptr,
|
||||
INFO_ptr);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* End of File
|
||||
*/
|
||||
Vendored
+233
@@ -0,0 +1,233 @@
|
||||
function OPTION=paramC(OPTION)
|
||||
%
|
||||
% Create SDPA-C parameters.
|
||||
% If there is no argument, default parameters are returned.
|
||||
%
|
||||
% OPTION=paramC % for default parameter
|
||||
% or
|
||||
% OPTION=paramC(field1,value1,field2,value2,....)
|
||||
%
|
||||
% <INPUT>
|
||||
% - field?: string : field name
|
||||
% - value?: numeric or string :
|
||||
%
|
||||
% <OUTPUT>
|
||||
% - OPTION: structure data: each field is as follows:
|
||||
% * maxIteration : The maximum number of iterations.
|
||||
% * epsilonStar : The accuracy of an approximate optimal solution
|
||||
% for primal and dual SDP.
|
||||
% * lambdaStar : An initial point.
|
||||
% * omegaStar : The search region for an optimal solution.
|
||||
% * lowerBound : Lower bound of the minimum objective value of
|
||||
% the primal SDP.
|
||||
% * upperBound : Upper bound of the maximum objective value of
|
||||
% the dual SDP
|
||||
% * betaStar : The parameter for controlling the search direction
|
||||
% if the current point is feasible.
|
||||
% * betaBar : The parameter for controlling the search direction
|
||||
% if the current point is infeasible.
|
||||
% * gammaStar : A reduction factor for the primal and dual step
|
||||
% lengths.
|
||||
% * epsilonDash : The relative accuracy of an approximate optimal
|
||||
% solution between primal and dual SDP.
|
||||
% * isSymmetric : The flag for the checking the symmetricity of input
|
||||
% matrices. (0 => no check, 1=> check)
|
||||
% * isDimacs : The flag to compute DIMACS ERROR
|
||||
% (0 => no computation, 1=> computation)
|
||||
% * xPrint : (default %+8.3e, NOPRINT skips printout)
|
||||
% * XPrint : (default %+8.3e, NOPRINT skips printout)
|
||||
% * YPrint : (default %+8.3e, NOPRINT skips printout)
|
||||
% * infPrint : (default %+10.16e, NOPRINT skips printout)
|
||||
% * print : Destination of file output. the default setting is
|
||||
% stdout by 'display'.
|
||||
% If print is set 'no' or empty, no message
|
||||
% is print out
|
||||
% * resultFile : Destination of detail file output
|
||||
% * NumThreads : Number of Threads for internal computation
|
||||
|
||||
% This file is a component of SDPA
|
||||
% Copyright (C) 2004-2013 SDPA Project
|
||||
%
|
||||
% This program is free software; you can redistribute it and/or modify
|
||||
% it under the terms of the GNU General Public License as published by
|
||||
% the Free Software Foundation; either version 2 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 General Public License for more details.
|
||||
%
|
||||
% You should have received a copy of the GNU General Public License
|
||||
% along with this program; if not, write to the Free Software
|
||||
% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
%
|
||||
% SDPA-M: $Revision: 6.2 $
|
||||
% $Id: param.m,v 6.2 2005/05/28 02:36:40 drophead Exp $
|
||||
|
||||
% create default OPTION
|
||||
OPTION0.maxIteration = 100;
|
||||
OPTION0.epsilonStar = 1.0E-7;
|
||||
OPTION0.lambdaStar = 1.0E2;
|
||||
OPTION0.omegaStar = 2.0;
|
||||
OPTION0.lowerBound = -1.0E5;
|
||||
OPTION0.upperBound = 1.0E5;
|
||||
OPTION0.betaStar = 0.1;
|
||||
OPTION0.betaBar = 0.3;
|
||||
OPTION0.gammaStar = 0.9;
|
||||
OPTION0.epsilonDash = 1.0E-7;
|
||||
OPTION0.isSymmetric = 0;
|
||||
OPTION0.isDimacs = 0;
|
||||
OPTION0.xPrint = '%+8.3e';
|
||||
OPTION0.XPrint = '%+8.3e';
|
||||
OPTION0.YPrint = '%+8.3e';
|
||||
OPTION0.infPrint = '%+16.10e';
|
||||
OPTION0.print = 'display';
|
||||
OPTION0.resultFile = '';
|
||||
try
|
||||
OPTION0.NumThreads = maxNumCompThreads; % Max Avialable Number
|
||||
catch
|
||||
fprintf(['Function maxNumCompThreads is not found, NumThreads ' ...
|
||||
'is set as 1.\n']);
|
||||
OPTION0.NumThreads = 1;
|
||||
end
|
||||
|
||||
|
||||
OPTION0.aggConeSize = [];
|
||||
|
||||
if (nargin == 0) || isempty(OPTION)
|
||||
OPTION = OPTION0;
|
||||
return
|
||||
else
|
||||
if ~isfield(OPTION,'maxIteration')
|
||||
OPTION.maxIteration=OPTION0.maxIteration;
|
||||
elseif ~isnumeric(OPTION.maxIteration)
|
||||
error('OPTION.maxIteration must be numeric.');
|
||||
end
|
||||
%
|
||||
if ~isfield(OPTION,'epsilonStar')
|
||||
OPTION.epsilonStar=OPTION0.epsilonStar;
|
||||
elseif ~isnumeric(OPTION.epsilonStar)
|
||||
error('epsilonStar must be numeric.');
|
||||
end
|
||||
%
|
||||
if ~isfield(OPTION,'lambdaStar')
|
||||
OPTION.lambdaStar=OPTION0.lambdaStar;
|
||||
elseif ~isnumeric(OPTION.lambdaStar)
|
||||
error('OPTION.lambdaStar must be numeric.');
|
||||
end
|
||||
%
|
||||
if ~isfield(OPTION,'omegaStar')
|
||||
OPTION.omegaStar=OPTION0.omegaStar;
|
||||
elseif ~isnumeric(OPTION.omegaStar)
|
||||
error('OPTION.omegaStar must be numeric.');
|
||||
end
|
||||
%
|
||||
if ~isfield(OPTION,'lowerBound')
|
||||
OPTION.lowerBound=OPTION0.lowerBound;
|
||||
elseif ~isnumeric(OPTION.lowerBound)
|
||||
error('OPTION.lowerBound must be numeric.');
|
||||
end
|
||||
%
|
||||
if ~isfield(OPTION,'upperBound')
|
||||
OPTION.upperBound=OPTION0.upperBound;
|
||||
elseif ~isnumeric(OPTION.upperBound)
|
||||
error('OPTION.upperBound must be numeric.');
|
||||
end
|
||||
%
|
||||
if ~isfield(OPTION,'betaStar')
|
||||
OPTION.betaStar=OPTION0.betaStar;
|
||||
elseif ~isnumeric(OPTION.betaStar)
|
||||
error('OPTION.beaStar must be numeric.');
|
||||
end
|
||||
%
|
||||
if ~isfield(OPTION,'betaBar')
|
||||
OPTION.betaBar=OPTION0.betaBar;
|
||||
elseif ~isnumeric(OPTION.betaBar)
|
||||
error('OPTION.betaBar must be numeric.');
|
||||
end
|
||||
%
|
||||
if ~isfield(OPTION,'gammaStar')
|
||||
OPTION.gammaStar=OPTION0.gammaStar;
|
||||
elseif ~isnumeric(OPTION.gammaStar)
|
||||
error('OPTION.gammaStar must be numeric.');
|
||||
end
|
||||
%
|
||||
if ~isfield(OPTION,'epsilonDash')
|
||||
OPTION.epsilonDash=OPTION0.epsilonDash;
|
||||
elseif ~isnumeric(OPTION.epsilonDash)
|
||||
error('OPTION.epsilonDash must be numeric.');
|
||||
end
|
||||
%
|
||||
if isfield(OPTION,'searchDir')
|
||||
disp('Parameter *searchDir* is no longer supported.');
|
||||
disp('HRVW/KSH/M is automatically used.');
|
||||
end
|
||||
%
|
||||
if ~isfield(OPTION,'isSymmetric')
|
||||
OPTION.isSymmetric=OPTION0.isSymmetric;
|
||||
elseif ~isnumeric(OPTION.isSymmetric) || ((OPTION.isSymmetric~=0) && (OPTION.isSymmetric~=1))
|
||||
error('OPTION.isSymmetric must be 0 or 1.');
|
||||
end
|
||||
%
|
||||
if ~isfield(OPTION,'isDimacs')
|
||||
OPTION.isDimacs=OPTION0.isDimacs;
|
||||
elseif ~isnumeric(OPTION.isDimacs) || ((OPTION.isDimacs~=0) && (OPTION.isDimacs~=1))
|
||||
error('OPTION.isDimacs must be 0 or 1.');
|
||||
end
|
||||
%
|
||||
if ~isfield(OPTION,'XPrint')
|
||||
OPTION.XPrint=OPTION0.XPrint;
|
||||
elseif ~ischar(OPTION.XPrint)
|
||||
error('OPTION.XPrint must be string.');
|
||||
end
|
||||
%
|
||||
if ~isfield(OPTION,'YPrint')
|
||||
OPTION.YPrint=OPTION0.YPrint;
|
||||
elseif ~ischar(OPTION.YPrint)
|
||||
error('OPTION.YPrint must be string for printf.');
|
||||
end
|
||||
%
|
||||
if ~isfield(OPTION,'infPrint')
|
||||
OPTION.infPrint=OPTION0.infPrint;
|
||||
elseif ~ischar(OPTION.infPrint)
|
||||
error('OPTION.infPrint must be string for printf.');
|
||||
end
|
||||
%
|
||||
if isfield(OPTION,'print') && ...
|
||||
(isempty(OPTION.print) || length(OPTION.print) == 0)
|
||||
OPTION.print = 'no';
|
||||
end
|
||||
if ~isfield(OPTION,'print')
|
||||
OPTION.print=OPTION0.print;
|
||||
elseif ~ischar(OPTION.print)
|
||||
disp('*** OPTION.print must be string for FILE. ***');
|
||||
disp(' "display" is for stdout.');
|
||||
disp(' "no" or empty is for skip message.');
|
||||
disp(' filename is filename in which message will be written.');
|
||||
error('*** OPTION.print must be string for FILE. ***');
|
||||
end
|
||||
%
|
||||
if ~isfield(OPTION,'resultFile') || isempty(OPTION.resultFile)
|
||||
OPTION.resultFile=OPTION0.resultFile;
|
||||
elseif ~ischar(OPTION.resultFile)
|
||||
error('OPTION.resultFile must be string.');
|
||||
end
|
||||
%
|
||||
if ~isfield(OPTION,'NumThreads')
|
||||
OPTION.NumThreads=OPTION0.NumThreads;
|
||||
elseif ~isnumeric(OPTION.NumThreads)
|
||||
error('OPTION.NumThreads must be positive integer.');
|
||||
end
|
||||
|
||||
if ~isfield(OPTION,'aggConeSize')
|
||||
OPTION.aggConeSize = OPTION0.aggConeSize;
|
||||
elseif (~isempty(OPTION.aggConeSize)) && ...
|
||||
((~isnumeric(OPTION.aggConeSize)) || (OPTION.aggConeSize <=0))
|
||||
error('OPTION.aggConeSize must be a positive integer.');
|
||||
end
|
||||
end
|
||||
|
||||
return
|
||||
|
||||
% End of File
|
||||
Vendored
+81
@@ -0,0 +1,81 @@
|
||||
function [objVal,x,X,Y,INFO]=sdpamC(mDIM,nBLOCK,bLOCKsTRUCT,c,F,...
|
||||
x0,X0,Y0,OPTION)
|
||||
%
|
||||
% Compute the solution of standard SDP.
|
||||
% Since some of input arguments are optional, sdpam can be
|
||||
% overloaded as below.
|
||||
%
|
||||
% [objVal,x,X,Y,INFO] = sdpamC(mDIM,nBLOCK,bLOCKsTRUCT,c,F,
|
||||
% x0,X0,Y0,OPTION);
|
||||
%
|
||||
% <INPUT>
|
||||
% - mDIM : integer ; number of primal variables
|
||||
% - nBLOCK : integer ; number of blocks of F
|
||||
% - bLOCKsTRUCT: vector ; represetns the block structure of F
|
||||
% - c : vector ; coefficient vector
|
||||
% - F : cell array; coefficient matrices
|
||||
% - x0,X0,Y0 : cell array; initial point
|
||||
% (NOTE: In SDPA-C, initial point is ignored.)
|
||||
% - OPTION : structure ; options
|
||||
%
|
||||
% <OUTPUT>
|
||||
% - objVal: [objValP objValD]; optimal value of P and D
|
||||
% - x : vector ; optimal solution
|
||||
% - X,Y : cell arrray ; optimal solutions
|
||||
% - INFO : structure ; infomation of the solution
|
||||
%
|
||||
|
||||
% This file is a component of SDPA
|
||||
% Copyright (C) 2004-2013 SDPA Project
|
||||
%
|
||||
% This program is free software; you can redistribute it and/or modify
|
||||
% it under the terms of the GNU General Public License as published by
|
||||
% the Free Software Foundation; either version 2 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 General Public License for more details.
|
||||
%
|
||||
% You should have received a copy of the GNU General Public License
|
||||
% along with this program; if not, write to the Free Software
|
||||
% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
%
|
||||
% SDPA-M: $Revision: 6.2 $
|
||||
% $Id: sdpam.m,v 6.2 2005/05/28 02:36:40 drophead Exp $
|
||||
|
||||
t = cputime;
|
||||
|
||||
if (nargin < 5 || nargin > 9)
|
||||
error('incorrect number of input arguments')
|
||||
elseif nargin == 5
|
||||
% make initial points empty
|
||||
x0=[];X0=[];Y0=[];
|
||||
% load default parameters
|
||||
OPTION=paramC;
|
||||
% solve by SDPA
|
||||
[objVal,x,X,Y,INFO]=mexsdpaC(mDIM,nBLOCK,bLOCKsTRUCT,...
|
||||
c,F,x0,X0,Y0,OPTION);
|
||||
elseif nargin == 6
|
||||
% use OPTION given by arguments
|
||||
OPTION=paramC(x0);
|
||||
% make initial points empty
|
||||
x0=[];X0=[];Y0=[];
|
||||
[objVal,x,X,Y,INFO]=mexsdpaC(mDIM,nBLOCK,bLOCKsTRUCT,...
|
||||
c,F,x0,X0,Y0,OPTION);
|
||||
elseif nargin == 8
|
||||
% load default parameters
|
||||
OPTION=paramC;
|
||||
%solve by SDPA
|
||||
[objVal,x,X,Y,INFO]=mexsdpaC(mDIM,nBLOCK,bLOCKsTRUCT,...
|
||||
c,F,x0,X0,Y0,OPTION);
|
||||
elseif nargin == 9
|
||||
OPTION=paramC(OPTION);
|
||||
% solve by SDPA
|
||||
[objVal,x,X,Y,INFO]=mexsdpaC(mDIM,nBLOCK,bLOCKsTRUCT,...
|
||||
c,F,x0,X0,Y0,OPTION);
|
||||
end
|
||||
INFO.cpusec = cputime-t;
|
||||
|
||||
% End of File
|
||||
Vendored
+382
@@ -0,0 +1,382 @@
|
||||
function [x,y,info]=sedumiwrapC(A,b,c,K,pars,OPTION);
|
||||
|
||||
%
|
||||
% SeDuMi wrapper for SDPA
|
||||
%
|
||||
% [x,y,info]=sedumiwrapC(A,b,c,K,pars,OPTION);
|
||||
% or
|
||||
% [x,y,info]=sedumiwrapC(A,b,c,K); % with SDPA-M default parameter
|
||||
%
|
||||
% Note :
|
||||
% 'A', in each SDP block, only upper triangle part is used.
|
||||
% 'K' can include only 'f'(free) 'l'(linear) 's'(SDP) cones.
|
||||
% 'pars' information is NOT used (just for SeDuMi compatibility)
|
||||
% 'OPTION' is option structure for SDPA-M (for details, try 'help param')
|
||||
% 'info' information is based on SDPA-M
|
||||
%
|
||||
% This file is a component of SDPA
|
||||
% Copyright (C) 2004-2013 SDPA Project
|
||||
%
|
||||
% This program is free software; you can redistribute it and/or modify
|
||||
% it under the terms of the GNU General Public License as published by
|
||||
% the Free Software Foundation; either version 2 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 General Public License for more details.
|
||||
%
|
||||
% You should have received a copy of the GNU General Public License
|
||||
% along with this program; if not, write to the Free Software
|
||||
% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
%
|
||||
% SDPA-M: $Revision: 7.3 $
|
||||
|
||||
|
||||
t = cputime;
|
||||
|
||||
fprintf('-SeDuMi Wrapper for SDPA-C Start-\n');
|
||||
|
||||
if (nargin < 4 || nargin > 6)
|
||||
error('incorrect number of input arguments')
|
||||
end
|
||||
if nargin >= 5
|
||||
if isfield(OPTION,'print') && ~isempty(OPTION.print)
|
||||
fprintf('Note: pars information [5th argument] is not used\n');
|
||||
end
|
||||
end
|
||||
if nargin < 6
|
||||
OPTION = paramC;
|
||||
else
|
||||
OPTION = paramC(OPTION);
|
||||
end
|
||||
|
||||
if isfield(K,'q') && ~isempty(K.q)
|
||||
error('Current Wrapper cannot handle K.q');
|
||||
end
|
||||
|
||||
if isfield(K,'r') && ~isempty(K.r)
|
||||
error('Current Wrapper cannot handle K.r');
|
||||
end
|
||||
|
||||
if size(b,2) ~= 1
|
||||
% fprintf('Transposing b to a column vector');
|
||||
b = b';
|
||||
end
|
||||
if size(b,2) ~= 1
|
||||
error('b must be a vector');
|
||||
end
|
||||
|
||||
if size(c,2) ~= 1
|
||||
% fprintf('Transposing c to a column vector\n');
|
||||
c = c';
|
||||
end
|
||||
if size(c,2) ~= 1
|
||||
error('c must be a vector');
|
||||
end
|
||||
|
||||
%%%%%
|
||||
% Constructing at least one SDP cone if necesary
|
||||
if (~isfield(K,'s')) || (isempty(K.s))
|
||||
[K] = LPtoLP_SDP(K);
|
||||
end
|
||||
%%%%%
|
||||
|
||||
totalLength = 0;
|
||||
Kf = 0;
|
||||
if isfield(K,'f') && ~isempty(K.f)
|
||||
totalLength = totalLength + K.f;
|
||||
Kf = K.f;
|
||||
end
|
||||
if isfield(K,'l') && ~isempty(K.l)
|
||||
totalLength = totalLength + K.l;
|
||||
else
|
||||
K.l = 0;
|
||||
end
|
||||
if isfield(K,'s') && ~isempty(K.s)
|
||||
if size(K.s,2) ~= 1
|
||||
% fprintf('Transposing K.s to a column vector\n');
|
||||
K.s = K.s';
|
||||
end
|
||||
Ks = sum(K.s .* K.s);
|
||||
totalLength = totalLength + Ks;
|
||||
else
|
||||
error('Cannot handle empty K.s');
|
||||
end
|
||||
m = size(b,1);
|
||||
n = size(c,1);
|
||||
|
||||
[mA,nA] = size(A);
|
||||
if (m~=mA || n~=nA) && (m~=nA || n~=mA)
|
||||
fprintf('Inconsistent Size of A,b,c\n');
|
||||
fprintf('size(A) = [%d,%d], size(b) = %d, size(c) = %d\n',...
|
||||
mA,nA, m,n);
|
||||
error('Cannot continue...');
|
||||
end
|
||||
|
||||
if (n~=totalLength)
|
||||
fprintf('Inconsistent Size of c and K\n');
|
||||
fprintf('size(c) = %d, totalSize(K) = %d\n',...
|
||||
n, totalLength);
|
||||
error('Cannot continue...');
|
||||
end
|
||||
|
||||
if ~issparse(A)
|
||||
if isfield(OPTION,'print') && ~isempty(OPTION.print)
|
||||
fprintf('Converting A from dense to sparse\n');
|
||||
end
|
||||
A = sparse(A);
|
||||
end
|
||||
|
||||
if issparse(b)
|
||||
% fprintf('Converting b from sparse to dense\n');
|
||||
b = full(b);
|
||||
end
|
||||
|
||||
if ~issparse(c)
|
||||
% fprintf('Converting c from dense to sparse\n');
|
||||
c = sparse(c);
|
||||
end
|
||||
|
||||
if issparse(K.s)
|
||||
% fprintf('Converting K.s from sparse to dense\n');
|
||||
K.s = full(K.s);
|
||||
end
|
||||
|
||||
if Kf ~= 0
|
||||
if isfield(OPTION,'print') && ~isempty(OPTION.print)
|
||||
fprintf(['Free Variables are divided into positive and ' ...
|
||||
'negative part of LP cone\n']);
|
||||
end
|
||||
Af = A(:,1:Kf);
|
||||
Kl = K.l;
|
||||
Al = A(:,Kf+1:Kf+Kl);
|
||||
As = A(:,Kf+Kl+1:Kf+Kl+Ks);
|
||||
Anew = [Af, -Af, Al, As];
|
||||
|
||||
cf = c(1:Kf);
|
||||
cl = c(Kf+1:Kf+Kl);
|
||||
cs = c(Kf+Kl+1:Kf+Kl+Ks);
|
||||
cnew = [cf; -cf; cl; cs];
|
||||
|
||||
Knew.l = 2*Kf + Kl;
|
||||
Knew.s = K.s;
|
||||
|
||||
A = Anew;
|
||||
c = cnew;
|
||||
K = Knew;
|
||||
|
||||
clear Af;
|
||||
clear Al;
|
||||
clear As;
|
||||
clear Anew;
|
||||
clear cf;
|
||||
clear cl;
|
||||
clear cs;
|
||||
clear cnew;
|
||||
clear Knew;
|
||||
end
|
||||
|
||||
if isfield(K,'s') && ~isempty(K.s)
|
||||
if size(K.s,2) ~= 1
|
||||
K.s = Ks';
|
||||
end
|
||||
end
|
||||
|
||||
%%%%%
|
||||
% Aggregating small SDP cones into larger SDP cones
|
||||
aggSW = 0;
|
||||
minNoSDPcones = 3;
|
||||
if (isfield(OPTION,'aggConeSize')) && (~isempty(OPTION.aggConeSize)) && (isnumeric(OPTION.aggConeSize)) && ...
|
||||
((OPTION.aggConeSize > 0)) && (length(K.s') > minNoSDPcones) && (length(find(K.s' < OPTION.aggConeSize)) > minNoSDPcones)
|
||||
fprintf('OPTION.aggConeSize = %d\n',OPTION.aggConeSize)
|
||||
K0 = K;
|
||||
aggSW = 1;
|
||||
[A,c,K1] = aggSDPcones(A,c,K,OPTION.aggConeSize);
|
||||
A = sparse(A);
|
||||
c = sparse(c);
|
||||
K = K1;
|
||||
end
|
||||
%%%%%
|
||||
|
||||
|
||||
% A should be transposed when passed to mex
|
||||
[mA,nA] = size(A);
|
||||
if mA ~= K.l + sum(K.s.*K.s)
|
||||
A = A';
|
||||
end
|
||||
% fprintf('size(A) = (%d,%d)\n',size(A,2),size(A,1));
|
||||
% fprintf('length(K.s) = %d\n',length(K.s));
|
||||
|
||||
[x,y,info] = mexSedumiWrapC(A,b,c,K,OPTION);
|
||||
|
||||
%%%%%
|
||||
% Retrieving the origianl primal SDP cone variables
|
||||
if aggSW == 1
|
||||
if (isfield(K,'l')) && (~isempty(K.l)) && (K.l > 0)
|
||||
xSDP = x(K.l+1:size(x,1),1);
|
||||
xLP = x(1:K.l,1);
|
||||
[xSDP] = mexDisAggSDPsol(xSDP,K0.s,K1.s);
|
||||
x = [xLP; xSDP];
|
||||
else
|
||||
[x] = mexDisAggSDPsol(x,K0.s,K1.s);
|
||||
end
|
||||
end
|
||||
%%%%%
|
||||
|
||||
if Kf ~=0
|
||||
xlength = size(x);
|
||||
xnew = x(1:Kf) - x(Kf+1:Kf+Kf);
|
||||
xnew = [xnew; x(Kf+Kf+1:xlength)];
|
||||
x = xnew;
|
||||
end
|
||||
|
||||
info.cpusec = cputime-t;
|
||||
% if isfield(OPTION,'print') && ~isempty(OPTION.print)
|
||||
fprintf('-SeDuMi Wrapper for SDPA-C End-\n');
|
||||
% end
|
||||
|
||||
% End of File
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
function [K] = LPtoLP_SDP(K)
|
||||
|
||||
if isfield(K,'q') && ~isempty(K.q)
|
||||
error('Current Wrapper cannot handle K.q');
|
||||
end
|
||||
|
||||
if isfield(K,'r') && ~isempty(K.r)
|
||||
error('Current Wrapper cannot handle K.r');
|
||||
end
|
||||
|
||||
if isfield(K,'s') && ~isempty(K.s)
|
||||
return;
|
||||
elseif ~isfield(K,'l') || isempty(K.l)
|
||||
error('Both LP and SDP cones are empty, so the problem can not be solved');
|
||||
else
|
||||
K.l = K.l-1;
|
||||
if K.l == 0
|
||||
K.l = [];
|
||||
end
|
||||
K.s = 1;
|
||||
end
|
||||
|
||||
return
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
function [A1,c1,K1] = aggSDPcones(A,c,K0,aggConeSize)
|
||||
%
|
||||
% [A1,c1,K1] = aggSDPcones(A,c,K0,aggConeSize)
|
||||
% Input : SeDuMi format
|
||||
% aggConeSize : the block size into which small blocks are converted
|
||||
% Output: Sedumi format with larger SDP cone matrices
|
||||
%
|
||||
|
||||
if (size(K0.s,2) > 1)
|
||||
K0.s = K0.s';
|
||||
end
|
||||
|
||||
if size(A,1) > size(A,2)
|
||||
A = A';
|
||||
end
|
||||
% if size(c,1) < size(c,2)
|
||||
% c = c';
|
||||
% end
|
||||
[m,n] = size(A);
|
||||
%
|
||||
if ~isfield(K0,'f') || isempty(K0.f)
|
||||
fDim = 0;
|
||||
else
|
||||
fDim = K0.f;
|
||||
end
|
||||
%
|
||||
if ~isfield(K0,'l') || isempty(K0.l)
|
||||
ellDim = 0;
|
||||
else
|
||||
ellDim = K0.l;
|
||||
end
|
||||
%
|
||||
if ~isfield(K0,'q')
|
||||
qDim = 0;
|
||||
else
|
||||
if size(K0.q,1) > size(K0.q,2)
|
||||
K0.q = K0.q'; % a row vector
|
||||
end
|
||||
qDim = sum(K0.q);
|
||||
end
|
||||
%
|
||||
if ~isfield(K0,'s') || isempty(K0.s)
|
||||
K1 = K0;
|
||||
A1 = A;
|
||||
c1 = c;
|
||||
return
|
||||
else
|
||||
if size(K0.s,2) > size(K0.s,1)
|
||||
K0.s = K0.s'; % a column vector
|
||||
end
|
||||
sDim = sum(K0.s .* K0.s);
|
||||
end
|
||||
|
||||
nonSDim = fDim+ellDim+qDim;
|
||||
if nonSDim == 0
|
||||
cNonSDP = [];
|
||||
AnonSDP = [];
|
||||
c0SDP = c;
|
||||
A0SDP = A;
|
||||
else
|
||||
cNonSDP = c(1:nonSDim,1);
|
||||
AnonSDP = A(:,1:nonSDim);
|
||||
c0SDP = c(nonSDim+1:n,1);
|
||||
A0SDP = A(:,nonSDim+1:n);
|
||||
end
|
||||
|
||||
K1s = [];
|
||||
coneSize = 0;
|
||||
for p=1:length(K0.s)
|
||||
if (K0.s(p) > aggConeSize)
|
||||
if coneSize > 0
|
||||
K1s = [K1s; coneSize; K0.s(p)];
|
||||
coneSize = 0;
|
||||
else
|
||||
K1s = [K1s; K0.s(p)];
|
||||
coneSize = 0;
|
||||
end
|
||||
elseif ((coneSize + K0.s(p) > aggConeSize))
|
||||
K1s = [K1s; coneSize];
|
||||
coneSize = K0.s(p);
|
||||
elseif ((coneSize + K0.s(p) == aggConeSize))
|
||||
K1s = [K1s; coneSize + K0.s(p)];
|
||||
coneSize = 0;
|
||||
else
|
||||
coneSize = coneSize + K0.s(p);
|
||||
end
|
||||
end
|
||||
if (coneSize > 0)
|
||||
K1s = [K1s; coneSize];
|
||||
end
|
||||
|
||||
K0s = K0.s; % K0.s is a column vector
|
||||
K1 = K0;
|
||||
K1.s = K1s; % K1s is a column vector
|
||||
|
||||
tStart = tic;
|
||||
% C0SDP, K0s and K1s need to be clolumn vector
|
||||
[A1SDP,c1SDP] = mexAggSDPcones(A0SDP,c0SDP',K0s,K1s);
|
||||
tElapsed = toc(tStart);
|
||||
fprintf('Original SDP: the max cone size, the number of cones = %3d, %3d\n',full(max(K0.s)),length(K0.s));
|
||||
fprintf('Transformed SDP: the max cone size, the number of cones = %3d, %3d\n',full(max(K1.s)),length(K1.s));
|
||||
% fprintf('Elapsed time for transformation = %6.2e\n',tElapsed);
|
||||
|
||||
c1SDP = c1SDP';
|
||||
|
||||
A1 = sparse([AnonSDP, A1SDP]);
|
||||
c1 = sparse([cNonSDP;c1SDP]);
|
||||
|
||||
% checkData(A1,b1,c1,K1);
|
||||
|
||||
% sedumi(A1,b1,c1,K1);
|
||||
|
||||
return
|
||||
|
||||
|
||||
Vendored
+15
@@ -0,0 +1,15 @@
|
||||
100 unsigned int maxIteration;
|
||||
1.0E-7 double 0.0 < epsilonStar;
|
||||
1.0E2 double 0.0 < lambdaStar;
|
||||
2.0 double 1.0 < omegaStar;
|
||||
-1.0E5 double lowerBound;
|
||||
1.0E5 double upperBound;
|
||||
0.1 double 0.0 <= betaStar < 1.0;
|
||||
0.3 double 0.0 <= betaBar < 1.0, betaStar <= betaBar;
|
||||
0.9 double 0.0 < gammaStar < 1.0;
|
||||
1.0E-7 double 0.0 < epsilonDash;
|
||||
%+8.3e char* xPrint (default %+8.3e, NOPRINT skips printout)
|
||||
%+8.3e char* XPrint (default %+8.3e, NOPRINT skips printout)
|
||||
%+8.3e char* YPrint (default %+8.3e, NOPRINT skips printout)
|
||||
%+10.16e char* infPrint (default %+10.16e, NOPRINT skips printout)
|
||||
|
||||
Vendored
+153
@@ -0,0 +1,153 @@
|
||||
/* -------------------------------------------------------------
|
||||
|
||||
This file is a component of SDPA
|
||||
Copyright (C) 2004-2013 SDPA Project
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
------------------------------------------------------------- */
|
||||
/* sdpa_algebra.h
|
||||
|
||||
LAPACK+BLAS definitions wrapper
|
||||
|
||||
Define macros to mangle the given C identifier (in lower and upper
|
||||
case), which must not contain underscores, for linking with Fortran.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __sdpa_algebra_h__
|
||||
#define __sdpa_algebra_h__
|
||||
|
||||
#define FC_RET_I int
|
||||
#define FC_RET_D double
|
||||
|
||||
#if defined(__APPLE__) // Dirty...
|
||||
#define FC_FUNC(name,NAME) name ## _
|
||||
#endif
|
||||
|
||||
|
||||
#define FC_FUNC(name,NAME) name ## _ // for SDPA-C temporary
|
||||
|
||||
#define dtrsm_fc FC_FUNC (dtrsm, DTRSM)
|
||||
#define dsyrk_fc FC_FUNC (dsyrk, DSYRK)
|
||||
#define dcopy_fc FC_FUNC (dcopy, DCOPY)
|
||||
#define daxpy_fc FC_FUNC (daxpy, DAXPY)
|
||||
#define dgemm_fc FC_FUNC (dgemm, DGEMM)
|
||||
#define dgemv_fc FC_FUNC (dgemv, DGEMV)
|
||||
#define dscal_fc FC_FUNC (dscal, DSCAL)
|
||||
#define dtrsv_fc FC_FUNC (dtrsv, DTRSV)
|
||||
#define dtrmv_fc FC_FUNC (dtrmv, DTRMV)
|
||||
#define ddot_fc FC_FUNC (ddot, DDOT)
|
||||
#define dtrmm_fc FC_FUNC (dtrmm, DTRMM)
|
||||
#define ilaenv_fc FC_FUNC (ilaenv, ILAENV)
|
||||
#define dsteqr_fc FC_FUNC (dsteqr, DSTEQR)
|
||||
#define dsyev_fc FC_FUNC (dsyev, DSYEV)
|
||||
#define dpotrf_fc FC_FUNC (dpotrf, DPORTRF)
|
||||
|
||||
|
||||
extern "C"
|
||||
{
|
||||
// BLAS
|
||||
FC_RET_I dtrsm_fc
|
||||
(char* side, char* uplo, char* trans, char* diag,
|
||||
int* M, int* N,
|
||||
double* alpha,
|
||||
double* A, int* lda,
|
||||
double* B, int* ldb, int side_len,
|
||||
int uplo_len, int trans_len, int diag_len);
|
||||
|
||||
FC_RET_I dsyrk_fc
|
||||
(char* uplo, char* trans, int* N, int* K,
|
||||
double* alpha,
|
||||
double* A, int* lda,
|
||||
double* beta,
|
||||
double* C, int* ldc, int uplo_len, int trans_len);
|
||||
|
||||
FC_RET_I dcopy_fc
|
||||
(int* N,
|
||||
double* X, int* incX,
|
||||
double* Y, int* incY);
|
||||
|
||||
FC_RET_I daxpy_fc
|
||||
(int* N,
|
||||
double* alpha,
|
||||
double* X, int* incX,
|
||||
double* Y, int* incY);
|
||||
|
||||
FC_RET_I dgemm_fc
|
||||
(char* transA, char* transB, int* M, int* N, int* K,
|
||||
double* alpha,
|
||||
double* A, int* lda,
|
||||
double* B, int* ldb,
|
||||
double* beta,
|
||||
double* C, int* ldc, int transA_len, int transB_len);
|
||||
|
||||
FC_RET_I dgemv_fc
|
||||
(char* trans, int* M, int* N,
|
||||
double* alpha,
|
||||
double* A, int* lda,
|
||||
double* X, int* incX,
|
||||
double* beta,
|
||||
double* Y, int* incY, int trans_len);
|
||||
|
||||
FC_RET_I dscal_fc
|
||||
(int* N,
|
||||
double* alpha,
|
||||
double* X, int* incX);
|
||||
|
||||
FC_RET_I dtrsv_fc
|
||||
(char* uplo, char* trans, char* diag, int* N,
|
||||
double* A, int* lda,
|
||||
double* X, int* incX, int uplo_len,
|
||||
int trans_len, int diag_len);
|
||||
|
||||
FC_RET_I dtrmv_fc
|
||||
(char* uplo, char *trans, char* diag, int *N,
|
||||
double *A, int *lda,
|
||||
double *X, int *incX, int uplo_len, int trans_len, int diag_len);
|
||||
|
||||
FC_RET_D ddot_fc
|
||||
(int* N, double* X, int* incX, double* Y, int* incY);
|
||||
|
||||
FC_RET_I dtrmm_fc
|
||||
(char* side, char* uplo, char* trans, char* diag,
|
||||
int* M, int* N,
|
||||
double* alpha,
|
||||
double* A, int* lda,
|
||||
double* B, int* ldb, int side_len, int uplo_len,
|
||||
int trans_len, int diag_len);
|
||||
|
||||
// LAPACK
|
||||
|
||||
FC_RET_I ilaenv_fc
|
||||
(int *ispec, char *name, char *opts, int *n1,
|
||||
int *n2, int *n3, int *n4, int name_len, int opts_len);
|
||||
|
||||
FC_RET_I dsteqr_fc
|
||||
(char *compz, int *n, double *d,
|
||||
double *e, double *z, int *ldz, double *work,
|
||||
int *info, int compz_len);
|
||||
|
||||
FC_RET_I dsyev_fc
|
||||
(char *jobz, char *uplo, int *n, double *a,
|
||||
int *lda, double *w, double *work, int *lwork,
|
||||
int *info, int jobz_len, int uplo_len);
|
||||
|
||||
FC_RET_I dpotrf_fc
|
||||
(char *uplo, int *n, double *a, int *lda,
|
||||
int *info, int uplo_len);
|
||||
}
|
||||
|
||||
#endif // __sdpa_algebra_h__
|
||||
Vendored
+140
@@ -0,0 +1,140 @@
|
||||
/* -------------------------------------------------------------
|
||||
|
||||
This file is a component of SDPA
|
||||
Copyright (C) 2004-2013 SDPA Project
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
------------------------------------------------------------- */
|
||||
|
||||
#include "sdpa_block.h"
|
||||
|
||||
namespace sdpa {
|
||||
|
||||
BlockStruct::BlockStruct()
|
||||
{
|
||||
nBlock = 0;
|
||||
blockStruct = NULL;
|
||||
blockNumber = NULL;
|
||||
blockType = NULL;
|
||||
SDP_nBlock = 0;
|
||||
SDP_blockStruct = NULL;
|
||||
LP_nBlock = 0;
|
||||
}
|
||||
|
||||
BlockStruct::~BlockStruct()
|
||||
{
|
||||
finalize();
|
||||
}
|
||||
|
||||
void BlockStruct::initialize(int nBlock)
|
||||
{
|
||||
this->nBlock = nBlock;
|
||||
NewArray(blockStruct,int,nBlock);
|
||||
NewArray(blockType, BlockType, nBlock);
|
||||
NewArray(blockNumber,int,nBlock);
|
||||
SDP_nBlock = 0;
|
||||
SDP_blockStruct = NULL;
|
||||
LP_nBlock = 0;
|
||||
}
|
||||
|
||||
void BlockStruct::finalize()
|
||||
{
|
||||
DeleteArray(blockStruct);
|
||||
DeleteArray(blockNumber);
|
||||
DeleteArray(blockType);
|
||||
DeleteArray(SDP_blockStruct);
|
||||
}
|
||||
|
||||
void BlockStruct::makeInternalStructure()
|
||||
{
|
||||
SDP_nBlock = 0;
|
||||
LP_nBlock = 0;
|
||||
for (int l=0; l<nBlock; l++){
|
||||
#if 0
|
||||
rMessage("blockStruct[" << l << "] = "<< blockStruct[l]
|
||||
<< ": blockType[" << l << "] = " << blockType[l]);
|
||||
#endif
|
||||
if (blockStruct[l] >= 2 && blockType[l] == btSDP) {
|
||||
blockType[l] = btSDP;
|
||||
blockNumber[l] = SDP_nBlock;
|
||||
SDP_nBlock++;
|
||||
} else if (blockStruct[l] < 0 || blockType[l] == btLP) {
|
||||
blockType[l] = btLP;
|
||||
if (blockStruct[l] < 0) {
|
||||
blockStruct[l] = - blockStruct[l];
|
||||
}
|
||||
blockNumber[l] = LP_nBlock;
|
||||
LP_nBlock += blockStruct[l];
|
||||
} else if (blockStruct[l] == 1) {
|
||||
blockType[l] = btLP;
|
||||
blockStruct[l] = 1;
|
||||
blockNumber[l] = LP_nBlock;
|
||||
LP_nBlock += blockStruct[l];
|
||||
} else {
|
||||
rError("block struct");
|
||||
}
|
||||
}
|
||||
|
||||
NewArray(SDP_blockStruct, int,SDP_nBlock);
|
||||
SDP_nBlock = 0;
|
||||
for (int l=0; l<nBlock; l++){
|
||||
if (blockType[l] == btSDP) {
|
||||
SDP_blockStruct[SDP_nBlock] = blockStruct[l];
|
||||
SDP_nBlock++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BlockStruct::display(FILE* fpout)
|
||||
{
|
||||
if (fpout == NULL) {
|
||||
return;
|
||||
}
|
||||
fprintf(fpout,"--- BlockStruct ---\n");
|
||||
fprintf(fpout,"nBlock = %d\n",nBlock);
|
||||
fprintf(fpout,"blockStruct = \n");
|
||||
for (int l=0; l<nBlock; ++l) {
|
||||
fprintf(fpout,"%5d,",blockStruct[l]);
|
||||
}
|
||||
fprintf(fpout,"\n");
|
||||
fprintf(fpout,"blockNumber = \n");
|
||||
for (int l=0; l<nBlock; ++l) {
|
||||
fprintf(fpout,"%5d,",blockNumber[l]);
|
||||
}
|
||||
fprintf(fpout,"\n");
|
||||
fprintf(fpout,"blockType = \n");
|
||||
for (int l=0; l<nBlock; ++l) {
|
||||
char displaychar = '-';
|
||||
if (blockType[l] == btSDP) {
|
||||
displaychar= 'S';
|
||||
} else if (blockType[l] == btLP) {
|
||||
displaychar= 'L';
|
||||
}
|
||||
fprintf(fpout," %c,",displaychar);
|
||||
}
|
||||
fprintf(fpout,"\n");
|
||||
fprintf(fpout,"SDP_nBlock = %d\n",SDP_nBlock);
|
||||
fprintf(fpout,"SDP_blockStruct = \n");
|
||||
for (int l=0; l<SDP_nBlock; ++l) {
|
||||
fprintf(fpout,"%5d,",SDP_blockStruct[l]);
|
||||
}
|
||||
fprintf(fpout,"\n");
|
||||
fprintf(fpout,"LP_nBlock = %d\n",LP_nBlock);
|
||||
fprintf(fpout,"--- BlockStruct ---\n");
|
||||
}
|
||||
|
||||
|
||||
} // end of namespace 'sdpa'
|
||||
Vendored
+52
@@ -0,0 +1,52 @@
|
||||
/* -------------------------------------------------------------
|
||||
|
||||
This file is a component of SDPA
|
||||
Copyright (C) 2004-2013 SDPA Project
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
------------------------------------------------------------- */
|
||||
|
||||
#ifndef __sdpa_block_h__
|
||||
#define __sdpa_block_h__
|
||||
|
||||
#include "sdpa_include.h"
|
||||
|
||||
namespace sdpa {
|
||||
|
||||
class BlockStruct
|
||||
{
|
||||
public:
|
||||
enum BlockType {btSDP,btLP};
|
||||
int nBlock;
|
||||
int* blockStruct;
|
||||
int* blockNumber;
|
||||
BlockType* blockType;
|
||||
int SDP_nBlock;
|
||||
int* SDP_blockStruct;
|
||||
int LP_nBlock;
|
||||
|
||||
BlockStruct();
|
||||
~BlockStruct();
|
||||
void initialize(int nBlock);
|
||||
void finalize();
|
||||
void makeInternalStructure();
|
||||
void display(FILE* fpOut = stdout);
|
||||
|
||||
};
|
||||
|
||||
} //end of namespace 'sdpa'
|
||||
|
||||
#endif // __sdpa_block_h__
|
||||
Vendored
+901
@@ -0,0 +1,901 @@
|
||||
/* -------------------------------------------------------------
|
||||
|
||||
This file is a component of SDPA
|
||||
Copyright (C) 2004-2013 SDPA Project
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
------------------------------------------------------------- */
|
||||
/*--------------------------------------------------
|
||||
sdpa_call.cpp
|
||||
--------------------------------------------------*/
|
||||
|
||||
#include "sdpa_call.h"
|
||||
#include "sdpa_io.h"
|
||||
#include "sdpa_linear.h"
|
||||
|
||||
using namespace sdpa;
|
||||
#define LengthOfBuffer 1024
|
||||
|
||||
SDPA::SDPA()
|
||||
{
|
||||
KAPPA = 1.5;
|
||||
m = 0;
|
||||
nBlock = 0;
|
||||
fpout = NULL;
|
||||
Display = NULL;
|
||||
isInitPoint = false;
|
||||
|
||||
typeParameter = PARAMETER_DEFAULT;
|
||||
param.setDefaultParameter(Parameter::PARAMETER_DEFAULT);
|
||||
}
|
||||
|
||||
SDPA::~SDPA()
|
||||
{
|
||||
finalize();
|
||||
}
|
||||
|
||||
void SDPA::setParameterType(ParameterType type)
|
||||
{
|
||||
if (type == PARAMETER_DEFAULT) {
|
||||
param.setDefaultParameter(Parameter::PARAMETER_DEFAULT);
|
||||
} else if (type == PARAMETER_UNSTABLE_BUT_FAST) {
|
||||
param.setDefaultParameter(Parameter::PARAMETER_UNSTABLE_BUT_FAST);
|
||||
} else if (type == PARAMETER_STABLE_BUT_SLOW) {
|
||||
param.setDefaultParameter(Parameter::PARAMETER_STABLE_BUT_SLOW);
|
||||
}
|
||||
typeParameter = type;
|
||||
}
|
||||
|
||||
void SDPA::setParameterMaxIteration(int maxIteration)
|
||||
{
|
||||
param.maxIteration = maxIteration;
|
||||
}
|
||||
|
||||
void SDPA::setParameterEpsilonStar (double epsilonStar)
|
||||
{
|
||||
param.epsilonStar = epsilonStar;
|
||||
}
|
||||
|
||||
void SDPA::setParameterLambdaStar (double lambdaStar)
|
||||
{
|
||||
param.lambdaStar = lambdaStar;
|
||||
}
|
||||
|
||||
void SDPA::setParameterOmegaStar (double omegaStar)
|
||||
{
|
||||
param.omegaStar = omegaStar;
|
||||
}
|
||||
|
||||
void SDPA::setParameterLowerBound (double lowerBound)
|
||||
{
|
||||
param.lowerBound = lowerBound;
|
||||
}
|
||||
|
||||
void SDPA::setParameterUpperBound (double upperBound)
|
||||
{
|
||||
param.upperBound = upperBound;
|
||||
}
|
||||
void SDPA::setParameterBetaStar (double betaStar)
|
||||
{
|
||||
param.betaStar = betaStar;
|
||||
}
|
||||
|
||||
void SDPA::setParameterBetaBar (double betaBar)
|
||||
{
|
||||
param.betaBar = betaBar;
|
||||
}
|
||||
|
||||
void SDPA::setParameterGammaStar (double gammaStar)
|
||||
{
|
||||
param.gammaStar = gammaStar;
|
||||
}
|
||||
|
||||
void SDPA::setParameterEpsilonDash (double epsilonDash)
|
||||
{
|
||||
param.epsilonDash = epsilonDash;
|
||||
}
|
||||
|
||||
void SDPA::setParameterPrintXVec(char* xPrint)
|
||||
{
|
||||
strncpy(param.xPrint,xPrint,PRINT_DEFAULT_LENGTH);
|
||||
}
|
||||
|
||||
void SDPA::setParameterPrintXMat(char* XPrint)
|
||||
{
|
||||
strncpy(param.XPrint,XPrint,PRINT_DEFAULT_LENGTH);
|
||||
}
|
||||
|
||||
void SDPA::setParameterPrintYMat(char* YPrint)
|
||||
{
|
||||
strncpy(param.YPrint,YPrint,PRINT_DEFAULT_LENGTH);
|
||||
}
|
||||
|
||||
void SDPA::setParameterPrintInformation(char* infPrint)
|
||||
{
|
||||
strncpy(param.infPrint,infPrint,PRINT_DEFAULT_LENGTH);
|
||||
}
|
||||
|
||||
void SDPA::setDisplay(FILE* Display)
|
||||
{
|
||||
this->Display = Display;
|
||||
}
|
||||
|
||||
void SDPA::setResultFile(FILE* fpout)
|
||||
{
|
||||
this->fpout = fpout;
|
||||
}
|
||||
|
||||
void SDPA::setNumThreads(int NumThreads)
|
||||
{
|
||||
newton.setNumThreads(Display,fpout,NumThreads);
|
||||
}
|
||||
|
||||
SDPA::ParameterType SDPA::getParameterType()
|
||||
{
|
||||
return typeParameter;
|
||||
}
|
||||
|
||||
int SDPA::getParameterMaxIteration()
|
||||
{
|
||||
return param.maxIteration;
|
||||
}
|
||||
double SDPA::getParameterEpsilonStar()
|
||||
{
|
||||
return param.epsilonStar;
|
||||
}
|
||||
double SDPA::getParameterLambdaStar()
|
||||
{
|
||||
return param.lambdaStar;
|
||||
}
|
||||
double SDPA::getParameterOmegaStar()
|
||||
{
|
||||
return param.omegaStar;
|
||||
}
|
||||
double SDPA::getParameterLowerBound()
|
||||
{
|
||||
return param.lowerBound;
|
||||
}
|
||||
double SDPA::getParameterUpperBound()
|
||||
{
|
||||
return param.upperBound;
|
||||
}
|
||||
double SDPA::getParameterBetaStar()
|
||||
{
|
||||
return param.betaStar;
|
||||
}
|
||||
double SDPA::getParameterBetaBar()
|
||||
{
|
||||
return param.betaBar;
|
||||
}
|
||||
double SDPA::getParameterGammaStar()
|
||||
{
|
||||
return param.gammaStar;
|
||||
}
|
||||
double SDPA::getParameterEpsilonDash()
|
||||
{
|
||||
return param.epsilonDash;
|
||||
}
|
||||
char* SDPA::getParameterPrintXVec()
|
||||
{
|
||||
return param.xPrint;
|
||||
}
|
||||
char* SDPA::getParameterPrintXMat()
|
||||
{
|
||||
return param.XPrint;
|
||||
}
|
||||
char* SDPA::getParameterPrintYMat()
|
||||
{
|
||||
return param.YPrint;
|
||||
}
|
||||
char* SDPA::getParameterPrintInformation()
|
||||
{
|
||||
return param.infPrint;
|
||||
}
|
||||
FILE* SDPA::getDisplay()
|
||||
{
|
||||
return Display;
|
||||
}
|
||||
FILE* SDPA::getResultFile()
|
||||
{
|
||||
return fpout;
|
||||
}
|
||||
bool SDPA::getInitPoint()
|
||||
{
|
||||
return isInitPoint;
|
||||
}
|
||||
|
||||
int SDPA::getNumThreads()
|
||||
{
|
||||
return newton.NUM_THREADS;
|
||||
}
|
||||
|
||||
void SDPA::inputConstraintNumber(int m)
|
||||
{
|
||||
this->m = m;
|
||||
}
|
||||
|
||||
void SDPA::inputBlockNumber(int nBlock)
|
||||
{
|
||||
this->nBlock = nBlock;
|
||||
bs.initialize(nBlock);
|
||||
}
|
||||
|
||||
void SDPA::inputBlockSize(int l, int size)
|
||||
{
|
||||
bs.blockStruct[l-1] = size;
|
||||
}
|
||||
|
||||
void SDPA::inputBlockType(int l, ConeType coneType)
|
||||
{
|
||||
if (coneType == SDPA::SDP) {
|
||||
bs.blockType[l-1] = BlockStruct::btSDP;
|
||||
}
|
||||
if (coneType == SDPA::LP) {
|
||||
bs.blockType[l-1] = BlockStruct::btLP;
|
||||
}
|
||||
}
|
||||
|
||||
void SDPA::inputCVec(int k, double value)
|
||||
{
|
||||
if (k > m || k <= 0) {
|
||||
rError("k exceeds ConstraintNumber or "
|
||||
"k is less than or equal to zero :: m= "
|
||||
<< m << " : k= " << k);
|
||||
|
||||
}
|
||||
inputData.b.ele[k-1] = value;
|
||||
}
|
||||
|
||||
void SDPA::inputElement(int k, int l, int i, int j, double value,
|
||||
bool inputCheck)
|
||||
{
|
||||
if (inputCheck) {
|
||||
if (k > m || k < 0) {
|
||||
rError ("k exceeds ConstraintNumber or "
|
||||
"k is less than zero :: m= "
|
||||
<< m << " : k= " << k << " : l= " << l
|
||||
<< " : i= " << i << " : j= " << j);
|
||||
}
|
||||
if (l > nBlock || l <= 0) {
|
||||
rError ("l exceeds nBlock or "
|
||||
"l is less than or equal to zero :: nBlock= "
|
||||
<< nBlock << " : k= " << k << " : l= " << l
|
||||
<< " : i= " << i << " : j= " << j);
|
||||
}
|
||||
int dim = bs.blockStruct[l-1];
|
||||
if (i > dim || i <= 0) {
|
||||
rError ("i exceeds dimension of the block or "
|
||||
"i is less than or equal to zero :: dim= "
|
||||
<< dim << " : k= " << k << " : l= " << l
|
||||
<< " : i= " << i << " : j= " << j);
|
||||
}
|
||||
if (j > dim || j <= 0) {
|
||||
rError ("j exceeds dimension of the block or "
|
||||
"j is less than or equal to zero :: dim= "
|
||||
<< dim << " : k= " << k << " : l= " << l
|
||||
<< " : i= " << i << " : j= " << j);
|
||||
}
|
||||
if (bs.blockType[l-1] == BlockStruct::btSDP) {
|
||||
if (i > j) {
|
||||
rMessage("Swap i and j [Only Upper Triangle]"
|
||||
" : k= " << k << " : l= " << l
|
||||
<< " : i= " << i << " : j= " << j);
|
||||
}
|
||||
}
|
||||
if (bs.blockType[l-1] == BlockStruct::btLP) {
|
||||
if (i!=j) {
|
||||
rError("i should be j in LP block"
|
||||
" : k= " << k << " : l= " << l
|
||||
<< " : i= " << i << " : j= " << j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (i > j) {
|
||||
int tmp = i; i = j; j = tmp;
|
||||
}
|
||||
|
||||
LIJV* indexLIJv;
|
||||
NewArray(indexLIJv,LIJV,1);
|
||||
indexLIJv[0].SDPl = -1;
|
||||
indexLIJv[0].LPl = -1;
|
||||
indexLIJv[0].i = i;
|
||||
indexLIJv[0].j = j;
|
||||
indexLIJv[0].value = value;
|
||||
|
||||
if (bs.blockType[l-1] == BlockStruct::btSDP) {
|
||||
int l2 = bs.blockNumber[l-1];
|
||||
indexLIJv[0].SDPl = l2;
|
||||
NonZeroElements[k].push_back(indexLIJv);
|
||||
} else if (bs.blockType[l-1] == BlockStruct::btLP) {
|
||||
int l2 = bs.blockNumber[l-1];
|
||||
indexLIJv[0].LPl = l2+i-1;
|
||||
NonZeroElements[k].push_back(indexLIJv);
|
||||
}
|
||||
// NonZeroElements[k].push_back(indexLIJv);
|
||||
}
|
||||
|
||||
void SDPA::inputInitXVec(int k, double value)
|
||||
{
|
||||
rError("This routine is not available in SDPA-C");
|
||||
}
|
||||
|
||||
void SDPA::inputInitXMat(int l, int i, int j, double value)
|
||||
{
|
||||
rError("This routine is not available in SDPA-C");
|
||||
}
|
||||
|
||||
void SDPA::inputInitYMat(int l, int i, int j, double value)
|
||||
{
|
||||
rError("This routine is not available in SDPA-C");
|
||||
}
|
||||
|
||||
|
||||
void SDPA::initializeUpperTriangleSpace()
|
||||
{
|
||||
bs.makeInternalStructure();
|
||||
NewArray(NonZeroElements,vector<LIJV*>,m+1);
|
||||
inputData.initialize(m, bs);
|
||||
|
||||
// In SDPA-C, currentPt.initialize will be called later
|
||||
// currentPt.initialize(m, bs, param.lambdaStar, com);
|
||||
}
|
||||
|
||||
|
||||
void SDPA::printNonZeroElements(FILE* fp)
|
||||
{
|
||||
for (int k=0; k<=m; ++k) {
|
||||
int size = NonZeroElements[k].size();
|
||||
for (int index = 0; index<size; ++index) {
|
||||
LIJV* a = NonZeroElements[k][index];
|
||||
int SDPl = a[0].SDPl;
|
||||
int LPl = a[0].LPl;
|
||||
int i = a[0].i;
|
||||
int j = a[0].j;
|
||||
double value = a[0].value;
|
||||
if (SDPl >= 0) {
|
||||
fprintf(fp,"%d, %d(S), %d, %d, ",k,SDPl,i,j);
|
||||
}
|
||||
if (LPl >= 0) {
|
||||
fprintf(fp,"%d, %d(L), %d, %d, ",k,LPl,i,j);
|
||||
}
|
||||
fprintf(fp,param.infPrint,value);
|
||||
fprintf(fp,"\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SDPA::checkNonZeroElements()
|
||||
{
|
||||
TimeStart(FILE_CHECK_START1);
|
||||
for (int k=0; k<=m; ++k) {
|
||||
int size = NonZeroElements[k].size();
|
||||
for (int index = 0; index<size-1; ++index) {
|
||||
LIJV* a = NonZeroElements[k][index];
|
||||
LIJV* b = NonZeroElements[k][index+1];
|
||||
if (a[0].SDPl == b[0].SDPl && a[0].LPl == b[0].SDPl
|
||||
&& a[0].i == b[0].i && a[0].j == b[0].j) {
|
||||
int SDPl = a[0].SDPl;
|
||||
int LPl = a[0].LPl;
|
||||
int i = a[0].i;
|
||||
int j = a[0].j;
|
||||
rError("Twice input to the same index. "
|
||||
": k = " << k << ": SDPl = " << SDPl << ": LPl = " << LPl
|
||||
<< ": i = " << i << ": j = " << j);
|
||||
}
|
||||
}
|
||||
}
|
||||
TimeEnd(FILE_CHECK_END1);
|
||||
com.FileChange += TimeCal(FILE_CHECK_START1,
|
||||
FILE_CHECK_END1);
|
||||
com.TotalTime += TimeCal(FILE_CHECK_START1,
|
||||
FILE_CHECK_END1);
|
||||
}
|
||||
|
||||
void SDPA::setNonZeroBlockStruct()
|
||||
{
|
||||
// almost equivalent to IO::setBlockStruct
|
||||
vector<int> LP_blockCount;
|
||||
vector<int> SDP_blockCount;
|
||||
for (int k=0; k<m+1; ++k) {
|
||||
LP_blockCount.clear();
|
||||
SDP_blockCount.clear();
|
||||
int length = NonZeroElements[k].size();
|
||||
for (int index1 = 0; index1 < length; ++index1) {
|
||||
LIJV* oneData = NonZeroElements[k].at(index1);
|
||||
if (oneData[0].LPl >= 0) {
|
||||
LP_blockCount.push_back(oneData[0].LPl);
|
||||
}
|
||||
if (oneData[0].SDPl >= 0) {
|
||||
SDP_blockCount.push_back(oneData[0].SDPl);
|
||||
}
|
||||
}
|
||||
sort(LP_blockCount.begin(), LP_blockCount.end());
|
||||
sort(SDP_blockCount.begin(), SDP_blockCount.end());
|
||||
int LP_sp_nBlock = 0;
|
||||
int SDP_sp_nBlock = 0;
|
||||
int LP_old_block = -1;
|
||||
int SDP_old_block = -1;
|
||||
const int LP_length = LP_blockCount.size();
|
||||
const int SDP_length = SDP_blockCount.size();
|
||||
for (int index1 = 0; index1 < LP_length; ++index1) {
|
||||
if (LP_blockCount[index1] != LP_old_block) {
|
||||
LP_old_block = LP_blockCount[index1];
|
||||
LP_sp_nBlock++;
|
||||
}
|
||||
}
|
||||
for (int index1 = 0; index1 < SDP_length; ++index1) {
|
||||
if (SDP_blockCount[index1] != SDP_old_block) {
|
||||
SDP_old_block = SDP_blockCount[index1];
|
||||
SDP_sp_nBlock++;
|
||||
}
|
||||
}
|
||||
|
||||
CompSpace* target = &inputData.C;
|
||||
if (k>0) {
|
||||
target = &inputData.A[k-1];
|
||||
}
|
||||
target->initialize(LP_sp_nBlock, SDP_sp_nBlock);
|
||||
int index_t = 0;
|
||||
LP_old_block = -1;
|
||||
for (int index1 = 0; index1 < LP_length; ++index1) {
|
||||
const int current_block = LP_blockCount[index1];
|
||||
if (current_block != LP_old_block) {
|
||||
target->LP_sp_index[index_t] = current_block;
|
||||
LP_old_block = current_block;
|
||||
index_t++;
|
||||
}
|
||||
}
|
||||
index_t = 0;
|
||||
SDP_old_block = -1;
|
||||
for (int index1 = 0; index1 < SDP_length; ++index1) {
|
||||
const int current_block = SDP_blockCount[index1];
|
||||
if (current_block != SDP_old_block) {
|
||||
target->SDP_sp_index[index_t] = current_block;
|
||||
SDP_old_block = current_block;
|
||||
target->SDP_sp_block[index_t].nRow = bs.SDP_blockStruct[current_block];
|
||||
target->SDP_sp_block[index_t].nCol = bs.SDP_blockStruct[current_block];
|
||||
index_t++;
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
rMessage("LP blocks = ");
|
||||
for (int index2 = 0; index2 < LP_sp_nBlock; ++index2) {
|
||||
printf(" %d", target->LP_sp_index[index2]);
|
||||
}
|
||||
printf("\n");
|
||||
rMessage("SDP blocks = ");
|
||||
for (int index2 = 0; index2 < SDP_sp_nBlock; ++index2) {
|
||||
printf(" %d", target->SDP_sp_index[index2]);
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
target->initializeInputVector();
|
||||
}
|
||||
LP_blockCount.clear();
|
||||
SDP_blockCount.clear();
|
||||
}
|
||||
|
||||
void SDPA::setNonZeroElements()
|
||||
{
|
||||
for (int k=0; k<m+1; ++k) {
|
||||
CompSpace* target = &inputData.C;
|
||||
double scale = -1.0; // Input of C should be reversed
|
||||
if (k>0) {
|
||||
target = &inputData.A[k-1];
|
||||
scale = 1.0;
|
||||
}
|
||||
int length = NonZeroElements[k].size();
|
||||
for (int index1 = 0; index1 < length; ++index1) {
|
||||
LIJV* oneData = NonZeroElements[k].at(index1);
|
||||
if (oneData[0].LPl >= 0) {
|
||||
target->setElement_LP(oneData[0].LPl, oneData[0].value*scale);
|
||||
}
|
||||
if (oneData[0].SDPl >= 0) {
|
||||
target->setElement_SDP(oneData[0].SDPl,
|
||||
oneData[0].i-1, oneData[0].j-1,
|
||||
oneData[0].value*scale);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
double v1 = 0; // dummy initialize
|
||||
double v2 = 0; // dummy initialize
|
||||
inputData.C.sortInputVector();
|
||||
int check_l = 0, check_i = 0, check_j = 0;
|
||||
double check_v1 = 0, check_v2 = 0;
|
||||
inputData.C.checkInputDataStructure(check_l, check_i, check_j,
|
||||
check_v1, check_v2);
|
||||
inputData.C.makeInternalStructure();
|
||||
if (check_l>=0) {
|
||||
printf("***** invalid data ******\n");
|
||||
printf("F[0]:%d-th SDP block:[%d, %d]-th element has more than one input\n",
|
||||
check_l+1, check_i+1, check_j+1);
|
||||
rError("Stop due to input error\n");
|
||||
}
|
||||
for (int k=0; k<m; ++k) {
|
||||
inputData.A[k].sortInputVector();
|
||||
inputData.A[k].checkInputDataStructure(check_l, check_i, check_j,
|
||||
check_v1, check_v2);
|
||||
inputData.A[k].makeInternalStructure();
|
||||
if (check_l>=0) {
|
||||
printf("***** invalid data ******\n");
|
||||
printf("F[%d]:%d-th SDP block:[%d, %d]-th element has more than one input\n",
|
||||
k+1, check_l+1, check_i+1, check_j+1);
|
||||
rError("Stop due to input error\n");
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
rMessage("************** Read finished, internal data is from here.");
|
||||
rMessage("C = -------------------------");
|
||||
inputData.C.display();
|
||||
for (int k=0; k<m; ++k) {
|
||||
rMessage("A[" << k << "] = -------------------------");
|
||||
inputData.A[k].display();
|
||||
}
|
||||
rMessage("************** Read finished, internal data is until here.");
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void SDPA::initializeUpperTriangle(bool checkTwiceInput)
|
||||
{
|
||||
if (checkTwiceInput) {
|
||||
checkNonZeroElements();
|
||||
}
|
||||
// printNonZeroElements();
|
||||
setNonZeroBlockStruct();
|
||||
setNonZeroElements();
|
||||
for (int k=0; k<=m; ++k) {
|
||||
int size = NonZeroElements[k].size();
|
||||
for (int index = 0; index < size; ++index) {
|
||||
DeleteArray(NonZeroElements[k][index]);
|
||||
}
|
||||
}
|
||||
DeleteArray(NonZeroElements);
|
||||
}
|
||||
|
||||
double* SDPA::getResultXVec()
|
||||
{
|
||||
return currentPt.cholmodSpace.yVec.ele;
|
||||
}
|
||||
|
||||
double* SDPA::getResultXMat(int l)
|
||||
{
|
||||
if (IO::judgeZmake(param) == false) {
|
||||
return NULL;
|
||||
}
|
||||
if (l > nBlock || l <= 0) {
|
||||
rError ("l exceeds nBlock or "
|
||||
"l is less than or equal to zero :: nBlock= "
|
||||
<< nBlock << " : l= " << l);
|
||||
}
|
||||
if (bs.blockType[l-1] == BlockStruct::btSDP) {
|
||||
int l2 = bs.blockNumber[l-1];
|
||||
return currentPt.finalZ.SDP_block[l2].de_ele;
|
||||
}
|
||||
else if (bs.blockType[l-1] == BlockStruct::btLP) {
|
||||
int start = bs.blockNumber[l-1];
|
||||
return ¤tPt.finalZ.LP_block[start];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
double* SDPA::getResultYMat(int l)
|
||||
{
|
||||
if (IO::judgeXmake(param) == false) {
|
||||
return NULL;
|
||||
}
|
||||
if (l > nBlock || l <= 0) {
|
||||
rError ("l exceeds nBlock or "
|
||||
"l is less than or equal to zero :: nBlock= "
|
||||
<< nBlock << " : l= " << l);
|
||||
}
|
||||
if (bs.blockType[l-1] == BlockStruct::btSDP) {
|
||||
int l2 = bs.blockNumber[l-1];
|
||||
return currentPt.finalX.SDP_block[l2].de_ele;
|
||||
}
|
||||
else if (bs.blockType[l-1] == BlockStruct::btLP) {
|
||||
int start = bs.blockNumber[l-1];
|
||||
return ¤tPt.finalX.LP_block[start];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
double SDPA::getPrimalObj()
|
||||
{
|
||||
// Note reverse primal-dual
|
||||
return -solveInfo.objValDual;
|
||||
}
|
||||
|
||||
double SDPA::getDualObj()
|
||||
{
|
||||
// Note reverse primal-dual
|
||||
return -solveInfo.objValPrimal;
|
||||
}
|
||||
|
||||
double SDPA::getPrimalError()
|
||||
{
|
||||
// Note reverse primal-dual
|
||||
return currentRes.normDual;
|
||||
}
|
||||
|
||||
double SDPA::getDualError()
|
||||
{
|
||||
// Note reverse primal-dual
|
||||
return currentRes.normPrimal;
|
||||
}
|
||||
|
||||
double SDPA::getDigits()
|
||||
{
|
||||
double mean = (fabs(solveInfo.objValPrimal)
|
||||
+ fabs(solveInfo.objValDual)) / 2.0;
|
||||
double PDgap = getDualityGap();
|
||||
double digits = -log10(fabs(PDgap/mean));
|
||||
return digits;
|
||||
}
|
||||
|
||||
int SDPA::getIteration()
|
||||
{
|
||||
return pIteration;
|
||||
}
|
||||
|
||||
double SDPA::getMu()
|
||||
{
|
||||
return mu.current;
|
||||
}
|
||||
|
||||
double SDPA::getDualityGap()
|
||||
{
|
||||
double PDgap = fabs(solveInfo.objValPrimal
|
||||
- solveInfo.objValDual);
|
||||
return PDgap;
|
||||
}
|
||||
|
||||
SDPA::PhaseType SDPA::getPhaseValue()
|
||||
{
|
||||
// Note reverse primal-dual
|
||||
switch (phase.value) {
|
||||
case SolveInfo::noINFO : return noINFO ; break;
|
||||
case SolveInfo::pFEAS : return pFEAS ; break;
|
||||
case SolveInfo::dFEAS : return dFEAS ; break;
|
||||
case SolveInfo::pdFEAS : return pdFEAS ; break;
|
||||
case SolveInfo::pdINF : return pdINF ; break;
|
||||
case SolveInfo::pFEAS_dINF: return pINF_dFEAS; break;
|
||||
case SolveInfo::pINF_dFEAS: return pFEAS_dINF; break;
|
||||
case SolveInfo::pdOPT : return pdOPT ; break;
|
||||
case SolveInfo::pUNBD : return dUNBD ; break;
|
||||
case SolveInfo::dUNBD : return pUNBD ; break;
|
||||
default: break;
|
||||
}
|
||||
return noINFO;
|
||||
}
|
||||
|
||||
void SDPA::getPhaseString(char* str)
|
||||
{
|
||||
switch (phase.value) {
|
||||
case SolveInfo::noINFO : strcpy(str,(char *)"noINFO "); break;
|
||||
case SolveInfo::pFEAS : strcpy(str,(char *)"pFEAS "); break;
|
||||
case SolveInfo::dFEAS : strcpy(str,(char *)"dFEAS "); break;
|
||||
case SolveInfo::pdFEAS : strcpy(str,(char *)"pdFEAS "); break;
|
||||
case SolveInfo::pdINF : strcpy(str,(char *)"pdINF "); break;
|
||||
case SolveInfo::pFEAS_dINF: strcpy(str,(char *)"pFEAS_dINF"); break;
|
||||
case SolveInfo::pINF_dFEAS: strcpy(str,(char *)"pINF_dFEAS"); break;
|
||||
case SolveInfo::pdOPT : strcpy(str,(char *)"pdOPT "); break;
|
||||
case SolveInfo::pUNBD : strcpy(str,(char *)"pUNBD "); break;
|
||||
case SolveInfo::dUNBD : strcpy(str,(char *)"dUNBD "); break;
|
||||
default:
|
||||
strcpy(str,(char *)"phase error");
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
double SDPA::getSolveTime()
|
||||
{
|
||||
return com.TotalTime;
|
||||
}
|
||||
|
||||
int SDPA::getConstraintNumber()
|
||||
{
|
||||
return m;
|
||||
}
|
||||
|
||||
int SDPA::getBlockNumber()
|
||||
{
|
||||
return nBlock;
|
||||
}
|
||||
|
||||
int SDPA::getBlockSize(int l)
|
||||
{
|
||||
if (l<=0 || l>nBlock) {
|
||||
rMessage("out of range : getBlockSize "
|
||||
": l = " << l
|
||||
<< " should be between 1 and nBlock " << nBlock);
|
||||
}
|
||||
return bs.blockStruct[l-1];
|
||||
}
|
||||
|
||||
SDPA::ConeType SDPA::getBlockType(int l)
|
||||
{
|
||||
if (l<=0 || l>nBlock) {
|
||||
rMessage("out of range : getBlockSize "
|
||||
": l = " << l
|
||||
<< " should be between 1 and nBlock " << nBlock);
|
||||
}
|
||||
switch (bs.blockType[l-1]) {
|
||||
case BlockStruct::btSDP : return SDPA::SDP ;
|
||||
case BlockStruct::btLP : return SDPA::LP ;
|
||||
}
|
||||
rError("Type Error in getBlockType ");
|
||||
return SDPA::SDP; // dummy return
|
||||
}
|
||||
|
||||
void SDPA::getDimacsError(double* DimacsError)
|
||||
{
|
||||
if (judgeDimacsAvailability() == false) {
|
||||
return;
|
||||
}
|
||||
IO::computeDimacs(DimacsError, solveInfo, currentRes,
|
||||
currentPt, inputData);
|
||||
}
|
||||
|
||||
void SDPA::printDimacsError(double* DimacsError, char* printFormat,
|
||||
FILE* fpout)
|
||||
{
|
||||
if (judgeDimacsAvailability() == false) {
|
||||
return;
|
||||
}
|
||||
IO::printDimacs(DimacsError,printFormat,fpout);
|
||||
}
|
||||
|
||||
void SDPA::printDimacsEasy(FILE* fpout)
|
||||
{
|
||||
double dimacs_error[7];
|
||||
currentPt.makeFinalSolution(true, true, bs);
|
||||
getDimacsError(dimacs_error);
|
||||
printf("Dimacs = ");
|
||||
for (int dd=1; dd<7; ++dd) {
|
||||
printf("%.3e ", dimacs_error[dd]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
|
||||
void SDPA::printResultXVec(FILE* fp)
|
||||
{
|
||||
// Note reverse primal-dual
|
||||
currentPt.cholmodSpace.yVec.display(fp,1.0,param.xPrint);
|
||||
}
|
||||
|
||||
void SDPA::printResultXMat(FILE* fp)
|
||||
{
|
||||
if (IO::judgeZmake(param) == false) {
|
||||
fprintf(fp, "Result XMat is not computed.\n");
|
||||
return;
|
||||
}
|
||||
// Note reverse primal-dual
|
||||
currentPt.finalZ.displaySolution(bs,fp,param.XPrint);
|
||||
}
|
||||
|
||||
void SDPA::printResultYMat(FILE* fp)
|
||||
{
|
||||
if (IO::judgeXmake(param) == false) {
|
||||
fprintf(fp, "Result YMat is not computed.\n");
|
||||
return;
|
||||
}
|
||||
// Note reverse primal-dual
|
||||
currentPt.finalX.displaySolution(bs,fp,param.YPrint);
|
||||
}
|
||||
|
||||
void SDPA::printComputationTime(FILE* fp)
|
||||
{
|
||||
com.display(fp);
|
||||
}
|
||||
|
||||
void SDPA::printParameters(FILE* fp)
|
||||
{
|
||||
param.display(fp);
|
||||
}
|
||||
|
||||
bool SDPA::judgeDimacsAvailability() // for only SDPA-C
|
||||
{
|
||||
bool Xmake = IO::judgeXmake(param);
|
||||
bool Zmake = IO::judgeZmake(param);
|
||||
if (Xmake == false || Zmake == false) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void SDPA::printSDPAVersion(FILE* fp)
|
||||
{
|
||||
if (fp) {
|
||||
fprintf(fp,"%s\n",(char*)sdpa_right);
|
||||
}
|
||||
}
|
||||
|
||||
void SDPA::readInput(char* filename, FILE* fpout)
|
||||
{
|
||||
TimeStart(FILE_READ_START1);
|
||||
FILE* fpinput = NULL;
|
||||
if ((fpinput = fopen(filename,"r")) == NULL) {
|
||||
rError("Cannot Open Data File " << filename);
|
||||
}
|
||||
#if 0
|
||||
if (fpout){
|
||||
fprintf(fpout,"data is %s ", filename);
|
||||
fprintf(fpout," : sparse\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
char titleAndComment[LengthOfBuffer];
|
||||
IO::read(fpinput,fpout,m,titleAndComment);
|
||||
IO::read(fpinput,nBlock);
|
||||
bs.initialize(nBlock);
|
||||
IO::read(fpinput,bs);
|
||||
bs.makeInternalStructure();
|
||||
inputData.initialize(m, bs);
|
||||
IO::read(fpinput, inputData.b);
|
||||
IO::read(fpinput, m, bs, inputData);
|
||||
// inputData.initialize_index();
|
||||
fclose(fpinput);
|
||||
TimeEnd(FILE_READ_END1);
|
||||
com.FileRead += TimeCal(FILE_READ_START1,
|
||||
FILE_READ_END1);
|
||||
com.TotalTime += TimeCal(FILE_READ_START1,
|
||||
FILE_READ_END1);
|
||||
return;
|
||||
}
|
||||
|
||||
void SDPA::readParameter(char* filename, FILE* fpout)
|
||||
{
|
||||
FILE* fp = NULL;
|
||||
if ((fp=fopen(filename,"r"))==NULL) {
|
||||
rError("Cannot Open parameter File " << filename);
|
||||
}
|
||||
param.readFile(fp);
|
||||
fclose(fp);
|
||||
return;
|
||||
}
|
||||
|
||||
void SDPA::finalize()
|
||||
{
|
||||
bs.finalize();
|
||||
inputData.finalize();
|
||||
chordal.finalize();
|
||||
newton.finalize();
|
||||
currentPt.finalize();
|
||||
initPt_xMat.finalize();
|
||||
initPt_zMat.finalize();
|
||||
currentRes.finalize();
|
||||
alpha.finalize();
|
||||
}
|
||||
|
||||
|
||||
void SDPA::copyCurrentToInit()
|
||||
{
|
||||
// This function is only compatibility with SDPA.
|
||||
rMessage("The function SDPA::copyCurrentToInit() does nothing in SDPA-C");
|
||||
return;
|
||||
}
|
||||
|
||||
void SDPA::setKappa(double KAPPA)
|
||||
{
|
||||
this->KAPPA = KAPPA;
|
||||
}
|
||||
|
||||
Vendored
+256
@@ -0,0 +1,256 @@
|
||||
/* -------------------------------------------------------------
|
||||
|
||||
This file is a component of SDPA
|
||||
Copyright (C) 2004-2013 SDPA Project
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
------------------------------------------------------------- */
|
||||
/*--------------------------------------------------
|
||||
sdpa_call.h
|
||||
--------------------------------------------------*/
|
||||
|
||||
/***************************************************
|
||||
In this header file,
|
||||
Do NOT use 'using namespace sdpa;'.
|
||||
Otherwise, if users define their OWN 'sdpa' namespace,
|
||||
it would be trouble.
|
||||
***************************************************/
|
||||
|
||||
|
||||
#ifndef __sdpa_call_h__
|
||||
#define __sdpa_call_h__
|
||||
|
||||
#include <sdpa_right.h>
|
||||
#include <sdpa_newton.h>
|
||||
#include <sdpa_chordal.h>
|
||||
#include <sdpa_parts.h>
|
||||
#include <sdpa_struct.h>
|
||||
#include <cstdio>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
/* The class list is generated by the following command
|
||||
$ grep class *.h | grep -v \; | grep -v SDPA | tr ':' ' ' | \
|
||||
awk '{print $2 " " $3 ";"}'
|
||||
*/
|
||||
|
||||
namespace sdpa {
|
||||
class BlockStruct;
|
||||
class Chordal;
|
||||
class Solutions;
|
||||
class InputData;
|
||||
class Residuals;
|
||||
class IO;
|
||||
class Lal;
|
||||
class Newton;
|
||||
class ComputeTime;
|
||||
class Parameter;
|
||||
class StepLength;
|
||||
class DirectionParameter;
|
||||
class Switch;
|
||||
class AverageComplementarity;
|
||||
class RatioInitResCurrentRes;
|
||||
class SolveInfo;
|
||||
class Phase;
|
||||
class Vector;
|
||||
class BlockVector;
|
||||
class SparseMatrix;
|
||||
class DenseMatrix;
|
||||
class SparseLinearSpace;
|
||||
class DenseLinearSpace;
|
||||
class Time;
|
||||
|
||||
class LIJV
|
||||
{
|
||||
public:
|
||||
int SDPl,LPl,i,j;
|
||||
double value;
|
||||
};
|
||||
};
|
||||
|
||||
class SDPA
|
||||
{
|
||||
public:
|
||||
|
||||
enum PhaseType {noINFO, pFEAS,dFEAS,pdFEAS,pdINF,
|
||||
pFEAS_dINF,pINF_dFEAS,pdOPT,pUNBD,dUNBD};
|
||||
enum ParameterType {PARAMETER_DEFAULT,
|
||||
PARAMETER_UNSTABLE_BUT_FAST,
|
||||
PARAMETER_STABLE_BUT_SLOW};
|
||||
|
||||
enum ConeType {SDP, SOCP, LP};
|
||||
// SOCP is not implemented in the current version.
|
||||
|
||||
enum SparseType {AUTO, SPARSE, DENSE};
|
||||
// SparseType is only for compatiblity with SDPA7
|
||||
// In SDPA-C, this always must be SPARSE.
|
||||
// enum SparseType {AUTO, SPARSE, DENSE};
|
||||
// when AUTO is set, the type is analyzed by the file extenstion.
|
||||
|
||||
SDPA();
|
||||
~SDPA();
|
||||
|
||||
void setParameterType(ParameterType type = PARAMETER_DEFAULT);
|
||||
void setParameterMaxIteration(int maxIteration);
|
||||
void setParameterEpsilonStar (double epsilonStar);
|
||||
void setParameterLambdaStar (double lambdaStar);
|
||||
void setParameterOmegaStar (double omegaStar);
|
||||
void setParameterLowerBound (double lowerBound);
|
||||
void setParameterUpperBound (double upperBound);
|
||||
void setParameterBetaStar (double betaStar);
|
||||
void setParameterBetaBar (double betaBar);
|
||||
void setParameterGammaStar (double gammaStar);
|
||||
void setParameterEpsilonDash (double epsilonDash);
|
||||
|
||||
void setParameterPrintXVec(char* xPrint);
|
||||
void setParameterPrintXMat(char* XPrint);
|
||||
void setParameterPrintYMat(char* YPrint);
|
||||
void setParameterPrintInformation(char* infPrint);
|
||||
|
||||
void setDisplay(FILE* Display = stdout);
|
||||
void setResultFile(FILE* fpout = stdout);
|
||||
|
||||
void setNumThreads(int NumThreads=0);
|
||||
|
||||
ParameterType getParameterType();
|
||||
int getParameterMaxIteration();
|
||||
double getParameterEpsilonStar ();
|
||||
double getParameterLambdaStar ();
|
||||
double getParameterOmegaStar ();
|
||||
double getParameterLowerBound ();
|
||||
double getParameterUpperBound ();
|
||||
double getParameterBetaStar ();
|
||||
double getParameterBetaBar ();
|
||||
double getParameterGammaStar ();
|
||||
double getParameterEpsilonDash ();
|
||||
|
||||
char* getParameterPrintXVec();
|
||||
char* getParameterPrintXMat();
|
||||
char* getParameterPrintYMat();
|
||||
char* getParameterPrintInformation();
|
||||
|
||||
FILE* getDisplay();
|
||||
FILE* getResultFile();
|
||||
bool getInitPoint();
|
||||
|
||||
int getNumThreads();
|
||||
|
||||
void inputConstraintNumber(int m);
|
||||
void inputBlockNumber(int nBlock);
|
||||
void inputBlockSize(int l, int size);
|
||||
void inputBlockType(int l, ConeType coneType);
|
||||
void inputCVec(int k, double value);
|
||||
void inputElement(int k, int l, int i, int j, double value,
|
||||
bool inputCheck = false);
|
||||
void inputInitXVec(int k, double value);
|
||||
void inputInitXMat(int l, int i, int j, double value);
|
||||
void inputInitYMat(int l, int i, int j, double value);
|
||||
|
||||
void initializeUpperTriangleSpace();
|
||||
void initializeUpperTriangle(bool inputTwiceCheck = false);
|
||||
void initializeSolve();
|
||||
|
||||
void solve();
|
||||
|
||||
double* getResultXVec();
|
||||
double* getResultXMat(int l);
|
||||
double* getResultYMat(int l);
|
||||
double getPrimalObj();
|
||||
double getDualObj();
|
||||
double getPrimalError();
|
||||
double getDualError();
|
||||
double getDigits();
|
||||
int getIteration();
|
||||
double getMu();
|
||||
double getDualityGap();
|
||||
PhaseType getPhaseValue();
|
||||
void getPhaseString(char* str);
|
||||
double getSolveTime();
|
||||
|
||||
int getConstraintNumber();
|
||||
int getBlockNumber();
|
||||
int getBlockSize(int l);
|
||||
ConeType getBlockType(int l);
|
||||
|
||||
void getDimacsError(double* DimacsError);
|
||||
void printDimacsError(double* DimacsError, char* printFormat,
|
||||
FILE* fp = stdout);
|
||||
|
||||
void printResultXVec(FILE* fp = stdout);
|
||||
void printResultXMat(FILE* fp = stdout);
|
||||
void printResultYMat(FILE* fp = stdout);
|
||||
void printComputationTime(FILE* fp = stdout);
|
||||
void printParameters(FILE* fp = stdout);
|
||||
|
||||
bool judgeDimacsAvailability(); // for only SDPA-C
|
||||
|
||||
static void printSDPAVersion(FILE* fp = stdout);
|
||||
|
||||
void readInput(char* filename, FILE* fpout = NULL);
|
||||
void readParameter(char* filename, FILE* fpout = NULL);
|
||||
void writeInputSparse(char* filename, char* printFormat);
|
||||
void writeInitSparse(char* filename, char* printFormat);
|
||||
|
||||
void finalize();
|
||||
void copyCurrentToInit();
|
||||
|
||||
// setKappa is for only SDPA developers
|
||||
void setKappa(double KAPPA);
|
||||
|
||||
// // for debugging, private is replaced by public
|
||||
// public:
|
||||
private:
|
||||
double KAPPA;
|
||||
int m;
|
||||
int nBlock;
|
||||
FILE* Display;
|
||||
FILE* fpout;
|
||||
bool isInitPoint;
|
||||
ParameterType typeParameter;
|
||||
|
||||
int pIteration;
|
||||
|
||||
sdpa::ComputeTime com;
|
||||
sdpa::Parameter param;
|
||||
sdpa::BlockStruct bs;
|
||||
sdpa::InputData inputData;
|
||||
sdpa::Newton newton;
|
||||
sdpa::Chordal chordal;
|
||||
sdpa::Solutions currentPt;
|
||||
sdpa::DenseLinearSpace initPt_xMat;
|
||||
sdpa::DenseLinearSpace initPt_zMat;
|
||||
sdpa::Residuals currentRes;
|
||||
sdpa::StepLength alpha;
|
||||
sdpa::DirectionParameter beta;
|
||||
sdpa::Switch reduction;
|
||||
sdpa::AverageComplementarity mu;
|
||||
sdpa::RatioInitResCurrentRes theta;
|
||||
sdpa::SolveInfo solveInfo;
|
||||
sdpa::Phase phase;
|
||||
|
||||
|
||||
// temporary space to store
|
||||
// upper trianguler part non-zeros.
|
||||
vector<sdpa::LIJV*> * NonZeroElements;
|
||||
void printNonZeroElements(FILE* fpout = stdout);
|
||||
void checkNonZeroElements();
|
||||
void setNonZeroBlockStruct();
|
||||
void setNonZeroElements();
|
||||
|
||||
void printDimacsEasy(FILE* fpout = stdout); // heavy but for each iteration
|
||||
};
|
||||
|
||||
#endif // __sdpa_call_h__
|
||||
Vendored
+557
@@ -0,0 +1,557 @@
|
||||
/* -------------------------------------------------------------
|
||||
|
||||
This file is a component of SDPA
|
||||
Copyright (C) 2004-2013 SDPA Project
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
------------------------------------------------------------- */
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#define PrintSparsity 1
|
||||
#define PLUS_ADJUST_DIAGONAL (1.0e-10)
|
||||
// #define PLUS_ADJUST_DIAGONAL (m*1.0e-10)
|
||||
|
||||
// For debug
|
||||
#define FORCE_SCHUR_DENSE 0
|
||||
#define FORCE_SCHUR_SPARSE 0
|
||||
|
||||
#include "sdpa_chordal.h"
|
||||
#define MUMPS_JOB_INIT -1
|
||||
#define MUMPS_JOB_END -2
|
||||
#define MUMPS_JOB_ANALYSIS 1
|
||||
#define MUMPS_JOB_FACTORIZE 2
|
||||
#define MUMPS_JOB_SOLVE 3
|
||||
#define MUMPS_USE_COMM_WORLD (-987654)
|
||||
|
||||
namespace sdpa {
|
||||
|
||||
Chordal::Chordal()
|
||||
{
|
||||
mumps_usage = false;
|
||||
sparse_bMat_ptr = NULL;
|
||||
best = 0;
|
||||
}
|
||||
|
||||
Chordal::~Chordal()
|
||||
{
|
||||
finalize();
|
||||
}
|
||||
|
||||
void Chordal::initialize(SparseMatrix* sparse_bMat_ptr)
|
||||
{
|
||||
// condition of sparse computation
|
||||
// m_threshold < mDim,
|
||||
// b_threshold < nBlock,
|
||||
// aggregate_threshold >= aggrigated sparsity ratio
|
||||
// extend_threshold >= extended sparsity ratio
|
||||
m_threshold = 100;
|
||||
b_threshold = 5;
|
||||
aggregate_threshold = 0.70;
|
||||
extend_threshold = 0.80;
|
||||
|
||||
#if FORCE_SCHUR_DENSE // DENSE computation for debugging
|
||||
m_threshold = 10000000;
|
||||
b_threshold = 1000000;
|
||||
aggregate_threshold = 0.0;
|
||||
extend_threshold = 0.0;
|
||||
#endif
|
||||
#if FORCE_SCHUR_SPARSE // SPARSE computation for debugging
|
||||
m_threshold = 0;
|
||||
b_threshold = 0;
|
||||
aggregate_threshold = 2.0;
|
||||
extend_threshold = 2.0;
|
||||
#endif
|
||||
// initialize by assuming Schur would be DENSE
|
||||
best = SELECT_DENSE;
|
||||
|
||||
this->sparse_bMat_ptr = sparse_bMat_ptr;
|
||||
|
||||
// initialize MUMPS
|
||||
mumps_id.job = MUMPS_JOB_INIT;
|
||||
mumps_id.comm_fortran = MUMPS_USE_COMM_WORLD;
|
||||
// rank 0 process participates factorizations
|
||||
mumps_id.par = 1;
|
||||
// Only symmetric positive definite matricies
|
||||
mumps_id.sym = 1;
|
||||
// No OUTPUTS
|
||||
mumps_id.icntl[1-1] = -1;
|
||||
mumps_id.icntl[2-1] = -1;
|
||||
mumps_id.icntl[3-1] = -1;
|
||||
mumps_id.icntl[4-1] = 0;
|
||||
|
||||
// MUMPS selects ordering automatically
|
||||
mumps_id.icntl[7-1] = SELECT_MUMPS_BEST;
|
||||
// for Minumum Degree Ordering
|
||||
// mumps_id.icntl[7-1] = 0;
|
||||
|
||||
dmumps_c(&mumps_id);
|
||||
mumps_usage = true;
|
||||
|
||||
}
|
||||
|
||||
void Chordal::finalize()
|
||||
{
|
||||
if (mumps_usage == true) {
|
||||
mumps_id.job = MUMPS_JOB_END;
|
||||
dmumps_c(&mumps_id);
|
||||
mumps_usage = false;
|
||||
}
|
||||
if (sparse_bMat_ptr) {
|
||||
sparse_bMat_ptr->finalize();
|
||||
}
|
||||
sparse_bMat_ptr = NULL;
|
||||
}
|
||||
|
||||
// merge array1 to array2
|
||||
void Chordal::mergeArray(int na1, int* array1, int na2, int* array2)
|
||||
{
|
||||
|
||||
int ptr = na1 + na2 - 1;
|
||||
int ptr1 = na1-1;
|
||||
int ptr2 = na2-1;
|
||||
int idx1, idx2;
|
||||
|
||||
while ((ptr1 >= 0) || (ptr2 >= 0)){
|
||||
|
||||
if (ptr1 >= 0){
|
||||
idx1 = array1[ptr1];
|
||||
} else {
|
||||
idx1 = -1;
|
||||
}
|
||||
if (ptr2 >= 0 ){
|
||||
idx2 = array2[ptr2];
|
||||
} else {
|
||||
idx2 = -1;
|
||||
}
|
||||
if (idx1 > idx2){
|
||||
array2[ptr] = idx1;
|
||||
ptr1--;
|
||||
} else {
|
||||
array2[ptr] = idx2;
|
||||
ptr2--;
|
||||
}
|
||||
ptr--;
|
||||
|
||||
}
|
||||
|
||||
// error check
|
||||
if (ptr != -1){
|
||||
rMessage("Chordal::mergeArray:: program bug");
|
||||
}
|
||||
}
|
||||
|
||||
void Chordal::catArray(int na1, int* array1, int na2, int* array2)
|
||||
{
|
||||
int ind1 = 0;
|
||||
for (int index=0; index<na1; ++index) {
|
||||
array2[na2] = array1[ind1];
|
||||
ind1++;
|
||||
na2++;
|
||||
}
|
||||
}
|
||||
|
||||
void Chordal::slimArray(int j, int length, int* array, int& slimedLength)
|
||||
{
|
||||
if (length == 0) {
|
||||
return;
|
||||
}
|
||||
sort(&array[0],&array[length]);
|
||||
|
||||
// We list up only lower triangular
|
||||
int index = 0;
|
||||
while (array[index] != j) {
|
||||
index++;
|
||||
}
|
||||
array[0] = j;
|
||||
slimedLength = 0;
|
||||
index++;
|
||||
for (; index<length; ++index) {
|
||||
if (array[slimedLength] == array[index]) {
|
||||
continue;
|
||||
}
|
||||
slimedLength++;
|
||||
array[slimedLength] = array[index];
|
||||
}
|
||||
slimedLength++;
|
||||
}
|
||||
|
||||
// make aggrigate sparsity pattern
|
||||
void Chordal::makeGraph(InputData& inputData, int m)
|
||||
{
|
||||
|
||||
int j,k,l;
|
||||
int SDP_nBlock = inputData.SDP_nBlock;
|
||||
int LP_nBlock = inputData.LP_nBlock;
|
||||
int* counter;
|
||||
NewArray(counter,int,m);
|
||||
for (j=0; j<m; j++){
|
||||
counter[j] = 0;
|
||||
}
|
||||
|
||||
// count maximum mumber of index
|
||||
for (l = 0; l<SDP_nBlock; l++){
|
||||
int SDP_nConstraint = inputData.SDP_nConstraint[l];
|
||||
for (k=0; k<SDP_nConstraint; k++){
|
||||
j = inputData.SDP_constraint[l][k];
|
||||
counter[j] += SDP_nConstraint;
|
||||
}
|
||||
}
|
||||
for (l = 0; l<LP_nBlock; l++){
|
||||
int LP_nConstraint = inputData.LP_nConstraint[l];
|
||||
for (k=0; k<LP_nConstraint; k++){
|
||||
j = inputData.LP_constraint[l][k];
|
||||
counter[j] += LP_nConstraint;
|
||||
}
|
||||
}
|
||||
|
||||
// allocate temporaly workspace
|
||||
int** tmp;
|
||||
NewArray(tmp,int*,m);
|
||||
for (j=0; j<m; j++){
|
||||
// Anyway B(j,j) exists even if A(j) is empty
|
||||
counter[j]++;
|
||||
}
|
||||
for (j=0; j<m; j++){
|
||||
NewArray(tmp[j],int,counter[j]);
|
||||
}
|
||||
for (j=0; j<m; j++){
|
||||
// Anyway B(j,j) exists even if A(j) is empty
|
||||
tmp[j][0] = j;
|
||||
}
|
||||
|
||||
// merge index
|
||||
for (j=0; j<m; j++){
|
||||
// Slide 1: Anyway B(j,j) exists even if A(j) is empty
|
||||
counter[j] = 1;
|
||||
}
|
||||
// merge index of for SDP
|
||||
for (l = 0; l<SDP_nBlock; l++){
|
||||
for (k=0; k<inputData.SDP_nConstraint[l]; k++){
|
||||
j = inputData.SDP_constraint[l][k];
|
||||
catArray(inputData.SDP_nConstraint[l],
|
||||
inputData.SDP_constraint[l],
|
||||
counter[j], tmp[j]);
|
||||
counter[j] += inputData.SDP_nConstraint[l];
|
||||
}
|
||||
}
|
||||
// merge index of for LP
|
||||
for (l = 0; l<LP_nBlock; l++){
|
||||
for (k=0; k<inputData.LP_nConstraint[l]; k++){
|
||||
j = inputData.LP_constraint[l][k];
|
||||
catArray(inputData.LP_nConstraint[l], inputData.LP_constraint[l],
|
||||
counter[j], tmp[j]);
|
||||
counter[j] += inputData.LP_nConstraint[l];
|
||||
}
|
||||
}
|
||||
|
||||
for (j=0; j<m; j++){
|
||||
#if 0
|
||||
printf("BeforeSlimArray[%d] = ",j);
|
||||
for (int index=0; index<counter[j]; ++index) {
|
||||
printf(" %d", tmp[j][index]);
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
int tmp2 = 0;
|
||||
slimArray(j,counter[j],tmp[j],tmp2);
|
||||
counter[j] = tmp2;
|
||||
|
||||
#if 0
|
||||
printf("slimArray[%d] = ",j);
|
||||
for (int index=0; index<counter[j]; ++index) {
|
||||
printf(" %d", tmp[j][index]);
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
}
|
||||
int nz = 0;
|
||||
for (j=0; j<m; j++){
|
||||
nz += counter[j];
|
||||
}
|
||||
|
||||
sparse_bMat_ptr -> initialize(m,m,SparseMatrix::SPARSE,
|
||||
nz,SparseMatrix::DSarrays);
|
||||
sparse_bMat_ptr -> NonZeroCount = nz;
|
||||
int indexNZ = 0;
|
||||
for (j=0; j<m; ++j) {
|
||||
for (int index_i=0; index_i<counter[j]; ++index_i) {
|
||||
// Note that MUMPS is written in FORTRAN
|
||||
// So, we need to slide all indices by +1
|
||||
sparse_bMat_ptr -> row_index[indexNZ] = tmp[j][index_i]+1;
|
||||
sparse_bMat_ptr -> column_index[indexNZ] = j+1;
|
||||
sparse_bMat_ptr -> sp_ele[indexNZ] = 0.0;
|
||||
indexNZ++;
|
||||
}
|
||||
}
|
||||
|
||||
DeleteArray(counter);
|
||||
for (j=0; j<m; j++){
|
||||
DeleteArray(tmp[j]);
|
||||
}
|
||||
DeleteArray(tmp);
|
||||
}
|
||||
|
||||
double Chordal::analysisAndcountLowerNonZero(int m)
|
||||
{
|
||||
mumps_id.job = MUMPS_JOB_ANALYSIS;
|
||||
mumps_id.n = m;
|
||||
mumps_id.nz = sparse_bMat_ptr->NonZeroCount;
|
||||
mumps_id.irn = sparse_bMat_ptr->row_index;
|
||||
mumps_id.jcn = sparse_bMat_ptr->column_index;
|
||||
mumps_id.a = sparse_bMat_ptr->sp_ele;
|
||||
|
||||
// sparse_bMat_ptr->display();
|
||||
// rMessage("m = " << m);
|
||||
// rMessage("NonZeroCount = " << sparse_bMat_ptr->NonZeroCount);
|
||||
|
||||
// No OUTPUTS for analysis
|
||||
mumps_id.icntl[1-1] = -1;
|
||||
mumps_id.icntl[2-1] = -1;
|
||||
mumps_id.icntl[3-1] = -1;
|
||||
mumps_id.icntl[4-1] = 0;
|
||||
// strcpy(mumps_id.write_problem,"write_problem");
|
||||
dmumps_c(&mumps_id);
|
||||
double lower_nonzeros = (double)mumps_id.infog[20-1];
|
||||
// if lower_nonzeros is greater than 1.0e+6,
|
||||
// the value infog[20-1] is lower_nonzeros*(-1)/(1.0e+6).
|
||||
// we need to adjust the value.
|
||||
if (lower_nonzeros < 0) {
|
||||
lower_nonzeros *= (-1.0e+6);
|
||||
}
|
||||
#if 0
|
||||
rMessage("lower_nonzeros = " << lower_nonzeros);
|
||||
rMessage("Schur density = " << lower_nonzeros/((m+1)*m/2)*100 << "%" );
|
||||
#endif
|
||||
|
||||
if (mumps_id.infog[1-1] != 0) {
|
||||
rError("MUMPS ERROR " << mumps_id.infog[1-1]);
|
||||
}
|
||||
return lower_nonzeros;
|
||||
}
|
||||
|
||||
void Chordal::ordering_bMat(int m, int nBlock,
|
||||
InputData& inputData,
|
||||
FILE* Display, FILE* fpOut)
|
||||
{
|
||||
best = SELECT_MUMPS_BEST;
|
||||
#if 0
|
||||
if ((m <= m_threshold)||(nBlock <= b_threshold)) {
|
||||
best = SELECT_DENSE;
|
||||
return;
|
||||
}
|
||||
#else
|
||||
if (m <= m_threshold) {
|
||||
best = SELECT_DENSE;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
for (int b=0; b<inputData.SDP_nBlock; b++){
|
||||
if (inputData.SDP_nConstraint[b] > m * sqrt(aggregate_threshold)){
|
||||
best = SELECT_DENSE;
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (int b=0; b<inputData.LP_nBlock; b++){
|
||||
if (inputData.LP_nConstraint[b] > m * sqrt(aggregate_threshold)){
|
||||
best = SELECT_DENSE;
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
makeGraph(inputData,m);
|
||||
// Here, we initialize sparse_bMat
|
||||
|
||||
int NonZeroAggregate = sparse_bMat_ptr->NonZeroCount*2-m;
|
||||
if (NonZeroAggregate > aggregate_threshold * (double)m * (double) m) {
|
||||
best = SELECT_DENSE;
|
||||
return;
|
||||
}
|
||||
|
||||
double lowerExtended = analysisAndcountLowerNonZero(m);
|
||||
double NonZeroExtended = lowerExtended*2 - m;
|
||||
double overM2 = 1.0/((double)m*(double)m)*100.0;
|
||||
#if PrintSparsity
|
||||
/* print sparsity information */
|
||||
if (Display) {
|
||||
|
||||
#if 0
|
||||
fprintf(Display,"dense matrix :\t\t\t%14d elements\n", m*m);
|
||||
fprintf(Display,"aggregate sparsity pattern :\t\t\t%14d elements\n",
|
||||
NonZeroAggregate);
|
||||
fprintf(Display,"extended sparsity pattern :\t\t\t%14d elements\n",
|
||||
(int)NonZeroExtended);
|
||||
fprintf(Display,"Schur density = %.8lf%%\n",
|
||||
(double)NonZeroExtended*overM2);
|
||||
fprintf(Display,"Fill in = %e%%\n",
|
||||
(double)(NonZeroExtended-NonZeroAggregate)*overM2);
|
||||
fprintf(Display, "Estimated FLOPs for elimation process = %e\n",
|
||||
mumps_id.rinfog[1-1]);
|
||||
fprintf(Display,
|
||||
"Maximum Processor Memory Requirement = %d MB = %.2lf GB\n",
|
||||
mumps_id.infog[16-1],(double)mumps_id.infog[16-1]/1024);
|
||||
fprintf(Display,
|
||||
"Total Processors Memory Requirement = %d MB = %.2lf GB\n",
|
||||
mumps_id.infog[17-1],(double)mumps_id.infog[17-1]/1024);
|
||||
#else
|
||||
fprintf(Display, "Full Schur Elements %ld, %.2e\n",
|
||||
(long int)((double)m*m),(double)m*m);
|
||||
fprintf(Display, "Agg %d (%.2e%%)->Ext %d (%.2e%%)"
|
||||
" [Fill %d (%.2e%%)]\n",
|
||||
NonZeroAggregate,
|
||||
(double)NonZeroAggregate*overM2,
|
||||
(int)NonZeroExtended,
|
||||
(double)NonZeroExtended*overM2,
|
||||
(int)(NonZeroExtended-NonZeroAggregate),
|
||||
(double)(NonZeroExtended-NonZeroAggregate)*overM2);
|
||||
fprintf(Display, "Est FLOPs Elim = %.2e:",
|
||||
mumps_id.rinfog[1-1]);
|
||||
fprintf(Display,
|
||||
"MaxMem = %dMB = %.2lfGB:",
|
||||
mumps_id.infog[16-1],(double)mumps_id.infog[16-1]/1024);
|
||||
fprintf(Display,
|
||||
"TotMem = %dMB = %.2lfGB\n",
|
||||
mumps_id.infog[17-1],(double)mumps_id.infog[17-1]/1024);
|
||||
#endif
|
||||
}
|
||||
if (fpOut) {
|
||||
#if 0
|
||||
fprintf(fpOut,"dense matrix :\t\t\t%14d elements\n", m*m);
|
||||
fprintf(fpOut,"aggregate sparsity pattern :\t\t\t%14d elements\n",
|
||||
NonZeroAggregate);
|
||||
fprintf(fpOut,"extended sparsity pattern :\t\t\t%14d elements\n",
|
||||
(int)NonZeroExtended);
|
||||
fprintf(fpOut,"Schur density = %.8lf%%\n",
|
||||
(double)NonZeroExtended*overM2);
|
||||
fprintf(fpOut,"Fill in = %e%%\n",
|
||||
(double)(NonZeroExtended-NonZeroAggregate)*overM2);
|
||||
fprintf(fpOut, "Estimated FLOPS for elimation process = %e\n",
|
||||
mumps_id.rinfog[1-1]);
|
||||
fprintf(fpOut,
|
||||
"Maximum Processor Memory Requirement = %d MB = %.2lf GB\n",
|
||||
mumps_id.infog[16-1],(double)mumps_id.infog[16-1]/1024);
|
||||
fprintf(fpOut,
|
||||
"Total Processors Memory Requirement = %d MB = %.2lf GB\n",
|
||||
mumps_id.infog[17-1],(double)mumps_id.infog[17-1]/1024);
|
||||
#else
|
||||
fprintf(fpOut, "Full Schur Elements Number %ld, %.2e\n",
|
||||
(long int)((double)m*m),(double)m*m);
|
||||
fprintf(fpOut, "Agg %d (%.2e%%)->Ext %d (%.2e%%)"
|
||||
" [Fill %d (%.2e%%)]\n",
|
||||
NonZeroAggregate,
|
||||
(double)NonZeroAggregate*overM2,
|
||||
(int)NonZeroExtended,
|
||||
(double)NonZeroExtended*overM2,
|
||||
(int)(NonZeroExtended-NonZeroAggregate),
|
||||
(double)(NonZeroExtended-NonZeroAggregate)*overM2);
|
||||
fprintf(fpOut, "Est FLOPs Elim = %.2e:",
|
||||
mumps_id.rinfog[1-1]);
|
||||
fprintf(fpOut,
|
||||
"MaxMem = %dMB = %.2lfGB:",
|
||||
mumps_id.infog[16-1],(double)mumps_id.infog[16-1]/1024);
|
||||
fprintf(fpOut,
|
||||
"TotMem = %dMB = %.2lfGB\n",
|
||||
mumps_id.infog[17-1],(double)mumps_id.infog[17-1]/1024);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
if (NonZeroExtended > extend_threshold * m * m){
|
||||
best = SELECT_DENSE;
|
||||
}
|
||||
|
||||
double sparse_cost = mumps_id.rinfog[1-1] * 1.15;
|
||||
double dense_cost = 1.0/3.0 * (double)m * (double)m * (double) m;
|
||||
double sd_ratio = 0.85;
|
||||
// The ratio of (dense/sparse)
|
||||
// estimated by BbRosenB10.dat-s
|
||||
#if 0
|
||||
rMessage("sparse_cost = " << sparse_cost
|
||||
<< " : dense_cost = " << dense_cost
|
||||
<< " : dense_cost * sd_ratio = "
|
||||
<< (dense_cost * sd_ratio));
|
||||
#endif
|
||||
|
||||
#if !FORCE_SCHUR_SPARSE
|
||||
if (sparse_cost > dense_cost * sd_ratio) {
|
||||
best = SELECT_DENSE;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool Chordal::factorizeSchur(int m, int* diagonalIndex,
|
||||
FILE* Display, FILE* fpOut)
|
||||
{
|
||||
// I need to adjust Schur before factorization
|
||||
// to loose Numerical Error Condition
|
||||
double adjustSize = PLUS_ADJUST_DIAGONAL;
|
||||
for (int i=0; i<m; ++i) {
|
||||
sparse_bMat_ptr->sp_ele[diagonalIndex[i]] += adjustSize;
|
||||
}
|
||||
|
||||
mumps_id.job = MUMPS_JOB_FACTORIZE;
|
||||
mumps_id.a = sparse_bMat_ptr->sp_ele;
|
||||
dmumps_c(&mumps_id);
|
||||
bool isSuccess = SDPA_SUCCESS;
|
||||
while (mumps_id.infog[1-1] == -9) {
|
||||
#if 0
|
||||
rMessage("mumps icntl(14) = " << mumps_id.icntl[14-1]);
|
||||
rMessage("mumps icntl(23) = " << mumps_id.icntl[23-1]);
|
||||
#endif
|
||||
if (Display) {
|
||||
fprintf(Display,"MUMPS needs more memory space. Trying ANALYSIS phase once more\n");
|
||||
}
|
||||
if (fpOut) {
|
||||
fprintf(fpOut, "MUMPS needs more memory space. Trying ANALYSIS phase once more\n");
|
||||
}
|
||||
mumps_id.icntl[14-1] += 20; // More 20% working memory space
|
||||
analysisAndcountLowerNonZero(m);
|
||||
mumps_id.job = MUMPS_JOB_FACTORIZE;
|
||||
dmumps_c(&mumps_id);
|
||||
}
|
||||
if (mumps_id.infog[1-1] < 0) {
|
||||
isSuccess = SDPA_FAILURE;
|
||||
if (mumps_id.infog[1-1] == -10) {
|
||||
rMessage("Cholesky failed by NUMERICAL ERROR");
|
||||
rMessage("There are some possibilities.");
|
||||
rMessage("1. SDPA finalizes due to inaccuracy of numerical error");
|
||||
rMessage("2. The input problem may not have (any) interior-points");
|
||||
rMessage("3. Input matrices are linearly dependent");
|
||||
}
|
||||
else {
|
||||
rMessage("Cholesky failed with Error Code "
|
||||
<< mumps_id.infog[1-1]);
|
||||
}
|
||||
}
|
||||
return isSuccess;
|
||||
}
|
||||
|
||||
bool Chordal::solveSchur(Vector& rhs)
|
||||
{
|
||||
mumps_id.job = MUMPS_JOB_SOLVE;
|
||||
mumps_id.rhs = rhs.ele;
|
||||
dmumps_c(&mumps_id);
|
||||
return SDPA_SUCCESS;
|
||||
}
|
||||
|
||||
} // end of namespace 'sdpa'
|
||||
|
||||
Vendored
+84
@@ -0,0 +1,84 @@
|
||||
/* -------------------------------------------------------------
|
||||
|
||||
This file is a component of SDPA
|
||||
Copyright (C) 2004-2013 SDPA Project
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
------------------------------------------------------------- */
|
||||
|
||||
/*-----------------------------------------
|
||||
sdpa_chordal.h
|
||||
-----------------------------------------*/
|
||||
|
||||
#ifndef __sdpa_chordal_h__
|
||||
#define __sdpa_chordal_h__
|
||||
|
||||
#include "sdpa_dataset.h"
|
||||
#include <dmumps_c.h>
|
||||
|
||||
#define SELECT_MUMPS_BEST 7 // MUMPS selects automatically when 7
|
||||
#define SELECT_DENSE -1 // This value must be minus
|
||||
|
||||
namespace sdpa {
|
||||
|
||||
class Chordal {
|
||||
public:
|
||||
|
||||
// condition of sparse computation
|
||||
// m_threshold < mDim,
|
||||
// b_threshold < nBlock,
|
||||
// aggregate_threshold >= aggrigated sparsity ratio
|
||||
// extend_threshold >= extended sparsity ratio
|
||||
int m_threshold;
|
||||
int b_threshold;
|
||||
double aggregate_threshold;
|
||||
double extend_threshold;
|
||||
|
||||
int best;
|
||||
/* indicates the used ordering method */
|
||||
/* -1: dense computation */
|
||||
/* 7: sparse computation by MUMPS */
|
||||
|
||||
SparseMatrix* sparse_bMat_ptr;
|
||||
DMUMPS_STRUC_C mumps_id;
|
||||
bool mumps_usage;
|
||||
|
||||
|
||||
Chordal(void);
|
||||
~Chordal();
|
||||
void initialize(SparseMatrix* sparse_bMat_ptr);
|
||||
void finalize();
|
||||
|
||||
// merge array1 to array2
|
||||
void mergeArray(int na1, int* array1, int na2, int* array2);
|
||||
void catArray(int na1, int* array1, int na2, int* array2);
|
||||
void slimArray(int i, int length, int* array, int& slimedLength);
|
||||
|
||||
void makeGraph(InputData& inputData, int m);
|
||||
|
||||
void ordering_bMat(int m, int nBlock,
|
||||
InputData& inputData, FILE* Display,
|
||||
FILE* fpOut);
|
||||
double analysisAndcountLowerNonZero(int m);
|
||||
bool factorizeSchur(int m, int* diagonalIndex,
|
||||
FILE* Display, FILE* fpOut);
|
||||
bool solveSchur(Vector& rhs);
|
||||
|
||||
};
|
||||
|
||||
} // end of namespace 'sdpa'
|
||||
|
||||
#endif // __sdpa_chordal_h__
|
||||
Vendored
+557
@@ -0,0 +1,557 @@
|
||||
/* -------------------------------------------------------------
|
||||
|
||||
This file is a component of SDPA
|
||||
Copyright (C) 2004-2013 SDPA Project
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
------------------------------------------------------------- */
|
||||
|
||||
#include "sdpa_dataset.h"
|
||||
#include "sdpa_parts.h"
|
||||
#include "sdpa_linear.h"
|
||||
#include "sdpa_newton.h"
|
||||
|
||||
namespace sdpa {
|
||||
|
||||
Solutions::Solutions()
|
||||
{
|
||||
initialize();
|
||||
}
|
||||
|
||||
Solutions::~Solutions()
|
||||
{
|
||||
finalize();
|
||||
}
|
||||
|
||||
void Solutions::initialize()
|
||||
{
|
||||
nDim = 0;
|
||||
mDim = 0;
|
||||
}
|
||||
|
||||
void Solutions::initialize(int m, BlockStruct& bs)
|
||||
{
|
||||
mDim = m;
|
||||
nDim = 0;
|
||||
for (int l=0; l<bs.SDP_nBlock; ++l) {
|
||||
nDim += bs.SDP_blockStruct[l];
|
||||
}
|
||||
nDim += bs.LP_nBlock;
|
||||
order.initialize(bs.SDP_nBlock, bs.SDP_blockStruct);
|
||||
cholmodSpace.initialize(bs.LP_nBlock, bs.SDP_nBlock);
|
||||
// Do not initialize finalX & finalZ here.
|
||||
// They will be initialized in makeFinalSolution.
|
||||
}
|
||||
|
||||
void Solutions::makeCliques(BlockStruct& bs, InputData& inputData)
|
||||
{
|
||||
cholmodSpace.makeAggregate(mDim, bs.SDP_nBlock, bs.SDP_blockStruct,
|
||||
inputData.C, inputData.A);
|
||||
cholmodSpace.analyze();
|
||||
order.extractCliques(cholmodSpace);
|
||||
cholmodSpace.initializeClique(mDim, order);
|
||||
#if 0
|
||||
rMessage("order = ");
|
||||
order.display();
|
||||
rMessage("cholmodSpace = ");
|
||||
cholmodSpace.display();
|
||||
#endif
|
||||
}
|
||||
|
||||
void Solutions::setInitialPoint(BlockStruct&bs, double lambda)
|
||||
{
|
||||
cholmodSpace.setXIdentity(lambda);
|
||||
cholmodSpace.yVec.setZero();
|
||||
cholmodSpace.setZIdentity(lambda);
|
||||
}
|
||||
|
||||
|
||||
void Solutions::finalize()
|
||||
{
|
||||
cholmodSpace.finalize();
|
||||
order.finalize();
|
||||
finalX.finalize();
|
||||
finalZ.finalize();
|
||||
nDim = 0;
|
||||
mDim = 0;
|
||||
}
|
||||
|
||||
|
||||
bool Solutions::update(StepLength& alpha,
|
||||
ComputeTime& com)
|
||||
{
|
||||
|
||||
bool total_judge = SDPA_SUCCESS;
|
||||
double primal = alpha.primal;
|
||||
double dual = alpha.dual;
|
||||
TimeStart(START1_1);
|
||||
for (int l=0; l<cholmodSpace.LP_nBlock; ++l) {
|
||||
cholmodSpace.LP_X[l] += cholmodSpace.LP_dX[l]*primal;
|
||||
}
|
||||
for (int l=0; l<cholmodSpace.SDP_nBlock; ++l) {
|
||||
CliqueMatrix& clique_xMat = cholmodSpace.SDP_block[l].clique_xMat;
|
||||
CliqueMatrix& clique_dX = cholmodSpace.SDP_block[l].clique_dX;
|
||||
for (int l2=0; l2<clique_xMat.nBlock; ++l2) {
|
||||
DenseMatrix& xMat = clique_xMat.ele[l2];
|
||||
DenseMatrix& DxMat = clique_dX.ele[l2];
|
||||
Lal::let(xMat,'=',xMat,'+',DxMat, &primal);
|
||||
}
|
||||
}
|
||||
TimeEnd(END1_1);
|
||||
com.xMatTime += TimeCal(START1_1,END1_1);
|
||||
Lal::let(cholmodSpace.yVec,'=',cholmodSpace.yVec,
|
||||
'+',cholmodSpace.dyVec,&dual);
|
||||
TimeStart(START1_2);
|
||||
for (int l=0; l<cholmodSpace.LP_nBlock; ++l) {
|
||||
cholmodSpace.LP_Z[l] += cholmodSpace.LP_dZ[l]*dual;
|
||||
}
|
||||
for (int l=0; l<cholmodSpace.SDP_nBlock; ++l) {
|
||||
cholmod_sparse* Z = cholmodSpace.SDP_block[l].Z;
|
||||
cholmod_sparse* dZ = cholmodSpace.SDP_block[l].dZ;
|
||||
int NNZ_Z = cholmodSpace.SDP_block[l].NNZ_Z;
|
||||
double* Zele = (double*)(Z->x);
|
||||
double* dZele = (double*)(dZ->x);
|
||||
for (int index1=0; index1 < NNZ_Z; ++index1) {
|
||||
Zele[index1] += dZele[index1]*dual;
|
||||
}
|
||||
}
|
||||
TimeEnd(END1_2);
|
||||
com.zMatTime += TimeCal(START1_2,END1_2);
|
||||
const double cannot_move = 1.0e-4;
|
||||
if (alpha.primal < cannot_move && alpha.dual < cannot_move) {
|
||||
rMessage("Step length is too small. ");
|
||||
return SDPA_FAILURE;
|
||||
}
|
||||
return total_judge;
|
||||
}
|
||||
|
||||
void Solutions::display(FILE* fpout, char* printFormat)
|
||||
{
|
||||
if (fpout == NULL) {
|
||||
return;
|
||||
}
|
||||
rMessage("Solutions @ start @@@@@@@@@@@@@@@@@@@@@@");
|
||||
fprintf(fpout, "cholmodSpace =========> \n");
|
||||
cholmodSpace.display(fpout, printFormat);
|
||||
fprintf(fpout, "order =========> \n");
|
||||
order.display(fpout, printFormat);
|
||||
rMessage("Solutions @ end @@@@@@@@@@@@@@@@@@@@@@");
|
||||
}
|
||||
|
||||
void Solutions::makeFinalSolution(bool Xmake, bool Zmake,
|
||||
BlockStruct& bs)
|
||||
{
|
||||
if (Xmake == true) {
|
||||
cholmodSpace.getCholesky(order);
|
||||
finalX.initialize(bs);
|
||||
for (int l=0; l<cholmodSpace.LP_nBlock; ++l) {
|
||||
finalX.LP_block[l] = cholmodSpace.LP_X[l];
|
||||
}
|
||||
for (int l=0; l<cholmodSpace.SDP_nBlock; ++l) {
|
||||
CholmodMatrix& cholmodMatrix = cholmodSpace.SDP_block[l];
|
||||
// rMessage("cholmodMatrix = "); cholmodMatrix.display();
|
||||
DenseMatrix& targetMatrix = finalX.SDP_block[l];
|
||||
const int nDim = cholmodMatrix.nDim;
|
||||
for (int j=0; j<nDim; ++j) {
|
||||
// rMessage("j = " << j) ;
|
||||
cholmodMatrix.setB_Xzero();
|
||||
double* b_x = (double*)(cholmodMatrix.b_x->x);
|
||||
b_x[j] = 1.0;
|
||||
cholmodMatrix.solveByX();
|
||||
double* x_x = (double*)(cholmodMatrix.x_x->x);
|
||||
// rMessage("b = "); CholmodMatrix::display_dense(cholmodMatrix.b_x);
|
||||
// rMessage("x = "); CholmodMatrix::display_dense(cholmodMatrix.x_x);
|
||||
for (int i=0; i<nDim; ++i) {
|
||||
targetMatrix.de_ele[i+j*nDim] = x_x[i];
|
||||
#if 0
|
||||
rMessage("i = "<< i << " : j = " << j
|
||||
<< " : pos = " << (i+j*nDim));
|
||||
rMessage("finalXin = "); targetMatrix.display();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
// rMessage("finalX = "); targetMatrix.display();
|
||||
}
|
||||
}
|
||||
if (Zmake == true) {
|
||||
finalZ.initialize(bs);
|
||||
for (int l=0; l<cholmodSpace.LP_nBlock; ++l) {
|
||||
finalZ.LP_block[l] = cholmodSpace.LP_Z[l];
|
||||
}
|
||||
for (int l=0; l<cholmodSpace.SDP_nBlock; ++l) {
|
||||
CholmodMatrix& cholmodMatrix = cholmodSpace.SDP_block[l];
|
||||
cholmod_sparse* Z = cholmodMatrix.Z;
|
||||
DenseMatrix& targetMatrix = finalZ.SDP_block[l];
|
||||
targetMatrix.setZero();
|
||||
const int ncol = (int) Z->ncol;
|
||||
for (int j=0; j < ncol; ++j) {
|
||||
const int start_row = ((int*)Z->p)[j];
|
||||
const int end_row = ((int*)Z->p)[j+1];
|
||||
for (int i_index = start_row; i_index < end_row; ++i_index) {
|
||||
const int i = (( int*)Z->i)[i_index];
|
||||
const double value = ((double*)Z->x)[i_index];
|
||||
targetMatrix.de_ele[i+j*ncol] = value;
|
||||
targetMatrix.de_ele[j+i*ncol] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
InputData::InputData()
|
||||
{
|
||||
A = NULL;
|
||||
SDP_nBlock = 0;
|
||||
SDP_nConstraint = NULL;
|
||||
SDP_constraint = NULL;
|
||||
SDP_blockIndex = NULL;
|
||||
SDP_nBlock = 0;
|
||||
LP_nConstraint = NULL;
|
||||
LP_constraint = NULL;
|
||||
LP_blockIndex = NULL;
|
||||
}
|
||||
|
||||
InputData::~InputData()
|
||||
{
|
||||
finalize();
|
||||
}
|
||||
|
||||
void InputData::initialize(int m, BlockStruct& bs)
|
||||
{
|
||||
SDP_nBlock = bs.SDP_nBlock;
|
||||
LP_nBlock = bs.LP_nBlock;
|
||||
|
||||
initialize_bVec(m);
|
||||
C.initialize();
|
||||
C.initializeInputVector();
|
||||
NewArray(A, CompSpace, m);
|
||||
for (int k=0; k<m; ++k) {
|
||||
A[k].initialize();
|
||||
A[k].initializeInputVector();
|
||||
}
|
||||
}
|
||||
|
||||
void InputData::initialize_bVec(int m)
|
||||
{
|
||||
b.initialize(m);
|
||||
}
|
||||
|
||||
void InputData::finalize()
|
||||
{
|
||||
C.finalize();
|
||||
if (A){
|
||||
for (int k=0; k<b.nDim; ++k) {
|
||||
A[k].finalize();
|
||||
}
|
||||
DeleteArray(A);
|
||||
}
|
||||
b.finalize();
|
||||
|
||||
DeleteArray(SDP_nConstraint);
|
||||
if (SDP_constraint) {
|
||||
for (int k=0; k<SDP_nBlock; ++k) {
|
||||
DeleteArray(SDP_constraint[k]);
|
||||
}
|
||||
DeleteArray(SDP_constraint);
|
||||
}
|
||||
if (SDP_blockIndex) {
|
||||
for (int k=0; k<SDP_nBlock; ++k) {
|
||||
DeleteArray(SDP_blockIndex[k]);
|
||||
}
|
||||
DeleteArray(SDP_blockIndex);
|
||||
}
|
||||
if (LP_nConstraint && LP_constraint && LP_blockIndex){
|
||||
for (int k=0; k<LP_nBlock; ++k) {
|
||||
DeleteArray(LP_constraint[k]);
|
||||
DeleteArray(LP_blockIndex[k]);
|
||||
}
|
||||
DeleteArray(LP_nConstraint);
|
||||
DeleteArray(LP_constraint);
|
||||
DeleteArray(LP_blockIndex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void InputData::initialize_index_SDP()
|
||||
{
|
||||
int mDim = b.nDim;
|
||||
int index;
|
||||
int* SDP_count;
|
||||
|
||||
NewArray(SDP_nConstraint,int,SDP_nBlock);
|
||||
|
||||
// count non-zero block matrix of A
|
||||
for (int l=0; l<SDP_nBlock; l++){
|
||||
SDP_nConstraint[l] = 0;
|
||||
}
|
||||
for (int k=0; k<mDim; k++){
|
||||
for (int l=0; l<A[k].SDP_sp_nBlock; l++){
|
||||
index = A[k].SDP_sp_index[l];
|
||||
SDP_nConstraint[index]++;
|
||||
}
|
||||
}
|
||||
// malloc SDP_constraint, SDP_blockIndex
|
||||
NewArray(SDP_constraint,int*,SDP_nBlock);
|
||||
for (int l=0; l<SDP_nBlock; l++){
|
||||
NewArray(SDP_constraint[l],int,SDP_nConstraint[l]);
|
||||
}
|
||||
NewArray(SDP_blockIndex,int*,SDP_nBlock);
|
||||
for (int l=0; l<SDP_nBlock; l++){
|
||||
NewArray(SDP_blockIndex[l],int,SDP_nConstraint[l]);
|
||||
}
|
||||
// input index of non-zero block matrix of A
|
||||
NewArray(SDP_count,int,SDP_nBlock);
|
||||
for (int l=0; l<SDP_nBlock; l++){
|
||||
SDP_count[l] = 0;
|
||||
}
|
||||
for (int k=0; k<mDim; k++){
|
||||
for (int l=0; l<A[k].SDP_sp_nBlock; l++){
|
||||
index = A[k].SDP_sp_index[l];
|
||||
SDP_constraint[index][SDP_count[index]] = k;
|
||||
SDP_blockIndex[index][SDP_count[index]] = l;
|
||||
SDP_count[index]++;
|
||||
}
|
||||
}
|
||||
DeleteArray(SDP_count);
|
||||
}
|
||||
|
||||
void InputData::initialize_index_LP()
|
||||
{
|
||||
int mDim = b.nDim;
|
||||
int index;
|
||||
int* LP_count;
|
||||
|
||||
NewArray(LP_nConstraint,int,LP_nBlock);
|
||||
|
||||
// count non-zero block matrix of A
|
||||
for (int l=0; l<LP_nBlock; l++){
|
||||
LP_nConstraint[l] = 0;
|
||||
}
|
||||
for (int k=0; k<mDim; k++){
|
||||
for (int l=0; l<A[k].LP_sp_nBlock; l++){
|
||||
index = A[k].LP_sp_index[l];
|
||||
LP_nConstraint[index]++;
|
||||
}
|
||||
}
|
||||
|
||||
// malloc LP_constraint, LP_blockIndex
|
||||
NewArray(LP_constraint,int*,LP_nBlock);
|
||||
for (int l=0; l<LP_nBlock; l++){
|
||||
NewArray(LP_constraint[l],int,LP_nConstraint[l]);
|
||||
}
|
||||
NewArray(LP_blockIndex,int*,LP_nBlock);
|
||||
for (int l=0; l<LP_nBlock; l++){
|
||||
NewArray(LP_blockIndex[l],int,LP_nConstraint[l]);
|
||||
}
|
||||
|
||||
// input index of non-zero block matrix of A
|
||||
NewArray(LP_count,int,LP_nBlock);
|
||||
for (int l=0; l<LP_nBlock; l++){
|
||||
LP_count[l] = 0;
|
||||
}
|
||||
for (int k=0; k<mDim; k++){
|
||||
for (int l=0; l<A[k].LP_sp_nBlock; l++){
|
||||
index = A[k].LP_sp_index[l];
|
||||
LP_constraint[index][LP_count[index]] = k;
|
||||
LP_blockIndex[index][LP_count[index]] = l;
|
||||
LP_count[index]++;
|
||||
}
|
||||
}
|
||||
|
||||
DeleteArray(LP_count);
|
||||
}
|
||||
|
||||
|
||||
void InputData::initialize_index()
|
||||
{
|
||||
initialize_index_SDP();
|
||||
// initialize_index_SOCP();
|
||||
if (LP_nBlock > 0) {
|
||||
initialize_index_LP();
|
||||
}
|
||||
}
|
||||
|
||||
void InputData::assignAgg(CholmodSpace& cholmodSpace)
|
||||
{
|
||||
for (int l_index = 0; l_index < C.SDP_sp_nBlock; ++l_index) {
|
||||
const int l = C.SDP_sp_index[l_index];
|
||||
CompMatrix& Cl = C.SDP_sp_block[l_index];
|
||||
Cl.assignAgg(cholmodSpace.SDP_block[l]);
|
||||
}
|
||||
const int m = b.nDim;
|
||||
for (int k=0; k<m; ++k) {
|
||||
for (int l_index = 0; l_index < A[k].SDP_sp_nBlock; ++l_index) {
|
||||
const int l = A[k].SDP_sp_index[l_index];
|
||||
CompMatrix& Akl = A[k].SDP_sp_block[l_index];
|
||||
Akl.assignAgg(cholmodSpace.SDP_block[l]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void InputData::assignBlockIndex(OrderingSpace& order)
|
||||
{
|
||||
for (int l_index = 0; l_index < C.SDP_sp_nBlock; ++l_index) {
|
||||
const int l = C.SDP_sp_index[l_index];
|
||||
CompMatrix& Cl = C.SDP_sp_block[l_index];
|
||||
Cl.assignBlockIndex(order.SDP_block[l]);
|
||||
}
|
||||
const int m = b.nDim;
|
||||
for (int k=0; k<m; ++k) {
|
||||
for (int l_index = 0; l_index < A[k].SDP_sp_nBlock; ++l_index) {
|
||||
const int l = A[k].SDP_sp_index[l_index];
|
||||
CompMatrix& Akl = A[k].SDP_sp_block[l_index];
|
||||
Akl.assignBlockIndex(order.SDP_block[l]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void InputData::display(FILE* fpout)
|
||||
{
|
||||
if (fpout == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
fprintf(fpout,"b = \n");
|
||||
b.display(fpout);
|
||||
fprintf(fpout,"C = \n");
|
||||
C.display(fpout);
|
||||
for (int k=0; k<b.nDim; k++){
|
||||
fprintf(fpout,"A[%d] = \n",k);
|
||||
A[k].display(fpout);
|
||||
}
|
||||
}
|
||||
|
||||
void InputData::display_index(FILE* fpout)
|
||||
{
|
||||
if (fpout == NULL) {
|
||||
return;
|
||||
}
|
||||
fprintf(fpout, "display_index: LP:%d SDP:%d\n", LP_nBlock, SDP_nBlock);
|
||||
for (int l=0; l<LP_nBlock; l++){
|
||||
fprintf(fpout, "LP:%dth block\n",l);
|
||||
for (int k=0; k<LP_nConstraint[l]; k++){
|
||||
fprintf(fpout, "A[k=%d][l=%d], that is, constraint:%d block:%d \n",
|
||||
LP_constraint[l][k],LP_blockIndex[l][k],
|
||||
LP_constraint[l][k],LP_blockIndex[l][k]);
|
||||
}
|
||||
}
|
||||
for (int l=0; l<SDP_nBlock; l++){
|
||||
fprintf(fpout, "SDP:%dth block\n",l);
|
||||
for (int k=0; k<SDP_nConstraint[l]; k++){
|
||||
fprintf(fpout, "A[k=%d][l=%d], that is, constraint:%d block:%d \n",
|
||||
SDP_constraint[l][k],SDP_blockIndex[l][k],
|
||||
SDP_constraint[l][k],SDP_blockIndex[l][k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Residuals::Residuals()
|
||||
{
|
||||
initialize();
|
||||
}
|
||||
|
||||
|
||||
Residuals::~Residuals()
|
||||
{
|
||||
finalize();
|
||||
}
|
||||
|
||||
void Residuals::initialize()
|
||||
{
|
||||
initNormPrimal = 0.0;
|
||||
initNormDual = 0.0;
|
||||
normPrimal = 0.0;
|
||||
normDual = 0.0;
|
||||
centerNorm = 0.0;
|
||||
}
|
||||
|
||||
void Residuals::finalize()
|
||||
{
|
||||
initialize();
|
||||
}
|
||||
|
||||
double Residuals::computeMaxNorm(Vector& primalVec)
|
||||
{
|
||||
double ret = 0.0;
|
||||
for (int k=0; k<primalVec.nDim; ++k) {
|
||||
double tmp = fabs(primalVec.ele[k]);
|
||||
if (tmp > ret) {
|
||||
ret = tmp;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
double Residuals::computeMaxNorm(cholmod_sparse* rD)
|
||||
{
|
||||
double ret = 0.0;
|
||||
for (int index1=0; index1<rD->nzmax; ++index1) {
|
||||
const double tmp = fabs(((double*)rD->x)[index1]);
|
||||
if (tmp > ret) {
|
||||
ret = tmp;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Residuals::update(CholmodSpace& cholmodSpace)
|
||||
{
|
||||
// p[k] = b[k] - A[k].X;
|
||||
normPrimal = computeMaxNorm(cholmodSpace.rp);
|
||||
|
||||
double tmpNorm = 0.0;
|
||||
for (int l = 0; l < cholmodSpace.LP_nBlock; ++l) {
|
||||
double tmp2 = fabs(cholmodSpace.LP_rD[l]);
|
||||
if (tmp2 > tmpNorm) {
|
||||
tmpNorm = tmp2;
|
||||
}
|
||||
}
|
||||
for (int l = 0; l < cholmodSpace.SDP_nBlock; ++l) {
|
||||
double tmp2 = computeMaxNorm(cholmodSpace.SDP_block[l].rD);
|
||||
if (tmp2 > tmpNorm) {
|
||||
tmpNorm = tmp2;
|
||||
}
|
||||
}
|
||||
normDual = tmpNorm;
|
||||
}
|
||||
|
||||
void Residuals::copyToInit()
|
||||
{
|
||||
initNormPrimal = normPrimal;
|
||||
initNormDual = normDual;
|
||||
centerNorm = 0.0;
|
||||
}
|
||||
|
||||
void Residuals::display(FILE* fpout)
|
||||
{
|
||||
if (fpout == NULL) {
|
||||
return;
|
||||
}
|
||||
fprintf(fpout," initial.normPrimal = %8.3e\n",
|
||||
initNormPrimal);
|
||||
fprintf(fpout," initial.normDual = %8.3e\n",
|
||||
initNormDual);
|
||||
fprintf(fpout," currentRes.normPrimal = %8.3e\n",
|
||||
normPrimal);
|
||||
fprintf(fpout," currentRes.normDual = %8.3e\n",
|
||||
normDual);
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // end of namespace 'sdpa'
|
||||
|
||||
Vendored
+135
@@ -0,0 +1,135 @@
|
||||
/* -------------------------------------------------------------
|
||||
|
||||
This file is a component of SDPA
|
||||
Copyright (C) 2004-2013 SDPA Project
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
------------------------------------------------------------- */
|
||||
|
||||
#ifndef __sdpa_detaset_h__
|
||||
#define __sdpa_detaset_h__
|
||||
|
||||
#include "sdpa_include.h"
|
||||
#include "sdpa_struct.h"
|
||||
|
||||
namespace sdpa {
|
||||
|
||||
class Newton;
|
||||
|
||||
class Solutions;
|
||||
class InputData;
|
||||
class Residuals;
|
||||
|
||||
class ComputeTime;
|
||||
class Parameter;
|
||||
class StepLength;
|
||||
class DirectionParameter;
|
||||
class Switch;
|
||||
class RatioInitResCurrentRes;
|
||||
class SolveInfo;
|
||||
class Phase;
|
||||
class AverageComplementarity;
|
||||
|
||||
|
||||
class Solutions
|
||||
{
|
||||
public:
|
||||
int nDim;
|
||||
int mDim;
|
||||
|
||||
CholmodSpace cholmodSpace;
|
||||
OrderingSpace order;
|
||||
|
||||
DenseLinearSpace finalX;
|
||||
DenseLinearSpace finalZ;
|
||||
|
||||
Solutions();
|
||||
~Solutions();
|
||||
void initialize();
|
||||
void initialize(int m, BlockStruct& bs);
|
||||
void finalize();
|
||||
|
||||
void makeCliques(BlockStruct& bs, InputData& inputData);
|
||||
void setInitialPoint(BlockStruct&bs, double lambda);
|
||||
|
||||
bool update(StepLength& alpha, ComputeTime& com);
|
||||
void display(FILE* fpout=stdout, char* printFormat = P_FORMAT);
|
||||
|
||||
void makeFinalSolution(bool Xmake, bool Zmake,
|
||||
BlockStruct& bs);
|
||||
};
|
||||
|
||||
class InputData
|
||||
{
|
||||
public:
|
||||
Vector b;
|
||||
CompSpace C;
|
||||
CompSpace* A;
|
||||
|
||||
// nBLock : number of block
|
||||
// nConstraint[k]: number of nonzero matrix in k-th block
|
||||
// When A[i].block[k] is nonzero matrix, for t,
|
||||
// i <-> constraint[k][t]
|
||||
// A[i].block[k] <-> A[i].sp_block[blockIndex[k][t]]
|
||||
int SDP_nBlock; int* SDP_nConstraint;
|
||||
int** SDP_constraint; int** SDP_blockIndex;
|
||||
int LP_nBlock; int* LP_nConstraint;
|
||||
int** LP_constraint; int** LP_blockIndex;
|
||||
|
||||
InputData();
|
||||
~InputData();
|
||||
void initialize(int m, BlockStruct& bs);
|
||||
void finalize();
|
||||
void initialize_bVec(int m);
|
||||
void initialize_index_SDP();
|
||||
void initialize_index_LP();
|
||||
void initialize_index();
|
||||
|
||||
void assignAgg(CholmodSpace& cholmodSpace);
|
||||
void assignBlockIndex(OrderingSpace& order);
|
||||
|
||||
void display(FILE* fpout=stdout);
|
||||
void display_index(FILE* fpout=stdout);
|
||||
};
|
||||
|
||||
class Residuals
|
||||
{
|
||||
public:
|
||||
double initNormPrimal;
|
||||
double initNormDual;
|
||||
double normPrimal;
|
||||
double normDual;
|
||||
double centerNorm;
|
||||
|
||||
Residuals();
|
||||
~Residuals();
|
||||
|
||||
void initialize();
|
||||
void finalize();
|
||||
|
||||
static double computeMaxNorm(Vector& primalVec);
|
||||
static double computeMaxNorm(cholmod_sparse* rD);
|
||||
|
||||
void update(CholmodSpace& cholmodSpace);
|
||||
void copyToInit();
|
||||
void display(FILE* fpout = stdout);
|
||||
|
||||
};
|
||||
|
||||
|
||||
} // end of namespace 'sdpa'
|
||||
|
||||
#endif // __sdpa_dataset_h__
|
||||
Vendored
+274
@@ -0,0 +1,274 @@
|
||||
/* -------------------------------------------------------------
|
||||
|
||||
This file is a component of SDPA
|
||||
Copyright (C) 2004-2013 SDPA Project
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
------------------------------------------------------------- */
|
||||
/*-----------------------------------------------
|
||||
rsdpa_dpotrf.cpp
|
||||
modification of ATL_dpotrfL
|
||||
for dealing with numerical error
|
||||
in diagonal elements.
|
||||
|
||||
int rATL_dpotrfL(int N, double *A,int lda)
|
||||
|
||||
modified by Makoto Yamshita 2002.07.11
|
||||
-----------------------------------------------*/
|
||||
#define POTRF_NONZERO (1.0e-14)
|
||||
#define POTRF_ASSIGN (1.0e+100)
|
||||
#define POTRF_LIMIT (-1.0e-6)
|
||||
|
||||
/*
|
||||
* Automatically Tuned Linear Algebra Software v3.4.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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "sdpa_include.h"
|
||||
#include "sdpa_algebra.h"
|
||||
#if 0
|
||||
#define CHOLESKY_ADJUST(val) rMessage("Choleksy adjust from " << val << " to " << POTRF_NONZERO);
|
||||
#else
|
||||
#define CHOLESKY_ADJUST(val) ;
|
||||
#endif
|
||||
|
||||
namespace sdpa {
|
||||
|
||||
extern "C" {
|
||||
static int potrf4(double* A,const int n)
|
||||
{
|
||||
double* A1 = A+n+1;
|
||||
double* A2 = A1+n+1;
|
||||
double* A3 = A2+n+1;
|
||||
double L11 = *A;
|
||||
double L21 = A[1], L22 = *A1;
|
||||
double L31 = A[2], L32 = A1[1], L33 = *A2;
|
||||
double L41 = A[3], L42 = A1[2], L43 = A2[1], L44 = *A3;
|
||||
|
||||
if (L11 < POTRF_LIMIT) {
|
||||
return 1;
|
||||
}
|
||||
if (L11 < POTRF_NONZERO) {
|
||||
CHOLESKY_ADJUST(L11);
|
||||
L11 = POTRF_ASSIGN;
|
||||
}
|
||||
|
||||
*A = L11 = sqrt(L11);
|
||||
L11 = 1.0/L11;
|
||||
L21 *= L11;
|
||||
L31 *= L11;
|
||||
L41 *= L11;
|
||||
|
||||
L22 -= L21*L21;
|
||||
if (L22 < POTRF_LIMIT) {
|
||||
return 2;
|
||||
}
|
||||
if (L22 < POTRF_NONZERO) {
|
||||
CHOLESKY_ADJUST(L22);
|
||||
L22 = POTRF_ASSIGN;
|
||||
}
|
||||
*A1 = L22 = sqrt(L22);
|
||||
L22 = 1.0/L22;
|
||||
L32 = (L32 - L31*L21)*L22;
|
||||
L42 = (L42 - L41*L21)*L22;
|
||||
|
||||
L33 -= L31*L31 + L32*L32;
|
||||
if (L33 < POTRF_LIMIT) {
|
||||
return 3;
|
||||
}
|
||||
if (L33 < POTRF_NONZERO) {
|
||||
CHOLESKY_ADJUST(L33);
|
||||
L33 = POTRF_ASSIGN;
|
||||
}
|
||||
*A2 = L33 = sqrt(L33);
|
||||
L43 = (L43-L41*L31-L42*L32)/L33;
|
||||
L44 -= L41*L41 + L42*L42 + L43*L43;
|
||||
if (L44 < POTRF_LIMIT) {
|
||||
return 4;
|
||||
}
|
||||
if (L44 < POTRF_NONZERO) {
|
||||
CHOLESKY_ADJUST(L44);
|
||||
L44 = POTRF_ASSIGN;
|
||||
}
|
||||
*A3 = sqrt(L44);
|
||||
|
||||
A[1] = L21;
|
||||
A[2] = L31; A1[1] = L32;
|
||||
A[3] = L41; A1[2] = L42; A2[1] = L43;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int potrf3(double* A,const int n)
|
||||
{
|
||||
double* A1 = A+n+1;
|
||||
double* A2 = A1+n+1;
|
||||
double L11 = *A;
|
||||
double L21 = A[1], L22 = *A1;
|
||||
double L31 = A[2], L32 = A1[1], L33 = *A2;
|
||||
|
||||
if (L11 < POTRF_LIMIT) {
|
||||
return 1;
|
||||
}
|
||||
if (L11 < POTRF_NONZERO) {
|
||||
CHOLESKY_ADJUST(L11);
|
||||
L11 = POTRF_ASSIGN;
|
||||
}
|
||||
|
||||
*A = L11 = sqrt(L11);
|
||||
L11 = 1.0/L11;
|
||||
L21 *= L11;
|
||||
L31 *= L11;
|
||||
|
||||
L22 -= L21*L21;
|
||||
if (L22 < POTRF_LIMIT) {
|
||||
return 2;
|
||||
}
|
||||
if (L22 < POTRF_NONZERO) {
|
||||
CHOLESKY_ADJUST(L22);
|
||||
L22 = POTRF_ASSIGN;
|
||||
}
|
||||
L22 = sqrt(L22);
|
||||
L32 = (L32 - L31*L21)/L22;
|
||||
|
||||
L33 -= L31*L31 + L32*L32;
|
||||
if (L33 < POTRF_LIMIT) {
|
||||
return 3;
|
||||
}
|
||||
if (L33 < POTRF_NONZERO) {
|
||||
CHOLESKY_ADJUST(L33);
|
||||
L33 = POTRF_ASSIGN;
|
||||
}
|
||||
*A2 = sqrt(L33);
|
||||
|
||||
A[1] = L21; *A1 = L22;
|
||||
A[2] = L31; A1[1] = L32;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int potrf2(double* A,const int n)
|
||||
{
|
||||
double* A1 = A+n+1;
|
||||
double L11 = *A;
|
||||
double L21 = A[1], L22 = *A1;
|
||||
|
||||
if (L11 < POTRF_LIMIT) {
|
||||
return 1;
|
||||
}
|
||||
if (L11 < POTRF_NONZERO) {
|
||||
CHOLESKY_ADJUST(L11);
|
||||
L11 = POTRF_ASSIGN;
|
||||
}
|
||||
|
||||
*A = L11 = sqrt(L11);
|
||||
L21 /= L11;
|
||||
L22 -= L21*L21;
|
||||
if (L22 < POTRF_LIMIT) {
|
||||
return 2;
|
||||
}
|
||||
if (L22 < POTRF_NONZERO) {
|
||||
CHOLESKY_ADJUST(L22);
|
||||
L22 = POTRF_ASSIGN;
|
||||
}
|
||||
*A = L11;
|
||||
A[1] = L21; *A1 = sqrt(L22);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rATL_dpotrfL(int N, double *A,int lda)
|
||||
{
|
||||
double *An, *Ar;
|
||||
int Nleft, Nright, ierr;
|
||||
|
||||
if (N > 4) {
|
||||
Nleft = N >> 1;
|
||||
#if 0
|
||||
int nb = ilaenv_fc(&IONE, "DPOTRF", "L", &N,
|
||||
&IMONE,&IONE, &IMONE, strlen("DPOTRF"), strlen("L"));
|
||||
if (Nleft > nb<<1) Nleft = (Nleft/nb)*nb;
|
||||
#endif
|
||||
#if 0
|
||||
if (Nleft > 64) {
|
||||
Nleft = 64;
|
||||
}
|
||||
#endif
|
||||
Nright = N - Nleft;
|
||||
ierr = rATL_dpotrfL(Nleft, A,lda);
|
||||
if (!ierr) {
|
||||
Ar = A + Nleft;
|
||||
An = Ar + lda * Nleft;
|
||||
dtrsm_fc ((char *)"R",(char *)"L",(char *)"T",(char *)"N",
|
||||
&Nright,&Nleft,&DONE,A,&lda,
|
||||
Ar, &lda, strlen("R"),strlen("L"),
|
||||
strlen("T"),strlen("N"));
|
||||
dsyrk_fc ((char *)"L",(char *)"N",&Nright,&Nleft,&DMONE,
|
||||
Ar, &lda, &DONE,An,&lda,strlen("L"),strlen("N"));
|
||||
ierr = rATL_dpotrfL(Nright, An,lda);
|
||||
if (ierr) return(ierr+Nleft);
|
||||
}
|
||||
else return(ierr);
|
||||
}
|
||||
else if (N==4) return(potrf4(A,lda));
|
||||
else if (N==3) return(potrf3(A,lda));
|
||||
else if (N==2) return(potrf2(A,lda));
|
||||
else if (N==1) {
|
||||
if (*A < POTRF_LIMIT) {
|
||||
return 1;
|
||||
}
|
||||
if (*A < POTRF_NONZERO) {
|
||||
CHOLESKY_ADJUST(*A);
|
||||
*A = POTRF_ASSIGN;
|
||||
}
|
||||
*A = sqrt(*A);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
void rdpotrfl_(int* N, double *A,int* lda,int* info)
|
||||
{
|
||||
*info = rATL_dpotrfL(*N,A,*lda);
|
||||
}
|
||||
|
||||
}; // end of extern "C"
|
||||
|
||||
} // end of namespace 'sdpa'
|
||||
Vendored
+43
@@ -0,0 +1,43 @@
|
||||
/* -------------------------------------------------------------
|
||||
|
||||
This file is a component of SDPA
|
||||
Copyright (C) 2004-2013 SDPA Project
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
------------------------------------------------------------- */
|
||||
/*-----------------------------------------------
|
||||
rsdpa_dpotrf.cpp
|
||||
modification of ATL_dpotrfL
|
||||
int rATL_dpotrfL(int N, double *A,int lda)
|
||||
$Id: rsdpa_dpotrf.h,v 1.2 2004/09/01 06:34:12 makoto Exp $
|
||||
-----------------------------------------------*/
|
||||
|
||||
#ifndef __sdpa_dpotrf_h__
|
||||
#define __sdpa_dpotrf_h__
|
||||
|
||||
namespace sdpa {
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" int rATL_dpotrfL(int N, double *A,int lda);
|
||||
#else
|
||||
extern int rATL_dpotrfL(int N, double *A,int lda);
|
||||
#endif
|
||||
|
||||
} // end of namespace 'sdpa'
|
||||
|
||||
#endif // __sdpa_dpotrf_h__
|
||||
|
||||
|
||||
Vendored
+360
@@ -0,0 +1,360 @@
|
||||
/* -------------------------------------------------------------
|
||||
|
||||
This file is a component of SDPA
|
||||
Copyright (C) 2004-2013 SDPA Project
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
------------------------------------------------------------- */
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <sdpa_call.h>
|
||||
using namespace sdpa;
|
||||
|
||||
#define USER_PARAMETER_FILE ((char *)"./param.sdpaC")
|
||||
#define DEFAULT_PARAMETER_FILE ((char *)"/usr/share/sdpa/param.sdpaC")
|
||||
// PARAMETER_FILE is decided by the following priority
|
||||
// 1: The file assigned by '-p' option of 'option type 2'.
|
||||
// For 'option type1', this is skipped.
|
||||
// 2: USER_PARAMETER_FILE
|
||||
// For 'option type2', this is skipped.
|
||||
// 3: DEFAULT_PARAMETER_FILE
|
||||
// 4: Default parameter
|
||||
static void message(char* argv0)
|
||||
{
|
||||
cout << endl;
|
||||
cout << "*** Please assign data file and output file.***" << endl;
|
||||
cout << endl;
|
||||
cout << "---- option type 1 ------------" << endl;
|
||||
cout << argv0 <<" SparseDataFile OutputFile"
|
||||
" [-pt parameters] [-dimacs] [-numThreads numThreads]"<< endl;
|
||||
cout << "parameters = 0 default, 1 fast (unstable),"
|
||||
" 2 slow (stable)" << endl;
|
||||
cout << " -dimacs : printout dimacs information incurring additional computation cost " << endl;
|
||||
cout << " -numThreads: Number of pthreads for internal computation" << endl;
|
||||
cout << "example1-1: " << argv0
|
||||
<< " example1.dat-s example1.result" << endl;
|
||||
cout << "example1-2: " << argv0
|
||||
<< " example1.dat-s example1.result -pt 2" << endl;
|
||||
cout << "example1-3: " << argv0
|
||||
<< " example1.dat-s example1.result -dimacs" << endl;
|
||||
cout << "example1-4: " << argv0
|
||||
<< " example1.dat-s example1.result -numThreads 4" << endl;
|
||||
|
||||
cout << endl;
|
||||
cout << "---- option type 2 ------------" << endl;
|
||||
cout << argv0 << " [option filename]+ " << endl;
|
||||
cout << " -ds : data sparse " << endl;
|
||||
cout << " -o : output :: -p : parameter " << endl;
|
||||
cout << " -pt : parameters , 0 default, 1 fast (unstable)" << endl;
|
||||
cout << " 2 slow (stable) " << endl;
|
||||
cout << " -dimacs : printout dimacs information incurring additional computation cost " << endl;
|
||||
cout << " -numThreads: Number of pthreads for internal computation" << endl;
|
||||
cout << "example2-1: " << argv0
|
||||
<< " -ds example1.dat-s -o example1.result "
|
||||
<< "-p param.sdpaC" << endl;
|
||||
cout << "example2-2: " << argv0
|
||||
<< " -ds example1.dat-s -o example1.result "
|
||||
<< "-pt 2" << endl;
|
||||
cout << "example2-3: " << argv0
|
||||
<< " -ds example1.dat-s -o example1.result "
|
||||
<< "-dimacs" << endl;
|
||||
cout << "example2-4: " << argv0
|
||||
<< " -ds example1.dat-s -o example1.result "
|
||||
<< "-numThreads 4" << endl;
|
||||
|
||||
cout << endl;
|
||||
cout << "---- option type 3 ------------" << endl;
|
||||
cout << argv0 << " --version " << endl;
|
||||
cout << " to print out version and exit." << endl;
|
||||
|
||||
cout << endl << endl;
|
||||
cout << "PARAMETER_FILE is decided by the following priority" << endl;
|
||||
cout << " 1: The file assigned by '-p' option of 'option type 2'." << endl;
|
||||
cout << " For 'option type1', this is skipped." << endl;
|
||||
cout << " 2: " << USER_PARAMETER_FILE << endl;
|
||||
cout << " For 'option type2', this is skipped." << endl;
|
||||
cout << " 3: " << DEFAULT_PARAMETER_FILE << endl;
|
||||
cout << " 4: Default parameter" << endl;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static void argumentAnalysis(SDPA& Problem1,
|
||||
int argc, char** argv,
|
||||
char*& inputFileName,
|
||||
char*& resultFileName,
|
||||
char*& paramFileName,
|
||||
SDPA::ParameterType& parameterType,
|
||||
bool& isDimacs, int& numThreads)
|
||||
{
|
||||
if (argc == 1) {
|
||||
message(argv[0]);
|
||||
}
|
||||
if (strcmp(argv[1],"--version") == 0) {
|
||||
fprintf(stdout,"====\n");
|
||||
fprintf(stdout,"SDPA-C (SemiDefinite Programming Algorithm with Completion) %s\n",sdpa_version);
|
||||
fprintf(stdout," %s\n",sdpa_right);
|
||||
fprintf(stdout,"====\n");
|
||||
exit(0);
|
||||
}
|
||||
if (argv[1][0] == '-') {
|
||||
// rsdpa argument
|
||||
|
||||
for (int index = 0; index < argc; ++index) {
|
||||
char* target = argv[index];
|
||||
if (strcmp(target,"-dd")==0 && index+1 < argc) {
|
||||
fprintf(stdout,"*** Dense Data is NOT supported ***\n");
|
||||
inputFileName = argv[index+1];
|
||||
inputFileName = NULL;
|
||||
// isInputSparse = SDPA::DENSE;
|
||||
index++;
|
||||
continue;
|
||||
}
|
||||
if (strcmp(target,"-ds")==0 && index+1 < argc) {
|
||||
inputFileName = argv[index+1];
|
||||
// isInputSparse = SDPA::SPARSE;
|
||||
continue;
|
||||
}
|
||||
if (strcmp(target,"-o")==0 && index+1 < argc) {
|
||||
resultFileName = argv[index+1];
|
||||
index++;
|
||||
continue;
|
||||
}
|
||||
if (strcmp(target,"-p")==0 && index+1 < argc) {
|
||||
paramFileName = argv[index+1];
|
||||
index++;
|
||||
continue;
|
||||
}
|
||||
if (strcmp(target,"-dimacs")==0) {
|
||||
isDimacs = true;
|
||||
continue;
|
||||
}
|
||||
if (strcmp(target,"-pt")==0 && index+1 < argc) {
|
||||
int tmp = atoi(argv[index+1]);
|
||||
switch (tmp) {
|
||||
case 0:
|
||||
parameterType = SDPA::PARAMETER_DEFAULT;
|
||||
break;
|
||||
case 1:
|
||||
parameterType = SDPA::PARAMETER_UNSTABLE_BUT_FAST;
|
||||
break;
|
||||
case 2:
|
||||
parameterType = SDPA::PARAMETER_STABLE_BUT_SLOW;
|
||||
break;
|
||||
default:
|
||||
parameterType = SDPA::PARAMETER_DEFAULT;
|
||||
}
|
||||
index++;
|
||||
paramFileName = NULL;
|
||||
continue;
|
||||
}
|
||||
if (strcmp(target,"-numThreads")==0 && index+1 < argc) {
|
||||
numThreads = atoi(argv[index+1]);
|
||||
index++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
else { // SDPA argument
|
||||
inputFileName = argv[1];
|
||||
int len = strlen(inputFileName);
|
||||
if (inputFileName[len-1] == 's'
|
||||
&& inputFileName[len-2] == '-') {
|
||||
}
|
||||
else {
|
||||
fprintf(stdout, "File may not be Sparse SDPA format. \n");
|
||||
fprintf(stdout, "The file extension must be 'dat-s'. \n");
|
||||
inputFileName = NULL;
|
||||
}
|
||||
|
||||
resultFileName = argv[2];
|
||||
|
||||
paramFileName = USER_PARAMETER_FILE;
|
||||
|
||||
for (int index=3; index<argc; ++index) {
|
||||
if (strcmp(argv[index],"-dimacs")==0) {
|
||||
isDimacs = true;
|
||||
}
|
||||
else if (strcmp(argv[index],"-numThreads")==0 && index+1 < argc) {
|
||||
numThreads = atoi(argv[index+1]);
|
||||
++index;
|
||||
}
|
||||
else if (strcmp(argv[index],"-pt")==0 && index+1 < argc) {
|
||||
int tmp = atoi(argv[index+1]);
|
||||
switch (tmp) {
|
||||
case 0:
|
||||
parameterType = SDPA::PARAMETER_DEFAULT;
|
||||
break;
|
||||
case 1:
|
||||
parameterType = SDPA::PARAMETER_UNSTABLE_BUT_FAST;
|
||||
break;
|
||||
case 2:
|
||||
parameterType = SDPA::PARAMETER_STABLE_BUT_SLOW;
|
||||
break;
|
||||
default:
|
||||
parameterType = SDPA::PARAMETER_DEFAULT;
|
||||
}
|
||||
index++;
|
||||
paramFileName = NULL;
|
||||
} // end of "-pt"
|
||||
else {
|
||||
#if 0 // NO initial point file
|
||||
initFileName = argv[index];
|
||||
int len = strlen(initFileName);
|
||||
if (initFileName[len-1] == 's'
|
||||
&& initFileName[len-2] == '-') {
|
||||
isInitSparse = SDPA::SPARSE;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
} // end of 'for'
|
||||
}
|
||||
|
||||
if (paramFileName != NULL) {
|
||||
// check the availability for paramFileName,
|
||||
// usually USER_PARAMETER_FILE
|
||||
FILE* fptmp = NULL;
|
||||
if ((fptmp=fopen(paramFileName,"r"))==NULL) {
|
||||
// we try DEFAULT_PARAMETER_FILE
|
||||
if ((fptmp=fopen(DEFAULT_PARAMETER_FILE,"r"))==NULL) {
|
||||
rMessage("Cannot Open user parameter File " << paramFileName
|
||||
<< " and default parameter file " << DEFAULT_PARAMETER_FILE);
|
||||
rMessage("Default parameter will be used.");
|
||||
paramFileName = NULL;
|
||||
}
|
||||
else {
|
||||
paramFileName = DEFAULT_PARAMETER_FILE;
|
||||
}
|
||||
}
|
||||
if (fptmp != NULL) {
|
||||
fclose(fptmp);
|
||||
}
|
||||
} // end of 'if (paramFileName != NULL)'
|
||||
|
||||
|
||||
if (inputFileName == NULL || resultFileName == NULL) {
|
||||
message(argv[0]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
TimeStart(ALL_START1);
|
||||
SDPA Problem1;
|
||||
time_t ltime;
|
||||
time(<ime);
|
||||
char string_time[1024];
|
||||
strcpy(string_time,ctime(<ime));
|
||||
string_time[strlen(string_time)-1]='\0';
|
||||
fprintf(stdout,"SDPA-C (Version %s) start at [%s]\n", sdpa_version, string_time);
|
||||
// cout << "let me see your ..." << endl;
|
||||
if (argc == 1) {
|
||||
message(argv[0]);
|
||||
}
|
||||
char* inputFileName = NULL;
|
||||
char* resultFileName = NULL;
|
||||
char* paramFileName = NULL;
|
||||
|
||||
SDPA::SparseType isInputSparse = SDPA::SPARSE;
|
||||
SDPA::ParameterType parameterType = SDPA::PARAMETER_DEFAULT;
|
||||
|
||||
bool isDimacs = false;
|
||||
int numThreads = 0; // 0 means automatic computation
|
||||
|
||||
argumentAnalysis(Problem1, argc, argv,
|
||||
inputFileName, resultFileName,
|
||||
paramFileName, parameterType, isDimacs, numThreads);
|
||||
Problem1.setDisplay(stdout);
|
||||
FILE* fpresult;
|
||||
if ((fpresult = fopen(resultFileName,"w")) == NULL) {
|
||||
rError("Cannot Open Result File : " << resultFileName);
|
||||
}
|
||||
fprintf(fpresult,"SDPA-C start at [%s]\n",string_time);
|
||||
|
||||
Problem1.setResultFile(fpresult);
|
||||
if (paramFileName == NULL) {
|
||||
if (parameterType == SDPA::PARAMETER_DEFAULT) {
|
||||
fprintf(stdout ,"set is DEFAULT\n");
|
||||
fprintf(fpresult,"set is DEFAULT\n");
|
||||
}
|
||||
else if (parameterType == SDPA::PARAMETER_UNSTABLE_BUT_FAST) {
|
||||
fprintf(stdout ,"set is UNSTABLE_BUT_FAST\n");
|
||||
fprintf(fpresult,"set is UNSTABLE_BUT_FAST\n");
|
||||
}
|
||||
else if (parameterType == SDPA::PARAMETER_STABLE_BUT_SLOW) {
|
||||
fprintf(stdout ,"set is STABLE_BUT_SLOW\n");
|
||||
fprintf(fpresult,"set is STABLE_BUT_SLOW\n");
|
||||
}
|
||||
Problem1.setParameterType(parameterType);
|
||||
}
|
||||
|
||||
if (paramFileName) {
|
||||
fprintf(stdout ,"param is %s\n", paramFileName);
|
||||
fprintf(fpresult,"param is %s\n", paramFileName);
|
||||
Problem1.readParameter(paramFileName,fpresult);
|
||||
}
|
||||
if (isDimacs == true && Problem1.judgeDimacsAvailability()==false) {
|
||||
rError("When XPrint or YPrint are " << NO_P_FORMAT
|
||||
<< ", Dimacs information is not available");
|
||||
}
|
||||
fprintf(stdout ,"data is %s", inputFileName);
|
||||
fprintf(stdout ," : sparse\n");
|
||||
fprintf(fpresult,"data is %s", inputFileName);
|
||||
fprintf(fpresult," : sparse\n");
|
||||
|
||||
Problem1.readInput(inputFileName, fpresult);
|
||||
|
||||
fprintf(stdout ,"out is %s\n", resultFileName);
|
||||
fprintf(fpresult,"out is %s\n", resultFileName);
|
||||
|
||||
if (isDimacs) {
|
||||
fprintf(stdout ,"Dimacs information will be computed after the iteration.\n");
|
||||
fprintf(fpresult,"Dimacs information will be computed after the iteration.\n");
|
||||
}
|
||||
|
||||
Problem1.setNumThreads(numThreads);
|
||||
Problem1.initializeSolve();
|
||||
Problem1.solve();
|
||||
|
||||
if (isDimacs) {
|
||||
double dimacs_error[7];
|
||||
fprintf(stdout, "Dimacs is under computation now.\n");
|
||||
Problem1.getDimacsError(dimacs_error);
|
||||
Problem1.printDimacsError(dimacs_error,
|
||||
Problem1.getParameterPrintInformation(),
|
||||
stdout);
|
||||
Problem1.printDimacsError(dimacs_error,
|
||||
Problem1.getParameterPrintInformation(),
|
||||
fpresult);
|
||||
}
|
||||
|
||||
Problem1.finalize();
|
||||
|
||||
time(<ime);
|
||||
strcpy(string_time,ctime(<ime));
|
||||
string_time[strlen(string_time)-1]='\0';
|
||||
fprintf(stdout ,"SDPA-C end at [%s]\n",string_time);
|
||||
fprintf(fpresult,"SDPA-C end at [%s]\n",string_time);
|
||||
TimeEnd(ALL_END1);
|
||||
double all_time = TimeCal(ALL_START1,ALL_END1);
|
||||
fprintf(stdout ,"ALL TIME = %.6lf\n", all_time);
|
||||
fprintf(fpresult,"ALL TIME = %.6lf\n", all_time);
|
||||
fclose(fpresult);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Vendored
+51
@@ -0,0 +1,51 @@
|
||||
/* -------------------------------------------------------------
|
||||
|
||||
This file is a component of SDPA
|
||||
Copyright (C) 2004-2013 SDPA Project
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
------------------------------------------------------------- */
|
||||
/*--------------------------------------------------
|
||||
sdpa_include.h
|
||||
--------------------------------------------------*/
|
||||
|
||||
#ifndef __sdpa_include_h__
|
||||
#define __sdpa_include_h__
|
||||
|
||||
#include "sdpa_right.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
|
||||
using namespace std;
|
||||
|
||||
#define SDPA_SUCCESS true
|
||||
#define SDPA_FAILURE false
|
||||
|
||||
|
||||
|
||||
// for CHOLMOD routine
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
|
||||
#include "sdpa_tool.h"
|
||||
// #include "sdpa_algebra.h"
|
||||
|
||||
#endif // __sdpa_include_h__
|
||||
Vendored
+1155
File diff suppressed because it is too large
Load Diff
Vendored
+118
@@ -0,0 +1,118 @@
|
||||
/* -------------------------------------------------------------
|
||||
|
||||
This file is a component of SDPA
|
||||
Copyright (C) 2004-2013 SDPA Project
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
------------------------------------------------------------- */
|
||||
|
||||
#ifndef __sdpa_io_h__
|
||||
#define __sdpa_io_h__
|
||||
|
||||
#define lengthOfString 256
|
||||
|
||||
#include "sdpa_block.h"
|
||||
#include "sdpa_parts.h"
|
||||
|
||||
namespace sdpa {
|
||||
|
||||
class IO
|
||||
{
|
||||
public:
|
||||
static void read(FILE* fpData, FILE* fpout, int& m, char* str);
|
||||
static void read(FILE* fpData, int& nBlock);
|
||||
static void read(FILE* fpData, BlockStruct& bs);
|
||||
static void read(FILE* fpData, Vector& b);
|
||||
static void read(FILE* fpData, DenseLinearSpace& xMat,
|
||||
Vector& yVec, DenseLinearSpace& zMat,
|
||||
BlockStruct& bs, bool inputSparse);
|
||||
static void read(FILE* fpData, int m,
|
||||
BlockStruct& bs,
|
||||
InputData& inputData, bool isDataSparse);
|
||||
static void read(FILE* fpData, int m,
|
||||
BlockStruct& bs, InputData& inputData);
|
||||
|
||||
// read data is first introduced into this class
|
||||
class LIJV
|
||||
{
|
||||
public:
|
||||
int SDPl,LPl,i,j;
|
||||
double value;
|
||||
};
|
||||
|
||||
|
||||
// 2008/02/27 kazuhide nakata
|
||||
// without LP_ANonZeroCount
|
||||
static void setBlockStruct(FILE* fpData, InputData& inputData,
|
||||
int m, BlockStruct& bs,
|
||||
long position, bool isDataSparse);
|
||||
|
||||
// 2008/02/27 kazuhide nakata
|
||||
// without LP_ANonZeroCount
|
||||
static void setElement(FILE* fpData, InputData& inputData, int m,
|
||||
BlockStruct& bs,
|
||||
long position, bool isDataSparse);
|
||||
|
||||
static void printHeader(FILE* fpout, FILE* Display);
|
||||
|
||||
static void printOneIteration(int pIteration,
|
||||
AverageComplementarity& mu,
|
||||
RatioInitResCurrentRes& theta,
|
||||
SolveInfo& solveInfo,
|
||||
StepLength& alpha,
|
||||
DirectionParameter& beta,
|
||||
FILE* fpout,
|
||||
FILE* Display);
|
||||
|
||||
static void printLastInfo(int pIteration,
|
||||
AverageComplementarity& mu,
|
||||
RatioInitResCurrentRes& theta,
|
||||
SolveInfo& solveInfo,
|
||||
StepLength& alpha,
|
||||
DirectionParameter& beta,
|
||||
Residuals& currentRes,
|
||||
Phase & phase,
|
||||
Solutions& currentPt,
|
||||
InputData& inputData,
|
||||
double cputime,
|
||||
ComputeTime& com,
|
||||
Parameter& param,
|
||||
FILE* fpout,
|
||||
FILE* Display,
|
||||
bool printTime = true);
|
||||
|
||||
static void computeDimacs(double* dimacs_error,
|
||||
SolveInfo& solveInfo,
|
||||
Residuals& currentRes,
|
||||
Solutions& currentPt,
|
||||
InputData& inputData);
|
||||
|
||||
static void printDimacs(double* dimacs_error,
|
||||
char* printFormat,
|
||||
FILE* fpout);
|
||||
|
||||
static bool judgeXmake(Parameter& param);
|
||||
static bool judgeZmake(Parameter& param);
|
||||
|
||||
static void printSolution(BlockStruct& bs, Solutions& currentPt,
|
||||
Parameter& param, FILE* fpout,
|
||||
bool Xmake, bool Zmake);
|
||||
|
||||
};
|
||||
|
||||
} // end of namespace 'sdpa'
|
||||
|
||||
#endif // __sdpa_io_h__
|
||||
Vendored
+2959
File diff suppressed because it is too large
Load Diff
Vendored
+331
@@ -0,0 +1,331 @@
|
||||
/* -------------------------------------------------------------
|
||||
|
||||
This file is a component of SDPA
|
||||
Copyright (C) 2004-2013 SDPA Project
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
------------------------------------------------------------- */
|
||||
|
||||
#ifndef __sdpa_linear_h__
|
||||
#define __sdpa_linear_h__
|
||||
|
||||
#include "sdpa_struct.h"
|
||||
|
||||
namespace sdpa {
|
||||
|
||||
class Lal
|
||||
{
|
||||
public:
|
||||
// calculate the minimum eigenvalue of lMat*xMat*(lMat^T)
|
||||
// by Lanczos metnod
|
||||
static double getMinEigen(DenseMatrix& lMat, DenseMatrix& xMat,
|
||||
DenseMatrix& Q,
|
||||
Vector& out, Vector& b, Vector& r,
|
||||
Vector& q, Vector& qold,
|
||||
Vector& w, Vector& tmp,
|
||||
Vector& diagVec, Vector& diagVec2,
|
||||
Vector& workVec, char charTranspose='N');
|
||||
|
||||
// caluculate all eigenvalues of aMat by QR method
|
||||
static double getMinEigenValue(DenseMatrix& aMat,
|
||||
Vector& eigenVec,
|
||||
Vector& workVec);
|
||||
// calculate Lanzcos for cholmod_sparse
|
||||
static double getMinEigenValue(CholmodMatrix& cholmodMatrix);
|
||||
|
||||
static double getOneNorm(Vector& b);
|
||||
static double getOneNorm(SparseMatrix& C);
|
||||
static double getOneNorm(SparseLinearSpace& C);
|
||||
static double getOneNorm(CompMatrix& C);
|
||||
static double getOneNorm(CompSpace& C);
|
||||
|
||||
static double getTwoNorm(Vector& b);
|
||||
static double getTwoNorm(DenseMatrix& X);
|
||||
static double getTwoNorm(DenseLinearSpace& X);
|
||||
|
||||
|
||||
static bool getInnerProduct(double& ret,
|
||||
Vector& aVec, Vector& bVec);
|
||||
static bool getInnerProduct(double& ret,
|
||||
BlockVector& aVec,
|
||||
BlockVector& bVec);
|
||||
static bool getInnerProduct(double& ret,
|
||||
DenseMatrix& aMat,
|
||||
DenseMatrix& bMat);
|
||||
static bool getInnerProduct(double& ret,
|
||||
SparseMatrix& aMat,
|
||||
DenseMatrix& bMat);
|
||||
|
||||
static bool getCholesky(DenseMatrix& retMat, DenseMatrix& aMat);
|
||||
|
||||
// nakata 2004/12/01
|
||||
// diagonal part of Cholesky matrix is set these inverse.
|
||||
static bool getCholesky(SparseMatrix& aMat, int* diagonalIndex);
|
||||
|
||||
static bool getInvLowTriangularMatrix(DenseMatrix& retMat,
|
||||
DenseMatrix& aMat);
|
||||
static bool getSymmetrize(DenseMatrix& aMat);
|
||||
|
||||
static bool getTranspose(DenseMatrix& retMat,
|
||||
DenseMatrix& aMat);
|
||||
|
||||
static int rdpotf2_(char*uplo, int *n, double *a, int *lda, int *info);
|
||||
static int rdpotrf_(char *uplo, int *n, double *a, int *lda, int *info);
|
||||
static bool choleskyFactorWithAdjust(DenseMatrix& aMat);
|
||||
|
||||
static bool solveSystems(Vector& xVec,
|
||||
DenseMatrix& aMat, Vector& bVec);
|
||||
// solve aMat * xVec = bVec
|
||||
// aMat must be Cholesky Factorized.
|
||||
|
||||
// nakata 2004/12/01
|
||||
static bool solveSystems(Vector& xVec,
|
||||
SparseMatrix& aMat, Vector& bVec);
|
||||
// solve aMat * xVec = bVec
|
||||
// aMat must be Cholesky Factorized.
|
||||
|
||||
static bool getSymmetrize(DenseLinearSpace& aMat);
|
||||
|
||||
static bool getTranspose(DenseLinearSpace& retMat,
|
||||
DenseLinearSpace& aMat);
|
||||
|
||||
static bool multiply(DenseMatrix& retMat,
|
||||
DenseMatrix& aMat, DenseMatrix& bMat,
|
||||
double* scalar = NULL);
|
||||
static bool multiply(DenseMatrix& retMat,
|
||||
SparseMatrix& aMat, DenseMatrix& bMat,
|
||||
double* scalar = NULL);
|
||||
static bool multiply(DenseMatrix& retMat,
|
||||
DenseMatrix& aMat, SparseMatrix& bMat,
|
||||
double* scalar = NULL);
|
||||
static bool multiply(DenseMatrix& retMat,
|
||||
DenseMatrix& aMat, double* scalar = NULL);
|
||||
static bool multiply(Vector& retVec,
|
||||
Vector& aVec, double* scalar = NULL);
|
||||
static bool multiply(BlockVector& retVec,
|
||||
BlockVector& aVec,
|
||||
double* scalar = NULL);
|
||||
static bool multiply(Vector& retVec,
|
||||
DenseMatrix& aMat, Vector& bVec,
|
||||
double* scalar = NULL);
|
||||
// ret = aMat**T * bMat
|
||||
static bool tran_multiply(DenseMatrix& retMat,
|
||||
DenseMatrix& aMat, DenseMatrix& bMat,
|
||||
double* scalar = NULL);
|
||||
// ret = aMat * bMat**T
|
||||
static bool multiply_tran(DenseMatrix& retMat,
|
||||
DenseMatrix& aMat, DenseMatrix& bMat,
|
||||
double* scalar = NULL);
|
||||
// ret = a + (*scalar)*b
|
||||
static bool plus(Vector& retVec, Vector& aVec,
|
||||
Vector& bVec, double* scalar = NULL);
|
||||
static bool plus(DenseMatrix& retMat,
|
||||
DenseMatrix& aMat, DenseMatrix& bMat,
|
||||
double* scalar = NULL);
|
||||
static bool plus(DenseMatrix& retMat,
|
||||
SparseMatrix& aMat, DenseMatrix& bMat,
|
||||
double* scalar = NULL);
|
||||
static bool plus(DenseMatrix& retMat,
|
||||
DenseMatrix& aMat, SparseMatrix& bMat,
|
||||
double* scalar = NULL);
|
||||
|
||||
static bool plus(BlockVector& retVec,
|
||||
BlockVector& aVec,
|
||||
BlockVector& bVec, double* scalar = NULL);
|
||||
|
||||
// ret = a '*' (*scalar)
|
||||
static bool let(Vector& retVec, const char eq,
|
||||
Vector& aVec, const char op,
|
||||
double* scalar = NULL);
|
||||
|
||||
// ret = a '*' (*scalar)
|
||||
static bool let(BlockVector& retVec, const char eq,
|
||||
BlockVector& aVec, const char op,
|
||||
double* scalar = NULL);
|
||||
|
||||
// ret = a '*' (*scalar)
|
||||
static bool let(DenseMatrix& retMat, const char eq,
|
||||
DenseMatrix& aMat, const char op,
|
||||
double* scalar = NULL);
|
||||
|
||||
// ret = a '+' '-' b*(*scalar)
|
||||
static bool let(Vector& retVec, const char eq,
|
||||
Vector& aVec, const char op,
|
||||
Vector& bVec, double* scalar = NULL);
|
||||
|
||||
// ret = a '+' '-' '*' 't' 'T' b*(*scalar)
|
||||
static bool let(DenseMatrix& retMat, const char eq,
|
||||
DenseMatrix& aMat, const char op,
|
||||
DenseMatrix& bMat, double* scalar = NULL);
|
||||
|
||||
// ret = a '+' '-' '*' b*(*scalar)
|
||||
static bool let(DenseMatrix& retMat, const char eq,
|
||||
SparseMatrix& aMat, const char op,
|
||||
DenseMatrix& bMat, double* scalar = NULL);
|
||||
|
||||
// ret = a '+' '-' '*' b*(*scalar)
|
||||
static bool let(DenseMatrix& retMat, const char eq,
|
||||
DenseMatrix& aMat, const char op,
|
||||
SparseMatrix& bMat, double* scalar = NULL);
|
||||
|
||||
// ret = aMat '*' '/' bVec
|
||||
static bool let(Vector& rVec, const char eq,
|
||||
DenseMatrix& aMat, const char op,
|
||||
Vector& bVec);
|
||||
|
||||
// nakata 2004/12/01
|
||||
// ret = aMat '/' bVec
|
||||
static bool let(Vector& rVec, const char eq,
|
||||
SparseMatrix& aMat, const char op,
|
||||
Vector& bVec);
|
||||
|
||||
// ret = inner_product(a,b) // op = '.'
|
||||
static bool let(double& ret, const char eq,
|
||||
Vector& aVec, const char op,
|
||||
Vector& bVec);
|
||||
|
||||
// ret = inner_product(a,b) // op = '.'
|
||||
static bool let(double& ret, const char eq,
|
||||
DenseMatrix& aMat, const char op,
|
||||
DenseMatrix& bMat);
|
||||
|
||||
// ret = inner_product(a,b) // op = '.'
|
||||
static bool let(double& ret, const char eq,
|
||||
DenseMatrix& aMat, const char op,
|
||||
SparseMatrix& bMat);
|
||||
|
||||
// ret = inner_product(a,b) // op = '.'
|
||||
static bool let(double& ret, const char eq,
|
||||
SparseMatrix& aMat, const char op,
|
||||
DenseMatrix& bMat);
|
||||
|
||||
// ret = inner_product(a,b) // op = '.'
|
||||
static bool let(double& ret, const char eq,
|
||||
BlockVector& aVec, const char op,
|
||||
BlockVector& bVec);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
static bool getInnerProduct(double& ret,
|
||||
DenseLinearSpace& aMat,
|
||||
DenseLinearSpace& bMat);
|
||||
|
||||
static bool getInnerProduct(double& ret,
|
||||
SparseLinearSpace& aMat,
|
||||
DenseLinearSpace& bMat);
|
||||
|
||||
// ret = a (*scalar)*b
|
||||
static bool multiply(DenseLinearSpace& retMat,
|
||||
DenseLinearSpace& aMat,
|
||||
double* scalar = NULL);
|
||||
// ret = a + (*scalar)*b
|
||||
static bool plus(DenseLinearSpace& retMat,
|
||||
DenseLinearSpace& aMat,
|
||||
DenseLinearSpace& bMat,
|
||||
double* scalar = NULL);
|
||||
// CAUTION!!! We don't initialize retMat to zero matrix for efficiently.
|
||||
static bool plus(DenseLinearSpace& retMat,
|
||||
SparseLinearSpace& aMat,
|
||||
DenseLinearSpace& bMat,
|
||||
double* scalar = NULL);
|
||||
// CAUTION!!! We don't initialize retMat to zero matrix for efficiently.
|
||||
static bool plus(DenseLinearSpace& retMat,
|
||||
DenseLinearSpace& aMat,
|
||||
SparseLinearSpace& bMat,
|
||||
double* scalar = NULL);
|
||||
|
||||
// retMat(Cholmod->A) = retMat(Cholmod->A) + aMat*(*scalar);
|
||||
static void plus(CholmodMatrix& retMat,
|
||||
CompMatrix& aMat,
|
||||
double* scalar = NULL);
|
||||
|
||||
// retMat(Cholmod->A) = retMat(Cholmod->A) + aMat*(*scalar);
|
||||
static void plus(CholmodSpace& retMat,
|
||||
CompSpace& aMat,
|
||||
double* scalar = NULL);
|
||||
|
||||
// ret = a '*' (*scalar)
|
||||
static bool let(DenseLinearSpace& retMat, const char eq,
|
||||
DenseLinearSpace& aMat, const char op,
|
||||
double* scalar = NULL);
|
||||
|
||||
// ret = a '+' '-' b*(*scalar)
|
||||
static bool let(DenseLinearSpace& retMat, const char eq,
|
||||
DenseLinearSpace& aMat, const char op,
|
||||
DenseLinearSpace& bMat, double* scalar = NULL);
|
||||
|
||||
// ret = a '+' '-' b*(*scalar)
|
||||
static bool let(DenseLinearSpace& retMat, const char eq,
|
||||
SparseLinearSpace& aMat, const char op,
|
||||
DenseLinearSpace& bMat, double* scalar = NULL);
|
||||
|
||||
// ret = a '+' '-' '*' b*(*scalar)
|
||||
static bool let(DenseLinearSpace& retMat, const char eq,
|
||||
DenseLinearSpace& aMat, const char op,
|
||||
SparseLinearSpace& bMat, double* scalar = NULL);
|
||||
|
||||
// ret = inner_product(a,b) // op = '.'
|
||||
static bool let(double& ret, const char eq,
|
||||
DenseLinearSpace& aMat, const char op,
|
||||
DenseLinearSpace& bMat);
|
||||
|
||||
// ret = inner_product(a,b) // op = '.'
|
||||
static bool let(double& ret, const char eq,
|
||||
SparseLinearSpace& aMat, const char op,
|
||||
DenseLinearSpace& bMat);
|
||||
|
||||
// ret = inner_product(a,b) // op = '.'
|
||||
static bool let(double& ret, const char eq,
|
||||
DenseLinearSpace& aMat, const char op,
|
||||
SparseLinearSpace& bMat);
|
||||
|
||||
|
||||
//=======================================================================
|
||||
// for SDPA-C
|
||||
//=======================================================================
|
||||
|
||||
static void getInnerProduct(double& ret,
|
||||
CompMatrix& A,
|
||||
CliqueMatrix& X,
|
||||
OrderingMatrix& order);
|
||||
|
||||
static void getInnerProduct(double& ret,
|
||||
cholmod_sparse* Z,
|
||||
CliqueMatrix& X,
|
||||
OrderingMatrix& order,
|
||||
int* Z_blockNumber, int* Z_blockIndex);
|
||||
|
||||
static void getInnerProduct(double& ret,
|
||||
CompSpace& A,
|
||||
CliqueSpace& X,
|
||||
OrderingSpace& order);
|
||||
|
||||
static void getInnerProduct(double& ret,
|
||||
CompMatrix& A,
|
||||
double* aVec,
|
||||
double* bVec);
|
||||
|
||||
static void getInnerProduct(double& ret,
|
||||
cholmod_sparse* A,
|
||||
double* aVec,
|
||||
double* bVec);
|
||||
|
||||
|
||||
};
|
||||
|
||||
} // end of namespace 'sdpa'
|
||||
|
||||
#endif // __sdpa_linear_h__
|
||||
Vendored
+1889
File diff suppressed because it is too large
Load Diff
Vendored
+253
@@ -0,0 +1,253 @@
|
||||
/* -------------------------------------------------------------
|
||||
|
||||
This file is a component of SDPA
|
||||
Copyright (C) 2004-2013 SDPA Project
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
------------------------------------------------------------- */
|
||||
|
||||
#ifndef __sdpa_newton_h__
|
||||
#define __sdpa_newton_h__
|
||||
|
||||
#include "sdpa_chordal.h"
|
||||
// #include <pthread.h>
|
||||
|
||||
#define SparseCholesky 1
|
||||
|
||||
namespace sdpa {
|
||||
|
||||
class Newton;
|
||||
|
||||
class Solutions;
|
||||
class InputData;
|
||||
class Residuals;
|
||||
|
||||
class ComputeTime;
|
||||
class Parameter;
|
||||
class StepLength;
|
||||
class DirectionParameter;
|
||||
class Switch;
|
||||
class RatioInitResCurrentRes;
|
||||
class SolveInfo;
|
||||
class Phase;
|
||||
class AverageComplementarity;
|
||||
|
||||
|
||||
|
||||
class Newton
|
||||
{
|
||||
public:
|
||||
enum bMat_Sp_De {SPARSE, DENSE};
|
||||
bMat_Sp_De bMat_type;
|
||||
|
||||
SparseMatrix sparse_bMat;
|
||||
DenseMatrix bMat; // the coefficent of Schur complement
|
||||
Vector gVec; // the right hand side of Schur complement
|
||||
|
||||
// Caution:
|
||||
// if SDPA doesn't use sparse bMat, following variables are indefinite.
|
||||
//
|
||||
// nBlock : number of block
|
||||
// nConstraint[k]: number of combination of nonzero matrices in k-th block
|
||||
// when A[k].block[i] and A[k].block[j] are nonzero matrices,
|
||||
// i <-> constraint1[k][t]
|
||||
// j <-> constraint2[k][t]
|
||||
// A[k].block[i] <-> A[k].sp_block[blockIndex1[k][t]]
|
||||
// A[k].block[j] <-> A[k].sp_block[blockIndex2[k][t]]
|
||||
// B_{ij} <-> sparse_bMat.sp_ele[location_sparse_bMat[k][t]]
|
||||
int SDP_nBlock; int* SDP_number;
|
||||
int** SDP_constraint1; int** SDP_constraint2;
|
||||
int** SDP_blockIndex1; int** SDP_blockIndex2;
|
||||
int** SDP_location_sparse_bMat;
|
||||
int* SDP_nStartIndex2; // start new j&jb from this index
|
||||
int** SDP_startIndex2; // start new j&jb from this index
|
||||
int LP_nBlock; int* LP_number;
|
||||
int** LP_constraint1; int** LP_constraint2;
|
||||
int** LP_blockIndex1; int** LP_blockIndex2;
|
||||
int** LP_location_sparse_bMat;
|
||||
int* LP_nStartIndex2; // start new j&jb from this index
|
||||
int** LP_startIndex2; // start new j&jb from this index
|
||||
|
||||
// from index of aggrigate sparsity pattern to index of sparse_bMat
|
||||
// B_{ii} <-> sparse_bMat[diagonalIndex[i]]
|
||||
int* diagonalIndex;
|
||||
// B_{ij} for all i is between diagonalIndex[j] and rowStartIndex[j+1]
|
||||
|
||||
Newton();
|
||||
Newton(int m, BlockStruct& bs);
|
||||
~Newton();
|
||||
|
||||
void initialize(int m, BlockStruct& bs);
|
||||
|
||||
void finalize();
|
||||
|
||||
void initialize_dense_bMat(int m);
|
||||
// 2008/03/12 kazuhide nakata
|
||||
void initialize_sparse_bMat(int m);
|
||||
// 2008/03/12 kazuhide nakata
|
||||
void initialize_bMat(int m, Chordal& chordal, InputData& inputData,
|
||||
FILE* Display, FILE* fpOut);
|
||||
|
||||
int binarySearchIndex(int i, int j);
|
||||
void make_aggrigateIndex_SDP(InputData& inputData);
|
||||
void make_aggrigateIndex_LP(InputData& inputData);
|
||||
void make_aggrigateIndex(InputData& inputData);
|
||||
|
||||
enum WHICH_DIRECTION {PREDICTOR, CORRECTOR};
|
||||
|
||||
void compute_bMatgVec_dense(InputData& inputData,
|
||||
Solutions& currentPt,
|
||||
Residuals& currentRes,
|
||||
AverageComplementarity& mu,
|
||||
DirectionParameter& beta,
|
||||
Phase& phase,
|
||||
ComputeTime& com);
|
||||
|
||||
static pthread_mutex_t job_mutex;
|
||||
static int Column_Number;
|
||||
static int Column_NumberDx;
|
||||
|
||||
void compute_bMatgVec_dense_threads(InputData& inputData,
|
||||
Solutions& currentPt,
|
||||
Residuals& currentRes,
|
||||
AverageComplementarity& mu,
|
||||
DirectionParameter& beta,
|
||||
Phase& phase,
|
||||
ComputeTime& com);
|
||||
static void* compute_bMatgVec_dense_threads_SDP(void* arg);
|
||||
|
||||
void compute_bMatgVec_sparse(InputData& inputData,
|
||||
Solutions& currentPt,
|
||||
Residuals& currentRes,
|
||||
AverageComplementarity& mu,
|
||||
DirectionParameter& beta,
|
||||
Phase& phase,
|
||||
ComputeTime& com);
|
||||
|
||||
void compute_bMatgVec_sparse_threads(InputData& inputData,
|
||||
Solutions& currentPt,
|
||||
Residuals& currentRes,
|
||||
AverageComplementarity& mu,
|
||||
DirectionParameter& beta,
|
||||
Phase& phase,
|
||||
ComputeTime& com);
|
||||
|
||||
static void* compute_bMatgVec_sparse_threads_SDP(void* arg);
|
||||
|
||||
void Make_bMatgVec(InputData& inputData,
|
||||
Solutions& currentPt,
|
||||
Residuals& currentRes,
|
||||
AverageComplementarity& mu,
|
||||
DirectionParameter& beta,
|
||||
Phase& phase,
|
||||
ComputeTime& com);
|
||||
|
||||
bool compute_DyVec(Newton::WHICH_DIRECTION direction,
|
||||
int m,
|
||||
InputData& inputData,
|
||||
Chordal& chordal,
|
||||
Solutions& currentPt,
|
||||
ComputeTime& com,
|
||||
FILE* Display, FILE* fpOut);
|
||||
|
||||
void compute_DzMat(InputData& inputData,
|
||||
Solutions& currentPt,
|
||||
Residuals& currentRes,
|
||||
Phase& phase,
|
||||
ComputeTime& com);
|
||||
|
||||
void compute_DxMat(Solutions& currentPt,
|
||||
AverageComplementarity& mu,
|
||||
DirectionParameter& beta,
|
||||
ComputeTime& com);
|
||||
|
||||
void compute_DxMat_threads(Solutions& currentPt,
|
||||
AverageComplementarity& mu,
|
||||
DirectionParameter& beta,
|
||||
ComputeTime& com);
|
||||
|
||||
static void* compute_DxMat_threads_SDP(void* arg);
|
||||
|
||||
bool Mehrotra(WHICH_DIRECTION direction,
|
||||
int m,
|
||||
InputData& inputData,
|
||||
Chordal& chordal,
|
||||
Solutions& currentPt,
|
||||
Residuals& currentRes,
|
||||
AverageComplementarity& mu,
|
||||
DirectionParameter& beta,
|
||||
Switch& reduction,
|
||||
Phase& phase,
|
||||
ComputeTime& com,
|
||||
FILE* Display, FILE* fpOut);
|
||||
|
||||
void checkDirection(int m, InputData& inputData,
|
||||
Solutions& currentPt,
|
||||
Residuals& currentRes,
|
||||
AverageComplementarity& mu,
|
||||
DirectionParameter& beta,
|
||||
Switch& reduction,
|
||||
Phase& phase,
|
||||
ComputeTime& com,
|
||||
FILE* Display, FILE* fpOut);
|
||||
|
||||
void display(FILE* fpout=stdout);
|
||||
void display_index(FILE* fpout=stdout);
|
||||
void display_sparse_bMat(FILE* fpout=stdout);
|
||||
|
||||
int NUM_THREADS;
|
||||
void setNumThreads(FILE* Display, FILE* fpOut, int NumThreads=0);
|
||||
};
|
||||
|
||||
typedef struct _thread_arg {
|
||||
int l;
|
||||
int m;
|
||||
double target_mu;
|
||||
int thread_num;
|
||||
InputData* addr_inputData;
|
||||
CholmodMatrix* addr_cholmodMatrix;
|
||||
DenseMatrix* addr_bMat;
|
||||
Vector* addr_gVec;
|
||||
Phase* addr_phase;
|
||||
|
||||
} thread_arg_t;
|
||||
|
||||
typedef struct _thread_arg_s {
|
||||
int l;
|
||||
int m;
|
||||
double target_mu;
|
||||
int thread_num;
|
||||
InputData* addr_inputData;
|
||||
CholmodMatrix* addr_cholmodMatrix;
|
||||
SparseMatrix* addr_sparse_bMat;
|
||||
Vector* addr_gVec;
|
||||
Phase* addr_phase;
|
||||
Newton* addr_newton;
|
||||
|
||||
} thread_arg_s;
|
||||
|
||||
typedef struct _thread_DX {
|
||||
int l;
|
||||
int thread_num;
|
||||
double target_mu;
|
||||
CholmodMatrix* addr_cholmodMatrix;
|
||||
OrderingMatrix* addr_order;
|
||||
} thread_DX_t;
|
||||
|
||||
|
||||
} // end of namespace 'sdpa'
|
||||
|
||||
#endif // __sdpa_newton_h__
|
||||
Vendored
+1314
File diff suppressed because it is too large
Load Diff
Vendored
+269
@@ -0,0 +1,269 @@
|
||||
/* -------------------------------------------------------------
|
||||
|
||||
This file is a component of SDPA
|
||||
Copyright (C) 2004-2013 SDPA Project
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
------------------------------------------------------------- */
|
||||
|
||||
#ifndef __sdpa_parts_h__
|
||||
#define __sdpa_parts_h__
|
||||
|
||||
#include "sdpa_include.h"
|
||||
#include "sdpa_dataset.h"
|
||||
|
||||
namespace sdpa {
|
||||
|
||||
class Newton;
|
||||
|
||||
class Solutions;
|
||||
class InputData;
|
||||
class Residuals;
|
||||
|
||||
class ComputeTime;
|
||||
class Parameter;
|
||||
class StepLength;
|
||||
class DirectionParameter;
|
||||
class Switch;
|
||||
class RatioInitResCurrentRes;
|
||||
class SolveInfo;
|
||||
class Phase;
|
||||
class AverageComplementarity;
|
||||
|
||||
|
||||
class ComputeTime
|
||||
{
|
||||
public:
|
||||
double Predictor;
|
||||
double Corrector;
|
||||
double StepPredictor;
|
||||
double StepCorrector;
|
||||
double xMatTime;
|
||||
double zMatTime;
|
||||
double invzMatTime;
|
||||
double xMatzMatTime;
|
||||
double EigxMatTime;
|
||||
double EigzMatTime;
|
||||
double EigxMatzMatTime;
|
||||
double makerMat;
|
||||
double makebMat;
|
||||
double B_DIAG;
|
||||
double B_F1;
|
||||
double B_F2;
|
||||
double B_F3;
|
||||
double B_PRE;
|
||||
double makebMatgVec;
|
||||
double choleskybMat;
|
||||
double solve;
|
||||
double sumDz;
|
||||
double makedX;
|
||||
double symmetriseDx;
|
||||
double makedXdZ;
|
||||
double updateRes;
|
||||
double MainLoop;
|
||||
double FileRead;
|
||||
double FileCheck;
|
||||
double FileChange;
|
||||
double TotalTime;
|
||||
ComputeTime();
|
||||
~ComputeTime();
|
||||
void display(FILE* fpout=stdout);
|
||||
};
|
||||
|
||||
class Parameter
|
||||
{
|
||||
public:
|
||||
enum parameterType {PARAMETER_DEFAULT,
|
||||
PARAMETER_UNSTABLE_BUT_FAST,
|
||||
PARAMETER_STABLE_BUT_SLOW};
|
||||
int maxIteration;
|
||||
double epsilonStar;
|
||||
double lambdaStar;
|
||||
double omegaStar;
|
||||
double lowerBound;
|
||||
double upperBound;
|
||||
double betaStar;
|
||||
double betaBar;
|
||||
double gammaStar;
|
||||
double epsilonDash;
|
||||
#define PRINT_DEFAULT_LENGTH 30
|
||||
static char xPRINT_DEFAULT[PRINT_DEFAULT_LENGTH];
|
||||
static char XPRINT_DEFAULT[PRINT_DEFAULT_LENGTH];
|
||||
static char YPRINT_DEFAULT[PRINT_DEFAULT_LENGTH];
|
||||
static char infPRINT_DEFAULT[PRINT_DEFAULT_LENGTH];
|
||||
char xPrint[PRINT_DEFAULT_LENGTH];
|
||||
char XPrint[PRINT_DEFAULT_LENGTH];
|
||||
char YPrint[PRINT_DEFAULT_LENGTH];
|
||||
char infPrint[PRINT_DEFAULT_LENGTH];
|
||||
Parameter();
|
||||
Parameter(FILE* parameterFile);
|
||||
~Parameter();
|
||||
void setDefaultParameter(parameterType type
|
||||
= PARAMETER_DEFAULT);
|
||||
void readFile(FILE* parameterFile);
|
||||
void display(FILE* fpout=stdout, char* printFormat=infPRINT_DEFAULT);
|
||||
};
|
||||
|
||||
class StepLength
|
||||
{
|
||||
public:
|
||||
|
||||
double primal;
|
||||
double dual;
|
||||
StepLength();
|
||||
StepLength(double alphaP, double alphaD, int nBlock,
|
||||
int* blockStruct);
|
||||
~StepLength();
|
||||
void initialize(double alphaP, double alphaD);
|
||||
void finalize();
|
||||
|
||||
static double minBlockVector(BlockVector& aVec);
|
||||
|
||||
void computeStepLength(Solutions& currentPt,
|
||||
ComputeTime& com);
|
||||
void MehrotraPredictor(InputData& inputData,
|
||||
Solutions& currentPt,
|
||||
Phase& phase,
|
||||
Switch& reduction,
|
||||
AverageComplementarity& mu,
|
||||
RatioInitResCurrentRes& theta,
|
||||
Parameter& param,
|
||||
ComputeTime& com);
|
||||
void Centering(Solutions& currentPt,
|
||||
Parameter& param,
|
||||
ComputeTime& com);
|
||||
void display(FILE* fpout = stdout);
|
||||
};
|
||||
|
||||
class DirectionParameter
|
||||
{
|
||||
public:
|
||||
double value;
|
||||
DirectionParameter(double betaStar=0.0);
|
||||
~DirectionParameter();
|
||||
void initialize(double betaStar=0.0);
|
||||
|
||||
void Predictor(Phase& phase, Switch& reduction,
|
||||
Parameter& param);
|
||||
void Centering();
|
||||
void MehrotraCorrector(Phase& phase, StepLength& alpha,
|
||||
Solutions& currentPt,
|
||||
AverageComplementarity& mu,
|
||||
Parameter& param);
|
||||
void display(FILE* fpout = stdout);
|
||||
};
|
||||
|
||||
class Switch
|
||||
{
|
||||
public:
|
||||
enum SwitchType {CENTERING,AFFINE}; // {ON,OFF}
|
||||
SwitchType switchType;
|
||||
|
||||
Switch(SwitchType switchType=CENTERING);
|
||||
~Switch();
|
||||
void initialize(SwitchType switchType=CENTERING);
|
||||
|
||||
void MehrotraPredictor(Phase& phase);
|
||||
void display(FILE* fpout = stdout);
|
||||
|
||||
};
|
||||
|
||||
class AverageComplementarity
|
||||
{
|
||||
public:
|
||||
double initial;
|
||||
double current;
|
||||
AverageComplementarity(double lambdaStar = 0.0);
|
||||
~AverageComplementarity();
|
||||
void initialize(double lambdaStar = 0.0);
|
||||
void update(Solutions& currentPt);
|
||||
void display(FILE* fpout = stdout);
|
||||
};
|
||||
|
||||
class RatioInitResCurrentRes
|
||||
{
|
||||
public:
|
||||
double primal;
|
||||
double dual;
|
||||
|
||||
RatioInitResCurrentRes();
|
||||
~RatioInitResCurrentRes();
|
||||
|
||||
void initialize(Parameter& param, Residuals& currentRes);
|
||||
|
||||
void update(Switch& reduction, StepLength& alpha);
|
||||
void update_exact(Residuals& currentRes, Parameter& param);
|
||||
void display(FILE* fpout = stdout);
|
||||
};
|
||||
|
||||
class SolveInfo
|
||||
{
|
||||
public:
|
||||
enum phaseType { noINFO,pFEAS,dFEAS,pdFEAS,pdINF,pFEAS_dINF,
|
||||
pINF_dFEAS,pdOPT,pUNBD,dUNBD};
|
||||
|
||||
double rho;
|
||||
double etaPrimal;
|
||||
double etaDual;
|
||||
double objValPrimal;
|
||||
double objValDual;
|
||||
|
||||
SolveInfo();
|
||||
SolveInfo(InputData& inputData, Solutions& currentPt,
|
||||
double mu0, double omegaStar);
|
||||
~SolveInfo();
|
||||
|
||||
void initialize(InputData& inputData, Solutions& currentPt,
|
||||
double mu0, double omegaStar);
|
||||
|
||||
void update(InputData& inputData,
|
||||
Solutions& currentPt,
|
||||
Residuals& currentRes,
|
||||
AverageComplementarity& mu,
|
||||
RatioInitResCurrentRes& theta,
|
||||
Parameter& param);
|
||||
// check mu, gap, feasibility 2007/09/13
|
||||
void check(InputData& inputData,
|
||||
Solutions& currentPt,
|
||||
Residuals& currentRes,
|
||||
AverageComplementarity& mu,
|
||||
RatioInitResCurrentRes& theta,
|
||||
Parameter& param);
|
||||
void display(FILE* fpout = stdout);
|
||||
};
|
||||
|
||||
class Phase
|
||||
{
|
||||
public:
|
||||
int nDim;
|
||||
SolveInfo::phaseType value;
|
||||
|
||||
Phase();
|
||||
~Phase();
|
||||
|
||||
bool initialize(Residuals& currentRes,
|
||||
SolveInfo& solveInfo,
|
||||
Parameter& param, int nDim);
|
||||
bool updateCheck(Residuals& currentRes,
|
||||
SolveInfo& solveInfo,
|
||||
Parameter& param);
|
||||
void reverse();
|
||||
void display(FILE* fpout = stdout);
|
||||
};
|
||||
|
||||
} // end of namespace 'sdpa'
|
||||
|
||||
#endif // __sdpa_parts_h__
|
||||
Vendored
+45
@@ -0,0 +1,45 @@
|
||||
/* -------------------------------------------------------------
|
||||
|
||||
This file is a component of SDPA
|
||||
Copyright (C) 2004-2013 SDPA Project
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
------------------------------------------------------------- */
|
||||
/*--------------------------------------------------
|
||||
sdpa_right.h
|
||||
--------------------------------------------------*/
|
||||
|
||||
#ifndef __sdpa_right_h__
|
||||
#define __sdpa_right_h__
|
||||
|
||||
/*------------------------------------------
|
||||
Version Code Name
|
||||
|
||||
SDPA 6 : Rosemary/2003Aug
|
||||
SDPA 7 : Margaret/2008Feb
|
||||
|
||||
------------------------------------------*/
|
||||
|
||||
static const char sdpa_right[] =
|
||||
"SDPA7 (Margaret/since 2008Feb) has been developed by SDPA Project.";
|
||||
#ifdef VERSION
|
||||
// VERSION is set by configure script
|
||||
static const char sdpa_version[] = VERSION;
|
||||
#else
|
||||
// static const char sdpa_version[] = "7";
|
||||
#endif
|
||||
|
||||
#endif // __sdpa_right_h__
|
||||
Vendored
+259
@@ -0,0 +1,259 @@
|
||||
/* -------------------------------------------------------------
|
||||
|
||||
This file is a component of SDPA
|
||||
Copyright (C) 2004-2013 SDPA Project
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
------------------------------------------------------------- */
|
||||
/*--------------------------------------------------
|
||||
sdpa_solve.cpp
|
||||
--------------------------------------------------*/
|
||||
|
||||
#include "sdpa_call.h"
|
||||
#include "sdpa_linear.h"
|
||||
#include "sdpa_io.h"
|
||||
using namespace sdpa;
|
||||
|
||||
void SDPA::initializeSolve()
|
||||
{
|
||||
TimeStart(FILE_CHANGE_START1);
|
||||
TimeEnd(FILE_CHANGE_END1);
|
||||
com.FileChange += TimeCal(FILE_CHANGE_START1,
|
||||
FILE_CHANGE_END1);
|
||||
com.TotalTime += TimeCal(FILE_CHANGE_START1,
|
||||
FILE_CHANGE_END1);
|
||||
inputData.initialize_index();
|
||||
// rMessage("inputData = "); inputData.display();
|
||||
currentPt.initialize(m, bs);
|
||||
currentPt.makeCliques(bs, inputData);
|
||||
// rMessage("order = "); currentPt.order.display();
|
||||
currentPt.order.displayStatistics(Display, currentPt.cholmodSpace);
|
||||
currentPt.order.displayStatistics(fpout, currentPt.cholmodSpace);
|
||||
currentPt.setInitialPoint(bs, param.lambdaStar);
|
||||
inputData.assignAgg(currentPt.cholmodSpace);
|
||||
inputData.assignBlockIndex(currentPt.order);
|
||||
currentPt.cholmodSpace.assignBlockIndex(currentPt.order);
|
||||
// rMessage("currentPt.initial = "); currentPt.display();
|
||||
newton.initialize(m,bs);
|
||||
int nBlock2 = bs.SDP_nBlock + bs.LP_nBlock;
|
||||
chordal.initialize(&newton.sparse_bMat);
|
||||
chordal.ordering_bMat(m, nBlock2, inputData, Display, fpout);
|
||||
newton.initialize_bMat(m, chordal, inputData, Display, fpout);
|
||||
|
||||
mu.initialize(param.lambdaStar);
|
||||
TimeStart(UPDATE_START);
|
||||
currentPt.cholmodSpace.computeResiduals(inputData, currentPt.order);
|
||||
TimeEnd(UPDATE_END);
|
||||
com.updateRes += TimeCal(UPDATE_START,UPDATE_END);
|
||||
// currentPt.cholmodSpace.display();
|
||||
// inputData.display();
|
||||
currentRes.initialize();
|
||||
currentRes.update(currentPt.cholmodSpace);
|
||||
currentRes.copyToInit();
|
||||
// rMessage("currentRes = "); currentRes.display();
|
||||
beta.initialize(param.betaStar);
|
||||
theta.initialize(param, currentRes);
|
||||
solveInfo.initialize(inputData, currentPt, mu.initial,
|
||||
param.omegaStar);
|
||||
phase.initialize(currentRes, solveInfo, param, currentPt.nDim);
|
||||
// writeInputSparse((char*)"tmp.dat-s",(char*)"%+8.3e");
|
||||
}
|
||||
|
||||
void SDPA::solve()
|
||||
{
|
||||
pIteration = 0;
|
||||
TimeStart(MAIN_LOOP_START1);
|
||||
IO::printHeader(fpout,Display);
|
||||
while (phase.updateCheck(currentRes, solveInfo, param)
|
||||
&& pIteration < param.maxIteration) {
|
||||
// Mehrotra's Predictor
|
||||
TimeEnd(THIS_ITERATION_TIME);
|
||||
#if 0
|
||||
rMessage("++ " << pIteration << " turn ++ with "
|
||||
<< TimeCal(MAIN_LOOP_START1, THIS_ITERATION_TIME)
|
||||
<< " seconds in main loop");
|
||||
#endif
|
||||
|
||||
TimeStart(MEHROTRA_PREDICTOR_START1);
|
||||
// set variable of Mehrotra
|
||||
reduction.MehrotraPredictor(phase);
|
||||
beta.Predictor(phase, reduction, param);
|
||||
// rMessage("reduction = "); reduction.display();
|
||||
// rMessage("phase = "); phase.display();
|
||||
// rMessage("beta.predictor.value = " << beta.value);
|
||||
// rMessage(" mu = " << mu.current);
|
||||
// rMessage("currentPt = "); currentPt.display();
|
||||
// rMessage("currentRes = "); currentRes.display();
|
||||
// inputData.display();
|
||||
|
||||
bool isSuccessCholesky;
|
||||
isSuccessCholesky = newton.Mehrotra(Newton::PREDICTOR,
|
||||
m, inputData, chordal,
|
||||
currentPt, currentRes,
|
||||
mu, beta, reduction,
|
||||
phase, com,
|
||||
Display, fpout);
|
||||
if (isSuccessCholesky == false) {
|
||||
break;
|
||||
}
|
||||
#if 0
|
||||
newton.checkDirection(m, inputData, currentPt, currentRes,
|
||||
mu, beta, reduction, phase, com, Display, fpout);
|
||||
#endif
|
||||
// rMessage("order = "); currentPt.order.display();
|
||||
// rMessage("currentPt.cholmodSpace = "); currentPt.cholmodSpace.display();
|
||||
|
||||
TimeEnd(MEHROTRA_PREDICTOR_END1);
|
||||
com.Predictor += TimeCal(MEHROTRA_PREDICTOR_START1,
|
||||
MEHROTRA_PREDICTOR_END1);
|
||||
|
||||
TimeStart(STEP_PRE_START1);
|
||||
|
||||
alpha.MehrotraPredictor(inputData, currentPt, phase, reduction,
|
||||
mu, theta, param, com);
|
||||
// rMessage("alpha predictor = "); alpha.display();
|
||||
|
||||
TimeStart(STEP_PRE_END1);
|
||||
com.StepPredictor += TimeCal(STEP_PRE_START1,STEP_PRE_END1);
|
||||
|
||||
// rMessage("alphaStar = " << param.alphaStar);
|
||||
IO::printOneIteration(pIteration, mu, theta, solveInfo,
|
||||
alpha, beta, fpout, Display);
|
||||
|
||||
if (currentPt.update(alpha,com)==false) {
|
||||
// if step length is too short,
|
||||
// we finish algorithm
|
||||
rMessage("cannot move");
|
||||
pIteration++;
|
||||
break;
|
||||
}
|
||||
// rMessage("currentPt = ");
|
||||
// currentPt.display();
|
||||
|
||||
// rMessage("updated");
|
||||
const double old_mu = mu.current;
|
||||
theta.update(reduction,alpha);
|
||||
// rMessage("theta = "); theta.display();
|
||||
// rMessage("Before mu update");
|
||||
mu.update(currentPt);
|
||||
// rMessage("mu = "); mu.display();
|
||||
currentPt.cholmodSpace.computeResiduals(inputData, currentPt.order);
|
||||
currentRes.update(currentPt.cholmodSpace);
|
||||
// rMessage("currentPt = "); currentPt.display();
|
||||
theta.update_exact(currentRes, param);
|
||||
// rMessage("theta.exact = "); theta.display();
|
||||
solveInfo.update(inputData, currentPt, currentRes, mu, theta, param);
|
||||
|
||||
// printDimacsEasy();
|
||||
pIteration++;
|
||||
// rMessage("currentPt = "); currentPt.display();
|
||||
// rMessage("No Centering"); continue;
|
||||
// Centering
|
||||
if ((alpha.primal < 0.3)
|
||||
||(alpha.dual < 0.3)
|
||||
||((phase.value == SolveInfo::pdFEAS)
|
||||
&&(old_mu * 0.5 < mu.current))) {
|
||||
|
||||
TimeStart(CORRECTOR_START1);
|
||||
reduction.MehrotraPredictor(phase);
|
||||
#if 1
|
||||
beta.Centering();
|
||||
#else
|
||||
beta.MehrotraCorrector(phase, alpha, currentPt, mu, param);
|
||||
rMessage("beta = "); beta.display();
|
||||
#endif
|
||||
isSuccessCholesky = newton.Mehrotra(Newton::PREDICTOR,
|
||||
m, inputData, chordal,
|
||||
currentPt, currentRes,
|
||||
mu, beta, reduction,
|
||||
phase, com,
|
||||
Display, fpout);
|
||||
if (isSuccessCholesky == false) {
|
||||
break;
|
||||
}
|
||||
TimeEnd(CORRECTOR_END1);
|
||||
com.Corrector += TimeCal(CORRECTOR_START1, CORRECTOR_END1);
|
||||
TimeStart(CORRECTOR_STEP_START1);
|
||||
#if 0
|
||||
newton.checkDirection(m, inputData, currentPt, currentRes,
|
||||
mu, beta, reduction, phase, com, Display, fpout);
|
||||
#endif
|
||||
alpha.Centering(currentPt, param, com);
|
||||
TimeEnd(CORRECTOR_STEP_END1);
|
||||
com.StepCorrector += TimeCal(CORRECTOR_STEP_START1,
|
||||
CORRECTOR_STEP_END1);
|
||||
|
||||
IO::printOneIteration(pIteration, mu, theta, solveInfo,
|
||||
alpha, beta, fpout, Display);
|
||||
|
||||
if (currentPt.update(alpha,com)==false) {
|
||||
// if step length is too short,
|
||||
// we finish algorithm
|
||||
rMessage("cannot move");
|
||||
pIteration++;
|
||||
break;
|
||||
}
|
||||
|
||||
theta.update(reduction,alpha);
|
||||
mu.update(currentPt);
|
||||
currentPt.cholmodSpace.computeResiduals(inputData, currentPt.order);
|
||||
currentRes.update(currentPt.cholmodSpace);
|
||||
theta.update_exact(currentRes, param);
|
||||
solveInfo.update(inputData, currentPt, currentRes, mu, theta, param);
|
||||
// printDimacsEasy();
|
||||
pIteration++;
|
||||
}
|
||||
} // end of MAIN_LOOP
|
||||
|
||||
if (pIteration == param.maxIteration) {
|
||||
rMessage("maxIteration is reached");
|
||||
}
|
||||
TimeEnd(MAIN_LOOP_END1);
|
||||
|
||||
com.MainLoop = TimeCal(MAIN_LOOP_START1,
|
||||
MAIN_LOOP_END1);
|
||||
com.TotalTime += com.MainLoop;
|
||||
currentRes.update(currentPt.cholmodSpace);
|
||||
#if REVERSE_PRIMAL_DUAL
|
||||
Lal::let(currentPt.cholmodSpace.yVec,
|
||||
'=',currentPt.cholmodSpace.yVec,'*',&DMONE);
|
||||
phase.reverse();
|
||||
#endif
|
||||
IO::printLastInfo(pIteration, mu, theta, solveInfo, alpha, beta,
|
||||
currentRes, phase, currentPt,
|
||||
inputData, com.TotalTime, com,
|
||||
param, fpout, Display);
|
||||
bool Xmake = IO::judgeXmake(param);
|
||||
bool Zmake = IO::judgeZmake(param);
|
||||
currentPt.makeFinalSolution(Xmake, Zmake, bs);
|
||||
IO::printSolution(bs, currentPt, param, fpout, Xmake, Zmake);
|
||||
// com.display(fpout);
|
||||
|
||||
if (Display) {
|
||||
fprintf(Display, " main loop time = %.6f\n",com.MainLoop);
|
||||
fprintf(Display, " total time = %.6f\n",com.TotalTime);
|
||||
fprintf(Display, "file check time = %.6f\n",com.FileCheck);
|
||||
fprintf(Display, "file change time = %.6f\n",com.FileChange);
|
||||
fprintf(Display, "file read time = %.6f\n",com.FileRead);
|
||||
}
|
||||
if (fpout) {
|
||||
fprintf(fpout, " main loop time = %.6f\n",com.MainLoop);
|
||||
fprintf(fpout, " total time = %.6f\n",com.TotalTime);
|
||||
fprintf(fpout, " file check time = %.6f\n",com.FileCheck);
|
||||
fprintf(fpout, " file change time = %.6f\n",com.FileChange);
|
||||
fprintf(fpout, " file read time = %.6f\n",com.FileRead);
|
||||
}
|
||||
}
|
||||
Vendored
+3642
File diff suppressed because it is too large
Load Diff
Vendored
+574
@@ -0,0 +1,574 @@
|
||||
/* -------------------------------------------------------------
|
||||
|
||||
This file is a component of SDPA
|
||||
Copyright (C) 2004-2013 SDPA Project
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
------------------------------------------------------------- */
|
||||
|
||||
// printing presicion of vectors and matrices
|
||||
#define P_FORMAT ((char*)"%+8.3e")
|
||||
#define NO_P_FORMAT "NOPRINT"
|
||||
|
||||
|
||||
#ifndef __sdpa_struct_h__
|
||||
#define __sdpa_struct_h__
|
||||
|
||||
#include "sdpa_include.h"
|
||||
#include "sdpa_block.h"
|
||||
|
||||
#include <cholmod.h>
|
||||
|
||||
#define DATA_CAPSULE 1
|
||||
// DATA_CAPSULE 0 : Three Arrays (row,column,sp_ele)
|
||||
// DATA_CAPSULE 1 : Capsuled data storage
|
||||
|
||||
namespace sdpa {
|
||||
|
||||
class CholmodMatrix;
|
||||
class CholmodSpace;
|
||||
class OrderingMatrix;
|
||||
class OrderingSpace;
|
||||
|
||||
|
||||
class Vector
|
||||
{
|
||||
public:
|
||||
int nDim;
|
||||
double* ele;
|
||||
|
||||
Vector();
|
||||
Vector(int nDim, double value = 0.0);
|
||||
~Vector();
|
||||
|
||||
void initialize();
|
||||
void initialize(int nDim, double value = 0.0);
|
||||
void initialize(double value);
|
||||
void finalize();
|
||||
|
||||
void setZero();
|
||||
void display(FILE* fpout = stdout, char* printFormat = P_FORMAT);
|
||||
void display(FILE* fpout,double scalar, char* printFormat = P_FORMAT);
|
||||
bool copyFrom(Vector& other);
|
||||
};
|
||||
|
||||
class BlockVector
|
||||
{
|
||||
public:
|
||||
int nBlock;
|
||||
int* blockStruct;
|
||||
|
||||
Vector* ele;
|
||||
|
||||
BlockVector();
|
||||
BlockVector(BlockStruct& bs, double value = 0.0);
|
||||
BlockVector(int nBlock, int* blockStruct, double value = 0.0);
|
||||
~BlockVector();
|
||||
|
||||
void initialize(BlockStruct& bs, double value = 0.0);
|
||||
void initialize(int nBlock, int* blockStruct, double value = 0.0);
|
||||
void initialize(double value);
|
||||
void finalize();
|
||||
|
||||
void setZero();
|
||||
void display(FILE* fpout = stdout, char* printFormat = P_FORMAT);
|
||||
bool copyFrom(BlockVector& other);
|
||||
};
|
||||
|
||||
class SparseMatrix
|
||||
{
|
||||
public:
|
||||
int nRow, nCol;
|
||||
|
||||
enum Type { SPARSE, DENSE};
|
||||
Type type;
|
||||
|
||||
int NonZeroNumber;
|
||||
// for memory
|
||||
int NonZeroCount;
|
||||
// currentry stored
|
||||
int NonZeroEffect;
|
||||
// use for calculation of F1,F2,F3
|
||||
|
||||
// for Dense
|
||||
double* de_ele;
|
||||
|
||||
// for Sparse ; 0:sparse 1:dense
|
||||
enum dsType {DSarrays, DScapsule};
|
||||
dsType DataStruct;
|
||||
|
||||
// for Sparse Data1 // dsArrays
|
||||
int* row_index;
|
||||
int* column_index;
|
||||
double* sp_ele;
|
||||
|
||||
// for Sparse Data2 // dsCapsule
|
||||
typedef struct{
|
||||
int vRow;
|
||||
int vCol;
|
||||
double vEle;
|
||||
} SparseElement __attribute__( (aligned (16)));
|
||||
|
||||
SparseElement* DataS;
|
||||
|
||||
SparseMatrix();
|
||||
SparseMatrix(int nRow,int nCol, Type type, int NonZeroNumber);
|
||||
~SparseMatrix();
|
||||
|
||||
#if DATA_CAPSULE
|
||||
void initialize(int nRow,int nCol, Type type, int NonZeroNumber,
|
||||
dsType DataStruct = DScapsule);
|
||||
#else
|
||||
void initialize(int nRow,int nCol, Type type, int NonZeroNumber,
|
||||
dsType DataStruct = DSarrays);
|
||||
#endif
|
||||
void finalize();
|
||||
|
||||
void display(FILE* fpout = stdout, char* printFormat = P_FORMAT);
|
||||
bool copyFrom(SparseMatrix& other);
|
||||
|
||||
void changeToDense(bool forceChange = false);
|
||||
void setZero();
|
||||
void setIdentity(double scalar = 1.0);
|
||||
|
||||
bool sortSparseIndex(int&i, int& j);
|
||||
};
|
||||
|
||||
class DenseMatrix
|
||||
{
|
||||
public:
|
||||
int nRow, nCol;
|
||||
|
||||
double* de_ele;
|
||||
|
||||
DenseMatrix();
|
||||
~DenseMatrix();
|
||||
|
||||
void initialize();
|
||||
void initialize(int nRow,int nCol);
|
||||
void finalize();
|
||||
|
||||
void display(FILE* fpout = stdout, char* printFormat = P_FORMAT);
|
||||
bool copyFrom(DenseMatrix& other);
|
||||
bool copyFrom(SparseMatrix& other);
|
||||
|
||||
void setZero();
|
||||
void setIdentity(double scalar = 1.0);
|
||||
};
|
||||
|
||||
class SparseLinearSpace
|
||||
{
|
||||
public:
|
||||
int SDP_sp_nBlock;
|
||||
int SOCP_sp_nBlock;
|
||||
int LP_sp_nBlock;
|
||||
|
||||
int* SDP_sp_index;
|
||||
int* SOCP_sp_index;
|
||||
int* LP_sp_index;
|
||||
|
||||
SparseMatrix* SDP_sp_block;
|
||||
SparseMatrix* SOCP_sp_block;
|
||||
double* LP_sp_block;
|
||||
|
||||
SparseLinearSpace();
|
||||
SparseLinearSpace(int SDP_nBlock, int* SDP_blockStruct,
|
||||
int* SDP_NonZeroNumber,
|
||||
int SOCP_nBlock, int* SOCP_blockStruct,
|
||||
int* SOCP_NonZeroNumber,
|
||||
int LP_nBlock, bool* LP_NonZeroNumber);
|
||||
SparseLinearSpace(int SDP_sp_nBlock,
|
||||
int* SDP_sp_index,
|
||||
int* SDP_sp_blockStruct,
|
||||
int* SDP_sp_NonZeroNumber,
|
||||
int SOCP_sp_nBlock,
|
||||
int* SOCP_sp_index,
|
||||
int* SOCP_sp_blockStruct,
|
||||
int* SOCP_sp_NonZeroNumber,
|
||||
int LP_sp_nBlock,
|
||||
int* LP_sp_index);
|
||||
~SparseLinearSpace();
|
||||
|
||||
// dense form of block index
|
||||
void initialize(int SDP_nBlock, int* SDP_blockStruct,
|
||||
int* SDP_NonZeroNumber,
|
||||
int SOCP_nBlock, int* SOCP_blockStruct,
|
||||
int* SOCP_NonZeroNumber,
|
||||
int LP_nBlock, bool* LP_NonZeroNumber);
|
||||
// sparse form of block index 2008/02/27 kazuhide nakata
|
||||
void initialize(int SDP_sp_nBlock,
|
||||
int* SDP_sp_index,
|
||||
int* SDP_sp_blockStruct,
|
||||
int* SDP_sp_NonZeroNumber,
|
||||
int SOCP_sp_nBlock,
|
||||
int* SOCP_sp_index,
|
||||
int* SOCP_sp_blockStruct,
|
||||
int* SOCP_sp_NonZeroNumber,
|
||||
int LP_sp_nBlock,
|
||||
int* LP_sp_index);
|
||||
void finalize();
|
||||
|
||||
void changeToDense(bool forceChange=false);
|
||||
void display(FILE* fpout = stdout, char* printFormat = P_FORMAT);
|
||||
bool copyFrom(SparseLinearSpace& other);
|
||||
|
||||
void setElement_SDP(int block, int nCol, int nRow, double ele);
|
||||
void setElement_SOCP(int block, int nCol, int nRow, double ele);
|
||||
void setElement_LP(int block, double ele);
|
||||
|
||||
void setZero();
|
||||
void setIdentity(double scalar = 1.0);
|
||||
// no check
|
||||
bool sortSparseIndex(int&l , int& i, int& j);
|
||||
};
|
||||
|
||||
class DenseLinearSpace
|
||||
{
|
||||
public:
|
||||
int SDP_nBlock;
|
||||
int LP_nBlock;
|
||||
|
||||
DenseMatrix* SDP_block;
|
||||
double* LP_block;
|
||||
|
||||
DenseLinearSpace();
|
||||
DenseLinearSpace(BlockStruct& bs);
|
||||
~DenseLinearSpace();
|
||||
void initialize(BlockStruct& bs);
|
||||
void finalize();
|
||||
|
||||
void display(FILE* fpout = stdout, char* printFormat = P_FORMAT);
|
||||
void displaySolution(BlockStruct& bs, FILE* fpout = stdout,
|
||||
char* printFormat = P_FORMAT);
|
||||
bool copyFrom(DenseLinearSpace& other);
|
||||
void setElement_SDP(int block, int nCol, int nRow, double ele);
|
||||
void setElement_SOCP(int block, int nCol, int nRow, double ele);
|
||||
void setElement_LP(int block, double ele);
|
||||
void setZero();
|
||||
void setIdentity(double scalar = 1.0);
|
||||
};
|
||||
|
||||
// Input Matrix A_k for Compleition
|
||||
// Column-Compressed structure
|
||||
class CompMatrix
|
||||
{
|
||||
public:
|
||||
int nRow;
|
||||
int nCol;
|
||||
int nzColumn; // nunmber of non-zero columns
|
||||
int effectiveNzColumn; // nunmber of non-zero LOWER columns
|
||||
int* column_index; // index of non-zero columns [length:nzColumn]
|
||||
int NNZ; // number of non-zero
|
||||
int lowerNNZ; // number of non-zero in lower triangular matrix
|
||||
int* column_start; // starting point of each non-zero columns
|
||||
// [length:nzColumn+1]
|
||||
// the last one should be NNZ
|
||||
int* row_index; // row-index of each element [length:NNZ]
|
||||
double* ele; // value of each element [length:NNZ]
|
||||
int* diag_index; // diagonal point of each non-zero columns
|
||||
// [length:nzColumn]
|
||||
// if diagonal is empty, diag_index[j] = -1;
|
||||
int* agg_index; // aggregate index [length: NNZ]
|
||||
|
||||
// This element corresponds to X.ele[blockNumber].de_ele[blockIndex]
|
||||
int* blockNumber;
|
||||
int* blockIndex;
|
||||
|
||||
int nzColumn_diag; // number of LOWER non-zero columns with diagonal elements
|
||||
int* column_diag_index;
|
||||
int nzColumn_nondiag; // number of LOWER non-zero columns WITHOUT diagonal elements
|
||||
int* column_nondiag_index;
|
||||
|
||||
|
||||
class inputIJV
|
||||
{
|
||||
public:
|
||||
int i;
|
||||
int j;
|
||||
double v;
|
||||
};
|
||||
vector<CompMatrix::inputIJV*>* inputVector;
|
||||
// inputVector is the vector
|
||||
// After makeInternalStructure(), this vector will be released
|
||||
|
||||
void display(FILE* fpout = stdout, char* printFormat = P_FORMAT);
|
||||
void initialize();
|
||||
CompMatrix();
|
||||
void finalize();
|
||||
~CompMatrix();
|
||||
|
||||
void initializeInputVector();
|
||||
void setElement(int i, int j, double v);
|
||||
static bool compareIJV(inputIJV* a, inputIJV* b);
|
||||
void sortInputVector();
|
||||
void makeInternalStructure();
|
||||
void checkInputDataStructure(int& i, int& j, double& v1, double& v2);
|
||||
|
||||
void assignAgg(CholmodMatrix& cholmodMatrix);
|
||||
// Aggregate contains only lower triangular
|
||||
|
||||
void assignBlockIndex(OrderingMatrix& order);
|
||||
};
|
||||
|
||||
// diagonal block structure of CompMatrix
|
||||
class CompSpace
|
||||
{
|
||||
public:
|
||||
|
||||
int LP_sp_nBlock;
|
||||
int SDP_sp_nBlock;
|
||||
int* LP_sp_index;
|
||||
int* SDP_sp_index;
|
||||
|
||||
double* LP_sp_block;
|
||||
CompMatrix* SDP_sp_block;
|
||||
|
||||
int NNZ;
|
||||
int lowerNNZ;
|
||||
|
||||
// LP_agg_index is not neccesarry, because LP_sp_index does the same thing
|
||||
|
||||
CompSpace();
|
||||
~CompSpace();
|
||||
void initialize();
|
||||
void initialize(int LP_sp_nBlock, int SDP_sp_nBlock);
|
||||
void finalize();
|
||||
|
||||
void display(FILE* fpout = stdout, char* printFormat = P_FORMAT);
|
||||
|
||||
void initializeInputVector();
|
||||
void setElement_LP(int i, double v);
|
||||
void setElement_SDP(int l, int i, int j, double v);
|
||||
|
||||
void sortInputVector();
|
||||
void makeInternalStructure();
|
||||
void checkInputDataStructure(int& l, int& i, int& j, double& v1, double& v2);
|
||||
void assignAgg(CholmodSpace& cholModSpace);
|
||||
void assignBlockIndex(OrderingSpace& order);
|
||||
};
|
||||
|
||||
// CliqueMatrix should be diagonal block of fully-dense matrix
|
||||
// LP block is handled separately by CliqueSpace
|
||||
class CliqueMatrix
|
||||
{
|
||||
public:
|
||||
int nBlock;
|
||||
int* blockStruct;
|
||||
DenseMatrix* ele;
|
||||
|
||||
CliqueMatrix();
|
||||
~CliqueMatrix();
|
||||
void initialize();
|
||||
void initialize(int nBlock, int* blockStruct);
|
||||
void finalize();
|
||||
void display(FILE* fpout = stdout, char* printFormat = P_FORMAT);
|
||||
void setZero();
|
||||
void setIdentity(double scalar = 1.0);
|
||||
};
|
||||
// diagonal block structure of CliqueMatrix
|
||||
class CliqueSpace
|
||||
{
|
||||
public:
|
||||
int LP_nBlock;
|
||||
double* LP_block;
|
||||
int SDP_nBlock;
|
||||
CliqueMatrix* SDP_block; // each block is decomposed into multiple matrices
|
||||
|
||||
CliqueSpace();
|
||||
~CliqueSpace();
|
||||
void initialize();
|
||||
void initialize(BlockStruct& bs, OrderingSpace& order);
|
||||
void finalize();
|
||||
void display(FILE* fpout = stdout, char* printFormat = P_FORMAT);
|
||||
void setZero();
|
||||
void setIdentity(double scalar = 1.0);
|
||||
};
|
||||
|
||||
class OrderingMatrix
|
||||
{
|
||||
public:
|
||||
int nClique;
|
||||
int* cliqueSize; //length nCliques
|
||||
// arrays of nCliques, i-th array has cliqueSize[i] length
|
||||
int** cliqueIndex;
|
||||
|
||||
int nDim;
|
||||
int* Perm;
|
||||
int* ReversePerm;
|
||||
|
||||
// dXt means dX~tilde
|
||||
// This matrix is nonsymemetric and [dX~]_{*k}
|
||||
// is usually computed.
|
||||
// By copying nonzero elements of [dX~]_{*k} to a clique structure,
|
||||
// its efficiency will be enhanced.
|
||||
// Details::
|
||||
// The dXtildeIndex-th element of [dX~]_{*k} will be mapped to
|
||||
// cliqueMatrix{dXtilde[k][dXtClique]}(dXtBlock);
|
||||
// dXtBlock is the index of the corresponding block inside.
|
||||
int* dXtNonzeros; // size of nDim
|
||||
int** dXtIndex; // size of nDim*dXtNonzeros
|
||||
int** dXtClique; // size of nDim*dXtNonzeros
|
||||
int** dXtBlock; // size of nDim*dXtNonzeros
|
||||
|
||||
// tmporary class for making dXtNonzers, etc.
|
||||
class ISB {
|
||||
public:
|
||||
int i;
|
||||
int s;
|
||||
int b; // blockIndex
|
||||
};
|
||||
|
||||
static bool compareISB(ISB* a, ISB* b);
|
||||
|
||||
OrderingMatrix();
|
||||
~OrderingMatrix();
|
||||
void initialize();
|
||||
void initialize(int nDim);
|
||||
void finalize();
|
||||
|
||||
// A[i,j] * X[i,j] means A[i,j] * X.ele[blockNumber].ele[blockIndex]
|
||||
void getIndex(int i, int j, int& blockNumber, int& blockIndex);
|
||||
void extractCliques(CholmodMatrix& C);
|
||||
void displayDxIndex(FILE* fpout = stdout, char* printFormat = P_FORMAT);
|
||||
void display(FILE* fpout = stdout, char* printFormat = P_FORMAT);
|
||||
void displayStatistics(FILE* fpout, CholmodMatrix& cholmodMatrix);
|
||||
|
||||
};
|
||||
|
||||
class OrderingSpace
|
||||
{
|
||||
public:
|
||||
int SDP_nBlock;
|
||||
OrderingMatrix* SDP_block;
|
||||
OrderingSpace();
|
||||
~OrderingSpace();
|
||||
void initialize();
|
||||
void initialize(int SDP_nBlock, int* SDP_blockStruct);
|
||||
void finalize();
|
||||
void displayDxIndex(FILE* fpout = stdout, char* printFormat = P_FORMAT);
|
||||
void display(FILE* fpout = stdout, char* printFormat = P_FORMAT);
|
||||
void displayStatistics(FILE* fpout, CholmodSpace& cholmodSpace);
|
||||
void extractCliques(CholmodSpace& C);
|
||||
|
||||
};
|
||||
|
||||
class CholmodMatrix
|
||||
{
|
||||
public:
|
||||
int nDim;
|
||||
cholmod_sparse* Z;
|
||||
cholmod_factor* Lz;
|
||||
cholmod_factor* Lx;
|
||||
cholmod_sparse* dZ;
|
||||
cholmod_sparse* rD;
|
||||
CliqueMatrix clique_xMat;
|
||||
CliqueMatrix clique_dX;
|
||||
CliqueMatrix clique_choleskyX;
|
||||
CliqueMatrix clique_invCholeskyX;
|
||||
|
||||
cholmod_dense* x_x; // solution of cholmod_solve
|
||||
cholmod_dense* x_z; // solution of cholmod_solve
|
||||
cholmod_dense* b_x; // right-hand-side of cholmod_solve
|
||||
cholmod_dense* b_z; // right-hand-side of cholmod_solve
|
||||
|
||||
cholmod_common common;
|
||||
int NNZ_Z;
|
||||
int NNZ_L;
|
||||
int* Z_blockNumber;
|
||||
int* Z_blockIndex;
|
||||
|
||||
CholmodMatrix();
|
||||
~CholmodMatrix();
|
||||
void initialize();
|
||||
void finalize();
|
||||
|
||||
void display(FILE* fpout = stdout, char* printFormat = P_FORMAT);
|
||||
static void display_sparse(cholmod_sparse* A, FILE* fpout = stdout,
|
||||
char* printFormat = P_FORMAT);
|
||||
static void display_factor(cholmod_factor* L, FILE* fpout = stdout,
|
||||
char* printFormat = P_FORMAT);
|
||||
static void display_dense(cholmod_dense* X, FILE* fpout = stdout,
|
||||
char* printFormat = P_FORMAT);
|
||||
void analyze();
|
||||
void solveByZ(); // b should be set properly before solve.
|
||||
void solveByX(); // b should be set properly before solve.
|
||||
|
||||
void assignBlockIndex(OrderingMatrix& order);
|
||||
|
||||
static void setZero_sparse(cholmod_sparse* A);
|
||||
void setZzero();
|
||||
void setZIdentity(double scalar = 1.0);
|
||||
void setXIdentity(double scalar = 1.0);
|
||||
void setB_Zzero();
|
||||
void setB_Xzero();
|
||||
void setDxZero();
|
||||
void initializeClique(OrderingMatrix& order);
|
||||
|
||||
bool getCholesky(OrderingMatrix& order);
|
||||
};
|
||||
|
||||
class InputData;
|
||||
// diagonal block structure of cholmod_sparse & cholmod_factor
|
||||
// for Aggregate Matrix & Factorized Matrix
|
||||
class CholmodSpace
|
||||
{
|
||||
public:
|
||||
|
||||
int LP_nBlock;
|
||||
double* LP_Z;
|
||||
double* LP_invZ;
|
||||
double* LP_dZ;
|
||||
double* LP_X;
|
||||
double* LP_invX;
|
||||
double* LP_dX;
|
||||
int SDP_nBlock;
|
||||
CholmodMatrix* SDP_block;
|
||||
|
||||
Vector yVec;
|
||||
Vector dyVec;
|
||||
|
||||
Vector rp; // primal residual vector
|
||||
double* LP_rD; // dual residual vector
|
||||
|
||||
CholmodSpace();
|
||||
~CholmodSpace();
|
||||
void initialize();
|
||||
void initialize(int LP_nBlock, int SDP_nBlock);
|
||||
void finalize();
|
||||
|
||||
void makeAggregate(int m, int SDP_nBlock, int* SDP_blockStruct,
|
||||
CompSpace& C, CompSpace* A);
|
||||
void assignBlockIndex(OrderingSpace& order);
|
||||
void setZzero();
|
||||
void setZIdentity(double scalar = 1.0);
|
||||
void setXIdentity(double scalar = 1.0);
|
||||
void display(FILE* fpout = stdout, char* printFormat = P_FORMAT);
|
||||
void analyze();
|
||||
void initializeClique(int m, OrderingSpace& order);
|
||||
|
||||
void getInnerProductAX(double& ret,
|
||||
CompSpace& A, OrderingSpace& order);
|
||||
void getInnerProductAdX(double& ret,
|
||||
CompSpace& A, OrderingSpace& order);
|
||||
void computeResiduals(InputData& inputData, OrderingSpace& order);
|
||||
|
||||
bool getCholesky(OrderingSpace& order);
|
||||
|
||||
};
|
||||
|
||||
} // end of namespace 'sdpa'
|
||||
|
||||
#endif // __sdpa_struct_h__
|
||||
Vendored
+71
@@ -0,0 +1,71 @@
|
||||
/* -------------------------------------------------------------
|
||||
|
||||
This file is a component of SDPA
|
||||
Copyright (C) 2004-2013 SDPA Project
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
------------------------------------------------------------- */
|
||||
/*-----------------------------------------
|
||||
sdpa_tool.cpp
|
||||
-----------------------------------------*/
|
||||
|
||||
#include "sdpa_tool.h"
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#ifndef CLK_TCK
|
||||
#define CLK_TCK sysconf(_SC_CLK_TCK)
|
||||
#endif
|
||||
|
||||
namespace sdpa {
|
||||
|
||||
// These are constant.
|
||||
// Do Not Change .
|
||||
int IZERO = 0;
|
||||
int IONE = 1;
|
||||
int IMONE = -1;
|
||||
double DZERO = 0.0;
|
||||
double DONE = 1.0;
|
||||
double DMONE = -1.0;
|
||||
|
||||
double Time::rGetUseTime()
|
||||
{
|
||||
#if PROCESS_TIME
|
||||
struct tms TIME;
|
||||
times(&TIME);
|
||||
return (double)TIME.tms_utime/(double)CLK_TCK;
|
||||
#else
|
||||
return 0.0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void Time::rSetTimeVal(struct timeval& targetVal)
|
||||
{
|
||||
static struct timezone tz;
|
||||
gettimeofday(&targetVal,&tz);
|
||||
}
|
||||
|
||||
double Time::rGetRealTime(const struct timeval& start,
|
||||
const struct timeval& end)
|
||||
{
|
||||
const long int second = end.tv_sec - start.tv_sec;
|
||||
const long int usecond = end.tv_usec - start.tv_usec;
|
||||
return ((double)second) + ((double)usecond)*(1.0e-6);
|
||||
}
|
||||
|
||||
} // end of namespace 'sdpa'
|
||||
|
||||
Vendored
+147
@@ -0,0 +1,147 @@
|
||||
/* -------------------------------------------------------------
|
||||
|
||||
This file is a component of SDPA
|
||||
Copyright (C) 2004-2013 SDPA Project
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
------------------------------------------------------------- */
|
||||
/*--------------------------------------------------
|
||||
sdpa_tool.h
|
||||
--------------------------------------------------*/
|
||||
|
||||
#ifndef __sdpa_tool_h__
|
||||
#define __sdpa_tool_h__
|
||||
|
||||
#include "sdpa_right.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <sys/time.h>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
|
||||
|
||||
namespace sdpa {
|
||||
|
||||
// Note : only GNU has the macro __PRETTY_FUNCTION__
|
||||
#define USE_PRETTY_FUNCTION 0
|
||||
#if USE_PRETTY_FUNCTION
|
||||
#define rMessage(message) \
|
||||
{ cout << message << " :: line " << __LINE__ \
|
||||
<< " in " << __FILE__ \
|
||||
<< " [ " << __PRETTY_FUNCTION__ << " ] " << endl; }
|
||||
#elif 1
|
||||
#define rMessage(message) \
|
||||
{cout << message << " :: line " << __LINE__ \
|
||||
<< " in " << __FILE__ << endl; }
|
||||
#else
|
||||
#define rMessage(message) ;
|
||||
#endif
|
||||
|
||||
#if USE_PRETTY_FUNCTION
|
||||
#define rError(message) \
|
||||
{ cout << message << " :: line " << __LINE__ \
|
||||
<< " in " << __FILE__ \
|
||||
<< " [ " << __PRETTY_FUNCTION__ << " ] " << endl; \
|
||||
exit(false);}
|
||||
#else
|
||||
#define rError(message) \
|
||||
{cout << message << " :: line " << __LINE__ \
|
||||
<< " in " << __FILE__ << endl; \
|
||||
exit(false);}
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
#define NewArray(val,type,number) \
|
||||
{val = NULL; \
|
||||
try{ val = new type[number]; } \
|
||||
catch(bad_alloc){ \
|
||||
rMessage("Memory Exhausted (bad_alloc)"); abort(); } \
|
||||
catch(...){ \
|
||||
rMessage("Fatal Error (related memory allocation"); abort(); } \
|
||||
}
|
||||
#else
|
||||
#define NewArray(val,type,number) \
|
||||
{rMessage("New Invoked"); \
|
||||
val = NULL; val = new type[number]; \
|
||||
if (val==NULL) {rError("Over Memory");} \
|
||||
}
|
||||
#endif
|
||||
|
||||
#define DeleteArray(val) \
|
||||
{ if (val!=NULL) { \
|
||||
delete[] val; \
|
||||
val = NULL; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define REVERSE_PRIMAL_DUAL 1
|
||||
|
||||
|
||||
// These are constant. Do NOT change
|
||||
extern int IZERO ; // = 0;
|
||||
extern int IONE ; // = 1;
|
||||
extern int IMONE ; // = -1;
|
||||
extern double DZERO; // = 0.0;
|
||||
extern double DONE ; // = 1.0;
|
||||
extern double DMONE; // = -1.0;
|
||||
|
||||
class Time
|
||||
{
|
||||
public:
|
||||
static double rGetUseTime();
|
||||
static void rSetTimeVal(struct timeval & targetVal);
|
||||
static double rGetRealTime(const struct timeval & start,
|
||||
const struct timeval & end);
|
||||
};
|
||||
|
||||
#define PROCESS_TIME 0
|
||||
#if PROCESS_TIME // count time with process time
|
||||
#include <sys/times.h>
|
||||
#define TimeStart(START__) \
|
||||
static double START__; START__ = Time::rGetUseTime()
|
||||
#define TimeEnd(END__) \
|
||||
static double END__; END__ = Time::rGetUseTime()
|
||||
#define TimeCal(START__,END__) (END__ - START__)
|
||||
#else // count time with real time
|
||||
#define TimeStart(START__) \
|
||||
static struct timeval START__; Time::rSetTimeVal(START__)
|
||||
#define TimeEnd(END__) \
|
||||
static struct timeval END__; Time::rSetTimeVal(END__)
|
||||
#define TimeCal(START__,END__) Time::rGetRealTime(START__,END__)
|
||||
#endif
|
||||
|
||||
#define sdpa_dset(dset_length,dset_value,dset_pointer,dset_step) \
|
||||
for (int dset_i=0,dset_index = 0; dset_i<dset_length; ++dset_i) { \
|
||||
dset_pointer[dset_index] = dset_value; \
|
||||
dset_index += dset_step; \
|
||||
}
|
||||
|
||||
|
||||
#ifdef OPENBLAS
|
||||
extern "C" void openblas_set_num_threads(int num_threads);
|
||||
#define blas_set_num_threads(num_threads) \
|
||||
openblas_set_num_threads(num_threads);
|
||||
|
||||
#else
|
||||
// nothing is used
|
||||
#define blas_set_num_threads(num_threads) {};
|
||||
#endif
|
||||
|
||||
|
||||
} // end of namespace 'sdpa'
|
||||
|
||||
#endif // __sdpa_tool_h__
|
||||
@@ -0,0 +1,34 @@
|
||||
import Common;
|
||||
|
||||
struct DebugVertex
|
||||
{
|
||||
float3 position;
|
||||
float3 color;
|
||||
};
|
||||
|
||||
struct VertexStageOutput
|
||||
{
|
||||
float3 color : VERTEX_COLOR;
|
||||
float4 position : SV_Position;
|
||||
};
|
||||
|
||||
[shader("vertex")]
|
||||
VertexStageOutput vertexMain(
|
||||
DebugVertex input)
|
||||
{
|
||||
VertexStageOutput output;
|
||||
float4 viewpos = mul(gViewParams.viewMatrix, float4(input.position, 1.0f));
|
||||
output.position = mul(gViewParams.projectionMatrix, viewpos);
|
||||
output.color = input.color;
|
||||
return output;
|
||||
}
|
||||
|
||||
|
||||
[shader("fragment")]
|
||||
float4 fragmentMain(
|
||||
float3 color : VERTEX_COLOR,
|
||||
float4 position : SV_Position
|
||||
) : SV_Target
|
||||
{
|
||||
return float4(color, 1.0f);
|
||||
}
|
||||
@@ -6,4 +6,12 @@ struct PrimitiveSceneData
|
||||
};
|
||||
|
||||
layout(set = INDEX_SCENE_DATA, binding = 0, std430)
|
||||
ConstantBuffer<PrimitiveSceneData> gSceneData;
|
||||
StructuredBuffer<PrimitiveSceneData> gSceneData;
|
||||
|
||||
[[vk::push_constant]]
|
||||
ConstantBuffer<uint> gSceneDataIndex;
|
||||
|
||||
PrimitiveSceneData getSceneData()
|
||||
{
|
||||
return gSceneData[gSceneDataIndex];
|
||||
}
|
||||
@@ -131,9 +131,10 @@ struct VertexShaderInput
|
||||
|
||||
float3 getWorldPosition()
|
||||
{
|
||||
float4x4 localToWorld = gSceneData.localToWorld;
|
||||
float4x4 localToWorld = getSceneData().localToWorld;
|
||||
float3 rotatedPosition = localToWorld[0].xyz * position.xxx + localToWorld[1].xyz * position.yyy + localToWorld[2].xyz * position.zzz;
|
||||
return rotatedPosition + localToWorld[3].xyz;
|
||||
return mul(getSceneData().localToWorld, position).xyz;
|
||||
//rotatedPosition + float3(localToWorld[0].w, localToWorld[1].w, localToWorld[2].w);
|
||||
}
|
||||
|
||||
VertexValueCache getVertexCache()
|
||||
@@ -152,9 +153,9 @@ struct VertexShaderInput
|
||||
cache.tangentToLocal[1] = tangentToLocal[1];
|
||||
cache.tangentToLocal[2] = tangentToLocal[2];
|
||||
|
||||
cache.tangentToWorld[0] = mul(gSceneData.localToWorld, float4(tangentToLocal[0], 0.0f)).xyz;
|
||||
cache.tangentToWorld[1] = mul(gSceneData.localToWorld, float4(tangentToLocal[1], 0.0f)).xyz;
|
||||
cache.tangentToWorld[2] = mul(gSceneData.localToWorld, float4(tangentToLocal[2], 0.0f)).xyz;
|
||||
cache.tangentToWorld[0] = mul(getSceneData().localToWorld, float4(tangentToLocal[0], 0.0f)).xyz;
|
||||
cache.tangentToWorld[1] = mul(getSceneData().localToWorld, float4(tangentToLocal[1], 0.0f)).xyz;
|
||||
cache.tangentToWorld[2] = mul(getSceneData().localToWorld, float4(tangentToLocal[2], 0.0f)).xyz;
|
||||
|
||||
return cache;
|
||||
}
|
||||
@@ -183,9 +184,9 @@ struct VertexShaderInput
|
||||
{
|
||||
ShaderAttributeInterpolation result = (ShaderAttributeInterpolation)0;
|
||||
float3x3 tangentToWorld = cache.getTangentToWorld();
|
||||
result.normal = mul(gSceneData.localToWorld, float4(normal, 0.0f)).xyz;
|
||||
result.tangent = mul(gSceneData.localToWorld, float4(tangent, 0.0f)).xyz;
|
||||
result.biTangent = mul(gSceneData.localToWorld, float4(biTangent, 0.0f)).xyz;
|
||||
result.normal = mul(getSceneData().localToWorld, float4(normal, 0.0f)).xyz;
|
||||
result.tangent = mul(getSceneData().localToWorld, float4(tangent, 0.0f)).xyz;
|
||||
result.biTangent = mul(getSceneData().localToWorld, float4(biTangent, 0.0f)).xyz;
|
||||
result.color = color;
|
||||
result.worldPosition = vertexParams.worldPosition;
|
||||
result.viewPosition = vertexParams.viewPosition;
|
||||
@@ -215,8 +216,9 @@ struct PositionOnlyVertexShaderInput
|
||||
#endif // USE_INSTANCING
|
||||
float3 getWorldPosition()
|
||||
{
|
||||
float4x4 localToWorld = gSceneData.localToWorld;
|
||||
float4x4 localToWorld = getSceneData().localToWorld;
|
||||
float3 rotatedPosition = localToWorld[0].xyz * position.xxx + localToWorld[1].xyz * position.yyy + localToWorld[2].xyz * position.zzz;
|
||||
return rotatedPosition + localToWorld[3].xyz;
|
||||
return mul(getSceneData().localToWorld, position).xyz;
|
||||
//rotatedPosition + float3(localToWorld[0].w, localToWorld[1].w, localToWorld[2].w);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -20,7 +20,7 @@ SceneView::SceneView(Gfx::PGraphics graphics, PWindow owner, const ViewportCreat
|
||||
LightCullingPass(graphics),
|
||||
BasePass(graphics)
|
||||
))
|
||||
, cameraSystem(createInfo.dimensions, Math::Vector(0, 0, 10))
|
||||
, cameraSystem(createInfo.dimensions, Vector(0, 0, 10))
|
||||
{
|
||||
AssetRegistry::importFile("C:\\Users\\Dynamitos\\TestSeeleProject\\Assets\\Ayaka\\Avatar_Girl_Sword_Ayaka_Tex_Body_Diffuse.png");
|
||||
AssetRegistry::importFile("C:\\Users\\Dynamitos\\TestSeeleProject\\Assets\\Ayaka\\Avatar_Girl_Sword_Ayaka_Tex_Body_Lightmap.png");
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
ViewportControl::ViewportControl(const Math::URect& viewportDimensions, Math::Vector initialPos)
|
||||
ViewportControl::ViewportControl(const URect& viewportDimensions, Vector initialPos)
|
||||
: position(initialPos)
|
||||
, fieldOfView(glm::radians(70.f))
|
||||
, aspectRatio(static_cast<float>(viewportDimensions.size.x) / viewportDimensions.size.y)
|
||||
@@ -25,9 +25,9 @@ void ViewportControl::update(Component::Camera& camera, float deltaTime)
|
||||
{
|
||||
cameraMove *= 4;
|
||||
}
|
||||
Math::Vector moveVector = Math::Vector();
|
||||
Math::Vector forward = glm::normalize(springArm);
|
||||
Math::Vector side = glm::cross(Math::Vector(0, 1, 0), forward);
|
||||
Vector moveVector = Vector();
|
||||
Vector forward = glm::normalize(springArm);
|
||||
Vector side = glm::cross(Vector(0, 1, 0), forward);
|
||||
if(keys[KeyCode::KEY_W])
|
||||
{
|
||||
moveVector += forward * cameraMove;
|
||||
@@ -64,11 +64,11 @@ void ViewportControl::update(Component::Camera& camera, float deltaTime)
|
||||
lastX = mouseX;
|
||||
lastY = mouseY;
|
||||
springArm = glm::normalize(
|
||||
Math::Vector(
|
||||
Vector(
|
||||
cos(yaw) * cos(pitch),
|
||||
sin(pitch),
|
||||
sin(yaw) * cos(pitch)));
|
||||
camera.viewMatrix = glm::lookAt(position, position + springArm, Math::Vector(0, 1, 0));
|
||||
camera.viewMatrix = glm::lookAt(position, position + springArm, Vector(0, 1, 0));
|
||||
camera.projectionMatrix = glm::perspective(fieldOfView, aspectRatio, 0.1f, 1000.0f);
|
||||
std::cout << yaw << " " << pitch << std::endl;
|
||||
}
|
||||
@@ -96,7 +96,7 @@ void ViewportControl::mouseButtonCallback(MouseButton button, InputAction action
|
||||
}
|
||||
}
|
||||
|
||||
void ViewportControl::viewportResize(Math::URect dimensions)
|
||||
void ViewportControl::viewportResize(URect dimensions)
|
||||
{
|
||||
aspectRatio = static_cast<float>(dimensions.size.x) / dimensions.size.y;
|
||||
}
|
||||
|
||||
@@ -8,16 +8,16 @@ namespace Seele
|
||||
class ViewportControl
|
||||
{
|
||||
public:
|
||||
ViewportControl(const Math::URect& viewportDimensions, Math::Vector initialPos /*TODO: configurable initial rotations*/);
|
||||
ViewportControl(const URect& viewportDimensions, Vector initialPos /*TODO: configurable initial rotations*/);
|
||||
~ViewportControl();
|
||||
void update(Component::Camera& camera, float deltaTime);
|
||||
void keyCallback(KeyCode key, InputAction action);
|
||||
void mouseMoveCallback(double xPos, double yPos);
|
||||
void mouseButtonCallback(MouseButton button, InputAction action);
|
||||
void viewportResize(Math::URect dimensions);
|
||||
void viewportResize(URect dimensions);
|
||||
private:
|
||||
Math::Vector position;
|
||||
Math::Vector springArm;
|
||||
Vector position;
|
||||
Vector springArm;
|
||||
float fieldOfView;
|
||||
float aspectRatio;
|
||||
StaticArray<bool, static_cast<size_t>(KeyCode::KEY_LAST)> keys;
|
||||
|
||||
@@ -6,7 +6,7 @@ using namespace Seele;
|
||||
Actor::Actor(PScene scene)
|
||||
: Entity(scene)
|
||||
{
|
||||
scene->attachComponent<Component::Transform>(identifier);
|
||||
attachComponent<Component::Transform>();
|
||||
}
|
||||
|
||||
Actor::~Actor()
|
||||
@@ -32,13 +32,9 @@ void Actor::removeChild(PActor child)
|
||||
children.remove(children.find(child), false);
|
||||
child->setParent(nullptr);
|
||||
}
|
||||
const Component::Transform& Actor::getTransform() const
|
||||
|
||||
Component::Transform& Actor::getTransform()
|
||||
{
|
||||
return scene->accessComponent<Component::Transform>(identifier);
|
||||
return accessComponent<Component::Transform>();
|
||||
}
|
||||
|
||||
//Component::Transform& Actor::getTransform()
|
||||
//{
|
||||
// return scene->accessComponent<Component::Transform>(identifier);
|
||||
//}
|
||||
|
||||
|
||||
@@ -18,8 +18,7 @@ public:
|
||||
void removeChild(PActor child);
|
||||
Array<PActor> getChildren();
|
||||
|
||||
// Returns a read-only copy of the actors transform
|
||||
const Component::Transform& getTransform() const;
|
||||
Component::Transform& getTransform();
|
||||
|
||||
protected:
|
||||
//Component::Transform& getTransform();
|
||||
|
||||
@@ -6,8 +6,8 @@ using namespace Seele;
|
||||
CameraActor::CameraActor(PScene scene)
|
||||
: Actor(scene)
|
||||
{
|
||||
scene->attachComponent<Component::Camera>(identifier);
|
||||
scene->accessComponent<Component::Transform>(identifier).setRelativeLocation(Math::Vector(10, 5, 14));
|
||||
attachComponent<Component::Camera>();
|
||||
attachComponent<Component::Transform>().setRelativeLocation(Vector(10, 5, 14));
|
||||
}
|
||||
|
||||
CameraActor::~CameraActor()
|
||||
@@ -16,10 +16,10 @@ CameraActor::~CameraActor()
|
||||
|
||||
Component::Camera& CameraActor::getCameraComponent()
|
||||
{
|
||||
return scene->accessComponent<Component::Camera>(identifier);
|
||||
return accessComponent<Component::Camera>();
|
||||
}
|
||||
|
||||
const Component::Camera& CameraActor::getCameraComponent() const
|
||||
{
|
||||
return scene->accessComponent<Component::Camera>(identifier);
|
||||
return accessComponent<Component::Camera>();
|
||||
}
|
||||
@@ -11,5 +11,5 @@ Entity::Entity(PScene scene)
|
||||
|
||||
Entity::~Entity()
|
||||
{
|
||||
|
||||
scene->destroyEntity(identifier);
|
||||
}
|
||||
@@ -13,9 +13,19 @@ public:
|
||||
virtual ~Entity();
|
||||
|
||||
template<typename Component, typename... Args>
|
||||
Component& attachComponent(Args... args)
|
||||
Component& attachComponent(Args&&... args)
|
||||
{
|
||||
return scene->attachComponent<Component>(identifier, args...);
|
||||
return scene->attachComponent<Component>(identifier, std::forward<Args>(args)...);
|
||||
}
|
||||
template<typename Component>
|
||||
Component& accessComponent()
|
||||
{
|
||||
return scene->accessComponent<Component>(identifier);
|
||||
}
|
||||
template<typename Component>
|
||||
const Component& accessComponent() const
|
||||
{
|
||||
return scene->accessComponent<Component>(identifier);
|
||||
}
|
||||
protected:
|
||||
PScene scene;
|
||||
|
||||
@@ -2,18 +2,20 @@
|
||||
#include "MeshAsset.h"
|
||||
#include "FontAsset.h"
|
||||
#include "TextureAsset.h"
|
||||
#include "MaterialAsset.h"
|
||||
#include "FontLoader.h"
|
||||
#include "TextureLoader.h"
|
||||
#include "MaterialLoader.h"
|
||||
#include "MeshLoader.h"
|
||||
#include "Material/MaterialAsset.h"
|
||||
#include "Graphics/Mesh.h"
|
||||
#include "Graphics/Graphics.h"
|
||||
#include "Window/WindowManager.h"
|
||||
#include "MeshAsset.h"
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <iostream>
|
||||
|
||||
using namespace Seele;
|
||||
using json = nlohmann::json;
|
||||
|
||||
AssetRegistry::~AssetRegistry()
|
||||
{
|
||||
@@ -25,6 +27,11 @@ void AssetRegistry::init(const std::string& rootFolder)
|
||||
}
|
||||
|
||||
void AssetRegistry::importFile(const std::string &filePath)
|
||||
{
|
||||
importFile(filePath, "");
|
||||
}
|
||||
|
||||
void AssetRegistry::importFile(const std::string &filePath, const std::string& importPath)
|
||||
{
|
||||
std::filesystem::path fsPath = std::filesystem::path(filePath);
|
||||
std::string extension = fsPath.extension().string();
|
||||
@@ -32,43 +39,78 @@ void AssetRegistry::importFile(const std::string &filePath)
|
||||
|| extension.compare(".obj") == 0
|
||||
|| extension.compare(".blend") == 0)
|
||||
{
|
||||
get().importMesh(fsPath);
|
||||
get().importMesh(fsPath, importPath);
|
||||
}
|
||||
if (extension.compare(".png") == 0
|
||||
|| extension.compare(".jpg") == 0)
|
||||
{
|
||||
get().importTexture(fsPath);
|
||||
get().importTexture(fsPath, importPath);
|
||||
}
|
||||
if(extension.compare(".ttf") == 0)
|
||||
{
|
||||
get().importFont(fsPath);
|
||||
get().importFont(fsPath, importPath);
|
||||
}
|
||||
if (extension.compare(".asset") == 0)
|
||||
{
|
||||
get().importMaterial(fsPath);
|
||||
get().importMaterial(fsPath, importPath);
|
||||
}
|
||||
}
|
||||
|
||||
PMeshAsset AssetRegistry::findMesh(const std::string &filePath)
|
||||
{
|
||||
auto it = get().meshes.find(filePath);
|
||||
assert(it != get().meshes.end());
|
||||
AssetFolder& folder = get().assetRoot;
|
||||
std::string fileName = filePath;
|
||||
size_t slashLoc = filePath.rfind("/");
|
||||
if(slashLoc != -1)
|
||||
{
|
||||
folder = get().getOrCreateFolder(filePath.substr(0, slashLoc));
|
||||
fileName = filePath.substr(slashLoc+1, filePath.size());
|
||||
}
|
||||
auto it = folder.meshes.find(fileName);
|
||||
assert(it != folder.meshes.end());
|
||||
return it->second;
|
||||
}
|
||||
|
||||
PTextureAsset AssetRegistry::findTexture(const std::string &filePath)
|
||||
{
|
||||
return get().textures[filePath];
|
||||
std::string fileName = filePath;
|
||||
size_t slashLoc = filePath.rfind("/");
|
||||
if(slashLoc != -1)
|
||||
{
|
||||
AssetFolder& folder = get().getOrCreateFolder(filePath.substr(0, slashLoc));
|
||||
fileName = filePath.substr(slashLoc+1, filePath.size());
|
||||
return folder.textures[fileName];
|
||||
}
|
||||
else
|
||||
{
|
||||
return get().assetRoot.textures[fileName];
|
||||
}
|
||||
}
|
||||
|
||||
PFontAsset AssetRegistry::findFont(const std::string& name)
|
||||
PFontAsset AssetRegistry::findFont(const std::string& filePath)
|
||||
{
|
||||
return get().fonts[name];
|
||||
AssetFolder& folder = get().assetRoot;
|
||||
std::string fileName = filePath;
|
||||
size_t slashLoc = filePath.rfind("/");
|
||||
if(slashLoc != -1)
|
||||
{
|
||||
folder = get().getOrCreateFolder(filePath.substr(0, slashLoc));
|
||||
fileName = filePath.substr(slashLoc+1, filePath.size());
|
||||
}
|
||||
return folder.fonts[fileName];
|
||||
}
|
||||
|
||||
PMaterialAsset AssetRegistry::findMaterial(const std::string &filePath)
|
||||
{
|
||||
return get().materials[filePath];
|
||||
AssetFolder& folder = get().assetRoot;
|
||||
std::string fileName = filePath;
|
||||
size_t slashLoc = filePath.rfind("/");
|
||||
if(slashLoc != -1)
|
||||
{
|
||||
folder = get().getOrCreateFolder(filePath.substr(0, slashLoc));
|
||||
fileName = filePath.substr(slashLoc+1, filePath.size());
|
||||
}
|
||||
return folder.materials[fileName];
|
||||
}
|
||||
|
||||
std::ofstream AssetRegistry::createWriteStream(const std::string& relativePath, std::ios_base::openmode openmode)
|
||||
@@ -106,56 +148,65 @@ std::string AssetRegistry::getRootFolder()
|
||||
return get().rootFolder.generic_string();
|
||||
}
|
||||
|
||||
void AssetRegistry::importMesh(const std::filesystem::path &filePath)
|
||||
void AssetRegistry::importMesh(const std::filesystem::path &filePath, const std::string& importPath)
|
||||
{
|
||||
meshLoader->importAsset(filePath);
|
||||
meshLoader->importAsset(filePath, importPath);
|
||||
}
|
||||
|
||||
void AssetRegistry::importTexture(const std::filesystem::path &filePath)
|
||||
void AssetRegistry::importTexture(const std::filesystem::path &filePath, const std::string& importPath)
|
||||
{
|
||||
textureLoader->importAsset(filePath);
|
||||
textureLoader->importAsset(filePath, importPath);
|
||||
}
|
||||
|
||||
void AssetRegistry::importFont(const std::filesystem::path& filePath)
|
||||
void AssetRegistry::importFont(const std::filesystem::path& filePath, const std::string& importPath)
|
||||
{
|
||||
fontLoader->importAsset(filePath);
|
||||
fontLoader->importAsset(filePath, importPath);
|
||||
}
|
||||
|
||||
void AssetRegistry::importMaterial(const std::filesystem::path &filePath)
|
||||
void AssetRegistry::importMaterial(const std::filesystem::path &filePath, const std::string& importPath)
|
||||
{
|
||||
materialLoader->importAsset(filePath);
|
||||
materialLoader->importAsset(filePath, importPath);
|
||||
}
|
||||
|
||||
void AssetRegistry::registerMesh(PMeshAsset mesh)
|
||||
void AssetRegistry::registerMesh(PMeshAsset mesh, const std::string& importPath)
|
||||
{
|
||||
PMeshAsset existingMesh = meshes[mesh->getFileName()];
|
||||
if(existingMesh != nullptr)
|
||||
AssetFolder& folder = getOrCreateFolder(importPath);
|
||||
folder.meshes[mesh->getFileName()] = mesh;
|
||||
}
|
||||
|
||||
void AssetRegistry::registerTexture(PTextureAsset texture, const std::string& importPath)
|
||||
{
|
||||
AssetFolder& folder = getOrCreateFolder(importPath);
|
||||
folder.textures[texture->getFileName()] = texture;
|
||||
}
|
||||
|
||||
void AssetRegistry::registerFont(PFontAsset font, const std::string& importPath)
|
||||
{
|
||||
AssetFolder& folder = getOrCreateFolder(importPath);
|
||||
folder.fonts[font->getFileName()] = font;
|
||||
}
|
||||
|
||||
void AssetRegistry::registerMaterial(PMaterialAsset material, const std::string& importPath)
|
||||
{
|
||||
AssetFolder& folder = getOrCreateFolder(importPath);
|
||||
folder.materials[material->getFileName()] = material;
|
||||
}
|
||||
|
||||
AssetRegistry::AssetFolder& AssetRegistry::getOrCreateFolder(std::string fullPath)
|
||||
{
|
||||
AssetFolder& result = assetRoot;
|
||||
while(!fullPath.empty())
|
||||
{
|
||||
auto newMeshes = mesh->getMeshes();
|
||||
for(uint32 i = 0; i < newMeshes.size(); ++i)
|
||||
size_t slashLoc = fullPath.find("/");
|
||||
if(slashLoc == -1)
|
||||
{
|
||||
existingMesh->addMesh(newMeshes[i]);
|
||||
return result.children[fullPath];
|
||||
}
|
||||
std::string folderName = fullPath.substr(0, slashLoc);
|
||||
result = result.children[folderName];
|
||||
fullPath = fullPath.substr(slashLoc+1, fullPath.size());
|
||||
}
|
||||
else
|
||||
{
|
||||
meshes[mesh->getFileName()] = mesh;
|
||||
}
|
||||
}
|
||||
|
||||
void AssetRegistry::registerTexture(PTextureAsset texture)
|
||||
{
|
||||
textures[texture->getFileName()] = texture;
|
||||
}
|
||||
|
||||
void AssetRegistry::registerFont(PFontAsset font)
|
||||
{
|
||||
fonts[font->getFileName()] = font;
|
||||
}
|
||||
|
||||
void AssetRegistry::registerMaterial(PMaterialAsset material)
|
||||
{
|
||||
materials[material->getFileName()] = material;
|
||||
return result;
|
||||
}
|
||||
|
||||
std::ofstream AssetRegistry::internalCreateWriteStream(const std::string& relativePath, std::ios_base::openmode openmode)
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#pragma once
|
||||
#include "MinimalEngine.h"
|
||||
#include "Asset.h"
|
||||
#include "Material/MaterialAsset.h"
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
@@ -25,6 +24,7 @@ public:
|
||||
static std::string getRootFolder();
|
||||
|
||||
static void importFile(const std::string& filePath);
|
||||
static void importFile(const std::string& filePath, const std::string& importPath);
|
||||
|
||||
static PMeshAsset findMesh(const std::string& filePath);
|
||||
static PTextureAsset findTexture(const std::string& filePath);
|
||||
@@ -34,30 +34,38 @@ public:
|
||||
static std::ofstream createWriteStream(const std::string& relativePath, std::ios_base::openmode openmode = std::ios::out);
|
||||
static std::ifstream createReadStream(const std::string& relativePath, std::ios_base::openmode openmode = std::ios::in);
|
||||
private:
|
||||
struct AssetFolder
|
||||
{
|
||||
std::map<std::string, AssetFolder> children;
|
||||
//Todo: Seele::Map doesn't really work with strings for some reason, so just use std::map for now
|
||||
std::map<std::string, PTextureAsset> textures;
|
||||
std::map<std::string, PFontAsset> fonts;
|
||||
std::map<std::string, PMeshAsset> meshes;
|
||||
std::map<std::string, PMaterialAsset> materials;
|
||||
};
|
||||
|
||||
static AssetRegistry& get();
|
||||
|
||||
AssetRegistry();
|
||||
void init(const std::filesystem::path& rootFolder, Gfx::PGraphics graphics);
|
||||
|
||||
void importMesh(const std::filesystem::path& filePath);
|
||||
void importTexture(const std::filesystem::path& filePath);
|
||||
void importFont(const std::filesystem::path& filePath);
|
||||
void importMaterial(const std::filesystem::path& filePath);
|
||||
void importMesh(const std::filesystem::path& filePath, const std::string& importPath);
|
||||
void importTexture(const std::filesystem::path& filePath, const std::string& importPath);
|
||||
void importFont(const std::filesystem::path& filePath, const std::string& importPath);
|
||||
void importMaterial(const std::filesystem::path& filePath, const std::string& importPath);
|
||||
|
||||
void registerMesh(PMeshAsset mesh);
|
||||
void registerTexture(PTextureAsset texture);
|
||||
void registerFont(PFontAsset font);
|
||||
void registerMaterial(PMaterialAsset material);
|
||||
void registerMesh(PMeshAsset mesh, const std::string& importPath);
|
||||
void registerTexture(PTextureAsset texture, const std::string& importPath);
|
||||
void registerFont(PFontAsset font, const std::string& importPath);
|
||||
void registerMaterial(PMaterialAsset material, const std::string& importPath);
|
||||
|
||||
AssetFolder& getOrCreateFolder(std::string foldername);
|
||||
|
||||
std::ofstream internalCreateWriteStream(const std::string& relativePath, std::ios_base::openmode openmode = std::ios::out);
|
||||
std::ifstream internalCreateReadStream(const std::string& relaitvePath, std::ios_base::openmode openmode = std::ios::in);
|
||||
|
||||
std::filesystem::path rootFolder;
|
||||
//Todo: Seele::Map doesn't really work with strings for some reason, so just use std::map for now
|
||||
std::map<std::string, PTextureAsset> textures;
|
||||
std::map<std::string, PFontAsset> fonts;
|
||||
std::map<std::string, PMeshAsset> meshes;
|
||||
std::map<std::string, PMaterialAsset> materials;
|
||||
AssetFolder assetRoot;
|
||||
UPTextureLoader textureLoader;
|
||||
UPFontLoader fontLoader;
|
||||
UPMeshLoader meshLoader;
|
||||
|
||||
@@ -8,6 +8,10 @@ target_sources(Engine
|
||||
FontAsset.cpp
|
||||
FontLoader.h
|
||||
FontLoader.cpp
|
||||
MaterialAsset.h
|
||||
MaterialAsset.cpp
|
||||
MaterialInstanceAsset.h
|
||||
MaterialInstanceAsset.cpp
|
||||
MaterialLoader.h
|
||||
MaterialLoader.cpp
|
||||
MeshAsset.h
|
||||
@@ -26,6 +30,8 @@ target_sources(Engine
|
||||
AssetRegistry.h
|
||||
FontAsset.h
|
||||
FontLoader.h
|
||||
MaterialAsset.h
|
||||
MaterialInstanceAsset.h
|
||||
MaterialLoader.h
|
||||
MeshAsset.h
|
||||
MeshLoader.h
|
||||
|
||||
@@ -52,8 +52,8 @@ void FontAsset::load()
|
||||
continue;
|
||||
}
|
||||
Glyph& glyph = glyphs[c];
|
||||
glyph.size = Math::IVector2(face->glyph->bitmap.width, face->glyph->bitmap.rows);
|
||||
glyph.bearing = Math::IVector2(face->glyph->bitmap_left, face->glyph->bitmap_top);
|
||||
glyph.size = IVector2(face->glyph->bitmap.width, face->glyph->bitmap.rows);
|
||||
glyph.bearing = IVector2(face->glyph->bitmap_left, face->glyph->bitmap_top);
|
||||
glyph.advance = face->glyph->advance.x;
|
||||
TextureCreateInfo imageData;
|
||||
imageData.format = Gfx::SE_FORMAT_R8_UINT;
|
||||
|
||||
@@ -17,8 +17,8 @@ public:
|
||||
struct Glyph
|
||||
{
|
||||
Gfx::PTexture2D texture;
|
||||
Math::IVector2 size;
|
||||
Math::IVector2 bearing;
|
||||
IVector2 size;
|
||||
IVector2 bearing;
|
||||
uint32 advance;
|
||||
};
|
||||
const std::map<uint32, Glyph> getGlyphData() const { return glyphs; }
|
||||
|
||||
@@ -15,7 +15,7 @@ FontLoader::~FontLoader()
|
||||
{
|
||||
}
|
||||
|
||||
void FontLoader::importAsset(const std::filesystem::path& filePath)
|
||||
void FontLoader::importAsset(const std::filesystem::path& filePath, const std::string& importPath)
|
||||
{
|
||||
std::filesystem::path assetPath = filePath.filename();
|
||||
assetPath.replace_extension("asset");
|
||||
@@ -23,12 +23,11 @@ void FontLoader::importAsset(const std::filesystem::path& filePath)
|
||||
std::error_code code;
|
||||
std::filesystem::copy_file(filePath, asset->getFullPath(), code);
|
||||
asset->setStatus(Asset::Status::Loading);
|
||||
AssetRegistry::get().registerFont(asset);
|
||||
AssetRegistry::get().registerFont(asset, importPath);
|
||||
import(filePath, asset);
|
||||
}
|
||||
|
||||
void FontLoader::import(std::filesystem::path path, PFontAsset asset)
|
||||
{
|
||||
asset->load();
|
||||
AssetRegistry::get().registerFont(asset);
|
||||
}
|
||||
@@ -12,7 +12,7 @@ class FontLoader
|
||||
public:
|
||||
FontLoader(Gfx::PGraphics graphic);
|
||||
~FontLoader();
|
||||
void importAsset(const std::filesystem::path& filePath);
|
||||
void importAsset(const std::filesystem::path& filePath, const std::string& importPath);
|
||||
private:
|
||||
void import(std::filesystem::path path, PFontAsset asset);
|
||||
Gfx::PGraphics graphics;
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
#include "MaterialAsset.h"
|
||||
#include "Material/Material.h"
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
MaterialAsset::MaterialAsset()
|
||||
{
|
||||
}
|
||||
|
||||
MaterialAsset::MaterialAsset(const std::string& directory, const std::string& name)
|
||||
: Asset(directory, name)
|
||||
{
|
||||
}
|
||||
|
||||
MaterialAsset::MaterialAsset(const std::filesystem::path& fullPath)
|
||||
: Asset(fullPath)
|
||||
{
|
||||
}
|
||||
|
||||
MaterialAsset::~MaterialAsset()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void MaterialAsset::save()
|
||||
{
|
||||
}
|
||||
|
||||
void MaterialAsset::load()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
void MaterialAsset::beginFrame()
|
||||
{
|
||||
}
|
||||
|
||||
void MaterialAsset::endFrame()
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
#include "Asset.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
DECLARE_REF(Material)
|
||||
class MaterialAsset : public Asset
|
||||
{
|
||||
public:
|
||||
MaterialAsset();
|
||||
MaterialAsset(const std::string &directory, const std::string &name);
|
||||
MaterialAsset(const std::filesystem::path &fullPath);
|
||||
virtual ~MaterialAsset();
|
||||
virtual void beginFrame();
|
||||
virtual void endFrame();
|
||||
virtual void save() override;
|
||||
virtual void load() override;
|
||||
PMaterial getMaterial() const { return material; }
|
||||
private:
|
||||
PMaterial material;
|
||||
friend class MaterialLoader;
|
||||
};
|
||||
DEFINE_REF(MaterialAsset)
|
||||
} // namespace Seele
|
||||
@@ -0,0 +1,32 @@
|
||||
#include "MaterialInstanceAsset.h"
|
||||
#include "Material/MaterialInstance.h"
|
||||
#include "Material/Material.h"
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
MaterialInstanceAsset::MaterialInstanceAsset()
|
||||
{
|
||||
}
|
||||
|
||||
MaterialInstanceAsset::MaterialInstanceAsset(const std::string& directory, const std::string& name)
|
||||
: Asset(directory, name)
|
||||
{
|
||||
}
|
||||
|
||||
MaterialInstanceAsset::MaterialInstanceAsset(const std::filesystem::path& fullPath)
|
||||
: Asset(fullPath)
|
||||
{
|
||||
}
|
||||
|
||||
MaterialInstanceAsset::~MaterialInstanceAsset()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void MaterialInstanceAsset::save()
|
||||
{
|
||||
}
|
||||
|
||||
void MaterialInstanceAsset::load()
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
#include "Asset.h"
|
||||
#include "Material/MaterialInstance.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
class MaterialInstanceAsset : public Asset
|
||||
{
|
||||
public:
|
||||
MaterialInstanceAsset();
|
||||
MaterialInstanceAsset(const std::string &directory, const std::string &name);
|
||||
MaterialInstanceAsset(const std::filesystem::path &fullPath);
|
||||
virtual ~MaterialInstanceAsset();
|
||||
virtual void beginFrame();
|
||||
virtual void endFrame();
|
||||
virtual void save() override;
|
||||
virtual void load() override;
|
||||
private:
|
||||
PMaterialInstance material;
|
||||
};
|
||||
DEFINE_REF(MaterialInstanceAsset)
|
||||
} // namespace Seele
|
||||
@@ -1,37 +1,141 @@
|
||||
#include "MaterialLoader.h"
|
||||
#include "Graphics/Graphics.h"
|
||||
#include "Material/MaterialAsset.h"
|
||||
#include "MaterialAsset.h"
|
||||
#include "AssetRegistry.h"
|
||||
#include "Material/Material.h"
|
||||
#include "Material/BRDF.h"
|
||||
#include "Window/WindowManager.h"
|
||||
#include "Material/ShaderExpression.h"
|
||||
#include "TextureAsset.h"
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
using namespace Seele;
|
||||
using json = nlohmann::json;
|
||||
|
||||
MaterialLoader::MaterialLoader(Gfx::PGraphics graphics)
|
||||
: graphics(graphics)
|
||||
{
|
||||
placeholderMaterial = new MaterialAsset(std::filesystem::absolute("./shaders/Placeholder.asset"));
|
||||
placeholderMaterial->load();
|
||||
graphics->getShaderCompiler()->registerMaterial(placeholderMaterial);
|
||||
importAsset(std::filesystem::absolute("./shaders/Placeholder.asset"), "");
|
||||
}
|
||||
|
||||
MaterialLoader::~MaterialLoader()
|
||||
{
|
||||
}
|
||||
|
||||
void MaterialLoader::importAsset(const std::filesystem::path& name)
|
||||
void MaterialLoader::importAsset(const std::filesystem::path& name, const std::string& importPath)
|
||||
{
|
||||
std::filesystem::path assetPath = name.filename();
|
||||
assetPath.replace_extension("asset");
|
||||
PMaterialAsset asset = new MaterialAsset(assetPath.generic_string());
|
||||
asset->setStatus(Asset::Status::Loading);
|
||||
AssetRegistry::get().registerMaterial(asset);
|
||||
AssetRegistry::get().registerMaterial(asset, importPath);
|
||||
import(name, asset);
|
||||
}
|
||||
|
||||
void MaterialLoader::import(std::filesystem::path, PMaterialAsset asset)
|
||||
void MaterialLoader::import(std::filesystem::path name, PMaterialAsset asset)
|
||||
{
|
||||
asset->load();
|
||||
graphics->getShaderCompiler()->registerMaterial(asset);
|
||||
AssetRegistry::get().registerMaterial(asset);
|
||||
auto stream = std::ifstream(name.c_str());
|
||||
json j;
|
||||
stream >> j;
|
||||
std::string materialName = j["name"].get<std::string>() + "Material";
|
||||
Gfx::PDescriptorLayout layout = WindowManager::getGraphics()->createDescriptorLayout(materialName + "Layout");
|
||||
//Shader file needs to conform to the slang standard, which prohibits _
|
||||
materialName.erase(std::remove(materialName.begin(), materialName.end(), '_'), materialName.end());
|
||||
materialName.erase(std::remove(materialName.begin(), materialName.end(), '.'), materialName.end());
|
||||
std::ofstream codeStream("./shaders/generated/"+materialName+".slang");
|
||||
std::string profile = j["profile"].get<std::string>();
|
||||
|
||||
codeStream << "import Material;" << std::endl;
|
||||
codeStream << "import BRDF;" << std::endl;
|
||||
codeStream << "import MaterialParameter;" << std::endl << std::endl;
|
||||
|
||||
codeStream << "struct " << materialName << " : IMaterial {" << std::endl;
|
||||
uint32 uniformBufferOffset = 0;
|
||||
uint32 bindingCounter = 0; // Uniform buffers are always binding 0
|
||||
uint32 uniformBinding = -1;
|
||||
Array<PShaderParameter> parameters;
|
||||
for(auto param : j["params"].items())
|
||||
{
|
||||
std::string type = param.value()["type"].get<std::string>();
|
||||
auto defaultValue = param.value().find("default");
|
||||
// TODO: ALIGNMENT RULES
|
||||
if(type.compare("float") == 0)
|
||||
{
|
||||
PFloatParameter p = new FloatParameter(param.key(), uniformBufferOffset, 0);
|
||||
codeStream << "\tlayout(offset = " << uniformBufferOffset << ")";
|
||||
if(uniformBinding == -1)
|
||||
{
|
||||
layout->addDescriptorBinding(bindingCounter, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
|
||||
uniformBinding = bindingCounter++;
|
||||
}
|
||||
uniformBufferOffset += 4;
|
||||
if(defaultValue != param.value().end())
|
||||
{
|
||||
p->data = std::stof(defaultValue.value().get<std::string>());
|
||||
}
|
||||
parameters.add(p);
|
||||
}
|
||||
// TODO: ALIGNMENT RULES
|
||||
else if(type.compare("float3") == 0)
|
||||
{
|
||||
PVectorParameter p = new VectorParameter(param.key(), uniformBufferOffset, 0);
|
||||
codeStream << "\tlayout(offset = " << uniformBufferOffset << ")";
|
||||
if(uniformBinding == -1)
|
||||
{
|
||||
layout->addDescriptorBinding(bindingCounter, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
|
||||
uniformBinding = bindingCounter++;
|
||||
}
|
||||
uniformBufferOffset += 12;
|
||||
if(defaultValue != param.value().end())
|
||||
{
|
||||
p->data = parseVector(defaultValue.value().get<std::string>().c_str());
|
||||
}
|
||||
parameters.add(p);
|
||||
}
|
||||
else if(type.compare("Texture2D") == 0)
|
||||
{
|
||||
PTextureParameter p = new TextureParameter(param.key(), 0, bindingCounter);
|
||||
layout->addDescriptorBinding(bindingCounter++, Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE);
|
||||
if(defaultValue != param.value().end())
|
||||
{
|
||||
std::string defaultString = defaultValue.value().get<std::string>();
|
||||
p->data = AssetRegistry::findTexture(defaultString);
|
||||
}
|
||||
if(p->data == nullptr)
|
||||
{
|
||||
p->data = AssetRegistry::findTexture(""); // this will return placeholder texture
|
||||
}
|
||||
parameters.add(p);
|
||||
}
|
||||
else if(type.compare("SamplerState") == 0)
|
||||
{
|
||||
PSamplerParameter p = new SamplerParameter(param.key(), 0, bindingCounter);
|
||||
layout->addDescriptorBinding(bindingCounter++, Gfx::SE_DESCRIPTOR_TYPE_SAMPLER);
|
||||
p->data = WindowManager::getGraphics()->createSamplerState({});
|
||||
parameters.add(p);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Error unsupported parameter type" << std::endl;
|
||||
}
|
||||
codeStream << "\t" << type << " " << param.key() << ";\n";
|
||||
}
|
||||
uint32 uniformDataSize = uniformBufferOffset;
|
||||
|
||||
BRDF* brdf = BRDF::getBRDFByName(profile);
|
||||
brdf->generateMaterialCode(codeStream, j["code"]);
|
||||
codeStream << "};";
|
||||
codeStream.close();
|
||||
layout->create();
|
||||
asset->material = new Material(
|
||||
std::move(parameters),
|
||||
std::move(layout),
|
||||
uniformDataSize,
|
||||
uniformBinding,
|
||||
materialName
|
||||
);
|
||||
graphics->getShaderCompiler()->registerMaterial(asset->material);
|
||||
asset->setStatus(Asset::Status::Ready);
|
||||
////co_return;
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ class MaterialLoader
|
||||
public:
|
||||
MaterialLoader(Gfx::PGraphics graphic);
|
||||
~MaterialLoader();
|
||||
void importAsset(const std::filesystem::path& name);
|
||||
void importAsset(const std::filesystem::path& name, const std::string& importPath);
|
||||
PMaterialAsset getPlaceHolderMaterial();
|
||||
private:
|
||||
void import(std::filesystem::path filePath, PMaterialAsset asset);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "MeshAsset.h"
|
||||
#include "Graphics/Mesh.h"
|
||||
#include "Graphics/VertexShaderInput.h"
|
||||
#include "Material/MaterialInterface.h"
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
#pragma once
|
||||
#include "Asset.h"
|
||||
#include "Component/Collider.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
DECLARE_REF(Mesh)
|
||||
DECLARE_REF(MaterialAsset)
|
||||
DECLARE_REF(MaterialInterface)
|
||||
class MeshAsset : public Asset
|
||||
{
|
||||
public:
|
||||
@@ -17,8 +18,9 @@ public:
|
||||
void addMesh(PMesh mesh);
|
||||
const Array<PMesh> getMeshes();
|
||||
//Workaround while no editor
|
||||
Array<PMaterialAsset> referencedMaterials;
|
||||
Array<PMaterialInterface> referencedMaterials;
|
||||
Array<PMesh> meshes;
|
||||
Component::Collider physicsMesh;
|
||||
};
|
||||
DEFINE_REF(MeshAsset)
|
||||
} // namespace Seele
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "Graphics/Mesh.h"
|
||||
#include "Graphics/StaticMeshVertexInput.h"
|
||||
#include "AssetRegistry.h"
|
||||
#include "MaterialAsset.h"
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <nlohmann/json.hpp>
|
||||
@@ -26,17 +27,17 @@ MeshLoader::~MeshLoader()
|
||||
{
|
||||
}
|
||||
|
||||
void MeshLoader::importAsset(const std::filesystem::path &path)
|
||||
void MeshLoader::importAsset(const std::filesystem::path &path, const std::string& importPath)
|
||||
{
|
||||
std::filesystem::path assetPath = path.filename();
|
||||
assetPath.replace_extension("asset");
|
||||
PMeshAsset asset = new MeshAsset(assetPath.generic_string());
|
||||
asset->setStatus(Asset::Status::Loading);
|
||||
AssetRegistry::get().registerMesh(asset);
|
||||
AssetRegistry::get().registerMesh(asset, importPath);
|
||||
import(path, asset);
|
||||
}
|
||||
|
||||
void MeshLoader::loadMaterials(const aiScene* scene, Array<PMaterialAsset>& globalMaterials)
|
||||
void MeshLoader::loadMaterials(const aiScene* scene, Array<PMaterial>& globalMaterials)
|
||||
{
|
||||
using json = nlohmann::json;
|
||||
for(uint32 i = 0; i < scene->mNumMaterials; ++i)
|
||||
@@ -92,15 +93,13 @@ void MeshLoader::loadMaterials(const aiScene* scene, Array<PMaterialAsset>& glob
|
||||
outMatFile.close();
|
||||
|
||||
std::cout << "writing json to " << outMatFilename << std::endl;
|
||||
PMaterialAsset result = new MaterialAsset(outMatFilename);
|
||||
result->load();
|
||||
graphics->getShaderCompiler()->registerMaterial(result);
|
||||
AssetRegistry::get().registerMaterial(result);
|
||||
PMaterialAsset asset = AssetRegistry::findMaterial(result->getFileName());
|
||||
globalMaterials[i] = asset;
|
||||
AssetRegistry::importFile(AssetRegistry::getRootFolder() + "/" + outMatFilename);
|
||||
PMaterialAsset asset = AssetRegistry::findMaterial(matCode["name"].get<std::string>());
|
||||
globalMaterials[i] = asset->getMaterial();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void findMeshRoots(aiNode *node, List<aiNode *> &meshNodes)
|
||||
{
|
||||
if (node->mNumMeshes > 0)
|
||||
@@ -115,61 +114,70 @@ void findMeshRoots(aiNode *node, List<aiNode *> &meshNodes)
|
||||
}
|
||||
VertexStreamComponent createVertexStream(uint32 size, aiVector3D* sourceData, Gfx::PGraphics graphics)
|
||||
{
|
||||
Array<Math::Vector> buffer(size);
|
||||
Array<Vector> buffer(size);
|
||||
for(uint32 i = 0; i < size; ++i)
|
||||
{
|
||||
buffer[i] = Math::Vector(sourceData[i].x, sourceData[i].y, sourceData[i].z);
|
||||
}
|
||||
buffer[i] = Vector(sourceData[i].x, sourceData[i].y, sourceData[i].z);
|
||||
}
|
||||
VertexBufferCreateInfo vbInfo;
|
||||
vbInfo.numVertices = size;
|
||||
vbInfo.vertexSize = sizeof(Math::Vector);
|
||||
vbInfo.vertexSize = sizeof(Vector);
|
||||
vbInfo.resourceData.data = (uint8 *)buffer.data();
|
||||
vbInfo.resourceData.owner = Gfx::QueueType::DEDICATED_TRANSFER;
|
||||
vbInfo.resourceData.size = sizeof(Math::Vector) * buffer.size();
|
||||
vbInfo.resourceData.size = sizeof(Vector) * buffer.size();
|
||||
Gfx::PVertexBuffer vertexBuffer = graphics->createVertexBuffer(vbInfo);
|
||||
vertexBuffer->transferOwnership(Gfx::QueueType::GRAPHICS);
|
||||
return VertexStreamComponent(vertexBuffer, 0, vbInfo.vertexSize, Gfx::SE_FORMAT_R32G32B32_SFLOAT);
|
||||
}
|
||||
VertexStreamComponent createVertexStream(uint32 size, aiVector2D* sourceData, Gfx::PGraphics graphics)
|
||||
{
|
||||
Array<Math::Vector2> buffer(size);
|
||||
Array<Vector2> buffer(size);
|
||||
for(uint32 i = 0; i < size; ++i)
|
||||
{
|
||||
buffer[i] = Math::Vector2(sourceData[i].x, sourceData[i].y);
|
||||
buffer[i] = Vector2(sourceData[i].x, sourceData[i].y);
|
||||
}
|
||||
VertexBufferCreateInfo vbInfo;
|
||||
vbInfo.numVertices = size;
|
||||
vbInfo.vertexSize = sizeof(Math::Vector2);
|
||||
vbInfo.vertexSize = sizeof(Vector2);
|
||||
vbInfo.resourceData.data = (uint8 *)buffer.data();
|
||||
vbInfo.resourceData.owner = Gfx::QueueType::DEDICATED_TRANSFER;
|
||||
vbInfo.resourceData.size = sizeof(Math::Vector2) * buffer.size();
|
||||
vbInfo.resourceData.size = sizeof(Vector2) * buffer.size();
|
||||
Gfx::PVertexBuffer vertexBuffer = graphics->createVertexBuffer(vbInfo);
|
||||
vertexBuffer->transferOwnership(Gfx::QueueType::GRAPHICS);
|
||||
return VertexStreamComponent(vertexBuffer, 0, vbInfo.vertexSize, Gfx::SE_FORMAT_R32G32_SFLOAT);
|
||||
}
|
||||
VertexStreamComponent createVertexStream(uint32 size, aiColor4D* sourceData, Gfx::PGraphics graphics)
|
||||
{
|
||||
Array<Math::Vector4> buffer(size);
|
||||
Array<Vector4> buffer(size);
|
||||
for(uint32 i = 0; i < size; ++i)
|
||||
{
|
||||
buffer[i] = Math::Vector4(sourceData[i].r, sourceData[i].g, sourceData[i].b, sourceData[i].a);
|
||||
buffer[i] = Vector4(sourceData[i].r, sourceData[i].g, sourceData[i].b, sourceData[i].a);
|
||||
}
|
||||
VertexBufferCreateInfo vbInfo;
|
||||
vbInfo.numVertices = size;
|
||||
vbInfo.vertexSize = sizeof(Math::Vector4);
|
||||
vbInfo.vertexSize = sizeof(Vector4);
|
||||
vbInfo.resourceData.data = (uint8 *)buffer.data();
|
||||
vbInfo.resourceData.owner = Gfx::QueueType::DEDICATED_TRANSFER;
|
||||
vbInfo.resourceData.size = sizeof(Math::Vector4) * buffer.size();
|
||||
vbInfo.resourceData.size = sizeof(Vector4) * buffer.size();
|
||||
Gfx::PVertexBuffer vertexBuffer = graphics->createVertexBuffer(vbInfo);
|
||||
vertexBuffer->transferOwnership(Gfx::QueueType::GRAPHICS);
|
||||
return VertexStreamComponent(vertexBuffer, 0, vbInfo.vertexSize, Gfx::SE_FORMAT_R32G32_SFLOAT);
|
||||
return VertexStreamComponent(vertexBuffer, 0, vbInfo.vertexSize, Gfx::SE_FORMAT_R32G32B32A32_SFLOAT);
|
||||
}
|
||||
void MeshLoader::loadGlobalMeshes(const aiScene* scene, Array<PMesh>& globalMeshes, const Array<PMaterialAsset>& materials)
|
||||
void MeshLoader::loadGlobalMeshes(const aiScene* scene, const Array<PMaterial>& materials, Array<PMesh>& globalMeshes, Component::Collider& collider)
|
||||
{
|
||||
for (uint32 meshIndex = 0; meshIndex < scene->mNumMeshes; ++meshIndex)
|
||||
{
|
||||
aiMesh *mesh = scene->mMeshes[meshIndex];
|
||||
PMaterialAsset material = materials[mesh->mMaterialIndex];
|
||||
collider.boundingbox.adjust(Vector(mesh->mAABB.mMin.x, mesh->mAABB.mMin.y, mesh->mAABB.mMin.z));
|
||||
collider.boundingbox.adjust(Vector(mesh->mAABB.mMax.x, mesh->mAABB.mMax.y, mesh->mAABB.mMax.z));
|
||||
|
||||
//! \todo duplicate from createVertexStream, clean up
|
||||
Array<Vector> vertices(mesh->mNumVertices);
|
||||
for(uint32 i = 0; i < mesh->mNumVertices; ++i)
|
||||
{
|
||||
vertices[i] = Vector(mesh->mVertices[i].x, mesh->mVertices[i].y, mesh->mVertices[i].z);
|
||||
}
|
||||
|
||||
PStaticMeshVertexInput vertexShaderInput = new StaticMeshVertexInput(std::string(mesh->mName.C_Str()));
|
||||
StaticMeshDataType data;
|
||||
data.positionStream = createVertexStream(mesh->mNumVertices, mesh->mVertices, graphics);
|
||||
@@ -205,6 +213,9 @@ void MeshLoader::loadGlobalMeshes(const aiScene* scene, Array<PMesh>& globalMesh
|
||||
indices[faceIndex * 3 + 1] = mesh->mFaces[faceIndex].mIndices[1];
|
||||
indices[faceIndex * 3 + 2] = mesh->mFaces[faceIndex].mIndices[2];
|
||||
}
|
||||
|
||||
collider.physicsMesh.addCollider(vertices, indices, Matrix4(1.0f));
|
||||
|
||||
IndexBufferCreateInfo idxInfo;
|
||||
idxInfo.indexType = Gfx::SE_INDEX_TYPE_UINT32;
|
||||
idxInfo.resourceData.data = (uint8 *)indices.data();
|
||||
@@ -259,22 +270,23 @@ void MeshLoader::import(std::filesystem::path path, PMeshAsset meshAsset)
|
||||
std::cout << "Starting to import "<<path << std::endl;
|
||||
meshAsset->setStatus(Asset::Status::Loading);
|
||||
Assimp::Importer importer;
|
||||
importer.ReadFile(path.string().c_str(),
|
||||
importer.ReadFile(path.string().c_str(), (uint32)(
|
||||
aiProcess_FlipUVs |
|
||||
aiProcess_Triangulate |
|
||||
aiProcess_SortByPType |
|
||||
aiProcess_GenBoundingBoxes |
|
||||
aiProcess_GenSmoothNormals |
|
||||
aiProcess_GenUVCoords |
|
||||
aiProcess_FindDegenerates);
|
||||
aiProcess_FindDegenerates));
|
||||
const aiScene *scene = importer.ApplyPostProcessing(aiProcess_CalcTangentSpace);
|
||||
|
||||
Array<PMaterialAsset> globalMaterials(scene->mNumMaterials);
|
||||
Array<PMaterial> globalMaterials(scene->mNumMaterials);
|
||||
loadTextures(scene, path.parent_path());
|
||||
loadMaterials(scene, globalMaterials);
|
||||
|
||||
Array<PMesh> globalMeshes(scene->mNumMeshes);
|
||||
loadGlobalMeshes(scene, globalMeshes, globalMaterials);
|
||||
|
||||
Component::Collider collider;
|
||||
loadGlobalMeshes(scene, globalMaterials, globalMeshes, collider);
|
||||
|
||||
List<aiNode *> meshNodes;
|
||||
findMeshRoots(scene->mRootNode, meshNodes);
|
||||
@@ -286,6 +298,7 @@ void MeshLoader::import(std::filesystem::path path, PMeshAsset meshAsset)
|
||||
meshAsset->addMesh(globalMeshes[meshNode->mMeshes[i]]);
|
||||
}
|
||||
}
|
||||
meshAsset->physicsMesh = std::move(collider);
|
||||
meshAsset->setStatus(Asset::Status::Ready);
|
||||
meshAsset->save();
|
||||
std::cout << "Finished loading " << path << std::endl;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
#include "MinimalEngine.h"
|
||||
#include "Containers/List.h"
|
||||
#include "Component/Collider.h"
|
||||
#include <filesystem>
|
||||
|
||||
struct aiScene;
|
||||
@@ -9,18 +10,18 @@ namespace Seele
|
||||
{
|
||||
DECLARE_REF(Mesh)
|
||||
DECLARE_REF(MeshAsset)
|
||||
DECLARE_REF(MaterialAsset)
|
||||
DECLARE_REF(Material)
|
||||
DECLARE_NAME_REF(Gfx, Graphics)
|
||||
class MeshLoader
|
||||
{
|
||||
public:
|
||||
MeshLoader(Gfx::PGraphics graphic);
|
||||
~MeshLoader();
|
||||
void importAsset(const std::filesystem::path& filePath);
|
||||
void importAsset(const std::filesystem::path& filePath, const std::string& importPath);
|
||||
private:
|
||||
void loadMaterials(const aiScene* scene, Array<PMaterialAsset>& globalMaterials);
|
||||
void loadMaterials(const aiScene* scene, Array<PMaterial>& globalMaterials);
|
||||
void loadTextures(const aiScene* scene, const std::filesystem::path& meshPath);
|
||||
void loadGlobalMeshes(const aiScene* scene, Array<PMesh>& globalMeshes, const Array<PMaterialAsset>& materials);
|
||||
void loadGlobalMeshes(const aiScene* scene, const Array<PMaterial>& materials, Array<PMesh>& globalMeshes, Component::Collider& collider);
|
||||
void convertAssimpARGB(unsigned char* dst, aiTexel* src, uint32 numPixels);
|
||||
|
||||
void import(std::filesystem::path path, PMeshAsset meshAsset);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#pragma once
|
||||
#include "Asset.h"
|
||||
|
||||
namespace Seele
|
||||
|
||||
@@ -16,21 +16,21 @@ TextureLoader::TextureLoader(Gfx::PGraphics graphics)
|
||||
{
|
||||
placeholderAsset = new TextureAsset(std::filesystem::absolute("./textures/placeholder.ktx"));
|
||||
placeholderAsset->load();
|
||||
AssetRegistry::get().textures[""] = placeholderAsset;
|
||||
AssetRegistry::get().assetRoot.textures[""] = placeholderAsset;
|
||||
}
|
||||
|
||||
TextureLoader::~TextureLoader()
|
||||
{
|
||||
}
|
||||
|
||||
void TextureLoader::importAsset(const std::filesystem::path& path)
|
||||
void TextureLoader::importAsset(const std::filesystem::path& path, const std::string& importPath)
|
||||
{
|
||||
std::filesystem::path assetPath = path.filename();
|
||||
assetPath.replace_extension("asset");
|
||||
PTextureAsset asset = new TextureAsset(assetPath.generic_string());
|
||||
asset->setStatus(Asset::Status::Loading);
|
||||
asset->setTexture(placeholderAsset->getTexture());
|
||||
AssetRegistry::get().registerTexture(asset);
|
||||
AssetRegistry::get().registerTexture(asset, importPath);
|
||||
import(path, asset);
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ class TextureLoader
|
||||
public:
|
||||
TextureLoader(Gfx::PGraphics graphic);
|
||||
~TextureLoader();
|
||||
void importAsset(const std::filesystem::path& filePath);
|
||||
void importAsset(const std::filesystem::path& filePath, const std::string& importPath);
|
||||
PTextureAsset getPlaceholderTexture();
|
||||
private:
|
||||
void import(std::filesystem::path path, PTextureAsset asset);
|
||||
|
||||
+70
-22
@@ -2,16 +2,64 @@
|
||||
#include "Math/Vector.h"
|
||||
#include "Math/Matrix.h"
|
||||
#include "Containers/Array.h"
|
||||
|
||||
#include "Graphics/DebugVertex.h"
|
||||
namespace Seele
|
||||
{
|
||||
struct AABB
|
||||
{
|
||||
Math::Vector min = Math::Vector(std::numeric_limits<float>::max());
|
||||
Math::Vector max = Math::Vector(std::numeric_limits<float>::min());
|
||||
Vector min = Vector(std::numeric_limits<float>::max());
|
||||
Vector max = Vector(std::numeric_limits<float>::lowest());// cause of reasons
|
||||
void visualize(Array<DebugVertex>& vertices) const
|
||||
{
|
||||
StaticArray<DebugVertex, 8> corners;
|
||||
corners[0] = DebugVertex { .position = Vector(min.x, min.y, min.z), .color = Vector(0, 1, 0) };
|
||||
corners[1] = DebugVertex { .position = Vector(min.x, min.y, max.z), .color = Vector(0, 1, 0) };
|
||||
corners[2] = DebugVertex { .position = Vector(min.x, max.y, min.z), .color = Vector(0, 1, 0) };
|
||||
corners[3] = DebugVertex { .position = Vector(min.x, max.y, max.z), .color = Vector(0, 1, 0) };
|
||||
corners[4] = DebugVertex { .position = Vector(max.x, min.y, min.z), .color = Vector(0, 1, 0) };
|
||||
corners[5] = DebugVertex { .position = Vector(max.x, min.y, max.z), .color = Vector(0, 1, 0) };
|
||||
corners[6] = DebugVertex { .position = Vector(max.x, max.y, min.z), .color = Vector(0, 1, 0) };
|
||||
corners[7] = DebugVertex { .position = Vector(max.x, max.y, max.z), .color = Vector(0, 1, 0) };
|
||||
|
||||
vertices.add(corners[0]);
|
||||
vertices.add(corners[1]);
|
||||
|
||||
vertices.add(corners[1]);
|
||||
vertices.add(corners[3]);
|
||||
|
||||
vertices.add(corners[2]);
|
||||
vertices.add(corners[3]);
|
||||
|
||||
vertices.add(corners[0]);
|
||||
vertices.add(corners[2]);
|
||||
|
||||
vertices.add(corners[0]);
|
||||
vertices.add(corners[4]);
|
||||
|
||||
vertices.add(corners[1]);
|
||||
vertices.add(corners[5]);
|
||||
|
||||
vertices.add(corners[2]);
|
||||
vertices.add(corners[6]);
|
||||
|
||||
vertices.add(corners[3]);
|
||||
vertices.add(corners[7]);
|
||||
|
||||
vertices.add(corners[4]);
|
||||
vertices.add(corners[5]);
|
||||
|
||||
vertices.add(corners[5]);
|
||||
vertices.add(corners[7]);
|
||||
|
||||
vertices.add(corners[6]);
|
||||
vertices.add(corners[7]);
|
||||
|
||||
vertices.add(corners[4]);
|
||||
vertices.add(corners[6]);
|
||||
}
|
||||
float surfaceArea() const
|
||||
{
|
||||
Math::Vector d = max - min;
|
||||
Vector d = max - min;
|
||||
return 2.0f * (d.x * d.y + d.y * d.z + d.z * d.x);
|
||||
}
|
||||
bool intersects(const AABB& other) const
|
||||
@@ -52,31 +100,31 @@ struct AABB
|
||||
}
|
||||
return true;
|
||||
}
|
||||
AABB getTransformedBox(const Math::Matrix4& matrix) const
|
||||
AABB getTransformedBox(const Matrix4& matrix) const
|
||||
{
|
||||
StaticArray<Math::Vector, 8> corners;
|
||||
corners[0] = Math::Vector(min.x, min.y, min.z);
|
||||
corners[1] = Math::Vector(min.x, min.y, max.z);
|
||||
corners[2] = Math::Vector(min.x, max.y, min.z);
|
||||
corners[3] = Math::Vector(min.x, max.y, max.z);
|
||||
corners[4] = Math::Vector(max.x, min.y, min.z);
|
||||
corners[5] = Math::Vector(max.x, min.y, max.z);
|
||||
corners[6] = Math::Vector(max.x, max.y, min.z);
|
||||
corners[7] = Math::Vector(max.x, max.y, max.z);
|
||||
Math::Vector tmin = Math::Vector(1, 1, 1) * std::numeric_limits<float>::max();
|
||||
Math::Vector tmax = Math::Vector(1, 1, 1) * std::numeric_limits<float>::min();
|
||||
StaticArray<Vector, 8> corners;
|
||||
corners[0] = Vector(min.x, min.y, min.z);
|
||||
corners[1] = Vector(min.x, min.y, max.z);
|
||||
corners[2] = Vector(min.x, max.y, min.z);
|
||||
corners[3] = Vector(min.x, max.y, max.z);
|
||||
corners[4] = Vector(max.x, min.y, min.z);
|
||||
corners[5] = Vector(max.x, min.y, max.z);
|
||||
corners[6] = Vector(max.x, max.y, min.z);
|
||||
corners[7] = Vector(max.x, max.y, max.z);
|
||||
Vector tmin = Vector(1, 1, 1) * std::numeric_limits<float>::max();
|
||||
Vector tmax = Vector(1, 1, 1) * std::numeric_limits<float>::lowest();
|
||||
for(int i = 0; i < 8; ++i)
|
||||
{
|
||||
Math::Vector transformed = matrix * Math::Vector4(corners[i], 1.0f);
|
||||
tmin = Math::Vector(std::min(tmin.x, transformed.x), std::min(tmin.y, transformed.y), std::min(tmin.z, transformed.z));
|
||||
tmax = Math::Vector(std::max(tmax.x, transformed.x), std::max(tmax.y, transformed.y), std::max(tmax.z, transformed.z));
|
||||
Vector transformed = matrix * Vector4(corners[i], 1.0f);
|
||||
tmin = Vector(std::min(tmin.x, transformed.x), std::min(tmin.y, transformed.y), std::min(tmin.z, transformed.z));
|
||||
tmax = Vector(std::max(tmax.x, transformed.x), std::max(tmax.y, transformed.y), std::max(tmax.z, transformed.z));
|
||||
}
|
||||
return AABB {
|
||||
.min = tmin,
|
||||
.max = tmax,
|
||||
};
|
||||
}
|
||||
void adjust(const Math::Vector vertex)
|
||||
void adjust(const Vector vertex)
|
||||
{
|
||||
min.x = std::min(min.x, vertex.x);
|
||||
min.y = std::min(min.y, vertex.y);
|
||||
@@ -89,12 +137,12 @@ struct AABB
|
||||
AABB combine(const AABB& other) const
|
||||
{
|
||||
return AABB {
|
||||
.min = Math::Vector(
|
||||
.min = Vector(
|
||||
std::min(min.x, other.min.x),
|
||||
std::min(min.y, other.min.y),
|
||||
std::min(min.z, other.min.z)
|
||||
),
|
||||
.max = Math::Vector (
|
||||
.max = Vector (
|
||||
std::max(max.x, other.max.x),
|
||||
std::max(max.y, other.max.y),
|
||||
std::max(max.z, other.max.z)
|
||||
|
||||
@@ -15,14 +15,14 @@ struct Camera
|
||||
Camera();
|
||||
~Camera();
|
||||
|
||||
Math::Matrix4 getViewMatrix() const
|
||||
Matrix4 getViewMatrix() const
|
||||
{
|
||||
assert (!bNeedsViewBuild);
|
||||
return viewMatrix;
|
||||
}
|
||||
Math::Vector getCameraPosition() const
|
||||
Vector getCameraPosition() const
|
||||
{
|
||||
return Math::Vector(viewMatrix[3]);
|
||||
return Vector(viewMatrix[3]);
|
||||
}
|
||||
void setViewport(Gfx::PViewport viewport);
|
||||
void mouseMove(float deltaX, float deltaY);
|
||||
@@ -30,7 +30,7 @@ struct Camera
|
||||
void moveX(float amount);
|
||||
void moveY(float amount);
|
||||
void buildViewMatrix();
|
||||
Math::Matrix4 viewMatrix;
|
||||
Matrix4 viewMatrix;
|
||||
//Transforms relative to actor
|
||||
float yaw;
|
||||
float pitch;
|
||||
|
||||
@@ -13,7 +13,7 @@ enum class ColliderType
|
||||
};
|
||||
struct Collider
|
||||
{
|
||||
ColliderType type;
|
||||
ColliderType type = ColliderType::STATIC;
|
||||
AABB boundingbox;
|
||||
ShapeBase physicsMesh;
|
||||
Collider transform(const Transform& transform) const;
|
||||
|
||||
@@ -8,10 +8,10 @@ namespace Component
|
||||
struct RigidBody
|
||||
{
|
||||
float mass = 1.0f;
|
||||
Math::Vector force;
|
||||
Math::Vector torque;
|
||||
Math::Vector linearMomentum;
|
||||
Math::Vector angularMomentum;
|
||||
Vector force;
|
||||
Vector torque;
|
||||
Vector linearMomentum;
|
||||
Vector angularMomentum;
|
||||
};
|
||||
} // namespace Component
|
||||
} // namespace Seele
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "ShapeBase.h"
|
||||
#include "AABB.h"
|
||||
|
||||
using namespace Seele;
|
||||
using namespace Seele::Component;
|
||||
@@ -20,13 +21,13 @@ struct ComputationState
|
||||
|
||||
/* volume integrals */
|
||||
float T0;
|
||||
Math::Vector T1, T2, TP;
|
||||
Vector T1, T2, TP;
|
||||
};
|
||||
|
||||
struct Face
|
||||
{
|
||||
StaticArray<Math::Vector, 3> vertices;
|
||||
Math::Vector normal;
|
||||
StaticArray<Vector, 3> vertices;
|
||||
Vector normal;
|
||||
float w;
|
||||
};
|
||||
|
||||
@@ -126,7 +127,7 @@ void computeFaceIntegrals(Face& f, ComputationState& state)
|
||||
+ w * (2 * (n[state.A] * state.Paa + n[state.B] * state.Pab) + w * state.Pa));
|
||||
}
|
||||
|
||||
void computeVolumeIntegrals(const Array<Math::Vector> vertices, const Array<uint32>& indices, ComputationState& state)
|
||||
void computeVolumeIntegrals(const Array<Vector> vertices, const Array<uint32>& indices, ComputationState& state)
|
||||
{
|
||||
std::memset(&state, 0, sizeof(ComputationState));
|
||||
for (size_t i = 0; i < indices.size(); i+=3)
|
||||
@@ -138,8 +139,8 @@ void computeVolumeIntegrals(const Array<Math::Vector> vertices, const Array<uint
|
||||
vertices[indices[i+2]],
|
||||
};
|
||||
|
||||
Math::Vector e1 = f.vertices[2] - f.vertices[0];
|
||||
Math::Vector e2 = f.vertices[1] - f.vertices[0];
|
||||
Vector e1 = f.vertices[2] - f.vertices[0];
|
||||
Vector e2 = f.vertices[1] - f.vertices[0];
|
||||
f.normal = glm::normalize(glm::cross(e1, e2));
|
||||
f.w = - f.normal.x * f.vertices[0].x
|
||||
- f.normal.y * f.vertices[0].y
|
||||
@@ -171,13 +172,13 @@ void computeVolumeIntegrals(const Array<Math::Vector> vertices, const Array<uint
|
||||
state.TP /= 2.0f;
|
||||
}
|
||||
|
||||
void computePhysicsParamsForMesh(Array<Math::Vector>& vertices, const Array<uint32_t>& indices, Math::Matrix3& bodyInertia, Math::Vector& centerOfMass, float& mass)
|
||||
void computePhysicsParamsForMesh(Array<Vector>& vertices, const Array<uint32_t>& indices, Matrix3& bodyInertia, Vector& centerOfMass, float& mass)
|
||||
{
|
||||
ComputationState state;
|
||||
computeVolumeIntegrals(vertices, indices, state);
|
||||
float density = 1;
|
||||
mass = density * state.T0;
|
||||
Math::Vector r = state.T1 / state.T0;
|
||||
Vector r = state.T1 / state.T0;
|
||||
centerOfMass = r;
|
||||
bodyInertia[0][0] = density * (state.T2.y + state.T2.z);
|
||||
bodyInertia[1][1] = density * (state.T2.z + state.T2.x);
|
||||
@@ -194,7 +195,12 @@ void computePhysicsParamsForMesh(Array<Math::Vector>& vertices, const Array<uint
|
||||
bodyInertia[2][1] = bodyInertia[1][2] += mass * r.z * r.x;
|
||||
}
|
||||
|
||||
ShapeBase::ShapeBase(Array<Math::Vector> vertices, Array<uint32> indices)
|
||||
ShapeBase::ShapeBase()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ShapeBase::ShapeBase(Array<Vector> vertices, Array<uint32> indices)
|
||||
: vertices(vertices)
|
||||
, indices(indices)
|
||||
{
|
||||
@@ -206,17 +212,17 @@ ShapeBase ShapeBase::transform(const Component::Transform& transform) const
|
||||
ShapeBase result = *this;
|
||||
for(auto& vert : result.vertices)
|
||||
{
|
||||
vert = transform.toMatrix() * Math::Vector4(vert, 1.0f);
|
||||
vert = transform.toMatrix() * Vector4(vert, 1.0f);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void ShapeBase::addCollider(Array<Math::Vector> verts, Array<uint32> inds, Math::Matrix4 matrix)
|
||||
void ShapeBase::addCollider(Array<Vector> verts, Array<uint32> inds, Matrix4 matrix)
|
||||
{
|
||||
size_t indOffset = vertices.size();
|
||||
for(auto vert : verts)
|
||||
{
|
||||
vertices.add(Math::Vector(matrix * Math::Vector4(vert, 1.0f)));
|
||||
vertices.add(Vector(matrix * Vector4(vert, 1.0f)));
|
||||
}
|
||||
for(auto ind : inds)
|
||||
{
|
||||
@@ -224,3 +230,39 @@ void ShapeBase::addCollider(Array<Math::Vector> verts, Array<uint32> inds, Math:
|
||||
}
|
||||
computePhysicsParamsForMesh(vertices, indices, bodyInertia, centerOfMass, mass);
|
||||
}
|
||||
|
||||
void ShapeBase::visualize() const
|
||||
{
|
||||
for(uint32 i = 0; i < indices.size(); i+=3)
|
||||
{
|
||||
gDebugVertices.add(DebugVertex{
|
||||
.position = Vector(vertices[indices[i+0]]),
|
||||
.color = Vector(1, 0, 0),
|
||||
});
|
||||
|
||||
gDebugVertices.add(DebugVertex{
|
||||
.position = Vector(vertices[indices[i+1]]),
|
||||
.color = Vector(1, 0, 0),
|
||||
});
|
||||
|
||||
gDebugVertices.add(DebugVertex{
|
||||
.position = Vector(vertices[indices[i+1]]),
|
||||
.color = Vector(1, 0, 0),
|
||||
});
|
||||
|
||||
gDebugVertices.add(DebugVertex{
|
||||
.position = Vector(vertices[indices[i+2]]),
|
||||
.color = Vector(1, 0, 0),
|
||||
});
|
||||
|
||||
gDebugVertices.add(DebugVertex{
|
||||
.position = Vector(vertices[indices[i+2]]),
|
||||
.color = Vector(1, 0, 0),
|
||||
});
|
||||
|
||||
gDebugVertices.add(DebugVertex{
|
||||
.position = Vector(vertices[indices[i+0]]),
|
||||
.color = Vector(1, 0, 0),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
#include "Containers/Array.h"
|
||||
#include "Transform.h"
|
||||
#include "Graphics/DebugVertex.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
@@ -8,13 +9,15 @@ namespace Component
|
||||
{
|
||||
struct ShapeBase
|
||||
{
|
||||
ShapeBase(Array<Math::Vector> vertices, Array<uint32> indices);
|
||||
ShapeBase();
|
||||
ShapeBase(Array<Vector> vertices, Array<uint32> indices);
|
||||
ShapeBase transform(const Component::Transform& transform) const;
|
||||
void addCollider(Array<Math::Vector> vertices, Array<uint32> indices, Math::Matrix4 matrix);
|
||||
Math::Vector centerOfMass;
|
||||
void addCollider(Array<Vector> vertices, Array<uint32> indices, Matrix4 matrix);
|
||||
void visualize() const;
|
||||
Vector centerOfMass;
|
||||
float mass;
|
||||
Math::Matrix3 bodyInertia;
|
||||
Array<Math::Vector> vertices;
|
||||
Matrix3 bodyInertia;
|
||||
Array<Vector> vertices;
|
||||
Array<uint32> indices;
|
||||
};
|
||||
} // namespace Component
|
||||
|
||||
@@ -7,6 +7,8 @@ namespace Component
|
||||
{
|
||||
struct StaticMesh
|
||||
{
|
||||
StaticMesh() {}
|
||||
StaticMesh(PMeshAsset mesh) : mesh(mesh) {}
|
||||
PMeshAsset mesh;
|
||||
};
|
||||
} // namespace Component
|
||||
|
||||
@@ -5,55 +5,55 @@ using namespace Seele::Component;
|
||||
DEFINE_COMPONENT(Transform)
|
||||
|
||||
|
||||
void Transform::setPosition(Math::Vector pos)
|
||||
void Transform::setPosition(Vector pos)
|
||||
{
|
||||
transform.setPosition(pos);
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
void Transform::setRotation(Math::Quaternion quat)
|
||||
void Transform::setRotation(Quaternion quat)
|
||||
{
|
||||
transform.setRotation(quat);
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
void Transform::setScale(Math::Vector scale)
|
||||
void Transform::setScale(Vector scale)
|
||||
{
|
||||
transform.setScale(scale);
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
void Transform::setRelativeLocation(Math::Vector location)
|
||||
void Transform::setRelativeLocation(Vector location)
|
||||
{
|
||||
transform = Math::Transform(location, transform.getRotation(), transform.getScale());
|
||||
dirty = true;
|
||||
}
|
||||
void Transform::setRelativeRotation(Math::Vector rotation)
|
||||
void Transform::setRelativeRotation(Vector rotation)
|
||||
{
|
||||
transform = Math::Transform(transform.getPosition(), Math::Quaternion(rotation), transform.getScale());
|
||||
transform = Math::Transform(transform.getPosition(), Quaternion(rotation), transform.getScale());
|
||||
dirty = true;
|
||||
}
|
||||
void Transform::setRelativeRotation(Math::Quaternion rotation)
|
||||
void Transform::setRelativeRotation(Quaternion rotation)
|
||||
{
|
||||
transform = Math::Transform(transform.getPosition(), rotation, transform.getScale());
|
||||
dirty = true;
|
||||
}
|
||||
void Transform::setRelativeScale(Math::Vector scale)
|
||||
void Transform::setRelativeScale(Vector scale)
|
||||
{
|
||||
transform = Math::Transform(transform.getPosition(), transform.getRotation(), scale);
|
||||
dirty = true;
|
||||
}
|
||||
void Transform::addRelativeLocation(Math::Vector translation)
|
||||
void Transform::addRelativeLocation(Vector translation)
|
||||
{
|
||||
transform = Math::Transform(transform.getPosition() + translation, transform.getRotation(), transform.getScale());
|
||||
dirty = true;
|
||||
}
|
||||
void Transform::addRelativeRotation(Math::Vector rotation)
|
||||
void Transform::addRelativeRotation(Vector rotation)
|
||||
{
|
||||
transform = Math::Transform(transform.getPosition(), transform.getRotation() * Math::Quaternion(rotation), transform.getScale());
|
||||
transform = Math::Transform(transform.getPosition(), transform.getRotation() * Quaternion(rotation), transform.getScale());
|
||||
dirty = true;
|
||||
}
|
||||
void Transform::addRelativeRotation(Math::Quaternion rotation)
|
||||
void Transform::addRelativeRotation(Quaternion rotation)
|
||||
{
|
||||
transform = Math::Transform(transform.getPosition(), transform.getRotation() * rotation, transform.getScale());
|
||||
dirty = true;
|
||||
|
||||
@@ -8,31 +8,31 @@ namespace Component
|
||||
{
|
||||
struct Transform
|
||||
{
|
||||
Math::Vector getPosition() const { return transform.getPosition(); }
|
||||
Math::Quaternion getRotation() const { return transform.getRotation(); }
|
||||
Math::Vector getScale() const { return transform.getScale(); }
|
||||
Vector getPosition() const { return transform.getPosition(); }
|
||||
Quaternion getRotation() const { return transform.getRotation(); }
|
||||
Vector getScale() const { return transform.getScale(); }
|
||||
|
||||
Math::Vector getForward() const { return transform.getForward(); }
|
||||
Math::Vector getUp() const { return transform.getUp(); }
|
||||
Math::Vector getRight() const { return transform.getRight(); }
|
||||
Vector getForward() const { return transform.getForward(); }
|
||||
Vector getUp() const { return transform.getUp(); }
|
||||
Vector getRight() const { return transform.getRight(); }
|
||||
|
||||
Math::Matrix4 toMatrix() const { return transform.toMatrix(); }
|
||||
Matrix4 toMatrix() const { return transform.toMatrix(); }
|
||||
|
||||
bool isDirty() const { return dirty; }
|
||||
void clean() { dirty = false; }
|
||||
|
||||
void setPosition(Math::Vector pos);
|
||||
void setRotation(Math::Quaternion quat);
|
||||
void setScale(Math::Vector scale);
|
||||
void setPosition(Vector pos);
|
||||
void setRotation(Quaternion quat);
|
||||
void setScale(Vector scale);
|
||||
|
||||
void setRelativeLocation(Math::Vector location);
|
||||
void setRelativeRotation(Math::Quaternion rotation);
|
||||
void setRelativeRotation(Math::Vector rotation);
|
||||
void setRelativeScale(Math::Vector scale);
|
||||
void setRelativeLocation(Vector location);
|
||||
void setRelativeRotation(Quaternion rotation);
|
||||
void setRelativeRotation(Vector rotation);
|
||||
void setRelativeScale(Vector scale);
|
||||
|
||||
void addRelativeLocation(Math::Vector translation);
|
||||
void addRelativeRotation(Math::Quaternion rotation);
|
||||
void addRelativeRotation(Math::Vector rotation);
|
||||
void addRelativeLocation(Vector translation);
|
||||
void addRelativeRotation(Quaternion rotation);
|
||||
void addRelativeRotation(Vector rotation);
|
||||
private:
|
||||
bool dirty = true;
|
||||
Math::Transform transform;
|
||||
|
||||
@@ -156,7 +156,8 @@ public:
|
||||
assert(_data != nullptr);
|
||||
std::uninitialized_copy(init.begin(), init.end(), begin());
|
||||
}
|
||||
Array(const Array &other)
|
||||
|
||||
constexpr Array(const Array &other)
|
||||
: arraySize(other.arraySize)
|
||||
, allocated(other.allocated)
|
||||
, allocator(std::allocator_traits<allocator_type>::select_on_container_copy_construction(other.allocator))
|
||||
@@ -165,7 +166,16 @@ public:
|
||||
assert(_data != nullptr);
|
||||
std::uninitialized_copy(other.begin(), other.end(), begin());
|
||||
}
|
||||
Array(Array &&other) noexcept
|
||||
constexpr Array(const Array& other, const Allocator& alloc)
|
||||
: arraySize(other.arraySize)
|
||||
, allocated(other.allocated)
|
||||
, allocator(alloc)
|
||||
{
|
||||
_data = allocateArray(other.allocated);
|
||||
assert(_data != nullptr);
|
||||
std::uninitialized_copy(other.begin(), other.end(), begin());
|
||||
}
|
||||
constexpr Array(Array &&other) noexcept
|
||||
: arraySize(std::move(other.arraySize))
|
||||
, allocated(std::move(other.allocated))
|
||||
, allocator(std::move(other.allocator))
|
||||
@@ -175,10 +185,26 @@ public:
|
||||
other.allocated = 0;
|
||||
other.arraySize = 0;
|
||||
}
|
||||
constexpr Array(Array &&other, const Allocator& alloc) noexcept
|
||||
: arraySize(std::move(other.arraySize))
|
||||
, allocated(std::move(other.allocated))
|
||||
, allocator(alloc)
|
||||
{
|
||||
_data = allocateArray(other.allocated);
|
||||
std::uninitialized_move(other.begin(), other.end(), begin());
|
||||
other.deallocateArray(other._data, other.allocated);
|
||||
other._data = nullptr;
|
||||
other.allocated = 0;
|
||||
other.arraySize = 0;
|
||||
}
|
||||
Array &operator=(const Array &other)
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
if (other.arraySize > allocated)
|
||||
{
|
||||
clear();
|
||||
}
|
||||
if constexpr (std::allocator_traits<allocator_type>::propagate_on_container_copy_assignment::value )
|
||||
{
|
||||
if (!std::allocator_traits<allocator_type>::is_always_equal::value
|
||||
@@ -188,10 +214,6 @@ public:
|
||||
}
|
||||
allocator = other.allocator;
|
||||
}
|
||||
if (other.arraySize > allocated)
|
||||
{
|
||||
clear();
|
||||
}
|
||||
if(_data == nullptr)
|
||||
{
|
||||
_data = allocateArray(other.allocated);
|
||||
@@ -207,14 +229,14 @@ public:
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
if constexpr (std::allocator_traits<allocator_type>::propagate_on_container_move_assignment::value)
|
||||
{
|
||||
allocator = std::move(other.allocator);
|
||||
}
|
||||
if (_data != nullptr)
|
||||
{
|
||||
clear();
|
||||
}
|
||||
if constexpr (std::allocator_traits<allocator_type>::propagate_on_container_move_assignment::value)
|
||||
{
|
||||
allocator = std::move(other.allocator);
|
||||
}
|
||||
allocated = std::move(other.allocated);
|
||||
arraySize = std::move(other.arraySize);
|
||||
_data = other._data;
|
||||
@@ -395,7 +417,7 @@ public:
|
||||
}
|
||||
constexpr void resize(size_type newSize)
|
||||
{
|
||||
resizeInternal(newSize, std::move(T()));
|
||||
resizeInternal(newSize, T());
|
||||
}
|
||||
constexpr void resize(size_type newSize, const value_type& value)
|
||||
{
|
||||
@@ -532,7 +554,7 @@ private:
|
||||
return _data[arraySize - 1];
|
||||
}
|
||||
template<typename Type>
|
||||
void resizeInternal(size_type newSize, Type&& value) noexcept
|
||||
void resizeInternal(size_type newSize, const Type& value) noexcept
|
||||
{
|
||||
if (newSize <= allocated)
|
||||
{
|
||||
@@ -550,7 +572,7 @@ private:
|
||||
// Or construct the new elements by default
|
||||
for(size_type i = arraySize; i < newSize; ++i)
|
||||
{
|
||||
std::allocator_traits<allocator_type>::construct(allocator, &_data[i], std::move(value));
|
||||
std::allocator_traits<allocator_type>::construct(allocator, &_data[i], value);
|
||||
}
|
||||
}
|
||||
arraySize = newSize;
|
||||
@@ -568,7 +590,7 @@ private:
|
||||
// As well as default initialize the others
|
||||
for(size_type i = arraySize; i < newSize; ++i)
|
||||
{
|
||||
std::allocator_traits<allocator_type>::construct(allocator, &newData[i], std::move(value));
|
||||
std::allocator_traits<allocator_type>::construct(allocator, &newData[i], value);
|
||||
}
|
||||
deallocateArray(_data, allocated);
|
||||
arraySize = newSize;
|
||||
|
||||
@@ -124,10 +124,46 @@ public:
|
||||
, beginIt(Iterator(root))
|
||||
, endIt(Iterator(tail))
|
||||
, _size(0)
|
||||
, allocator(NodeAllocator())
|
||||
, allocator(Allocator())
|
||||
{
|
||||
}
|
||||
explicit List(const Allocator& alloc)
|
||||
: root(nullptr)
|
||||
, tail(nullptr)
|
||||
, beginIt(Iterator(root))
|
||||
, endIt(Iterator(tail))
|
||||
, _size(0)
|
||||
, allocator(alloc)
|
||||
{
|
||||
}
|
||||
List(size_type count, const T& value = T(), const Allocator& alloc = Allocator())
|
||||
: List(alloc)
|
||||
{
|
||||
for(size_type i = 0; i < count; ++i)
|
||||
{
|
||||
add(value);
|
||||
}
|
||||
}
|
||||
List(size_type count, const Allocator& alloc = Allocator())
|
||||
: List(alloc)
|
||||
{
|
||||
for(size_type i = 0; i < count; ++i)
|
||||
{
|
||||
add(T());
|
||||
}
|
||||
}
|
||||
List(const List& other)
|
||||
: List(std::allocator_traits<allocator_type>::select_on_container_copy_construction(other.allocator))
|
||||
{
|
||||
//TODO: improve
|
||||
for(const auto& it : other)
|
||||
{
|
||||
add(it);
|
||||
}
|
||||
}
|
||||
|
||||
List(const List& other, const Allocator& alloc)
|
||||
: List(alloc)
|
||||
{
|
||||
//TODO: improve
|
||||
for(const auto& it : other)
|
||||
@@ -141,8 +177,19 @@ public:
|
||||
, beginIt(std::move(other.beginIt))
|
||||
, endIt(std::move(other.endIt))
|
||||
, _size(std::move(other._size))
|
||||
, allocator(std::move(other.allocator))
|
||||
{
|
||||
other._size = 0;
|
||||
other.clear();
|
||||
}
|
||||
List(List&& other, const Allocator& alloc)
|
||||
: root(std::move(other.root))
|
||||
, tail(std::move(other.tail))
|
||||
, beginIt(std::move(other.beginIt))
|
||||
, endIt(std::move(other.endIt))
|
||||
, _size(std::move(other._size))
|
||||
, allocator(allocator)
|
||||
{
|
||||
other.clear();
|
||||
}
|
||||
~List()
|
||||
{
|
||||
@@ -153,6 +200,15 @@ public:
|
||||
if(this != &other)
|
||||
{
|
||||
clear();
|
||||
if constexpr (std::allocator_traits<allocator_type>::propagate_on_container_copy_assignment::value )
|
||||
{
|
||||
if (!std::allocator_traits<allocator_type>::is_always_equal::value
|
||||
&& allocator != other.allocator)
|
||||
{
|
||||
clear();
|
||||
}
|
||||
allocator = other.allocator;
|
||||
}
|
||||
for(const auto& it : other)
|
||||
{
|
||||
add(it);
|
||||
@@ -166,6 +222,10 @@ public:
|
||||
if(this != &other)
|
||||
{
|
||||
clear();
|
||||
if constexpr (std::allocator_traits<allocator_type>::propagate_on_container_move_assignment::value)
|
||||
{
|
||||
allocator = std::move(other.allocator);
|
||||
}
|
||||
root = other.root;
|
||||
tail = other.tail;
|
||||
beginIt = other.beginIt;
|
||||
@@ -214,7 +274,7 @@ public:
|
||||
}
|
||||
// takes all elements from other and move-inserts them into
|
||||
// this, clearing other in the process
|
||||
void moveElements(List& other)
|
||||
void moveElements(List&& other)
|
||||
{
|
||||
tail->prev->next = other.root;
|
||||
other.root->prev = tail->prev;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user