From 6c8b66906d7b02a2d996e018b6609537da531555 Mon Sep 17 00:00:00 2001 From: Tobenna Peter Igwe Date: Sat, 7 Jun 2014 21:13:59 +0100 Subject: [PATCH 1/4] Added implementation of Lemke-Howson algorithm --- build.properties | 4 +- build.xml | 11 +- native-algo/lh-vector/.gitignore | 3 + native-algo/lh-vector/Depend | 17 + native-algo/lh-vector/Doxyfile | 1826 +++++++++++++++++ native-algo/lh-vector/Makefile | 87 + native-algo/lh-vector/README | 32 + native-algo/lh-vector/README.md | 36 + native-algo/lh-vector/alloc.c | 27 + native-algo/lh-vector/alloc.h | 44 + native-algo/lh-vector/col.c | 138 ++ native-algo/lh-vector/col.h | 49 + native-algo/lh-vector/equilibrium.c | 166 ++ native-algo/lh-vector/equilibrium.h | 107 + native-algo/lh-vector/gequilibrium.c | 172 ++ native-algo/lh-vector/glemke.c | 1547 ++++++++++++++ native-algo/lh-vector/gmp.h | 984 +++++++++ native-algo/lh-vector/gmpwrap.c | 45 + native-algo/lh-vector/gmpwrap.h | 77 + native-algo/lh-vector/grat.c | 417 ++++ native-algo/lh-vector/inlemke.c | 200 ++ native-algo/lh-vector/inlemkehowson.c | 586 ++++++ native-algo/lh-vector/labelstest | 17 + native-algo/lh-vector/lemke.c | 1491 ++++++++++++++ native-algo/lh-vector/lemke.h | 104 + native-algo/lh-vector/list.c | 152 ++ native-algo/lh-vector/list.h | 87 + native-algo/lh-vector/mp.c | 633 ++++++ native-algo/lh-vector/mp.h | 169 ++ native-algo/lh-vector/path/Makefile | 11 + native-algo/lh-vector/path/gen-path | 11 + native-algo/lh-vector/path/path-input | 91 + native-algo/lh-vector/path/path-input12 | 39 + native-algo/lh-vector/path/path.c | 200 ++ native-algo/lh-vector/rat.c | 359 ++++ native-algo/lh-vector/rat.h | 295 +++ native-algo/lh-vector/report/final.pdf | Bin 0 -> 139225 bytes native-algo/lh-vector/report/final/Makefile | 9 + .../lh-vector/report/final/computeall.tex | 80 + .../lh-vector/report/final/img/img0.pdf | Bin 0 -> 7562 bytes .../lh-vector/report/final/img/img1.pdf | Bin 0 -> 8299 bytes .../lh-vector/report/final/img/img2.pdf | Bin 0 -> 8818 bytes .../lh-vector/report/final/implementation.tex | 101 + native-algo/lh-vector/report/final/intro.tex | 9 + native-algo/lh-vector/report/final/observ.tex | 1 + native-algo/lh-vector/report/final/ref.bib | 15 + native-algo/lh-vector/report/final/report.tex | 45 + .../lh-vector/report/final/testing.tex | 128 ++ native-algo/lh-vector/report/mideval.pdf | Bin 0 -> 130233 bytes native-algo/lh-vector/report/summary.pdf | Bin 0 -> 87613 bytes native-algo/lh-vector/report/summary/Makefile | 7 + .../lh-vector/report/summary/summary.tex | 162 ++ native-algo/lh-vector/sample-input | 16 + native-algo/lh-vector/sample-output | 1047 ++++++++++ native-algo/lh-vector/summary.pdf | Bin 0 -> 87613 bytes .../lh-vector/test/dualcyclic/dx2d/2x4 | 8 + .../lh-vector/test/dualcyclic/dx2d/2x4bit | 63 + .../lh-vector/test/dualcyclic/dx2d/2x4path | 6 + .../lh-vector/test/dualcyclic/dx2d/4x8 | 12 + .../lh-vector/test/dualcyclic/dx2d/4x8path | 12 + .../lh-vector/test/dualcyclic/dx2d/6x12 | 16 + .../lh-vector/test/dualcyclic/dx2d/6x12path | 18 + .../lh-vector/test/dualcyclic/dx2d/out | 12 + .../test/dualcyclic/dx2d/pathlengthtestm1 | 27 + .../test/dualcyclic/dx2d/pathlengthtestm2 | 27 + native-algo/lh-vector/test/dualcyclic/dxd/2x2 | 8 + native-algo/lh-vector/test/dualcyclic/dxd/4x4 | 12 + native-algo/lh-vector/test/dualcyclic/dxd/6x6 | 16 + native-algo/lh-vector/test/dualcyclic/dxd/8x8 | 20 + .../lh-vector/test/dualcyclic/dxd/Makefile | 11 + .../test/dualcyclic/dxd/dualcyclictest | 22 + .../test/dualcyclic/dxd/dualcyclictestm1 | 45 + .../test/dualcyclic/dxd/dualcyclictestm2 | 45 + .../lh-vector/test/dualcyclic/dxd/lh-label.c | 231 +++ .../lh-vector/test/dualcyclic/dxd/sample | 3 + .../lh-vector/test/dualcyclic/thesis.mws | 241 +++ native-algo/lh-vector/test/identity/Makefile | 19 + .../lh-vector/test/identity/genidenpath.c | 30 + .../lh-vector/test/identity/genidentity.c | 43 + .../lh-vector/test/identity/identitytestm1 | 31 + .../lh-vector/test/identity/identitytestm2 | 31 + native-algo/lh-vector/test/invAB/Makefile | 11 + native-algo/lh-vector/test/invAB/invABdtest.c | 165 ++ native-algo/lh-vector/test/invAB/invABtest | 35 + native-algo/lh-vector/test/invAB/sample-input | 16 + .../lh-vector/test/rat_dec/rat_dectestm1 | 32 + .../lh-vector/test/rat_dec/rat_dectestm2 | 32 + native-algo/lh-vector/test/testall | 37 + .../src/lse/math/games/web/LHServlet.java | 367 ++++ web-service/war/WEB-INF/web.xml | 9 + web-service/war/builder/webservices.xml | 23 +- web-service/war/lh/index.jsp | 3 + web-service/war/lh/servlet/hidden.txt | 1 + 93 files changed, 13588 insertions(+), 6 deletions(-) create mode 100644 native-algo/lh-vector/.gitignore create mode 100644 native-algo/lh-vector/Depend create mode 100644 native-algo/lh-vector/Doxyfile create mode 100644 native-algo/lh-vector/Makefile create mode 100644 native-algo/lh-vector/README create mode 100644 native-algo/lh-vector/README.md create mode 100644 native-algo/lh-vector/alloc.c create mode 100644 native-algo/lh-vector/alloc.h create mode 100644 native-algo/lh-vector/col.c create mode 100644 native-algo/lh-vector/col.h create mode 100644 native-algo/lh-vector/equilibrium.c create mode 100644 native-algo/lh-vector/equilibrium.h create mode 100644 native-algo/lh-vector/gequilibrium.c create mode 100644 native-algo/lh-vector/glemke.c create mode 100644 native-algo/lh-vector/gmp.h create mode 100644 native-algo/lh-vector/gmpwrap.c create mode 100644 native-algo/lh-vector/gmpwrap.h create mode 100644 native-algo/lh-vector/grat.c create mode 100644 native-algo/lh-vector/inlemke.c create mode 100644 native-algo/lh-vector/inlemkehowson.c create mode 100755 native-algo/lh-vector/labelstest create mode 100644 native-algo/lh-vector/lemke.c create mode 100644 native-algo/lh-vector/lemke.h create mode 100644 native-algo/lh-vector/list.c create mode 100644 native-algo/lh-vector/list.h create mode 100644 native-algo/lh-vector/mp.c create mode 100644 native-algo/lh-vector/mp.h create mode 100644 native-algo/lh-vector/path/Makefile create mode 100755 native-algo/lh-vector/path/gen-path create mode 100644 native-algo/lh-vector/path/path-input create mode 100644 native-algo/lh-vector/path/path-input12 create mode 100644 native-algo/lh-vector/path/path.c create mode 100644 native-algo/lh-vector/rat.c create mode 100644 native-algo/lh-vector/rat.h create mode 100644 native-algo/lh-vector/report/final.pdf create mode 100644 native-algo/lh-vector/report/final/Makefile create mode 100644 native-algo/lh-vector/report/final/computeall.tex create mode 100644 native-algo/lh-vector/report/final/img/img0.pdf create mode 100644 native-algo/lh-vector/report/final/img/img1.pdf create mode 100644 native-algo/lh-vector/report/final/img/img2.pdf create mode 100644 native-algo/lh-vector/report/final/implementation.tex create mode 100644 native-algo/lh-vector/report/final/intro.tex create mode 100644 native-algo/lh-vector/report/final/observ.tex create mode 100644 native-algo/lh-vector/report/final/ref.bib create mode 100644 native-algo/lh-vector/report/final/report.tex create mode 100644 native-algo/lh-vector/report/final/testing.tex create mode 100644 native-algo/lh-vector/report/mideval.pdf create mode 100644 native-algo/lh-vector/report/summary.pdf create mode 100644 native-algo/lh-vector/report/summary/Makefile create mode 100644 native-algo/lh-vector/report/summary/summary.tex create mode 100644 native-algo/lh-vector/sample-input create mode 100644 native-algo/lh-vector/sample-output create mode 100644 native-algo/lh-vector/summary.pdf create mode 100644 native-algo/lh-vector/test/dualcyclic/dx2d/2x4 create mode 100644 native-algo/lh-vector/test/dualcyclic/dx2d/2x4bit create mode 100644 native-algo/lh-vector/test/dualcyclic/dx2d/2x4path create mode 100644 native-algo/lh-vector/test/dualcyclic/dx2d/4x8 create mode 100644 native-algo/lh-vector/test/dualcyclic/dx2d/4x8path create mode 100644 native-algo/lh-vector/test/dualcyclic/dx2d/6x12 create mode 100644 native-algo/lh-vector/test/dualcyclic/dx2d/6x12path create mode 100644 native-algo/lh-vector/test/dualcyclic/dx2d/out create mode 100755 native-algo/lh-vector/test/dualcyclic/dx2d/pathlengthtestm1 create mode 100755 native-algo/lh-vector/test/dualcyclic/dx2d/pathlengthtestm2 create mode 100644 native-algo/lh-vector/test/dualcyclic/dxd/2x2 create mode 100644 native-algo/lh-vector/test/dualcyclic/dxd/4x4 create mode 100644 native-algo/lh-vector/test/dualcyclic/dxd/6x6 create mode 100644 native-algo/lh-vector/test/dualcyclic/dxd/8x8 create mode 100644 native-algo/lh-vector/test/dualcyclic/dxd/Makefile create mode 100755 native-algo/lh-vector/test/dualcyclic/dxd/dualcyclictest create mode 100755 native-algo/lh-vector/test/dualcyclic/dxd/dualcyclictestm1 create mode 100755 native-algo/lh-vector/test/dualcyclic/dxd/dualcyclictestm2 create mode 100644 native-algo/lh-vector/test/dualcyclic/dxd/lh-label.c create mode 100644 native-algo/lh-vector/test/dualcyclic/dxd/sample create mode 100644 native-algo/lh-vector/test/dualcyclic/thesis.mws create mode 100644 native-algo/lh-vector/test/identity/Makefile create mode 100644 native-algo/lh-vector/test/identity/genidenpath.c create mode 100644 native-algo/lh-vector/test/identity/genidentity.c create mode 100755 native-algo/lh-vector/test/identity/identitytestm1 create mode 100755 native-algo/lh-vector/test/identity/identitytestm2 create mode 100644 native-algo/lh-vector/test/invAB/Makefile create mode 100644 native-algo/lh-vector/test/invAB/invABdtest.c create mode 100755 native-algo/lh-vector/test/invAB/invABtest create mode 100644 native-algo/lh-vector/test/invAB/sample-input create mode 100755 native-algo/lh-vector/test/rat_dec/rat_dectestm1 create mode 100755 native-algo/lh-vector/test/rat_dec/rat_dectestm2 create mode 100755 native-algo/lh-vector/test/testall create mode 100644 web-service/src/lse/math/games/web/LHServlet.java create mode 100644 web-service/war/lh/index.jsp create mode 100644 web-service/war/lh/servlet/hidden.txt diff --git a/build.properties b/build.properties index 3b82500..82ea773 100644 --- a/build.properties +++ b/build.properties @@ -1,5 +1,5 @@ -FLEX_HOME = /Users/rahul/Downloads/flex_sdk/ -JETTY_HOME = /Users/rahul/Downloads/jetty/jetty-distribution-9.1.2.v20140210/ +FLEX_HOME = ${env.FLEX_HOME} +JETTY_HOME = ${env.JETTY_HOME} WAR_DIST_DIR = ${JETTY_HOME}/webapps #FLEX_HOME = C:\\Users\\Martin\\Documents\\flex_sdk_4.1.0 #JETTY_HOME = C:\\Users\\Martin\\Documents\\Jetty8 diff --git a/build.xml b/build.xml index 72bdfcc..4e785ef 100644 --- a/build.xml +++ b/build.xml @@ -8,7 +8,7 @@ - + @@ -26,6 +26,7 @@ + @@ -67,7 +68,8 @@ - + + @@ -328,6 +330,7 @@ + @@ -361,6 +364,7 @@ + @@ -375,6 +379,9 @@ + + + diff --git a/native-algo/lh-vector/.gitignore b/native-algo/lh-vector/.gitignore new file mode 100644 index 0000000..4b02208 --- /dev/null +++ b/native-algo/lh-vector/.gitignore @@ -0,0 +1,3 @@ +*.o +inlh +inlemke diff --git a/native-algo/lh-vector/Depend b/native-algo/lh-vector/Depend new file mode 100644 index 0000000..1592524 --- /dev/null +++ b/native-algo/lh-vector/Depend @@ -0,0 +1,17 @@ +alloc.o: alloc.c alloc.h +col.o: col.c col.h +mp.o: mp.c mp.h +inlemke.o: inlemke.c alloc.h col.h rat.h mp.h lemke.h list.h \ + equilibrium.h +rat.o: rat.c rat.h mp.h +equilibrium.o: equilibrium.c rat.h mp.h equilibrium.h alloc.h col.h +list.o: list.c equilibrium.h alloc.h col.h rat.h mp.h list.h +lemke.o: lemke.c alloc.h col.h lemke.h list.h equilibrium.h rat.h mp.h +gmpwrap.o: gmpwrap.c gmp.h gmpwrap.h +grat.o: grat.c rat.h gmp.h gmpwrap.h mp.h +gequilibrium.o: gequilibrium.c rat.h gmp.h gmpwrap.h mp.h equilibrium.h \ + alloc.h col.h +glemke.o: glemke.c alloc.h col.h lemke.h list.h equilibrium.h rat.h gmp.h \ + gmpwrap.h mp.h +inlemkehowson.o: inlemkehowson.c alloc.h col.h rat.h mp.h lemke.h list.h \ + equilibrium.h diff --git a/native-algo/lh-vector/Doxyfile b/native-algo/lh-vector/Doxyfile new file mode 100644 index 0000000..a6827b3 --- /dev/null +++ b/native-algo/lh-vector/Doxyfile @@ -0,0 +1,1826 @@ +# Doxyfile 1.8.1.2 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# http://www.gnu.org/software/libiconv for the list of possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or sequence of words) that should +# identify the project. Note that if you do not use Doxywizard you need +# to put quotes around the project name if it contains spaces. + +PROJECT_NAME = "Lemke-Howson with Covering Vectors" + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer +# a quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = + +# With the PROJECT_LOGO tag one can specify an logo or icon that is +# included in the documentation. The maximum height of the logo should not +# exceed 55 pixels and the maximum width should not exceed 200 pixels. +# Doxygen will copy the logo to the output directory. + +PROJECT_LOGO = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = doc + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = YES + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, +# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English +# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, +# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, +# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = NO + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful if your file system +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = YES + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# This tag can be used to specify a number of word-keyword mappings (TCL only). +# A mapping has the form "name=value". For example adding +# "class=itcl::class" will allow you to use the command class in the +# itcl::class meaning. + +TCL_SUBST = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = YES + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for +# Java. For instance, namespaces will be presented as packages, qualified +# scopes will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources only. Doxygen will then generate output that is more tailored for +# Fortran. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for +# VHDL. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given extension. +# Doxygen has a built-in mapping, but you can override or extend it using this +# tag. The format is ext=language, where ext is a file extension, and language +# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, +# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make +# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C +# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions +# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all +# comments according to the Markdown format, which allows for more readable +# documentation. See http://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by doxygen, so you +# can mix doxygen, HTML, and XML commands with Markdown formatting. +# Disable only in case of backward compatibilities issues. + +MARKDOWN_SUPPORT = YES + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also makes the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +# Doxygen will parse them like normal C++ but will assume all classes use public +# instead of private inheritance when no explicit protection keyword is present. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate getter +# and setter methods for a property. Setting this option to YES (the default) +# will make doxygen replace the get and set methods by a property in the +# documentation. This will only work if the methods are indeed getting or +# setting a simple type. If this is not the case, or you want to show the +# methods anyway, you should set this option to NO. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and +# unions are shown inside the group in which they are included (e.g. using +# @ingroup) instead of on a separate page (for HTML and Man pages) or +# section (for LaTeX and RTF). + +INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and +# unions with only public data fields will be shown inline in the documentation +# of the scope in which they are defined (i.e. file, namespace, or group +# documentation), provided this scope is documented. If set to NO (the default), +# structs, classes, and unions are shown on a separate page (for HTML and Man +# pages) or section (for LaTeX and RTF). + +INLINE_SIMPLE_STRUCTS = NO + +# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum +# is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically +# be useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. + +TYPEDEF_HIDES_STRUCT = NO + +# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to +# determine which symbols to keep in memory and which to flush to disk. +# When the cache is full, less often used symbols will be written to disk. +# For small to medium size projects (<1000 input files) the default value is +# probably good enough. For larger projects a too small cache size can cause +# doxygen to be busy swapping symbols to and from disk most of the time +# causing a significant performance penalty. +# If the system has enough physical memory increasing the cache will improve the +# performance by keeping more symbols in memory. Note that the value works on +# a logarithmic scale so increasing the size by one will roughly double the +# memory usage. The cache size is given by this formula: +# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, +# corresponding to a cache size of 2^16 = 65536 symbols. + +SYMBOL_CACHE_SIZE = 0 + +# Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be +# set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given +# their name and scope. Since this can be an expensive process and often the +# same symbol appear multiple times in the code, doxygen keeps a cache of +# pre-resolved symbols. If the cache is too small doxygen will become slower. +# If the cache is too large, memory is wasted. The cache size is given by this +# formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0, +# corresponding to a cache size of 2^16 = 65536 symbols. + +LOOKUP_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal +# scope will be included in the documentation. + +EXTRACT_PACKAGE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespaces are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = NO + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen +# will list include files with double quotes in the documentation +# rather than with sharp brackets. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen +# will sort the (brief and detailed) documentation of class members so that +# constructors and destructors are listed first. If set to NO (the default) +# the constructors will appear in the respective orders defined by +# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. +# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO +# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) +# the group names will appear in their defined order. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to +# do proper type resolution of all parameters of a function it will reject a +# match between the prototype and the implementation of a member function even +# if there is only one candidate or it is obvious which candidate to choose +# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen +# will still accept a match between prototype and implementation in such cases. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or macro consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and macros in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. +# This will remove the Files entry from the Quick Index and from the +# Folder Tree View (if specified). The default is YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the +# Namespaces page. This will remove the Namespaces entry from the Quick Index +# and from the Folder Tree View (if specified). The default is YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. To create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. +# You can optionally specify a file name after the option, if omitted +# DoxygenLayout.xml will be used as the name of the layout file. + +LAYOUT_FILE = + +# The CITE_BIB_FILES tag can be used to specify one or more bib files +# containing the references data. This must be a list of .bib files. The +# .bib extension is automatically appended if omitted. Using this command +# requires the bibtex tool to be installed. See also +# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style +# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this +# feature you need bibtex and perl available in the search path. + +CITE_BIB_FILES = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# The WARN_NO_PARAMDOC option can be enabled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = . + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh +# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py +# *.f90 *.f *.for *.vhd *.vhdl + +FILE_PATTERNS = *.c \ + *.cc \ + *.cxx \ + *.cpp \ + *.c++ \ + *.d \ + *.java \ + *.ii \ + *.ixx \ + *.ipp \ + *.i++ \ + *.inl \ + *.h \ + *.hh \ + *.hxx \ + *.hpp \ + *.h++ \ + *.idl \ + *.odl \ + *.cs \ + *.php \ + *.php3 \ + *.inc \ + *.m \ + *.markdown \ + *.md \ + *.mm \ + *.dox \ + *.py \ + *.f90 \ + *.f \ + *.for \ + *.vhd \ + *.vhdl + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should be +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. +# Note that relative paths are relative to the directory from which doxygen is +# run. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = * + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty or if +# non of the patterns match the file name, INPUT_FILTER is applied. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) +# and it is also possible to disable source filtering for a specific pattern +# using *.ext= (so without naming a filter). This option only has effect when +# FILTER_SOURCE_FILES is enabled. + +FILTER_SOURCE_PATTERNS = + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = YES + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C, C++ and Fortran comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. Otherwise they will link to the documentation. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = YES + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. Note that when using a custom header you are responsible +# for the proper inclusion of any scripts and style sheets that doxygen +# needs, which is dependent on the configuration options used. +# It is advised to generate a default header using "doxygen -w html +# header.html footer.html stylesheet.css YourConfigFile" and then modify +# that header. Note that the header is subject to change so you typically +# have to redo this when upgrading to a newer version of doxygen or when +# changing the value of configuration settings such as GENERATE_TREEVIEW! + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# style sheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that +# the files will be copied as-is; there are no commands or markers available. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. +# Doxygen will adjust the colors in the style sheet and background images +# according to this color. Hue is specified as an angle on a colorwheel, +# see http://en.wikipedia.org/wiki/Hue for more information. +# For instance the value 0 represents red, 60 is yellow, 120 is green, +# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. +# The allowed range is 0 to 359. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of +# the colors in the HTML output. For a value of 0 the output will use +# grayscales only. A value of 255 will produce the most vivid colors. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to +# the luminance component of the colors in the HTML output. Values below +# 100 gradually make the output lighter, whereas values above 100 make +# the output darker. The value divided by 100 is the actual gamma applied, +# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, +# and 100 does not change the gamma. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting +# this to NO can help when comparing the output of multiple runs. + +HTML_TIMESTAMP = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. + +HTML_DYNAMIC_SECTIONS = NO + +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of +# entries shown in the various tree structured indices initially; the user +# can expand and collapse entries dynamically later on. Doxygen will expand +# the tree to such a level that at most the specified number of entries are +# visible (unless a fully collapsed tree already exceeds this amount). +# So setting the number of entries 1 will produce a full collapsed tree by +# default. 0 is a special value representing an infinite number of entries +# and will result in a full expanded tree by default. + +HTML_INDEX_NUM_ENTRIES = 100 + +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, introduced with OSX 10.5 (Leopard). +# To create a documentation set, doxygen will generate a Makefile in the +# HTML output directory. Running make will produce the docset in that +# directory and running "make install" will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +# it at startup. +# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. + +GENERATE_DOCSET = NO + +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +# feed. A documentation feed provides an umbrella under which multiple +# documentation sets from a single provider (such as a company or product suite) +# can be grouped. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +# should uniquely identify the documentation set bundle. This should be a +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +# will append .docset to the name. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING +# is used to encode HtmlHelp index (hhk), content (hhc) and project file +# content. + +CHM_INDEX_ENCODING = + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated +# that can be used as input for Qt's qhelpgenerator to generate a +# Qt Compressed Help (.qch) of the generated HTML documentation. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can +# be used to specify the file name of the resulting .qch file. +# The path specified is relative to the HTML output folder. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#namespace + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#virtual-folders + +QHP_VIRTUAL_FOLDER = doc + +# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to +# add. For more information please see +# http://doc.trolltech.com/qthelpproject.html#custom-filters + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see +# +# Qt Help Project / Custom Filters. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's +# filter section matches. +# +# Qt Help Project / Filter Attributes. + +QHP_SECT_FILTER_ATTRS = + +# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can +# be used to specify the location of Qt's qhelpgenerator. +# If non-empty doxygen will try to run qhelpgenerator on the generated +# .qhp file. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files +# will be generated, which together with the HTML files, form an Eclipse help +# plugin. To install this plugin and make it available under the help contents +# menu in Eclipse, the contents of the directory containing the HTML and XML +# files needs to be copied into the plugins directory of eclipse. The name of +# the directory within the plugins directory should be the same as +# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before +# the help appears. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have +# this name. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) +# at top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. Since the tabs have the same information as the +# navigation tree you can set this option to NO if you already set +# GENERATE_TREEVIEW to YES. + +DISABLE_INDEX = NO + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. +# If the tag value is set to YES, a side panel will be generated +# containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). +# Windows users are probably better off using the HTML help feature. +# Since the tree basically has the same information as the tab index you +# could consider to set DISABLE_INDEX to NO when enabling this option. + +GENERATE_TREEVIEW = NO + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values +# (range [0,1..20]) that doxygen will group on one line in the generated HTML +# documentation. Note that a value of 0 will completely suppress the enum +# values from appearing in the overview section. + +ENUM_VALUES_PER_LINE = 4 + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open +# links to external symbols imported via tag files in a separate window. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of Latex formulas included +# as images in the HTML documentation. The default is 10. Note that +# when you change the font size after a successful doxygen run you need +# to manually remove any form_*.png images from the HTML output directory +# to force them to be regenerated. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are +# not supported properly for IE 6.0, but are supported on all modern browsers. +# Note that when changing this option you need to delete any form_*.png files +# in the HTML output before the changes have effect. + +FORMULA_TRANSPARENT = YES + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax +# (see http://www.mathjax.org) which uses client side Javascript for the +# rendering instead of using prerendered bitmaps. Use this if you do not +# have LaTeX installed or if you want to formulas look prettier in the HTML +# output. When enabled you may also need to install MathJax separately and +# configure the path to it using the MATHJAX_RELPATH option. + +USE_MATHJAX = NO + +# When MathJax is enabled you need to specify the location relative to the +# HTML output directory using the MATHJAX_RELPATH option. The destination +# directory should contain the MathJax.js script. For instance, if the mathjax +# directory is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to +# the MathJax Content Delivery Network so you can quickly see the result without +# installing MathJax. However, it is strongly recommended to install a local +# copy of MathJax from http://www.mathjax.org before deployment. + +MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest + +# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension +# names that should be enabled during MathJax rendering. + +MATHJAX_EXTENSIONS = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box +# for the HTML output. The underlying search engine uses javascript +# and DHTML and should work on any modern browser. Note that when using +# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets +# (GENERATE_DOCSET) there is already a search function so this one should +# typically be disabled. For large projects the javascript based search engine +# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. + +SEARCHENGINE = YES + +# When the SERVER_BASED_SEARCH tag is enabled the search engine will be +# implemented using a PHP enabled web server instead of at the web client +# using Javascript. Doxygen will generate the search PHP script and index +# file to put on the web server. The advantage of the server +# based approach is that it scales better to large projects and allows +# full text search. The disadvantages are that it is more difficult to setup +# and does not have live searching capabilities. + +SERVER_BASED_SEARCH = NO + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = YES + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. +# Note that when enabling USE_PDFLATEX this option is only used for +# generating bitmaps for formulas in the HTML output, but not in the +# Makefile that is written to the output directory. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4 + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for +# the generated latex document. The footer should contain everything after +# the last chapter. If it is left blank doxygen will generate a +# standard footer. Notice: only use this tag if you know what you are doing! + +LATEX_FOOTER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +# If LATEX_SOURCE_CODE is set to YES then doxygen will include +# source code with syntax highlighting in the LaTeX output. +# Note that which sources are shown also depends on other settings +# such as SOURCE_BROWSER. + +LATEX_SOURCE_CODE = NO + +# The LATEX_BIB_STYLE tag can be used to specify the style to use for the +# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See +# http://en.wikipedia.org/wiki/BibTeX for more info. + +LATEX_BIB_STYLE = plain + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load style sheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = NO + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# pointed to by INCLUDE_PATH will be searched when a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition that +# overrules the definition found in the source code. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all references to function-like macros +# that are alone on a line, have an all uppercase name, and do not end with a +# semicolon, because these will confuse the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. For each +# tag file the location of the external documentation should be added. The +# format of a tag file without this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths +# or URLs. Note that each tag file must have a unique name (where the name does +# NOT include the path). If a tag file is not located in the directory in which +# doxygen is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option also works with HAVE_DOT disabled, but it is recommended to +# install and use dot, since it yields more powerful graphs. + +CLASS_DIAGRAMS = YES + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see +# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is +# allowed to run in parallel. When set to 0 (the default) doxygen will +# base this on the number of processors available in the system. You can set it +# explicitly to a value larger than 0 to get control over the balance +# between CPU load and processing speed. + +DOT_NUM_THREADS = 0 + +# By default doxygen will use the Helvetica font for all dot files that +# doxygen generates. When you want a differently looking font you can specify +# the font name using DOT_FONTNAME. You need to make sure dot is able to find +# the font, which can be done by putting it in a standard location or by setting +# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the +# directory containing the font. + +DOT_FONTNAME = Helvetica + +# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. +# The default size is 10pt. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the Helvetica font. +# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to +# set the path where dot can find it. + +DOT_FONTPATH = + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If the UML_LOOK tag is enabled, the fields and methods are shown inside +# the class node. If there are many fields or methods and many nodes the +# graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS +# threshold limits the number of items for each type to make the size more +# managable. Set this to 0 for no limit. Note that the threshold may be +# exceeded by 50% before the limit is enforced. + +UML_LIMIT_NUM_FIELDS = 10 + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs +# for selected functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller +# graphs for selected functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will generate a graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are svg, png, jpg, or gif. +# If left blank png will be used. If you choose svg you need to set +# HTML_FILE_EXTENSION to xhtml in order to make the SVG files +# visible in IE 9+ (other browsers do not have this requirement). + +DOT_IMAGE_FORMAT = png + +# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to +# enable generation of interactive SVG images that allow zooming and panning. +# Note that this requires a modern browser other than Internet Explorer. +# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you +# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files +# visible. Older versions of IE do not have SVG support. + +INTERACTIVE_SVG = NO + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MSCFILE_DIRS tag can be used to specify one or more directories that +# contain msc files that are included in the documentation (see the +# \mscfile command). + +MSCFILE_DIRS = + +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not +# seem to support this out of the box. Warning: Depending on the platform used, +# enabling this option may lead to badly anti-aliased labels on the edges of +# a graph (i.e. they become hard to read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES diff --git a/native-algo/lh-vector/Makefile b/native-algo/lh-vector/Makefile new file mode 100644 index 0000000..e315f27 --- /dev/null +++ b/native-algo/lh-vector/Makefile @@ -0,0 +1,87 @@ +# the file "Depend" must exist for make to run +# for lemke code only + +.SUFFIXES: +.SUFFIXES: .c .o .h + +CC = gcc +# -lm links the math library in +CFLAGS = -ansi -Wall -g + +LDFLAGS = -lm + +GMPLIB = -lgmp + +# needed for gmp library +LIBDIR = /usr/local/lib + +%.o : %.c + $(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@ + +DEPFILE = Depend + +COMOBJ = alloc.o col.o mp.o + +LEMKE = rat.o equilibrium.o list.o lemke.o + +GLEMKE = gmpwrap.o grat.o glist.o gequilibrium.o glemke.o + +INLEMOBJ = inlemke.o + +INLHOBJ = inlemkehowson.o + +ALLOBJ = $(COMOBJ) $(INLEMOBJ) $(LEMKE) $(GLEMKE) $(INGLEMOBJ) $(INLHOBJ) $(INGLHOBJ) + +# local variables for single substitutions + +GMP = $(COMOBJ) $(TREEOBJ) $(METHOBJ) $(GMPOBJ) + +INLEMKE = $(COMOBJ) $(LEMKE) $(INLEMOBJ) + +INGLEMKE = $(COMOBJ) $(GLEMKE) $(INLEMOBJ) + +INLH = $(COMOBJ) $(LEMKE) $(INLHOBJ) + +INGLH = $(COMOBJ) $(GLEMKE) $(INLHOBJ) + +inlh: $(INLH) + $(CC) -c $(CFLAGS) $(CPPFLAGS) inlemkehowson.c -o inlemkehowson.o; + $(CC) $(CFLAGS) $(INLH) $(LDFLAGS) -o inlh + +inglh: $(INGLH) + $(CC) -c -D GLEMKE $(CFLAGS) $(CPPFLAGS) inlemkehowson.c -o inlemkehowson.o; + $(CC) $(CFLAGS) $(INGLH) $(LDFLAGS) $(GMPLIB) -o inlh + +glist.o: list.c + $(CC) -c -D GLEMKE $(CFLAGS) list.c -o glist.o + +inlemke: $(INLEMKE) + $(CC) $(CFLAGS) $(INLEMKE) -o inlemke + +inglemke: $(INGLEMKE) + $(CC) -D GLEMKE $(CFLAGS) $(INGLEMKE) $(GMP) -o inlemke + +doc: Doxyfile + doxygen + +subdir: + cd path; $(MAKE) + cd test/identity/; $(MAKE) + cd test/dualcyclic/dxd/; $(MAKE) + cd test/invAB; $(MAKE) + +depend:: + gcc -MM $(ALLOBJ:.o=.c) > $(DEPFILE) + +.PHONY : clean cleansubdir doc + +cleansubdir: + cd path; $(MAKE) clean + cd test/identity/; $(MAKE) clean + cd test/dualcyclic/dxd/; $(MAKE) clean + cd test/invAB; $(MAKE) clean + +clean: + -rm -rf doc *.o core *.exe $(DEPFILE); touch $(DEPFILE); make depend + +include $(DEPFILE) diff --git a/native-algo/lh-vector/README b/native-algo/lh-vector/README new file mode 100644 index 0000000..aa8d371 --- /dev/null +++ b/native-algo/lh-vector/README @@ -0,0 +1,32 @@ +These are C-routines for an implementation of +Lemke's algorithm to solve the LCP +w = q + Mz >= 0, z >=0, z^T w=0. + +See file sample-input for input. + +COMPILE by simply typing + + make + +to create the executable file inlemke + +Test with + + ./inlemke < sample-input + +d is the covering vector needed to initialize + +with q + dz_0 >= 0, + +so it must have a positive entry whenever q has +a negative one. + +Restrictions: input are fractions with +int limitations on size (31 bit). +Big integers should be preferred here. +The gmp library (GNU multiprecision) is much preferable +for larger LCPs. The glemke.c version has this, +but gmp must be installed, and the code adapted. + +Bernhard von Stengel +26 March 2012 diff --git a/native-algo/lh-vector/README.md b/native-algo/lh-vector/README.md new file mode 100644 index 0000000..ba27ce5 --- /dev/null +++ b/native-algo/lh-vector/README.md @@ -0,0 +1,36 @@ +lh-vector +========= + +The Lemke Howson algorithm simulated with the use of covering vectors. + +Running the program +=================== +The program should be started with at least one argument to describe +what type of output is required, otherwise, no output is achieved. + +The arguments passed into the program are as follows: +if:vVI:maep + +- -a : Outputs the inverse of the tableau when restarting from an equilibrium. +- -e : Outputs an equilibrium once it has been computed. +- -f file : Outputs the LCP corresponding to the game into a file. +- -i : Allows the user to interactively select the leaving variable. +- -I n : Allows the user to interactively select the first n leaving variables. +- -m : Used to select the initialization method (see report/mideval.pdf section 2.2) +- -p : Output the LH bipartite graph +- -v : (Verbose output) output the initial and final tableaus for every equilibrium + computation, as well as, the entering and leaving variables for every pivoting step +- -V : (Verbose output) output the tableau, entering and leaving variables after ever + pivoting step in an equilibrium computation. + +The input for the game is taken from the command line in the format shown in 'sample-input' + +The file 'sample-output' shows the result of the program being run with the following setting + +./inlh -e -p -v < sample-input > sample-output + +Changes: +============ +- Temporary fix for bug regarding restarting from an equilibrium of a degenerate game. + Ignore the cases which generate this error, and let their LH-paths lead to equilibrium -1, + which does not exist. \ No newline at end of file diff --git a/native-algo/lh-vector/alloc.c b/native-algo/lh-vector/alloc.c new file mode 100644 index 0000000..3d3e88c --- /dev/null +++ b/native-algo/lh-vector/alloc.c @@ -0,0 +1,27 @@ +/** + * \file alloc.c + * Memory allocation with error output if fails. + * + * Author: Bernhard von Stengel stengel@maths.lse.ac.uk 17 Apr 2000 + */ + +#include + /* fprintf, stderr */ +#include + /* calloc, free */ +#include "alloc.h" + +void * xcalloc(size_t n, size_t s, int l, char* f) +{ + void *tmp; + tmp = calloc(n, s); + if (tmp==NULL) + { + fprintf(stderr, "Failure to allocate %d objects of %d bytes ", n, s); + fprintf(stderr, "on line %d of %s\n", l, f); + fprintf(stderr, "Emergency stop.\n"); + exit(1); + } + return tmp; +} + diff --git a/native-algo/lh-vector/alloc.h b/native-algo/lh-vector/alloc.h new file mode 100644 index 0000000..de44c77 --- /dev/null +++ b/native-algo/lh-vector/alloc.h @@ -0,0 +1,44 @@ +/** + * \file alloc.h + * Memory allocation with error output if fails. + * + * Author: Bernhard von Stengel stengel@maths.lse.ac.uk 17 Apr 2000 + */ + +/** + * Allocates n elements of size s + * @hideinitializer + */ +#define CALLOC(n,s) xcalloc((size_t) n, (size_t) s,__LINE__,__FILE__) + +/** + * Allocates an array of the specified type. + * @hideinitializer + */ +#define TALLOC(n,type) (type *) xcalloc((size_t) (n), sizeof(type),__LINE__,__FILE__) + +/** + * Allocate a 2-dim (nrows,ncols) array of type to ptr + * Example: T2ALLOC (sfpay, nseqs[1], nseqs[2], Payvec); + * necessary type: Payvec **sfpay; + * @hideinitializer + */ + +#define T2ALLOC(ptr,nrows,ncols,type) {int i; \ + ptr = TALLOC ((nrows), type *); \ + for (i=0; i < (nrows); i++) ptr[i] = TALLOC ((ncols), type);} + +/** + * Free a 2-dim (nrows) array, usually allocated with T2ALLOC + * @hideinitializer + */ + +#define FREE2(ptr,nrows) {int i; \ + for (i=0; i < nrows; i++) free(ptr[i]); free(ptr);} + +/** + * Allocate n objects of size s, + * if fails: error noting line l and filename f + */ +void * xcalloc(size_t n, size_t s, int l, char* f); + diff --git a/native-algo/lh-vector/col.c b/native-algo/lh-vector/col.c new file mode 100644 index 0000000..95ed3ea --- /dev/null +++ b/native-algo/lh-vector/col.c @@ -0,0 +1,138 @@ +/** + * \file col.c + * Automatic pretty printing in columns. + * Author: Bernhard von Stengel stengel@maths.lse.ac.uk 17 Apr 2000 + */ + +#include +#include + /* malloc, calloc, atoi */ +#include + /* typedef unsigned size_t; */ +#include + /* strcmp, strlen */ + +#include "col.h" + +/* contains in succession all strings generated by colpr, + * each terminated by '\0' + */ +static char buf[COLBUFSIZE]; + +static int posinbuf; /* first free byte is buf[posinbuf] */ +static int ncols; /* number of columns */ +static int *colwidth; /* [0..ncols-1] output widths */ +static int *widthsign; /* -1 for left, 1 for right adjustment */ +static int currlines; /* no of fully printed lines */ +static int currcol; /* current column, modulo ncols */ + +/* --------- routines ----------------------------------------- */ +void colset(int c) +{ + int j; + if (c < 1) + { + fprintf(stderr, "colset requires positive no of cols, not %d\n", c); + fprintf(stderr, "Emergency stop.\n"); + exit(1); + } + if (ncols) /* allocation has taken place before */ + /* free space of previously allocated arrays */ + { + free(colwidth); + free(widthsign); + } + colwidth = (int *) calloc(c, sizeof(int)); /* init to 0 */ + widthsign = (int *) calloc(c, sizeof(int)); + if (widthsign == NULL) + { + fprintf(stderr, "colset is out of memory for %d columns.\n", c); + fprintf(stderr, "Emergency stop.\n"); + exit(1); + } + for (j=0; j < c; j++) + widthsign[j] = 1; + ncols = c; + posinbuf = 0; + currcol = 0; + currlines = 0; +} + +void colipr(int i) +{ + char s[ISTR]; + sprintf(s, "%d", i); + colpr(s); +} + +void colleft(int c) + /* making column c in 0..ncols-1 left-adjusted */ +{ + widthsign[c] = -1; +} + +/* print the first cols strings starting at s + * followed by "\n". Print nothing if cols==0. + * return pointer to the next position. + */ +static char * prline (char *s, int cols) +{ + int j; + for (j=0; j < cols; j++) + { + printf("%*s", colwidth[j] * widthsign[j], s); + s += strlen(s) + 1; + if (j < cols - 1) /* avoid trailing blanks in line */ + printf(" "); /* more sophisticated spacing possible */ + else + printf("\n"); /* in loop to prevent newline if 0 cols */ + } + return s; +} + +void colout(void) +{ + int i; + char *s; + s = buf; + for (i=0; i < currlines; i++) + s = prline(s, ncols); + prline(s, currcol); +} + +void colpr(const char *s) +{ + int j; + int w = strlen(s); + + if (posinbuf + w + 1 > COLBUFSIZE) + /* not enough space in current buffer, flush */ + /* require w < COLBUFSIZE, otherwise undefined behavior */ + { + int cc = currcol; + colout(); + printf("\n-----output reset-----\n\n"); + colset(ncols); + for (j=0; j < cc; j++) + /* print blank columns to continue in the correct column */ + buf[posinbuf++] = '\0'; + currcol = cc; + } + if (colwidth[currcol] < w) + colwidth[currcol] = w; + strcpy(&buf[posinbuf], s); + posinbuf += w + 1; + currcol++; + if (currcol==ncols) /* this requires ncols > 0 */ + { + currcol = 0; + currlines++; + } +} + +void colnl(void) +{ + int j; + for (j=currcol; j < ncols; j++) + colpr(""); +} diff --git a/native-algo/lh-vector/col.h b/native-algo/lh-vector/col.h new file mode 100644 index 0000000..3ae97fe --- /dev/null +++ b/native-algo/lh-vector/col.h @@ -0,0 +1,49 @@ +/** \file col.h + * Automatic pretty printing in columns. + * + * Author: Bernhard von Stengel stengel@maths.lse.ac.uk 17 Apr 2000 + */ + +/** + * Number of bytes of buffer to print into. Buffer will be + * printed and flushed if full (not assumed to happen), + * suffices for one page of text + */ +#define COLBUFSIZE 30000 +#define ISTR 20 /**< Number of bytes to print an integer */ + +/** + * Resetting buffer with c columns. + * This method is assumed to be called before all other routines. + * + * \param c The number of columns to be printed out + */ +void colset(int c); + +/** + * Print integer into the current column + * + * \param i The integer to be printed out + */ +void colipr(int i); + +/** + * Making column c left-adjusted + * + * \param c index of column in range 0..ncols-1 + */ +void colleft(int c); + +/** Terminate current line early, prints blank line if in col 0 */ +void colnl(void); + +/** Print out the current buffer, without flushing */ +void colout(void); + +/** + * Store string into the current column. + * The column width is updated after printing the string. + * + * \param s The string to be printed out. + */ +void colpr(const char *s); diff --git a/native-algo/lh-vector/equilibrium.c b/native-algo/lh-vector/equilibrium.c new file mode 100644 index 0000000..1eada40 --- /dev/null +++ b/native-algo/lh-vector/equilibrium.c @@ -0,0 +1,166 @@ +/** + * \file equilibrium.c + * + * Storing tableaus representing equilibrium, and computing the equilibrium. + * This structure is mainly used by the list (list.h) to store the bi-partite + * graph of equilibria found. The tableau information of the equilibrium is + * stored, because the equilibrium can be computed from it, and if we want to + * restart from a given equilibrium, the tableau can simply be copied from this + * structure into the variables used for pivoting, initialised and the Lemke's + * algorithm runs to compute a new equilibrium. + * + * Author: Tobenna Peter, Igwe ptigwe@gmail.com August, 2012 + */ + +#include "rat.h" +#include "equilibrium.h" + + +#define Z(i) (i) +#define W(i,n) (i+n) +#define RHS(n) (n+1) /* q-column of tableau */ + +/* Create an equilibrium given the tableau representing it */ +Equilibrium createEquilibrium(mp** A, mp* scfa, mp det, int* bascobas, int* whichvar, int n, int nrows, int ncols) +{ + Equilibrium eq; + + T2ALLOC (eq.A, n, n+2, mp); + eq.scfa = TALLOC (n+2, mp); + eq.bascobas = TALLOC(2*n+1, int); + eq.whichvar = TALLOC(2*n+1, int); + + int i, j; + for(i = 0; i < n; ++i) + { + for(j = 0; j < n+2; ++j) + { + copy(eq.A[i][j], A[i][j]); + } + } + + for(i = 0; i < n+2; ++i) + { + copy(eq.scfa[i], scfa[i]); + } + + for(i = 0; i < 2*n+1; ++i) + { + eq.bascobas[i] = bascobas[i]; + eq.whichvar[i] = whichvar[i]; + } + copy(eq.det, det); + + eq.lcpdim = n; + eq.nrows = nrows; + eq.ncols = ncols; + + return eq; +} + +/* Frees the memory allocated for the equilibrium */ +void freeEquilibrium(Equilibrium eq) +{ + FREE2(eq.A, eq.lcpdim); + free(eq.scfa); + free(eq.bascobas); + free(eq.whichvar); +} + +/* Returns an array of rational numbers representing the ginven strategy */ +Rat* getStrategies(Equilibrium eq) +{ + int n = eq.lcpdim; + + Rat* strat; + strat = malloc((n) * sizeof(Rat)); + + int i, row; + mp num, den; + + for (i=1; i<=n; i++) + { + if((row = eq.bascobas[Z(i)]) < n) /* If Z(i) is basic */ + { + /* value of Z(i): scfa[Z(i)]*rhs[row] / (scfa[RHS]*det) */ + mulint(eq.scfa[Z(i)], eq.A[row][RHS(n)], num); + mulint(eq.det, eq.scfa[RHS(n)], den); + reduce(num, den); + copy(strat[i-1].num, num); + copy(strat[i-1].den, den); + } + else if((row = eq.bascobas[W(i,n)]) < n) + { + strat[i-1] = ratfromi(0); + /* value of W(i-n) is rhs[row] / (scfa[RHS]*det) + copy(num, eq.A[row][RHS(n)]); + mulint(eq.det, eq.scfa[RHS(n)], den); + reduce(num, den); + copy(strat[i-1].num, num); + copy(strat[i-1].den, den);*/ + } + else + { + strat[i-1] = ratfromi(0); + } + } /* end of for (i=...) */ + return strat; +} + +void colprEquilibrium(Equilibrium eq) +{ + char smp [2*DIG2DEC(MAX_DIGITS) + 4]; + + int i; + int n = eq.lcpdim; + + Rat *rats = getStrategies(eq); + + colpr("P1:"); + for(i = 2; i < eq.nrows + 2; ++i) + { + rattoa(rats[i], smp); + colpr(smp); + } + + colpr("P2:"); + for(; i < n; ++i) + { + rattoa(rats[i], smp); + colpr(smp); + } +} + +/* Print the equilibrium i.e the strategies being played */ +void printEquilibrium(Equilibrium eq) +{ + int n = eq.lcpdim; + colset(n+2); /* column printing to see complementarity of w and z */ + colprEquilibrium(eq); + colout(); +} + +/* Checks the two equlibria are equal */ +int equilibriumisEqual(Equilibrium e1, Equilibrium e2) +{ + int i; + int result = 1; + int n = e1.lcpdim; + + Rat* strat1 = getStrategies(e1); + Rat* strat2 = getStrategies(e2); + + /* Check the two strategies are equal represented by the equlibrium + * Ignore the payoff variables when checking equality */ + for(i = 2; i < n; ++i) + { + if(!(result = ratiseq(strat1[i], strat2[i]))) + { + break; + } + } + + free(strat1); + free(strat2); + return result; +} \ No newline at end of file diff --git a/native-algo/lh-vector/equilibrium.h b/native-algo/lh-vector/equilibrium.h new file mode 100644 index 0000000..61d53d3 --- /dev/null +++ b/native-algo/lh-vector/equilibrium.h @@ -0,0 +1,107 @@ +/** + * \file equilibrium.h + * + * Storing tableaus representing equilibrium, and computing the equilibrium. + * This structure is mainly used by the list (list.h) to store the bi-partite + * graph of equilibria found. The tableau information of the equilibrium is + * stored, because the equilibrium can be computed from it, and if we want to + * restart from a given equilibrium, the tableau can simply be copied from this + * structure into the variables used for pivoting, initialised and the Lemke's + * algorithm runs to compute a new equilibrium. + * + * Author: Tobenna Peter, Igwe ptigwe@gmail.com August, 2012 + */ + +/* Include rat.h before this file */ +#ifndef EQUILIBRIUM_H +#define EQUILIBRIUM_H + +#include +#include +#include +#include "alloc.h" +#include "col.h" +#include "rat.h" + +#ifdef GLEMKE +#include "gmp.h" +#include "gmpwrap.h" +#else +#include "mp.h" +#endif + +/** + * An equilibrium structure which represents a computed + * equilibrium. This stores the tableau representing an + * equilibrium, in such a way that it can be easily copied + * and initialised for the Lemke's algorithm. + */ +typedef struct equilibrium +{ + #ifndef GLEMKE + mp** A; /**< The tableau matrix */ + mp *scfa; /**< The scale factors for the TABCOLs */ + mp det; /**< The determinant of the tableau */ + #else + gmpt** A; /**< The tableau matrix */ + gmpt* scfa; /**< The scale factors for the TABCOLs */ + gmpt det; /**< The determinant of the tableau */ + #endif + + int* bascobas; /**< VARS -> ROWCOL */ + int* whichvar; /**< ROWCOL -> VARS, inverse of bascobas */ + int lcpdim; /**< Dimensions of the LCP */ + int nrows; + int ncols; +}Equilibrium; + +#ifndef GLEMKE +/** + * Creates an equilibrium structure given the information of the tableau. + */ +Equilibrium createEquilibrium(mp** A, mp* scfa, mp det, int* bascobas, int* whichvar, int dim, int nrows, int ncols); +#else +/** + * Creates an equilibrium structure given the information of the tableau. + */ +Equilibrium createEquilibrium(gmpt** A, gmpt* scfa, gmpt det, int* bascobas, int* whichvar, int dim, int nrows, int ncols); +#endif + +/** + * Frees the memory allocated to the various members + * of the given equilibrium. + * + * \param eq Equilibrium to be released from memory. + * \sa createEquilibrium + */ +void freeEquilibrium(Equilibrium eq); + +void colprEquilibrium(Equilibrium eq); + +/** + * Prints the specifie equilibrium. + * + * \param eq Equilibrium to be printed to the standard output. + */ +void printEquilibrium(Equilibrium eq); + +/** + * Returns the strategy represented by the given equilibrium. The array + * of rational numbers which are returned consist of player 1's + * strategies, followed by player 2's strategies. + * + * \param eq The tableau representation + * \returns An array of rational numbers representing the equilibrium + */ +Rat* getStrategies(Equilibrium eq); + +/** + * Returns an integer value representing TRUE or FALSE if both + * e1 and e2 are equal or not. + * + * \returns 1 if e1 and e2 are equal and 0 if e1 and e2 are not + * equal. + */ +int equilibriumisEqual(Equilibrium e1, Equilibrium e2); + +#endif \ No newline at end of file diff --git a/native-algo/lh-vector/gequilibrium.c b/native-algo/lh-vector/gequilibrium.c new file mode 100644 index 0000000..0e7cd61 --- /dev/null +++ b/native-algo/lh-vector/gequilibrium.c @@ -0,0 +1,172 @@ +/** + * \file gequilibrium.c + * + * Storing tableaus representing equilibrium, and computing the equilibrium. + * This structure is mainly used by the list (list.h) to store the bi-partite + * graph of equilibria found. The tableau information of the equilibrium is + * stored, because the equilibrium can be computed from it, and if we want to + * restart from a given equilibrium, the tableau can simply be copied from this + * structure into the variables used for pivoting, initialised and the Lemke's + * algorithm runs to compute a new equilibrium. + * + * Author: Tobenna Peter, Igwe ptigwe@gmail.com August, 2012 + */ + +#define GLEMKE + +#include "rat.h" +#include "equilibrium.h" + + +#define Z(i) (i) +#define W(i,n) (i+n) +#define RHS(n) (n+1) /* q-column of tableau */ + +Equilibrium createEquilibrium(gmpt** A, gmpt* scfa, gmpt det, int* bascobas, int* whichvar, int n, int nrows, int ncols) +{ + Equilibrium eq; + + T2ALLOC (eq.A, n, n+2, gmpt); + G2INIT (eq.A, n, n+2); + eq.scfa = TALLOC (n+2, gmpt); + eq.bascobas = TALLOC(2*n+1, int); + eq.whichvar = TALLOC(2*n+1, int); + + int i, j; + for(i = 0; i < n; ++i) + { + for(j = 0; j < n+2; ++j) + { + gset(eq.A[i][j], A[i][j]); + } + } + + for(i = 0; i < n+2; ++i) + { + gset(eq.scfa[i], scfa[i]); + } + + for(i = 0; i < 2*n+1; ++i) + { + eq.bascobas[i] = bascobas[i]; + eq.whichvar[i] = whichvar[i]; + } + ginit(eq.det); + gset(eq.det, det); + + eq.lcpdim = n; + eq.nrows = nrows; + eq.ncols = ncols; + + return eq; +} + +void freeEquilibrium(Equilibrium eq) +{ + G2CLEAR(eq.A, eq.lcpdim, eq.lcpdim+2) + FREE2(eq.A, eq.lcpdim); + free(eq.scfa); + free(eq.bascobas); + free(eq.whichvar); +} + +Rat* getStrategies(Equilibrium eq) +{ + int n = eq.lcpdim; + + Rat* strat; + strat = malloc((n) * sizeof(Rat)); + + int i, row; + gmpt num, den; + ginit(num); + ginit(den); + + for (i=1; i<=n; i++) + { + if((row = eq.bascobas[Z(i)]) < n) /* If Z(i) is basic */ + { + /* value of Z(i): scfa[Z(i)]*rhs[row] / (scfa[RHS]*det) */ + gmulint(eq.scfa[Z(i)], eq.A[row][RHS(n)], num); + gmulint(eq.det, eq.scfa[RHS(n)], den); + greduce(num, den); + strat[i-1] = ratinit(); + gset(strat[i-1].num, num); + gset(strat[i-1].den, den); + } + else if((row = eq.bascobas[W(i,n)]) < n) + { + strat[i-1] = ratfromi(0); + /* value of W(i-n) is rhs[row] / (scfa[RHS]*det) + copy(num, eq.A[row][RHS(n)]); + mulint(eq.det, eq.scfa[RHS(n)], den); + reduce(num, den); + copy(strat[i-1].num, num); + copy(strat[i-1].den, den);*/ + } + else + { + strat[i-1] = ratfromi(0); + } + } /* end of for (i=...) */ + gclear(num); + gclear(den); + return strat; +} + +void colprEquilibrium(Equilibrium eq) +{ + char smp [2*DIG2DEC(MAX_DIGITS) + 4]; + + int i; + int n = eq.lcpdim; + + Rat *rats = getStrategies(eq); + + colpr("P1:"); + for(i = 2; i < eq.nrows + 2; ++i) + { + rattoa(rats[i], smp); + colpr(smp); + } + + colpr("P2:"); + for(; i < n; ++i) + { + rattoa(rats[i], smp); + colpr(smp); + } +} + +void printEquilibrium(Equilibrium eq) +{ + int n = eq.lcpdim; + colset(n+2); /* column printing to see complementarity of w and z */ + colprEquilibrium(eq); + colout(); +} + +/* Checks the two equlibria are equal */ +int equilibriumisEqual(Equilibrium e1, Equilibrium e2) +{ + int i; + int result = 1; + int n = e1.lcpdim; + + Rat* strat1 = getStrategies(e1); + Rat* strat2 = getStrategies(e2); + + /* Check the two strategies are equal represented by the equlibrium + * Ignore the payoff variables when checking equality */ + for(i = 2; i < n; ++i) + { + if(!(result = ratiseq(strat1[i], strat2[i]))) + { + break; + } + } + + free(strat1); + free(strat2); + return result; +} \ No newline at end of file diff --git a/native-algo/lh-vector/glemke.c b/native-algo/lh-vector/glemke.c new file mode 100644 index 0000000..c83cf15 --- /dev/null +++ b/native-algo/lh-vector/glemke.c @@ -0,0 +1,1547 @@ +/** + * \file glemke.c + * + * LCP solver with GNU Multi Precision arithmetic + * + * Author: Bernhard von Stengel stengel@maths.lse.ac.uk 14 July 2000 + */ + +/* GSoC12: Tobenna Peter, Igwe */ +#define GLEMKE + +#include +#include + /* free() */ +#include + /* strcpy */ + +#include "alloc.h" +#include "col.h" + +#include "lemke.h" + +#include "gmp.h" +#include "gmpwrap.h" +#include "equilibrium.h" + + +long record_digits; /* not in the gmp package */ + +/* used for tableau: */ +#define Z(i) (i) +#define W(i) (i+n) + /* VARS = 0..2n = Z(0) .. Z(n) W(1) .. W(n) */ + /* ROWCOL = 0..2n, 0 .. n-1: tabl rows (basic vars) */ + /* n .. 2n: tabl cols 0..n (cobasic) */ +#define RHS (n+1) /* q-column of tableau */ +#define TABCOL(v) (bascobas[v]-n) + /* v in VARS, v cobasic: TABCOL(v) is v's tableau col */ + /* v basic: TABCOL(v) < 0, TABCOL(v)+n is v's row */ + +/* LCP input */ +Rat **lcpM; +Rat *rhsq; +Rat *vecd; +int lcpdim = 0; /* set in setlcp */ +static int n; /* LCP dimension as used here */ + +/* LCP result */ +Rat *solz; +int pivotcount; + +/* tableau: */ +static gmpt **A; /**< tableau */ +static int *bascobas; /**< VARS -> ROWCOL */ +static int *whichvar; /**< ROWCOL -> VARS, inverse of bascobas */ + +/** scale factors for variables z. +* scfa[Z(0)] for d, scfa[RHS] for q +* scfa[Z(1..n)] for cols of M +* result variables to be multiplied with these +*/ +static gmpt *scfa; + +static gmpt det; /**< determinant */ + +static int *lextested, *lexcomparisons;/**< statistics for lexminvar */ + +static int *leavecand; + /* should be local to lexminvar but defined globally for economy */ + + +/* GSoC12: Tobenna Peter, Igwe */ +/* User input */ +int nrows; /* The number of rows in the payoff matrix */ +int ncols; /* The number of columns in the payoff matrix */ +int k; /* The missing label */ +int k2; +Rat** payoffA; /* The payoff matrix A */ +Rat** payoffB; /* The payoff matrix B */ +gmpt** invAB; /**< Represents the inverse of AB */ +node* neg; /* The negative indexed equilibria */ +node* pos; /* The positive indexed equilibria */ + +/*------------------ error message ----------------*/ +/** + * Prints out an error message and exits. + * + * \param info The error message + */ +void errexit (char *info) +{ + fflush(stdout); + fprintf(stderr, "Error: %s\n", info); + fprintf(stderr, "Lemke terminated unsuccessfully.\n"); + exit(1); +} + +/* declares */ +int assertbasic (int v, const char *info); + +/*------------------ memory allocation -------------------------*/ +/** + * Allocates memory for the LCP given its dimensions. + * If the LCP has been previously allocated, it frees the memory and + * reallocates it. If the dimension given for the LCP is < 0 or + * > MAXLCPDIM then it exits with an error. + * + * \param newn The dimension of the LCP. + */ +void setlcp (int newn) +{ + if (newn < 1 || newn > MAXLCPDIM) + { + fprintf(stderr, "Problem dimension n= %d not allowed. ", newn); + fprintf(stderr, "Minimum n is 1, maximum %d.\n", MAXLCPDIM); + exit(1); + } + if (lcpdim > 0) /* free previously used space */ + { + FREE2(lcpM, lcpdim); + free(rhsq); + free(vecd); + free(solz); + + G2CLEAR(A, lcpdim, lcpdim + 2); + FREE2(A, lcpdim); + GCLEAR(scfa, lcpdim + 2); + free(scfa); + + free(bascobas); + free(whichvar); + free(leavecand); + + gclear(det); + + G2CLEAR(invAB, lcpdim, lcpdim); + FREE2(invAB, lcpdim); + } + n = lcpdim = newn; + /* LCP input/output data */ + T2ALLOC (lcpM, n, n, Rat); + rhsq = TALLOC(n, Rat); + vecd = TALLOC(n, Rat); + solz = TALLOC(n, Rat); + /* tableau */ + + T2ALLOC (A, n, n+2, gmpt); + G2INIT (A, n, n+2); + scfa = TALLOC (n+2, gmpt); + GINIT (scfa, n+2); + ginit(det); + + bascobas = TALLOC(2*n+1, int); + whichvar = TALLOC(2*n+1, int); + lextested = TALLOC(n+1, int); + lexcomparisons = TALLOC(n+1, int); + leavecand = TALLOC(n, int); + /* should be local to lexminvar but allocated here for economy */ + /* initialize all LCP entries to zero */ + { + int i,j; + Rat nix = ratfromi(0); + for (i=0; i= 0 and not q >= 0 (o/w trivial sol) +* and that q[i] < 0 implies d[i] > 0 +*/ +void isqdok (void) +{ + int i; + int isqpos = 1; + for (i=0; i=0. "); + printf("Trivial solution z=0.\n"); + exit(0); + } +} /* end of isqdok() */ + +/* ------------------- tableau setup ------------------ */ + +/** + * Initialise tableau variables. + * Z(0)...Z(n) nonbasic, W(1)...W(n) basic + */ +void inittablvars (void) +{ + int i; + for (i=0; i<=n; i++) + { + bascobas[Z(i)] = n+i; + whichvar[n+i] = Z(i); + } + for (i=1; i<=n; i++) + { + bascobas[W(i)] = i-1; + whichvar[i-1] = W(i); + } +} /* end of inittablvars() */ + +/** + * Fill tableau from M, q, d + */ +void filltableau (void) +{ + int i,j; + gmpt den, num; + gmpt tmp, tmp2; + + ginit(tmp); ginit(tmp2); + ginit(den); ginit(num); + for (j=0; j<=n+1; j++) + { + /* compute lcm scfa[j] of denominators for col j of A */ + gitomp(1, scfa[j]); + for (i=0; i n) + return sprintf(s, "w%d", v-n); + else + return sprintf(s, "z%d", v); +} + +/** + * Output the current tableau, column-adjusted + */ +void outtabl (void) +{ + int i, j; + char s[INFOSTRINGLENGTH]; + char smp [MAXGMPCHARS]; /* string to print mp into */ + gmptoa (det, smp); + printf("Determinant: %s\n", smp); + colset(n+3); + colleft(0); + colpr("var"); /* headers describing variables */ + for (j=0; j<=n+1; j++) + { + if (j==RHS) + colpr("RHS"); + else + { + vartoa(whichvar[j+n], s); + colpr(s); + } + } + colpr("scfa"); /* scale factors */ + for (j=0; j<=n+1; j++) + { + if (j==RHS) + gmptoa(scfa[RHS], smp); + else if (whichvar[j+n] > n) /* col j is some W */ + sprintf(smp, "1"); + else /* col j is some Z: scfa */ + gmptoa( scfa[whichvar[j+n]], smp); + colpr(smp); + } + colnl(); + for (i=0; i= n) + { + vartoa(v, s); + fprintf(stderr, "%s: Cobasic variable %s should be basic.\n", info, s); + /*errexit("");*/ + return -1; + } + return 0; +} + +/** + * Assert that v in VARS is a cobasic variable. + * If v is not cobasic, the program terminates with an error message + * + * \param v The variable to be asserted + * \param info Part of the error message + */ +int assertcobasic (int v, char *info) +{ + char s[INFOSTRINGLENGTH]; + if (TABCOL(v) < 0) + { + /* + vartoa(v, s); + fprintf(stderr, "%s: Basic variable %s should be cobasic.\n", info, s); + errexit("");*/ + return -1; + } + return 1; +} + +/** + * Document the current pivot. + * Asserts leave is basic and enter is cobasic, and + * print the current pivot + * + * \param leave The leaving variable + * \param enter The entering variable + */ +int docupivot (int leave, int enter, Flagsrunlemke flags) +{ + char s[INFOSTRINGLENGTH]; + + if (assertbasic(leave, "docupivot") < 0) + return -1; + if (assertcobasic(enter, "docupivot") < 0) + return -1; + + if(flags.boutpiv) + { + vartoa(leave, s); + printf("leaving: %-4s ", s); + vartoa(enter, s); + printf("entering: %s\n", s); + } + return 0; +} /* end of docupivot */ + +/** + * Outputs an error message and exits when a ray termination + * occurs while trying to pivot in the entering variable. + * + * \param enter The entering variable. + */ +void raytermination (int enter) +{ + char s[INFOSTRINGLENGTH]; + vartoa(enter, s); + fprintf(stderr, "Ray termination when trying to enter %s\n", s); + outtabl(); + printf("Current basis, not an LCP solution:\n"); + outsol(); + errexit(""); +} + +/** + * Tests the tableau variables. If the tableau variables are wrong, + * output error and continue. + */ +void testtablvars(void) +{ + int i, j; + for (i=0; i<=2*n; i++) /* check if somewhere tableauvars wrong */ + if (bascobas[whichvar[i]]!=i || whichvar[bascobas[i]]!=i) + /* found an inconsistency, print everything */ + { + printf("Inconsistent tableau variables:\n"); + for (j=0; j<=2*n; j++) + { + printf("var j:%3d bascobas:%3d whichvar:%3d ", + j, bascobas[j], whichvar[j]); + printf(" b[w[j]]==j: %1d w[b[j]]==j: %1d\n", + bascobas[whichvar[j]]==j, whichvar[bascobas[j]]==j); + } + break; + } +} +/* --------------- pivoting and related routines -------------- */ + +/** + * Complement of v in VARS. Error if v==Z(0). + * This is W(i) for Z(i) and vice versa, i=1...n. + * + * \param v The variable + * \returns The complement of v. Z(i) if v is W(i) and vice versa. + */ +int complement (int v) +{ + if (v==Z(0)) + errexit("Attempt to find complement of z0."); + return (v > n) ? Z(v-n) : W(v) ; +} /* end of complement (v) */ + +/** + * Initialize statistics for minimum ratio test + */ +void initstatistics(void) +{ + int i; + for (i=0; i<=n; i++) + lextested[i] = lexcomparisons[i] = 0; +} + +/** + * Output statistics of minimum ratio test + */ +void outstatistics(void) +{ + int i; + char s[LCPSTRL]; + + colset(n+2); + colleft(0); + colpr("lex-column"); + for (i=0; i<=n; i++) + colipr(i); + colnl(); + colpr("times tested"); + for (i=0; i<=n; i++) + colipr(lextested[i]); + colpr("% times tested"); + if (lextested[0] > 0) + { + colpr("100"); + for (i=1; i<=n; i++) + { + sprintf(s, "%2.0f", + (double) lextested[i] * 100.0 / (double) lextested[0]); + colpr(s); + } + } + else + colnl(); + colpr("avg comparisons"); + for (i=0; i<=n; i++) + if (lextested[i] > 0) + { + sprintf(s, "%1.1f", + (double) lexcomparisons[i] / (double) lextested[i]); + colpr(s); + } + else + colpr("-"); + colout(); +} + +/** + * Returns the leaving variable in VARS. This is given by lexmin row, + * when enter in VARS is entering variable + * only positive entries of entering column tested + * boolean *z0leave indicates back that z0 can leave the + * basis, but the lex-minratio test is performed fully, + * so the returned value might not be the index of z0. + * + * \param enter The entering variable + * \param z0leave Stores a boolean value stating if z0 can leave. + * \returns The leaving variable + */ +int lexminvar (int enter, int *z0leave) +{ + int col, i, j, testcol; + int numcand; + gmpt tmp1, tmp2; + + ginit(tmp1); ginit(tmp2); + assertcobasic(enter, "Lexminvar"); + col = TABCOL(enter); + numcand = 0; + /* leavecand [0..numcand-1] = candidates (rows) for leaving var */ + /* start with leavecand = { i | A[i][col] > 0 } */ + for (i=0; i 1; j++) + /* as long as there is more than one leaving candidate perform + * a minimum ratio test for the columns of j in RHS, W(1),... W(n) + * in the tableau. That test has an easy known result if + * the test column is basic or equal to the entering variable. + */ + { + if (j>n) /* impossible, perturbed RHS should have full rank */ + errexit("lex-minratio test failed"); + lextested[j] += 1 ; + lexcomparisons[j] += numcand ; + + testcol = (j==0) ? RHS : TABCOL(W(j)) ; + if (testcol != col) /* otherwise nothing will change */ + { + if (testcol >= 0) + /* not a basic testcolumn: perform minimum ratio tests */ + { + int sgn; + int newnum = 0; + /* leavecand[0..newnum] contains the new candidates */ + for (i=1; i < numcand; i++) + /* investigate remaining candidates */ + { + gmulint(A[leavecand[0]][testcol], A[leavecand[i]][col], tmp1); + gmulint(A[leavecand[i]][testcol], A[leavecand[0]][col], tmp2); + gsub (tmp1, tmp1, tmp2) ; + sgn = gsgn(tmp1) ; + /* sign of A[l_0,t] / A[l_0,col] - A[l_i,t] / A[l_i,col] */ + /* note only positive entries of entering column considered */ + if (sgn==0) /* new ratio is the same as before */ + leavecand[++newnum] = leavecand[i]; + else if (sgn==1) /* new smaller ratio detected */ + leavecand[newnum=0] = leavecand[i]; + } + numcand = newnum+1; + } + else + /* testcol < 0: W(j) basic, Eliminate its row from leavecand */ + /* since testcol is the jth unit column */ + for (i=0; i < numcand; i++) + if (leavecand[i] == bascobas[W(j)]) + { + leavecand[i] = leavecand[--numcand]; + /* shuffling of leavecand allowed */ + break; + } + } /* end of if(testcol != col) */ + + } /* end of for ( ... numcand > 1 ... ) */ + gclear(tmp1); gclear(tmp2); + *z0leave = (leavecand[0] == bascobas[Z(0)]); + return whichvar[leavecand[0]]; +} /* end of lexminvar (col, *z0leave); */ + +/** + * Returns the leaving variable in VARS as entered by user. + * When enter in VARS is entering variable + * only nonzero entries of entering column admitted + * boolean *z0leave indicates back that z0 has been + * entered as leaving variable, and then + * the returned value is the index of z0. + * + * \param enter The entering variable + * \param z0leave Stores a boolean value stating if z0 can leave. + * \returns The leaving variable + */ +int interactivevar (int enter, int *z0leave) +{ + char s[INFOSTRINGLENGTH], instring[2]; + + int inp, col, var; + int breject = 1; + assertcobasic(enter, "interactivevar"); + col = TABCOL(enter); + + vartoa(enter, s); + printf(" Entering variable (column): %s\n", s); + while (breject) + { + printf(" Leaving row (basic variable z.. or w..), "); + printf("or 't' for tableau:\n"); + strcpy(instring, "?"); + if (scanf("%1s", instring)==EOF) + { + printf ("Input terminated too early with EOF\n"); + exit(1); + } + if ( instring[0] == 't') + { + printf("\n"); + outtabl(); + vartoa(enter, s); + printf(" Entering variable (column): %s\n", s); + continue; + } + scanf("%d", &inp); + printf(" You typed %s%d\n", instring, inp); + if ( (inp < 0) || (inp > n)) + { + printf("Variable index %d outside 0..n=%d\n", + inp, n); + continue; + } + if ( instring[0] == 'w') + { + if (inp == 0) + { + printf("Variable w0 not allowed\n"); + continue; + } + var = inp + n; + } + else if ( instring[0] == 'z') + var = inp; + else + { + printf("Variable not starting with z or w\n"); + continue; + } + /* var == variable in VARS giving what has been input */ + if ( bascobas[var] >= n) + { + vartoa (var, s); + printf("Variable %s not basic\n", s); + continue; + } + if ( gzero( A [bascobas[var]] [col] ) ) + { + vartoa (var, s); + printf("Row %s has zero pivot element, not allowed\n", s); + continue; + } + breject = 0; /* now everything ok */ + } /* end of while (breject) for input */ + *z0leave = (var == Z(0)); + return var; +} /* end of interactivevar (col, *z0leave); */ + +/** + * Negates tableau column col + * \param col The column of the tableau to be negated. + */ +void negcol(int col) +{ + int i; + for (i=0; i nrows) /* if l is p2's strategy*/ + { + /* m < l <= m+n */ + l -= (nrows + 1); + int i; + /* The best response to l is the row with min value for the lth column + * because payoffA is -A. + */ + for(i = 1; i < nrows; ++i) + { + if(ratgreat(payoffA[m][l], payoffA[i][l])) + m = i; + if(ratiseq(payoffA[m][l], payoffA[i][l])) /* Due to lexmin ratio */ + m = i; + } + /* Converts m to p1's strategy */ + m += 1; + } + else /* if l is p1's strategy */ + { + /* 1 <= l <= m */ + l -= 1; + int i; + /* The best response to l is the column with min value for the lth row + * because payoffB is -B. + */ + for(i = 1; i < ncols; ++i) + { + if(ratgreat(payoffB[l][m], payoffB[l][i])) + m = i; + if(ratiseq(payoffB[l][m], payoffB[l][i])) /* Due to lexmin ratio */ + m = i; + } + /* Converts m to p2's strategy */ + m += (nrows + 1); + } + + return m; +} + +/** +* Pivots the tableau given the values for the leaving +* and entering variables, and outputs data based on the +* flags. +* +* \param leave The leaving variable +* \param enter The entering variable +* \param flags The flags for running Lemke's algorithm +*/ +/* GSoC12: Tobenna Peter, Igwe */ +int fpivot(int leave, int enter, Flagsrunlemke flags) +{ + testtablvars(); + if (flags.bdocupivot) + { + if(docupivot (leave, enter, flags) < 0) + return -1; + } + pivot (leave, enter); + if (flags.bouttabl) + outtabl(); + pivotcount++; + return 0; +} + +/** + * Initialise the LH algorithm with the first + * three pivots of method 1 as explained in the report. + */ +/* GSoC12: Tobenna Peter, Igwe */ + int initLH1(Flagsrunlemke flags) +{ + int enter, leave; + + enter = Z(0); + leave = (k > nrows) ? W(1) : W(2); + + fpivot(leave, enter, flags); + + enter = complement(leave); + leave = W(bestResponse(k) + 2); + + fpivot(leave, enter, flags); + + enter = complement(leave); + leave = (k > nrows) ? W(2) : W(1); + + fpivot(leave, enter, flags); + + enter = complement(leave); + leave = W(k + 2); + fpivot(leave, enter, flags); + + return leave; +} + +/** + * Initialise the LH algorithm with the first + * three pivots of method 1 as explained in the report. + */ +/* GSoC12: Tobenna Peter, Igwe */ +int initLH2(Flagsrunlemke flags) +{ + int enter, leave; + + enter = Z(0); + leave = (k > nrows) ? W(2) : W(1); + + fpivot(leave, enter, flags); + + enter = complement(leave); + leave = W(k + 2); + + fpivot(leave, enter, flags); + + enter = complement(leave); + leave = (k > nrows) ? W(1) : W(2); + + fpivot(leave, enter, flags); + + enter = complement(leave); + leave = W(bestResponse(k) + 2); + + fpivot(leave, enter, flags); + + return leave; +} + +/** + * Initialise the LH pivots given the flags. + * It chooses to initialise the LH pivots using either + * method 1 or 2 as specified by the user in flags. + * + * \param flags The flags for running Lemke's algorithm + */ +/* GSoC12: Tobenna Peter, Igwe */ +int initLH(Flagsrunlemke flags) +{ + if(flags.bisArtificial) + return flags.binitmethod ? complement(initLH2(flags)) : complement(initLH1(flags)); + else + return Z(0); +} + +/** + * Computes the inverse of A_B. + */ +/* GSoC12: Tobenna Peter, Igwe */ +void getinvAB(int verbose) +{ + int i; + + for(i = 0; i < n; ++i) + { + if(bascobas[W(i + 1)] < n) /* If W(i) is basic */ + { + int j = bascobas[W(i + 1)]; + int k; + for(k = 0; k < n; ++k) + { + if(k == j) /* The jth row of the ith column is 1 other rows are 0 */ + { + gset(invAB[k][i], det); + } + else + { + gitomp(0, invAB[k][i]); + } + } + } + else /* If W(i) is non-basic */ + { + int j = TABCOL(W(i + 1)); + int k; + for(k = 0; k < n; ++k) /* copy the column representing W(i) into the ith column */ + { + gset(invAB[k][i], A[k][j]); + /*copy(invAB[k][i], A[k][j]);*/ + } + } + } + + if(verbose) + { + colset(n); + printf("\nz0= "); + for(i = 0; i < n; ++i) + { + char str[MAXSTR]; + gmptoa(A[i][TABCOL(Z(0))], str); + printf("%s ", str); + } + colout(); + + printf("\nPrinting invAB:\n"); + colset(n); + + for(i = 0; i < n; ++i) + { + int j; + for(j = 0; j < n; ++j) + { + char str[MAXSTR]; + gmptoa(invAB[i][j], str); + colpr(str); + } + } + colout(); + } +} + +/* ------------------------------------------------------------ */ +int runlemke(Flagsrunlemke flags) +{ + int leave, enter, z0leave; + + pivotcount = 1; + initstatistics(); + + if (flags.binitabl) + { + printf("After filltableau:\n"); + outtabl(); + } + + /* now give the entering q-col its correct sign if it is from the artificial*/ + if(flags.bisArtificial)/* GSOC */ + { + negcol (RHS); + } + + if (flags.bouttabl) + { + printf("After negcol:\n"); + outtabl(); + } + + /* z0 enters the basis to obtain lex-feasible solution, or use the initialization */ + /*enter = Z(0)*/ /*GSOC*/ + enter = flags.binteract ? Z(0) : initLH(flags); + leave = flags.binteract ? interactivevar(enter, &z0leave) : lexminvar(enter, &z0leave) ; + + if(leave < 0) + return -1; + + while (1) /* main loop of complementary pivoting */ + { + if(flags.interactcount) + flags.binteract = --flags.interactcount ? 1 : 0; + testtablvars(); + if (flags.bdocupivot) + { + if(docupivot (leave, enter, flags) < 0) + return -1; + } + pivot (leave, enter); + if (z0leave) + break; /* z0 will have value 0 but may still be basic. Amend? */ + if (flags.bouttabl) + outtabl(); + enter = complement(leave); + leave = flags.binteract ? interactivevar(enter, &z0leave) : lexminvar(enter, &z0leave) ; + + if (leave < 0) + return -1; + + if (pivotcount++ == flags.maxcount) + { + printf("------- stop after %d pivoting steps --------\n", + flags.maxcount); + break; + } + } + + if (flags.binitabl) + { + printf("Final tableau:\n"); + outtabl(); + } + if (flags.boutsol) + outsol(); + if (flags.blexstats) + outstatistics(); + + notokcopysol(); + + /*GSOC: For test purpose only */ + if(flags.boutinvAB) + getinvAB(flags.boutinvAB); + + return 0; +} + +/** + * Copy the tableau from the given equilibrium to be + * used for computation. + */ +/* GSoC12: Tobenna Peter, Igwe */ +void copyEquilibrium(Equilibrium eq) +{ + int i, j; + for(i = 0; i < n; ++i) + { + for(j = 0; j < n+2; ++j) + { + gset(A[i][j], eq.A[i][j]); + } + } + + for(i = 0; i < n+2; ++i) + { + gset(scfa[i], eq.scfa[i]); + } + + for(i = 0; i < 2*n+1; ++i) + { + bascobas[i] = eq.bascobas[i]; + whichvar[i] = eq.whichvar[i]; + } + gset(det, eq.det); +} + +/** + * Setup the covering vector for the Artificial Equilibrium. + * Calculates the new covering vector for the missing label k + * from the artificial equilibrium, and substitutes that in the + * tableau. + */ +/* GSoC12: Tobenna Peter, Igwe */ +void setupArtificial() +{ + int i; + /* Copy the new covering vector into the tableau */ + for(i = 0; i < n; ++i) + { + gmpt tmp; + ginit(tmp); + if(i == k+1) + { + gitomp(0, tmp); + } + else + { + gitomp(1, tmp); + } + gset(A[i][TABCOL(Z(0))], tmp); + gclear(tmp); + } +} + +/** + * Setup the tableau from the current equilibrium using k2 as the missing label. + * This involves calculating the inverse of A_B to find the new covering vector, + * and replacing it in the tableau. + */ +/* GSoC12: Tobenna Peter, Igwe */ +void setupEquilibrium(Flagsrunlemke flags) +{ + getinvAB(flags.boutinvAB); + /* vecd2 represents the covering vector when k2 is the missing label */ + gmpt* vecd2 = TALLOC(n, gmpt); + GINIT(vecd2, n); + int i; + for(i = 0; i < n; ++i) + { + if(i == (k2 + 1)) + { + gitomp(0, vecd2[i]); + } + else + { + gitomp(1, vecd2[i]); + } + } + + /* sol represents the computed covering vector by multiplying + * invAB with vecd2, and multiplying the result by -1 */ + gmpt* sol = TALLOC(n, gmpt); + GINIT(sol, n); + for(i = 0; i < n; ++i) + { + int j; + gmpt sum; + ginit(sum); + gitomp(0, sum); + for(j = 0; j < n; ++j) + { + gmpt tmp; + ginit(tmp); + gmulint(invAB[i][j], vecd2[j], tmp); + gadd(sum, tmp, sum); + /*sum = ratadd(sum, tmp);*/ + } + gchangesign(sum); + gset(sol[i], sum); + } + /* Copy the new covering vector into the tableau */ + for(i = 0; i < n; ++i) + { + /*A[i][TABCOL(Z(0))] = sol[i];*/ + gset(A[i][TABCOL(Z(0))], sol[i]); + } + + if(flags.binitabl) + { + printf("\nTableau with new covering vector\n"); + outtabl(); + printf("\nRestarting with missing label: %d\n", k2); + } +} + +/** + * Compute the equilibria from the specified node. + * This computes all the equiibria directly reachable by + * dropping labels which do not have any equilibrium linked + * with from the current equilibrium. + * + * \param i Index position of the current equilibrium in the list + * \param isneg Boolean value indicating if the current equilibrium is + * a negatively indexed equilibrium. + * \param flags Flags for tunning Lemke's algorithm. + */ +/* GSoC12: Tobenna Peter, Igwe */ +void computeEquilibriafromnode(int i, int isneg, Flagsrunlemke flags) +{ + node* cur = (isneg) ? neg : pos; + node* res = (isneg) ? pos : neg; + + cur = getNodeat(cur, i); + Equilibrium eq; + int maxk = nrows + ncols; + for(k2 = 1; k2 <= maxk; ++k2) + { + if(cur->link[k2-1] != -1) + continue; + + copyEquilibrium(cur->eq); + if(flags.bisArtificial) + { + k = k2; + setupArtificial(); + } + else + { + setupEquilibrium(flags); + } + int err = runlemke(flags); + + if (err < 0) + continue; + /* Create the equilibrium and add it to the list */ + eq = createEquilibrium(A, scfa, det, bascobas, whichvar, n, nrows, ncols); + int plength = listlength(res); + /* The equilibrium is at the index j in the list */ + int j = addEquilibrium(res, eq); + /* Label k links both equilibria together */ + cur->link[k2-1] = j; + node* p = getNodeat(res, j); + p->link[k2-1] = i; + + if(flags.bouteq && plength != listlength(res)) + { + colprEquilibrium(eq); + } + + if(flags.boutsol) + { + printEquilibrium(eq); + } + } +} + +/* Compute all equilibrium */ +/* GSoC12: Tobenna Peter, Igwe */ +void computeEquilibria(Flagsrunlemke flags) +{ + int maxk = nrows + ncols; + int negi, posi; + + neg = newnode(n - 2); + pos = newnode(n - 2); + + + initstatistics(); + + isqdok(); + colset(n); + /* printf("LCP seems OK.\n"); */ + filltableau(); + /* printf("Tableau filled.\n"); */ + + /* Store the artificial equilibrium */ + Equilibrium eq = createEquilibrium(A, scfa, det, bascobas, whichvar, n, nrows, ncols); + neg->eq = eq; + + /* Compute and store the first equilibrium */ + runlemke(flags); + eq = createEquilibrium(A, scfa, det, bascobas, whichvar, n, nrows, ncols); + pos->eq = eq; + + if(flags.bouteq) + { + colprEquilibrium(eq); + } + if(flags.boutsol) + { + printEquilibrium(eq); + } + + /* Label 1 links the first equilibrium from both list */ + neg->link[0] = 0; + pos->link[0] = 0; + /* All labels for the artificial equilibrium */ + + computeEquilibriafromnode(0, 1, flags); + + flags.bisArtificial = 0; + negi = 1; + posi = 0; + int isneg = 0; + + while(1) + { + if(isneg) + { + while(negi < listlength(neg)) + { + computeEquilibriafromnode(negi, isneg, flags); + negi++; + } + } + else + { + while(posi < listlength(pos)) + { + computeEquilibriafromnode(posi, isneg, flags); + posi++; + } + } + isneg = !isneg; + if((negi == listlength(neg)) && (posi == listlength(pos))) + break; + } + + colout(); + if(flags.boutpath) + { + colset(n + 1); + int i; + for(i = 0; i < n + 1; ++i) + { + colleft(i); + } + char smp [2*DIG2DEC(MAX_DIGITS) + 4]; + + printf("\nEquilibria discovered: %d\n", (listlength(neg) - 1 + listlength(pos))); + sprintf(smp, "\n%d-ve index:", negi); + colpr(smp); + colnl(); + printlist(neg, 'N'); + sprintf(smp, "\n%d+ve index:", posi); + colpr(smp); + colnl(); + printlist(pos, 'P'); + colout(); + } +} + diff --git a/native-algo/lh-vector/gmp.h b/native-algo/lh-vector/gmp.h new file mode 100644 index 0000000..3555dac --- /dev/null +++ b/native-algo/lh-vector/gmp.h @@ -0,0 +1,984 @@ +/* gmp.h -- Definitions for GNU multiple precision functions. + +Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1999, 2000 Free Software +Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Library General Public License as published by +the Free Software Foundation; either version 2 of the License, or (at your +option) any later version. + +The GNU MP Library 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 Library General Public +License for more details. + +You should have received a copy of the GNU Library General Public License +along with the GNU MP Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +MA 02111-1307, USA. */ + +#ifndef __GMP_H__ + +#ifndef __GNU_MP__ /* to allow inclusion of both gmp.h and mp.h */ +#define __GNU_MP__ 2 +#define __need_size_t +#include +#undef __need_size_t + +#if defined (__mips) && defined (_ABIN32) +/* Force the use of 64-bit limbs for all 64-bit MIPS CPUs if ABI permits. */ +#define _LONG_LONG_LIMB +#endif + +#if (__STDC__-0) || defined (__cplusplus) +#define __gmp_const const +#define __gmp_signed signed +#else +#define __gmp_const +#define __gmp_signed +#endif + +#if defined (__GNUC__) +#define __gmp_inline __inline__ +#else +#define __gmp_inline +#endif + +#ifndef _EXTERN_INLINE +#ifdef __GNUC__ +#define _EXTERN_INLINE extern __inline__ +#else +#define _EXTERN_INLINE static +#endif +#endif + +#ifdef _SHORT_LIMB +typedef unsigned int mp_limb_t; +typedef int mp_limb_signed_t; +#else +#ifdef _LONG_LONG_LIMB +typedef unsigned long long int mp_limb_t; +typedef long long int mp_limb_signed_t; +#else +typedef unsigned long int mp_limb_t; +typedef long int mp_limb_signed_t; +#endif +#endif + +typedef mp_limb_t * mp_ptr; +typedef __gmp_const mp_limb_t * mp_srcptr; +#if defined (_CRAY) && ! defined (_CRAYMPP) +/* plain `int' is much faster (48 bits) */ +typedef int mp_size_t; +typedef int mp_exp_t; +#else +typedef long int mp_size_t; +typedef long int mp_exp_t; +#endif + +typedef struct +{ + int _mp_alloc; /* Number of *limbs* allocated and pointed + to by the _mp_d field. */ + int _mp_size; /* abs(_mp_size) is the number of limbs the + last field points to. If _mp_size is + negative this is a negative number. */ + mp_limb_t *_mp_d; /* Pointer to the limbs. */ +} __mpz_struct; +#endif /* __GNU_MP__ */ + +typedef __mpz_struct MP_INT; +typedef __mpz_struct mpz_t[1]; + +typedef struct +{ + __mpz_struct _mp_num; + __mpz_struct _mp_den; +} __mpq_struct; + +typedef __mpq_struct MP_RAT; +typedef __mpq_struct mpq_t[1]; + +typedef struct +{ + int _mp_prec; /* Max precision, in number of `mp_limb_t's. + Set by mpf_init and modified by + mpf_set_prec. The area pointed to by the + _mp_d field contains `prec' + 1 limbs. */ + int _mp_size; /* abs(_mp_size) is the number of limbs the + last field points to. If _mp_size is + negative this is a negative number. */ + mp_exp_t _mp_exp; /* Exponent, in the base of `mp_limb_t'. */ + mp_limb_t *_mp_d; /* Pointer to the limbs. */ +} __mpf_struct; + +/* typedef __mpf_struct MP_FLOAT; */ +typedef __mpf_struct mpf_t[1]; + +/* Available random number generation algorithms. */ +typedef enum +{ + GMP_RAND_ALG_DEFAULT = 0, + GMP_RAND_ALG_LC = GMP_RAND_ALG_DEFAULT /* Linear congruential. */ +} gmp_randalg_t; + +/* Linear congruential data struct. */ +typedef struct { + mpz_t a; /* Multiplier. */ + unsigned long int c; /* Adder. */ + mpz_t m; /* Modulus (valid only if m2exp == 0). */ + unsigned long int m2exp; /* If != 0, modulus is 2 ^ m2exp. */ +} __gmp_randata_lc; + +/* Random state struct. */ +typedef struct +{ + mpz_t seed; /* Current seed. */ + gmp_randalg_t alg; /* Algorithm used. */ + union { /* Algorithm specific data. */ + __gmp_randata_lc *lc; /* Linear congruential. */ + } algdata; +} __gmp_randstate_struct; +typedef __gmp_randstate_struct gmp_randstate_t[1]; + +/* Types for function declarations in gmp files. */ +/* ??? Should not pollute user name space with these ??? */ +typedef __gmp_const __mpz_struct *mpz_srcptr; +typedef __mpz_struct *mpz_ptr; +typedef __gmp_const __mpf_struct *mpf_srcptr; +typedef __mpf_struct *mpf_ptr; +typedef __gmp_const __mpq_struct *mpq_srcptr; +typedef __mpq_struct *mpq_ptr; + +#ifndef _PROTO +#if (__STDC__-0) || defined (__cplusplus) +#define _PROTO(x) x +#else +#define _PROTO(x) () +#endif +#endif + +#ifndef __MPN +/* Really use `defined (__STDC__)' here; we want it to be true for Sun C */ +#if defined (__STDC__) || defined (__cplusplus) +#define __MPN(x) __gmpn_##x +#else +#define __MPN(x) __gmpn_/**/x +#endif +#endif + +#if defined (FILE) || defined (H_STDIO) || defined (_H_STDIO) \ + || defined (_STDIO_H) || defined (_STDIO_H_) || defined (__STDIO_H__) \ + || defined (_STDIO_INCLUDED) || defined (__dj_include_stdio_h_) +#define _GMP_H_HAVE_FILE 1 +#endif + +#define mp_set_memory_functions __gmp_set_memory_functions +void mp_set_memory_functions _PROTO ((void *(*) (size_t), + void *(*) (void *, size_t, size_t), + void (*) (void *, size_t))); + +#define mp_bits_per_limb __gmp_bits_per_limb +extern __gmp_const int mp_bits_per_limb; + +/**************** Random number routines. ****************/ + +#define _gmp_rand __gmp_rand +#define gmp_randinit __gmp_randinit +#define gmp_randinit_lc __gmp_randinit_lc +#define gmp_randinit_lc_2exp __gmp_randinit_lc_2exp +#define gmp_randseed __gmp_randseed +#define gmp_randseed_ui __gmp_randseed_ui +#define gmp_randclear __gmp_randclear + +void _gmp_rand _PROTO ((mp_ptr, gmp_randstate_t, unsigned long int)); +void gmp_randinit _PROTO ((gmp_randstate_t, gmp_randalg_t, ...)); +void gmp_randinit_lc _PROTO ((gmp_randstate_t, mpz_t, unsigned long int, + mpz_t)); +void gmp_randinit_lc_2exp _PROTO ((gmp_randstate_t, mpz_t, unsigned long int, + unsigned long int)); +void gmp_randseed _PROTO ((gmp_randstate_t, mpz_t)); +void gmp_randseed_ui _PROTO ((gmp_randstate_t, unsigned long int)); +void gmp_randclear _PROTO ((gmp_randstate_t)); + +/**************** Integer (i.e. Z) routines. ****************/ + +#define _mpz_realloc __gmpz_realloc +#define mpz_realloc __gmpz_realloc +#define mpz_abs __gmpz_abs +#define mpz_add __gmpz_add +#define mpz_add_ui __gmpz_add_ui +#define mpz_addmul_ui __gmpz_addmul_ui +#define mpz_and __gmpz_and +#define mpz_array_init __gmpz_array_init +#define mpz_bin_ui __gmpz_bin_ui +#define mpz_bin_uiui __gmpz_bin_uiui +#define mpz_cdiv_q __gmpz_cdiv_q +#define mpz_cdiv_q_ui __gmpz_cdiv_q_ui +#define mpz_cdiv_qr __gmpz_cdiv_qr +#define mpz_cdiv_qr_ui __gmpz_cdiv_qr_ui +#define mpz_cdiv_r __gmpz_cdiv_r +#define mpz_cdiv_r_ui __gmpz_cdiv_r_ui +#define mpz_cdiv_ui __gmpz_cdiv_ui +#define mpz_clear __gmpz_clear +#define mpz_clrbit __gmpz_clrbit +#define mpz_cmp __gmpz_cmp +#define _mpz_cmp_si __gmpz_cmp_si +#define _mpz_cmp_ui __gmpz_cmp_ui +#define mpz_cmpabs __gmpz_cmpabs +#define mpz_cmpabs_ui __gmpz_cmpabs_ui +#define mpz_com __gmpz_com +#define mpz_divexact __gmpz_divexact +#define mpz_dump __gmpz_dump +#define mpz_fac_ui __gmpz_fac_ui +#define mpz_fdiv_q __gmpz_fdiv_q +#define mpz_fdiv_q_2exp __gmpz_fdiv_q_2exp +#define mpz_fdiv_q_ui __gmpz_fdiv_q_ui +#define mpz_fdiv_qr __gmpz_fdiv_qr +#define mpz_fdiv_qr_ui __gmpz_fdiv_qr_ui +#define mpz_fdiv_r __gmpz_fdiv_r +#define mpz_fdiv_r_2exp __gmpz_fdiv_r_2exp +#define mpz_fdiv_r_ui __gmpz_fdiv_r_ui +#define mpz_fdiv_ui __gmpz_fdiv_ui +#define mpz_fib_ui __gmpz_fib_ui +#define mpz_fits_sint_p __gmpz_fits_sint_p +#define mpz_fits_slong_p __gmpz_fits_slong_p +#define mpz_fits_sshort_p __gmpz_fits_sshort_p +#define mpz_fits_uint_p __gmpz_fits_uint_p +#define mpz_fits_ulong_p __gmpz_fits_ulong_p +#define mpz_fits_ushort_p __gmpz_fits_ushort_p +#define mpz_gcd __gmpz_gcd +#define mpz_gcd_ui __gmpz_gcd_ui +#define mpz_gcdext __gmpz_gcdext +#define mpz_get_d __gmpz_get_d +#define mpz_get_si __gmpz_get_si +#define mpz_get_str __gmpz_get_str +#define mpz_get_ui __gmpz_get_ui +#define mpz_getlimbn __gmpz_getlimbn +#define mpz_hamdist __gmpz_hamdist +#define mpz_init __gmpz_init +#define mpz_inp_binary __gmpz_inp_binary +#define mpz_inp_raw __gmpz_inp_raw +#define mpz_inp_str __gmpz_inp_str +#define mpz_init_set __gmpz_init_set +#define mpz_init_set_d __gmpz_init_set_d +#define mpz_init_set_si __gmpz_init_set_si +#define mpz_init_set_str __gmpz_init_set_str +#define mpz_init_set_ui __gmpz_init_set_ui +#define mpz_invert __gmpz_invert +#define mpz_ior __gmpz_ior +#define mpz_jacobi __gmpz_jacobi +#define mpz_lcm __gmpz_lcm +#define mpz_legendre __gmpz_legendre +#define mpz_mod __gmpz_mod +#define mpz_mul __gmpz_mul +#define mpz_mul_2exp __gmpz_mul_2exp +#define mpz_mul_ui __gmpz_mul_ui +#define mpz_neg __gmpz_neg +#define mpz_nextprime __gmpz_nextprime +#define mpz_out_binary __gmpz_out_binary +#define mpz_out_raw __gmpz_out_raw +#define mpz_out_str __gmpz_out_str +#define mpz_perfect_power_p __gmpz_perfect_power_p +#define mpz_perfect_square_p __gmpz_perfect_square_p +#define mpz_popcount __gmpz_popcount +#define mpz_pow_ui __gmpz_pow_ui +#define mpz_powm __gmpz_powm +#define mpz_powm_ui __gmpz_powm_ui +#define mpz_probab_prime_p __gmpz_probab_prime_p +#define mpz_random __gmpz_random +#define mpz_random2 __gmpz_random2 +#define mpz_remove __gmpz_remove +#define mpz_root __gmpz_root +#define mpz_rrandomb __gmpz_rrandomb +#define mpz_scan0 __gmpz_scan0 +#define mpz_scan1 __gmpz_scan1 +#define mpz_set __gmpz_set +#define mpz_set_d __gmpz_set_d +#define mpz_set_f __gmpz_set_f +#define mpz_set_q __gmpz_set_q +#define mpz_set_si __gmpz_set_si +#define mpz_set_str __gmpz_set_str +#define mpz_set_ui __gmpz_set_ui +#define mpz_setbit __gmpz_setbit +#define mpz_size __gmpz_size +#define mpz_sizeinbase __gmpz_sizeinbase +#define mpz_sqrt __gmpz_sqrt +#define mpz_sqrtrem __gmpz_sqrtrem +#define mpz_sub __gmpz_sub +#define mpz_sub_ui __gmpz_sub_ui +#define mpz_swap __gmpz_swap +#define mpz_tdiv_ui __gmpz_tdiv_ui +#define mpz_tdiv_q __gmpz_tdiv_q +#define mpz_tdiv_q_2exp __gmpz_tdiv_q_2exp +#define mpz_tdiv_q_ui __gmpz_tdiv_q_ui +#define mpz_tdiv_qr __gmpz_tdiv_qr +#define mpz_tdiv_qr_ui __gmpz_tdiv_qr_ui +#define mpz_tdiv_r __gmpz_tdiv_r +#define mpz_tdiv_r_2exp __gmpz_tdiv_r_2exp +#define mpz_tdiv_r_ui __gmpz_tdiv_r_ui +#define mpz_tstbit __gmpz_tstbit +#define mpz_ui_pow_ui __gmpz_ui_pow_ui +#define mpz_urandomb __gmpz_urandomb +#define mpz_urandomm __gmpz_urandomm +#define mpz_xor __gmpz_xor +#define mpz_eor __gmpz_xor + +#if defined (__cplusplus) +extern "C" { +#endif +void *_mpz_realloc _PROTO ((mpz_ptr, mp_size_t)); + +void mpz_abs _PROTO ((mpz_ptr, mpz_srcptr)); +void mpz_add _PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr)); +void mpz_add_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int)); +void mpz_addmul_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int)); +void mpz_and _PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr)); +void mpz_array_init _PROTO ((mpz_ptr, mp_size_t, mp_size_t)); +void mpz_bin_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int)); +void mpz_bin_uiui _PROTO ((mpz_ptr, unsigned long int, unsigned long int)); +void mpz_cdiv_q _PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr)); +unsigned long int mpz_cdiv_q_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int)); +void mpz_cdiv_qr _PROTO ((mpz_ptr, mpz_ptr, mpz_srcptr, mpz_srcptr)); +unsigned long int mpz_cdiv_qr_ui _PROTO ((mpz_ptr, mpz_ptr, mpz_srcptr, unsigned long int)); +void mpz_cdiv_r _PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr)); +unsigned long int mpz_cdiv_r_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int)); +unsigned long int mpz_cdiv_ui _PROTO ((mpz_srcptr, unsigned long int)); +void mpz_clear _PROTO ((mpz_ptr)); +void mpz_clrbit _PROTO ((mpz_ptr, unsigned long int)); +int mpz_cmp _PROTO ((mpz_srcptr, mpz_srcptr)); +int _mpz_cmp_si _PROTO ((mpz_srcptr, signed long int)); +int _mpz_cmp_ui _PROTO ((mpz_srcptr, unsigned long int)); +int mpz_cmpabs _PROTO ((mpz_srcptr, mpz_srcptr)); +int mpz_cmpabs_ui _PROTO ((mpz_srcptr, unsigned long int)); +void mpz_com _PROTO ((mpz_ptr, mpz_srcptr)); +void mpz_divexact _PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr)); +void mpz_dump _PROTO ((mpz_srcptr)); +void mpz_fac_ui _PROTO ((mpz_ptr, unsigned long int)); +void mpz_fdiv_q _PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr)); +void mpz_fdiv_q_2exp _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int)); +unsigned long int mpz_fdiv_q_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int)); +void mpz_fdiv_qr _PROTO ((mpz_ptr, mpz_ptr, mpz_srcptr, mpz_srcptr)); +unsigned long int mpz_fdiv_qr_ui _PROTO ((mpz_ptr, mpz_ptr, mpz_srcptr, unsigned long int)); +void mpz_fdiv_r _PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr)); +void mpz_fdiv_r_2exp _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int)); +unsigned long int mpz_fdiv_r_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int)); +unsigned long int mpz_fdiv_ui _PROTO ((mpz_srcptr, unsigned long int)); +void mpz_fib_ui _PROTO ((mpz_ptr, unsigned long int)); +int mpz_fits_sint_p _PROTO ((mpz_srcptr)); +int mpz_fits_slong_p _PROTO ((mpz_srcptr)); +int mpz_fits_sshort_p _PROTO ((mpz_srcptr)); +int mpz_fits_uint_p _PROTO ((mpz_srcptr)); +int mpz_fits_ulong_p _PROTO ((mpz_srcptr)); +int mpz_fits_ushort_p _PROTO ((mpz_srcptr)); +void mpz_gcd _PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr)); +unsigned long int mpz_gcd_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int)); +void mpz_gcdext _PROTO ((mpz_ptr, mpz_ptr, mpz_ptr, mpz_srcptr, mpz_srcptr)); +double mpz_get_d _PROTO ((mpz_srcptr)); +/* signed */ long int mpz_get_si _PROTO ((mpz_srcptr)); +char *mpz_get_str _PROTO ((char *, int, mpz_srcptr)); +unsigned long int mpz_get_ui _PROTO ((mpz_srcptr)); +mp_limb_t mpz_getlimbn _PROTO ((mpz_srcptr, mp_size_t)); +unsigned long int mpz_hamdist _PROTO ((mpz_srcptr, mpz_srcptr)); +void mpz_init _PROTO ((mpz_ptr)); +#ifdef _GMP_H_HAVE_FILE +size_t mpz_inp_binary _PROTO ((mpz_ptr, FILE *)); +size_t mpz_inp_raw _PROTO ((mpz_ptr, FILE *)); +size_t mpz_inp_str _PROTO ((mpz_ptr, FILE *, int)); +#endif +void mpz_init_set _PROTO ((mpz_ptr, mpz_srcptr)); +void mpz_init_set_d _PROTO ((mpz_ptr, double)); +void mpz_init_set_si _PROTO ((mpz_ptr, signed long int)); +int mpz_init_set_str _PROTO ((mpz_ptr, __gmp_const char *, int)); +void mpz_init_set_ui _PROTO ((mpz_ptr, unsigned long int)); +int mpz_invert _PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr)); +void mpz_ior _PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr)); +int mpz_jacobi _PROTO ((mpz_srcptr, mpz_srcptr)); +void mpz_lcm _PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr)); +int mpz_legendre _PROTO ((mpz_srcptr, mpz_srcptr)); +void mpz_mod _PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr)); +void mpz_mul _PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr)); +void mpz_mul_2exp _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int)); +void mpz_mul_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int)); +void mpz_neg _PROTO ((mpz_ptr, mpz_srcptr)); +void mpz_nextprime _PROTO ((mpz_ptr, mpz_srcptr)); +#ifdef _GMP_H_HAVE_FILE +size_t mpz_out_binary _PROTO ((FILE *, mpz_srcptr)); +size_t mpz_out_raw _PROTO ((FILE *, mpz_srcptr)); +size_t mpz_out_str _PROTO ((FILE *, int, mpz_srcptr)); +#endif +int mpz_perfect_power_p _PROTO ((mpz_srcptr)); +int mpz_perfect_square_p _PROTO ((mpz_srcptr)); +unsigned long int mpz_popcount _PROTO ((mpz_srcptr)); +void mpz_pow_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int)); +void mpz_powm _PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr, mpz_srcptr)); +void mpz_powm_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int, mpz_srcptr)); +int mpz_probab_prime_p _PROTO ((mpz_srcptr, int)); +void mpz_random _PROTO ((mpz_ptr, mp_size_t)); +void mpz_random2 _PROTO ((mpz_ptr, mp_size_t)); +unsigned long int mpz_remove _PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr)); +int mpz_root _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int)); +void mpz_rrandomb _PROTO ((mpz_ptr, gmp_randstate_t, unsigned long int)); +unsigned long int mpz_scan0 _PROTO ((mpz_srcptr, unsigned long int)); +unsigned long int mpz_scan1 _PROTO ((mpz_srcptr, unsigned long int)); +void mpz_set _PROTO ((mpz_ptr, mpz_srcptr)); +void mpz_set_d _PROTO ((mpz_ptr, double)); +void mpz_set_f _PROTO ((mpz_ptr, mpf_srcptr)); +void mpz_set_q _PROTO ((mpz_ptr, mpq_srcptr)); +void mpz_set_si _PROTO ((mpz_ptr, signed long int)); +int mpz_set_str _PROTO ((mpz_ptr, __gmp_const char *, int)); +void mpz_set_ui _PROTO ((mpz_ptr, unsigned long int)); +void mpz_setbit _PROTO ((mpz_ptr, unsigned long int)); +size_t mpz_size _PROTO ((mpz_srcptr)); +size_t mpz_sizeinbase _PROTO ((mpz_srcptr, int)); +void mpz_sqrt _PROTO ((mpz_ptr, mpz_srcptr)); +void mpz_sqrtrem _PROTO ((mpz_ptr, mpz_ptr, mpz_srcptr)); +void mpz_sub _PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr)); +void mpz_sub_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int)); +void mpz_swap _PROTO ((mpz_ptr, mpz_ptr)); +void mpz_tdiv_q _PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr)); +void mpz_tdiv_q_2exp _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int)); +unsigned long int mpz_tdiv_ui _PROTO ((mpz_srcptr, unsigned long int)); +unsigned long int mpz_tdiv_q_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int)); +void mpz_tdiv_qr _PROTO ((mpz_ptr, mpz_ptr, mpz_srcptr, mpz_srcptr)); +unsigned long int mpz_tdiv_qr_ui _PROTO ((mpz_ptr, mpz_ptr, mpz_srcptr, unsigned long int)); +void mpz_tdiv_r _PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr)); +void mpz_tdiv_r_2exp _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int)); +unsigned long int mpz_tdiv_r_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int)); +int mpz_tstbit _PROTO ((mpz_srcptr, unsigned long int)); +void mpz_ui_pow_ui _PROTO ((mpz_ptr, unsigned long int, unsigned long int)); +void mpz_urandomb _PROTO ((mpz_t, gmp_randstate_t, unsigned long int)); +void mpz_urandomm _PROTO ((mpz_t, gmp_randstate_t, mpz_t)); +void mpz_xor _PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr)); +#if defined (__cplusplus) +} +#endif + +/**************** Rational (i.e. Q) routines. ****************/ + +#define mpq_init __gmpq_init +#define mpq_clear __gmpq_clear +#define mpq_set __gmpq_set +#define mpq_set_ui __gmpq_set_ui +#define mpq_set_si __gmpq_set_si +#define mpq_set_z __gmpq_set_z +#define mpq_add __gmpq_add +#define mpq_sub __gmpq_sub +#define mpq_mul __gmpq_mul +#define mpq_div __gmpq_div +#define mpq_neg __gmpq_neg +#define mpq_cmp __gmpq_cmp +#define _mpq_cmp_ui __gmpq_cmp_ui +#define mpq_equal __gmpq_equal +#define mpq_inv __gmpq_inv +#define mpq_set_num __gmpq_set_num +#define mpq_set_den __gmpq_set_den +#define mpq_get_num __gmpq_get_num +#define mpq_get_den __gmpq_get_den +#define mpq_get_d __gmpq_get_d +#define mpq_set_d __gmpq_set_d +#define mpq_canonicalize __gmpq_canonicalize + +#if defined (__cplusplus) +extern "C" { +#endif +void mpq_init _PROTO ((mpq_ptr)); +void mpq_clear _PROTO ((mpq_ptr)); +void mpq_set _PROTO ((mpq_ptr, mpq_srcptr)); +void mpq_set_ui _PROTO ((mpq_ptr, unsigned long int, unsigned long int)); +void mpq_set_si _PROTO ((mpq_ptr, signed long int, unsigned long int)); +void mpq_set_z _PROTO ((mpq_ptr, mpz_srcptr)); +void mpq_add _PROTO ((mpq_ptr, mpq_srcptr, mpq_srcptr)); +void mpq_sub _PROTO ((mpq_ptr, mpq_srcptr, mpq_srcptr)); +void mpq_mul _PROTO ((mpq_ptr, mpq_srcptr, mpq_srcptr)); +void mpq_div _PROTO ((mpq_ptr, mpq_srcptr, mpq_srcptr)); +void mpq_neg _PROTO ((mpq_ptr, mpq_srcptr)); +int mpq_cmp _PROTO ((mpq_srcptr, mpq_srcptr)); +int mpq_cmp_ui _PROTO ((mpq_srcptr, unsigned long int, unsigned long int)); +int mpq_equal _PROTO ((mpq_srcptr, mpq_srcptr)); +void mpq_inv _PROTO ((mpq_ptr, mpq_srcptr)); +void mpq_set_num _PROTO ((mpq_ptr, mpz_srcptr)); +void mpq_set_den _PROTO ((mpq_ptr, mpz_srcptr)); +void mpq_get_num _PROTO ((mpz_ptr, mpq_srcptr)); +void mpq_get_den _PROTO ((mpz_ptr, mpq_srcptr)); +double mpq_get_d _PROTO ((mpq_srcptr)); +void mpq_set_d _PROTO ((mpq_ptr, double)); +void mpq_canonicalize _PROTO ((mpq_ptr)); +#if defined (__cplusplus) +} +#endif + +/**************** Float (i.e. F) routines. ****************/ + +#define mpf_abs __gmpf_abs +#define mpf_add __gmpf_add +#define mpf_add_ui __gmpf_add_ui +#define mpf_ceil __gmpf_ceil +#define mpf_clear __gmpf_clear +#define mpf_cmp __gmpf_cmp +#define mpf_cmp_si __gmpf_cmp_si +#define mpf_cmp_ui __gmpf_cmp_ui +#define mpf_div __gmpf_div +#define mpf_div_2exp __gmpf_div_2exp +#define mpf_div_ui __gmpf_div_ui +#define mpf_dump __gmpf_dump +#define mpf_floor __gmpf_floor +#define mpf_eq __gmpf_eq +#define mpf_get_d __gmpf_get_d +#define mpf_get_prec __gmpf_get_prec +#define mpf_get_str __gmpf_get_str +#define mpf_init __gmpf_init +#define mpf_init2 __gmpf_init2 +#define mpf_inp_str __gmpf_inp_str +#define mpf_init_set __gmpf_init_set +#define mpf_init_set_d __gmpf_init_set_d +#define mpf_init_set_si __gmpf_init_set_si +#define mpf_init_set_str __gmpf_init_set_str +#define mpf_init_set_ui __gmpf_init_set_ui +#define mpf_mul __gmpf_mul +#define mpf_mul_2exp __gmpf_mul_2exp +#define mpf_mul_ui __gmpf_mul_ui +#define mpf_neg __gmpf_neg +#define mpf_out_str __gmpf_out_str +#define mpf_pow_ui __gmpf_pow_ui +#define mpf_random2 __gmpf_random2 +#define mpf_reldiff __gmpf_reldiff +#define mpf_set __gmpf_set +#define mpf_set_d __gmpf_set_d +#define mpf_set_default_prec __gmpf_set_default_prec +#define mpf_set_prec __gmpf_set_prec +#define mpf_set_prec_raw __gmpf_set_prec_raw +#define mpf_set_q __gmpf_set_q +#define mpf_set_si __gmpf_set_si +#define mpf_set_str __gmpf_set_str +#define mpf_set_ui __gmpf_set_ui +#define mpf_set_z __gmpf_set_z +#define mpf_size __gmpf_size +#define mpf_sqrt __gmpf_sqrt +#define mpf_sqrt_ui __gmpf_sqrt_ui +#define mpf_sub __gmpf_sub +#define mpf_sub_ui __gmpf_sub_ui +#define mpf_trunc __gmpf_trunc +#define mpf_ui_div __gmpf_ui_div +#define mpf_ui_sub __gmpf_ui_sub +#define mpf_urandomb __gmpf_urandomb + +#if defined (__cplusplus) +extern "C" { +#endif +void mpf_abs _PROTO ((mpf_ptr, mpf_srcptr)); +void mpf_add _PROTO ((mpf_ptr, mpf_srcptr, mpf_srcptr)); +void mpf_add_ui _PROTO ((mpf_ptr, mpf_srcptr, unsigned long int)); +void mpf_ceil _PROTO ((mpf_ptr, mpf_srcptr)); +void mpf_clear _PROTO ((mpf_ptr)); +int mpf_cmp _PROTO ((mpf_srcptr, mpf_srcptr)); +int mpf_cmp_si _PROTO ((mpf_srcptr, signed long int)); +int mpf_cmp_ui _PROTO ((mpf_srcptr, unsigned long int)); +void mpf_div _PROTO ((mpf_ptr, mpf_srcptr, mpf_srcptr)); +void mpf_div_2exp _PROTO ((mpf_ptr, mpf_srcptr, unsigned long int)); +void mpf_div_ui _PROTO ((mpf_ptr, mpf_srcptr, unsigned long int)); +void mpf_dump _PROTO ((mpf_srcptr)); +int mpf_eq _PROTO ((mpf_srcptr, mpf_srcptr, unsigned long int)); +void mpf_floor _PROTO ((mpf_ptr, mpf_srcptr)); +double mpf_get_d _PROTO ((mpf_srcptr)); +unsigned long int mpf_get_prec _PROTO ((mpf_srcptr)); +char *mpf_get_str _PROTO ((char *, mp_exp_t *, int, size_t, mpf_srcptr)); +void mpf_init _PROTO ((mpf_ptr)); +void mpf_init2 _PROTO ((mpf_ptr, unsigned long int)); +#ifdef _GMP_H_HAVE_FILE +size_t mpf_inp_str _PROTO ((mpf_ptr, FILE *, int)); +#endif +void mpf_init_set _PROTO ((mpf_ptr, mpf_srcptr)); +void mpf_init_set_d _PROTO ((mpf_ptr, double)); +void mpf_init_set_si _PROTO ((mpf_ptr, signed long int)); +int mpf_init_set_str _PROTO ((mpf_ptr, __gmp_const char *, int)); +void mpf_init_set_ui _PROTO ((mpf_ptr, unsigned long int)); +void mpf_mul _PROTO ((mpf_ptr, mpf_srcptr, mpf_srcptr)); +void mpf_mul_2exp _PROTO ((mpf_ptr, mpf_srcptr, unsigned long int)); +void mpf_mul_ui _PROTO ((mpf_ptr, mpf_srcptr, unsigned long int)); +void mpf_neg _PROTO ((mpf_ptr, mpf_srcptr)); +#ifdef _GMP_H_HAVE_FILE +size_t mpf_out_str _PROTO ((FILE *, int, size_t, mpf_srcptr)); +#endif +void mpf_pow_ui _PROTO ((mpf_ptr, mpf_srcptr, unsigned long int)); +void mpf_random2 _PROTO ((mpf_ptr, mp_size_t, mp_exp_t)); +void mpf_reldiff _PROTO ((mpf_ptr, mpf_srcptr, mpf_srcptr)); +void mpf_set _PROTO ((mpf_ptr, mpf_srcptr)); +void mpf_set_d _PROTO ((mpf_ptr, double)); +void mpf_set_default_prec _PROTO ((unsigned long int)); +void mpf_set_prec _PROTO ((mpf_ptr, unsigned long int)); +void mpf_set_prec_raw _PROTO ((mpf_ptr, unsigned long int)); +void mpf_set_q _PROTO ((mpf_ptr, mpq_srcptr)); +void mpf_set_si _PROTO ((mpf_ptr, signed long int)); +int mpf_set_str _PROTO ((mpf_ptr, __gmp_const char *, int)); +void mpf_set_ui _PROTO ((mpf_ptr, unsigned long int)); +void mpf_set_z _PROTO ((mpf_ptr, mpz_srcptr)); +size_t mpf_size _PROTO ((mpf_srcptr)); +void mpf_sqrt _PROTO ((mpf_ptr, mpf_srcptr)); +void mpf_sqrt_ui _PROTO ((mpf_ptr, unsigned long int)); +void mpf_sub _PROTO ((mpf_ptr, mpf_srcptr, mpf_srcptr)); +void mpf_sub_ui _PROTO ((mpf_ptr, mpf_srcptr, unsigned long int)); +void mpf_trunc _PROTO ((mpf_ptr, mpf_srcptr)); +void mpf_ui_div _PROTO ((mpf_ptr, unsigned long int, mpf_srcptr)); +void mpf_ui_sub _PROTO ((mpf_ptr, unsigned long int, mpf_srcptr)); +void mpf_urandomb _PROTO ((mpf_t, gmp_randstate_t, unsigned long int)); + +#if defined (__cplusplus) +} +#endif +/************ Low level positive-integer (i.e. N) routines. ************/ + +/* This is ugly, but we need to make user calls reach the prefixed function. */ +#define mpn_add __MPN(add) +#define mpn_add_1 __MPN(add_1) +#define mpn_add_n __MPN(add_n) +#define mpn_add_nc __MPN(add_nc) +#define mpn_addmul_1 __MPN(addmul_1) +#define mpn_addmul_1c __MPN(addmul_1c) +#define mpn_addsub_n __MPN(addsub_n) +#define mpn_addsub_nc __MPN(addsub_nc) +/* #define mpn_and_n __MPN(and_n) */ +/* #define mpn_andn_n __MPN(andn_n) */ +#define mpn_bdivmod __MPN(bdivmod) +#define mpn_cmp __MPN(cmp) +/* #define mpn_com_n __MPN(com_n) */ +#define mpn_copyd __MPN(copyd) +#define mpn_copyi __MPN(copyi) +#define mpn_divexact_by3 __MPN(divexact_by3) +#define mpn_divmod_1 __MPN(divmod_1) +#define mpn_divmod_1c __MPN(divmod_1c) +#define mpn_divrem __MPN(divrem) +#define mpn_divrem_1 __MPN(divrem_1) +#define mpn_divrem_1c __MPN(divrem_1c) +#define mpn_divrem_2 __MPN(divrem_2) +#define mpn_dump __MPN(dump) +#define mpn_gcd __MPN(gcd) +#define mpn_gcd_1 __MPN(gcd_1) +#define mpn_gcdext __MPN(gcdext) +#define mpn_get_str __MPN(get_str) +#define mpn_hamdist __MPN(hamdist) +#define mpn_invert_limb __MPN(invert_limb) +/* #define mpn_ior_n __MPN(ior_n) */ +/* #define mpn_iorn_n __MPN(iorn_n) */ +/* #define mpn_kara_mul_n __MPN(kara_mul_n) internal */ +/* #define mpn_kara_sqr_n __MPN(kara_sqr_n) internal */ +#define mpn_lshift __MPN(lshift) +#define mpn_lshiftc __MPN(lshiftc) +#define mpn_mod_1 __MPN(mod_1) +#define mpn_mod_1c __MPN(mod_1c) +#define mpn_mul __MPN(mul) +#define mpn_mul_1 __MPN(mul_1) +#define mpn_mul_1c __MPN(mul_1c) +#define mpn_mul_basecase __MPN(mul_basecase) +#define mpn_mul_n __MPN(mul_n) +#define mpn_perfect_square_p __MPN(perfect_square_p) +#define mpn_popcount __MPN(popcount) +#define mpn_preinv_mod_1 __MPN(preinv_mod_1) +/* #define mpn_nand_n __MPN(nand_n) */ +/* #define mpn_nior_n __MPN(nior_n) */ +#define mpn_random __MPN(random) +#define mpn_random2 __MPN(random2) +#define mpn_rshift __MPN(rshift) +#define mpn_rshiftc __MPN(rshiftc) +#define mpn_scan0 __MPN(scan0) +#define mpn_scan1 __MPN(scan1) +#define mpn_set_str __MPN(set_str) +#define mpn_sqr_basecase __MPN(sqr_basecase) +#define mpn_sqr_n __MPN(sqr_n) +#define mpn_sqrtrem __MPN(sqrtrem) +#define mpn_sub __MPN(sub) +#define mpn_sub_1 __MPN(sub_1) +#define mpn_sub_n __MPN(sub_n) +#define mpn_sub_nc __MPN(sub_nc) +#define mpn_submul_1 __MPN(submul_1) +#define mpn_submul_1c __MPN(submul_1c) +/* #define mpn_toom3_mul_n __MPN(toom3_mul_n) internal */ +/* #define mpn_toom3_sqr_n __MPN(toom3_sqr_n) internal */ +/* #define mpn_xnor_n __MPN(xnor_n) */ +/* #define mpn_xor_n __MPN(xor_n) */ + +#if defined (__cplusplus) +extern "C" { +#endif +mp_limb_t mpn_add _PROTO ((mp_ptr, mp_srcptr, mp_size_t, mp_srcptr,mp_size_t)); +mp_limb_t mpn_add_1 _PROTO ((mp_ptr, mp_srcptr, mp_size_t, mp_limb_t)); +mp_limb_t mpn_add_n _PROTO ((mp_ptr, mp_srcptr, mp_srcptr, mp_size_t)); +mp_limb_t mpn_add_nc _PROTO ((mp_ptr, mp_srcptr, mp_srcptr, mp_size_t, mp_limb_t)); +mp_limb_t mpn_addmul_1 _PROTO ((mp_ptr, mp_srcptr, mp_size_t, mp_limb_t)); +mp_limb_t mpn_addsub_n _PROTO ((mp_ptr, mp_ptr, mp_srcptr, mp_srcptr, mp_size_t)); +mp_limb_t mpn_bdivmod _PROTO ((mp_ptr, mp_ptr, mp_size_t, mp_srcptr, mp_size_t, unsigned long int)); +int mpn_cmp _PROTO ((mp_srcptr, mp_srcptr, mp_size_t)); +mp_limb_t mpn_divexact_by3 _PROTO ((mp_ptr dst, mp_srcptr src, mp_size_t size)); +mp_limb_t mpn_divmod_1 _PROTO ((mp_ptr, mp_srcptr, mp_size_t, mp_limb_t)); +mp_limb_t mpn_divrem _PROTO((mp_ptr, mp_size_t, mp_ptr, mp_size_t, mp_srcptr, mp_size_t)); +mp_limb_t mpn_divrem_1 _PROTO ((mp_ptr, mp_size_t, mp_srcptr, mp_size_t, mp_limb_t)); +mp_limb_t mpn_divrem_2 _PROTO ((mp_ptr, mp_size_t, mp_ptr, mp_size_t, mp_srcptr)); +void mpn_dump _PROTO ((mp_srcptr, mp_size_t)); +mp_size_t mpn_gcd _PROTO ((mp_ptr, mp_ptr, mp_size_t, mp_ptr, mp_size_t)); +mp_limb_t mpn_gcd_1 _PROTO ((mp_srcptr, mp_size_t, mp_limb_t)); +mp_size_t mpn_gcdext _PROTO ((mp_ptr, mp_ptr, mp_size_t *, mp_ptr, mp_size_t, mp_ptr, mp_size_t)); +size_t mpn_get_str _PROTO ((unsigned char *, int, mp_ptr, mp_size_t)); +unsigned long int mpn_hamdist _PROTO ((mp_srcptr, mp_srcptr, mp_size_t)); +mp_limb_t mpn_lshift _PROTO ((mp_ptr, mp_srcptr, mp_size_t, unsigned int)); +mp_limb_t mpn_mod_1 _PROTO ((mp_srcptr, mp_size_t, mp_limb_t)); +mp_limb_t mpn_mul _PROTO ((mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t)); +mp_limb_t mpn_mul_1 _PROTO ((mp_ptr, mp_srcptr, mp_size_t, mp_limb_t)); +void mpn_mul_basecase _PROTO ((mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t)); +void mpn_mul_n _PROTO ((mp_ptr, mp_srcptr, mp_srcptr, mp_size_t)); +int mpn_perfect_square_p _PROTO ((mp_srcptr, mp_size_t)); +unsigned long int mpn_popcount _PROTO ((mp_srcptr, mp_size_t)); +mp_limb_t mpn_preinv_mod_1 _PROTO ((mp_srcptr, mp_size_t, mp_limb_t, mp_limb_t)); +void mpn_random _PROTO ((mp_ptr, mp_size_t)); +void mpn_random2 _PROTO ((mp_ptr, mp_size_t)); +mp_limb_t mpn_rshift _PROTO ((mp_ptr, mp_srcptr, mp_size_t, unsigned int)); +unsigned long int mpn_scan0 _PROTO ((mp_srcptr, unsigned long int)); +unsigned long int mpn_scan1 _PROTO ((mp_srcptr, unsigned long int)); +mp_size_t mpn_set_str _PROTO ((mp_ptr, __gmp_const unsigned char *, size_t, int)); +void mpn_sqr_n _PROTO ((mp_ptr, mp_srcptr, mp_size_t)); +void mpn_sqr_basecase _PROTO ((mp_ptr, mp_srcptr, mp_size_t)); +mp_size_t mpn_sqrtrem _PROTO ((mp_ptr, mp_ptr, mp_srcptr, mp_size_t)); +mp_limb_t mpn_sub _PROTO ((mp_ptr, mp_srcptr, mp_size_t, mp_srcptr,mp_size_t)); +mp_limb_t mpn_sub_1 _PROTO ((mp_ptr, mp_srcptr, mp_size_t, mp_limb_t)); +mp_limb_t mpn_sub_n _PROTO ((mp_ptr, mp_srcptr, mp_srcptr, mp_size_t)); +mp_limb_t mpn_sub_nc _PROTO ((mp_ptr, mp_srcptr, mp_srcptr, mp_size_t, mp_limb_t)); +mp_limb_t mpn_submul_1 _PROTO ((mp_ptr, mp_srcptr, mp_size_t, mp_limb_t)); +#if defined (__cplusplus) +} +#endif + +#define mpn_incr_u(p,incr) \ + do { mp_limb_t __x; mp_ptr __p = p; \ + __x = *__p + incr; \ + *__p = __x; \ + if (__x < incr) \ + while (++(*(++__p)) == 0) \ + ; \ + } while (0) + +#define mpn_decr_u(p,incr) \ + do { mp_limb_t __x; mp_ptr __p = p; \ + __x = *__p; \ + *__p = __x - incr; \ + if (__x < incr) \ + while ((*(++__p))-- == 0) \ + ; \ + } while (0) + +#if defined (__GNUC__) || defined (_FORCE_INLINES) +_EXTERN_INLINE mp_limb_t +#if (__STDC__-0) || defined (__cplusplus) +mpn_add_1 (register mp_ptr res_ptr, + register mp_srcptr s1_ptr, + register mp_size_t s1_size, + register mp_limb_t s2_limb) +#else +mpn_add_1 (res_ptr, s1_ptr, s1_size, s2_limb) + register mp_ptr res_ptr; + register mp_srcptr s1_ptr; + register mp_size_t s1_size; + register mp_limb_t s2_limb; +#endif +{ + register mp_limb_t x; + + x = *s1_ptr++; + s2_limb = x + s2_limb; + *res_ptr++ = s2_limb; + if (s2_limb < x) + { + while (--s1_size != 0) + { + x = *s1_ptr++ + 1; + *res_ptr++ = x; + if (x != 0) + goto fin; + } + + return 1; + } + + fin: + if (res_ptr != s1_ptr) + { + mp_size_t i; + for (i = 0; i < s1_size - 1; i++) + res_ptr[i] = s1_ptr[i]; + } + return 0; +} + +_EXTERN_INLINE mp_limb_t +#if (__STDC__-0) || defined (__cplusplus) +mpn_add (register mp_ptr res_ptr, + register mp_srcptr s1_ptr, + register mp_size_t s1_size, + register mp_srcptr s2_ptr, + register mp_size_t s2_size) +#else +mpn_add (res_ptr, s1_ptr, s1_size, s2_ptr, s2_size) + register mp_ptr res_ptr; + register mp_srcptr s1_ptr; + register mp_size_t s1_size; + register mp_srcptr s2_ptr; + register mp_size_t s2_size; +#endif +{ + mp_limb_t cy_limb = 0; + + if (s2_size != 0) + cy_limb = mpn_add_n (res_ptr, s1_ptr, s2_ptr, s2_size); + + if (s1_size - s2_size != 0) + cy_limb = mpn_add_1 (res_ptr + s2_size, + s1_ptr + s2_size, + s1_size - s2_size, + cy_limb); + return cy_limb; +} + +_EXTERN_INLINE mp_limb_t +#if (__STDC__-0) || defined (__cplusplus) +mpn_sub_1 (register mp_ptr res_ptr, + register mp_srcptr s1_ptr, + register mp_size_t s1_size, + register mp_limb_t s2_limb) +#else +mpn_sub_1 (res_ptr, s1_ptr, s1_size, s2_limb) + register mp_ptr res_ptr; + register mp_srcptr s1_ptr; + register mp_size_t s1_size; + register mp_limb_t s2_limb; +#endif +{ + register mp_limb_t x; + + x = *s1_ptr++; + s2_limb = x - s2_limb; + *res_ptr++ = s2_limb; + if (s2_limb > x) + { + while (--s1_size != 0) + { + x = *s1_ptr++; + *res_ptr++ = x - 1; + if (x != 0) + goto fin; + } + + return 1; + } + + fin: + if (res_ptr != s1_ptr) + { + mp_size_t i; + for (i = 0; i < s1_size - 1; i++) + res_ptr[i] = s1_ptr[i]; + } + return 0; +} + +_EXTERN_INLINE mp_limb_t +#if (__STDC__-0) || defined (__cplusplus) +mpn_sub (register mp_ptr res_ptr, + register mp_srcptr s1_ptr, + register mp_size_t s1_size, + register mp_srcptr s2_ptr, + register mp_size_t s2_size) +#else +mpn_sub (res_ptr, s1_ptr, s1_size, s2_ptr, s2_size) + register mp_ptr res_ptr; + register mp_srcptr s1_ptr; + register mp_size_t s1_size; + register mp_srcptr s2_ptr; + register mp_size_t s2_size; +#endif +{ + mp_limb_t cy_limb = 0; + + if (s2_size != 0) + cy_limb = mpn_sub_n (res_ptr, s1_ptr, s2_ptr, s2_size); + + if (s1_size - s2_size != 0) + cy_limb = mpn_sub_1 (res_ptr + s2_size, + s1_ptr + s2_size, + s1_size - s2_size, + cy_limb); + return cy_limb; +} +#endif /* __GNUC__ */ + +/* Allow faster testing for negative, zero, and positive. */ +#define mpz_sgn(Z) ((Z)->_mp_size < 0 ? -1 : (Z)->_mp_size > 0) +#define mpf_sgn(F) ((F)->_mp_size < 0 ? -1 : (F)->_mp_size > 0) +#define mpq_sgn(Q) ((Q)->_mp_num._mp_size < 0 ? -1 : (Q)->_mp_num._mp_size > 0) + +/* When using GCC, optimize certain common comparisons. */ +#if defined (__GNUC__) +#define mpz_cmp_ui(Z,UI) \ + (__builtin_constant_p (UI) && (UI) == 0 \ + ? mpz_sgn (Z) : _mpz_cmp_ui (Z,UI)) +#define mpz_cmp_si(Z,SI) \ + (__builtin_constant_p (SI) && (SI) == 0 ? mpz_sgn (Z) \ + : __builtin_constant_p (SI) && (SI) > 0 \ + ? _mpz_cmp_ui (Z, (unsigned long int) SI) \ + : _mpz_cmp_si (Z,SI)) +#define mpq_cmp_ui(Q,NUI,DUI) \ + (__builtin_constant_p (NUI) && (NUI) == 0 \ + ? mpq_sgn (Q) : _mpq_cmp_ui (Q,NUI,DUI)) +#else +#define mpz_cmp_ui(Z,UI) _mpz_cmp_ui (Z,UI) +#define mpz_cmp_si(Z,UI) _mpz_cmp_si (Z,UI) +#define mpq_cmp_ui(Q,NUI,DUI) _mpq_cmp_ui (Q,NUI,DUI) +#endif + +/* Allow direct user access to numerator and denominator of a mpq_t object. */ +#define mpq_numref(Q) (&((Q)->_mp_num)) +#define mpq_denref(Q) (&((Q)->_mp_den)) + +#define mpn_divmod(qp,np,nsize,dp,dsize) mpn_divrem (qp,0,np,nsize,dp,dsize) +#if 0 +#define mpn_divmod_1(qp,np,nsize,dlimb) mpn_divrem_1 (qp,0,np,nsize,dlimb) +#endif + +/* Compatibility with GMP 1. */ +#define mpz_mdiv mpz_fdiv_q +#define mpz_mdivmod mpz_fdiv_qr +#define mpz_mmod mpz_fdiv_r +#define mpz_mdiv_ui mpz_fdiv_q_ui +#define mpz_mdivmod_ui(q,r,n,d) \ + ((r == 0) ? mpz_fdiv_q_ui (q,n,d) : mpz_fdiv_qr_ui (q,r,n,d)) +#define mpz_mmod_ui(r,n,d) \ + ((r == 0) ? mpz_fdiv_ui (n,d) : mpz_fdiv_r_ui (r,n,d)) + +/* Useful synonyms, but not quite compatible with GMP 1. */ +#define mpz_div mpz_fdiv_q +#define mpz_divmod mpz_fdiv_qr +#define mpz_div_ui mpz_fdiv_q_ui +#define mpz_divmod_ui mpz_fdiv_qr_ui +#define mpz_mod_ui mpz_fdiv_r_ui +#define mpz_div_2exp mpz_fdiv_q_2exp +#define mpz_mod_2exp mpz_fdiv_r_2exp + +#define gmp_errno __gmp_errno +extern int gmp_errno; + +enum +{ + GMP_ERROR_NONE = 0, + GMP_ERROR_UNSUPPORTED_ARGUMENT = 1, + GMP_ERROR_DIVISION_BY_ZERO = 2, + GMP_ERROR_SQRT_OF_NEGATIVE = 4, + GMP_ERROR_INVALID_ARGUMENT = 8, + GMP_ERROR_ALLOCATE = 16, + GMP_ERROR_UNUSED_ERROR +}; + +#define __GNU_MP_VERSION 3 +#define __GNU_MP_VERSION_MINOR 0 +#define __GNU_MP_VERSION_PATCHLEVEL 1 +#define __GMP_H__ +#endif /* __GMP_H__ */ diff --git a/native-algo/lh-vector/gmpwrap.c b/native-algo/lh-vector/gmpwrap.c new file mode 100644 index 0000000..64c76e8 --- /dev/null +++ b/native-algo/lh-vector/gmpwrap.c @@ -0,0 +1,45 @@ +/* gmp-wrap.c + * 13 July 2000 + * wrapper for GMP functions similar to mp.h + * Author: Bernhard von Stengel stengel@maths.lse.ac.uk + */ + +#include +#include + /* atoi() */ +#include + /* INT_MAX, INT_MIN */ + +#include "gmp.h" +#include "gmpwrap.h" + +void greduce(mpz_t a, mpz_t b) +{ + mpz_t tmp; + mpz_init(tmp); + mpz_gcd(tmp, a, b); + mpz_divexact(a, a, tmp); + mpz_divexact(b, b, tmp); + mpz_clear(tmp); +} + +int gmptoi(mpz_t a, int *result, int bcomplain) +{ + char smp [MAXGMPCHARS]; /* string to print mp into */ + + gmptoa(a, smp); + *result = atoi(smp); + if (*result == INT_MAX || *result == INT_MIN) + { + if (bcomplain) + { + printf("Warning: Long integer %s ", smp); + printf("overflown, replaced by %d\n", *result); + } + return 1; + } + else + return 0; +} + + diff --git a/native-algo/lh-vector/gmpwrap.h b/native-algo/lh-vector/gmpwrap.h new file mode 100644 index 0000000..5eecc53 --- /dev/null +++ b/native-algo/lh-vector/gmpwrap.h @@ -0,0 +1,77 @@ +/* gmpwrap.h + * 13 July 2000 + * wrapper for GMP functions similar to mp.h + * Author: Bernhard von Stengel stengel@maths.lse.ac.uk + */ + +/* include before: "gmp.h" */ + +#ifndef GMPWRAP_H +#define GMPWRAP_H + +typedef mpz_t gmpt ; + +#define MAXGMPCHARS 500 + +/* a = b + c */ +#define gadd(a, b, c) mpz_add(a, b, c) +#define gchangesign(a) mpz_neg((a),(a)) +#define gclear(a) mpz_clear (a) +#define gexactdivint(a, b, c) mpz_divexact((c),(a),(b)) +#define ginit(a) mpz_init(a) +/* convert int n to mp a */ +#define gitomp(n, a) mpz_set_si( a , n ) +/* a = lcm(a,b) */ +#define glcm(a, b) mpz_lcm(a, a, b) +/* convert mp a to decimal string s, must be allocated */ +#define gmptoa(a, s) mpz_get_str(s, 10, a) +/* c = a * b */ +#define gmulint(a, b, c) mpz_mul((c),(a),(b)) +#define gset(a, b) mpz_set(a, b) +/* a = b - c */ +#define gsub(a, b, c) mpz_sub(a, b, c) +/* +1 0 -1 depending on sign of a */ +#define gsgn(a) mpz_sgn(a) + +/* a == 1 */ +#define gone(a) (mpz_cmp_si((a), 1) == 0) +/* a == 0 */ +#define gzero(a) (mpz_sgn(a) == 0) +/* a > 0 */ +#define gpositive(a) (mpz_sgn(a) > 0) +/* a < 0 */ +#define gnegative(a) (mpz_sgn(a) < 0) + +/* initialize the 1-dim array A of dimension n of mp's + * previously allocated with A = TALLOC(n, gmpt) + */ +#define GINIT(A, n) {int i; \ + for (i=0; i < (n); i++) ginit(A[i]);} +/* clear the 1-dim array A of dimension n of mp's + * previously initialized with GINIT(A, n) + */ +#define GCLEAR(A, n) {int i; \ + for (i=0; i < (n); i++) gclear(A[i]);} + +/* initialize the 2-dim nrows x ncols array A of mp's + * previously allocated with T2ALLOC(A, nrows, ncols, gmpt) + */ +#define G2INIT(A, nrows, ncols) {int i, j; \ + for (i=0; i < (nrows); i++) for (j=0; j < (ncols); j++) \ + ginit(A[i][j]);} +/* clear the 2-dim nrows x ncols array A of mp's + * previously initialized with G2INIT(A, nrows, ncols) + */ +#define G2CLEAR(A, nrows, ncols) {int i, j; \ + for (i=0; i < (nrows); i++) for (j=0; j < (ncols); j++) \ + gclear(A[i][j]);} +/* convert mp a back to integer in *result, + * bcomplain: give warning to stdout if overflow in conversion. + * return value: set to 1 if overflow, o/w 0 + */ +int gmptoi(gmpt a, int *result, int bcomplain) ; + +/* divide a and b both by gcd(a,b) */ +void greduce(gmpt a, gmpt b); + +#endif diff --git a/native-algo/lh-vector/grat.c b/native-algo/lh-vector/grat.c new file mode 100644 index 0000000..1638eca --- /dev/null +++ b/native-algo/lh-vector/grat.c @@ -0,0 +1,417 @@ +/** \file grat.c + * + * For the computation of rational numbers. The grat.c file + * contains the implementation of the methods defined in rat.h + * which use gmp. + * + * Author: Tobenna Peter, Igwe ptigwe@gmail.com August 2012. + */ + +#define GLEMKE + +#include +#include +#include +#include + /* sprintf */ +#include "rat.h" + +/* Initialise a rational number and returns it */ +Rat ratinit() +{ + Rat rat; + ginit(rat.num); + ginit(rat.den); + return rat; +} + +/* Creates a clone of the given rational number */ +Rat ratclone(Rat rat) +{ + Rat r = ratinit(); + gset(r.num, rat.num); + gset(r.den, rat.den); + return r; +} + +/* Frees the memory occupied by a rational number */ +void ratclear(Rat rat) +{ + gclear(rat.num); + gclear(rat.den); +} + +/* Creates a rational number from two integers */ +Rat itorat(int num, int den) +{ + Rat r = ratinit(); + gitomp(num, r.num); + gitomp(den, r.den); + ratreduce(r); + return r; +} + +/* Returns the equivalent rational number of an integer */ +Rat ratfromi(int i) +{ + Rat tmp = ratinit(); + /*tmp.num = i; */ + gitomp(i, tmp.num); + /*tmp.den = 1; */ + gitomp(1, tmp.den); + return tmp; +} + +Rat gmptorat(gmpt num, gmpt den) +{ + Rat r = ratinit(); + gset(r.num, num); + gset(r.den, den); + return r; +} + +Rat ratfromgmp(gmpt a) +{ + Rat rat = ratinit(); + gset(rat.num, a); + gitomp(1, rat.den); + return rat; +} + +/* Parses a string of characters of the format "num" or "num/den" +* and converts it to a rational number */ + Rat parseRat(char* srat, const char* info, int j) +{ + char snum[MAXSTR], sden[MAXSTR]; + gmpt num, den; + ginit(num); + ginit(den); + + atoaa(srat, snum, sden); + mpz_set_str(num, snum, 10); + if (sden[0]=='\0') + gitomp(1, den); + else + { + mpz_set_str(den, sden, 10); + if (gnegative(den) || gzero(num)) + { + char str[MAXSTR]; + gmptoa(den, str); + fprintf(stderr, "Warning: Denominator "); + fprintf(stderr, "%s of %s[%d] set to 1 since not positive\n", + str, info, j+1); + gitomp(1, den); + } + } + Rat r = gmptorat(num, den); + return r; +} + +/* Parses a string of characters of the format "i.d" to the a rational number */ +Rat parseDecimal(char* srat, const char* info, int j) +{ + double x; + int count; + char* sub; + + sscanf(srat, "%lf", &x); + + sub = strchr(srat, '.'); + if(strchr(sub+1, '.') != NULL) + { + fprintf(stderr, "Error: Decimal "); + fprintf(stderr, "%s of %s[%d] has more than one decimal point\n", srat, info, j); + exit(1); + } + count = strlen(sub+1); + + char* str = strtok(srat, "."); + strcat(str, strtok(NULL, ".")); + + /*int num = floor(x * pow(10, count));*/ + gmpt num; + mpz_set_str(num, str, 10); + + /*int den = pow(10, count);*/ + int i; + strcpy(str, "10"); + for(i = 1; i < count; ++i) + { + strcat(str, "0"); + } + gmpt den; + mpz_set_str(den, str, 10); + + Rat rat = gmptorat(num, den); + return rat; +} + +/* Parses a string that of the format "x", "x/y" and "x.y" +* and returns the equivalent rational numbers */ + Rat ratfroma(char* srat, const char* info, int j) +{ + char* pos; + Rat rat; + + if((pos = strchr(srat, '.')) != NULL) + { + rat = parseDecimal(srat, info, j); + } + else + { + rat = parseRat(srat, info, j); + } + return rat; +} + /* for improved precision in ratadd(a, b) */ +Rat ratadd (Rat a, Rat b) +{ + /* + a.num = a.num * b.den + a.den * b.num; + a.den *= b.den; + return ratreduce(a); + */ + + gmpt num, den, x, y, t; + Rat c = ratinit(); + + ginit(num); + ginit(den); + ginit(x); + ginit(y); + ginit(t); + + /*itomp (a.num, num) ;*/ + gset(num, a.num); + /*itomp (a.den, den) ;*/ + gset(den, a.den); + /*itomp (b.num, x) ;*/ + gset(x, b.num); + /*itomp (b.den, y) ;*/ + gset(y, b.den); + gmulint (y, num, t); + gset(num, t); + gmulint (den, x, x); + + /*linint (num, 1, x, 1);*/ + gadd(t, num, x); + gset(num, t); + + gmulint (y, den, den); + greduce(num, den) ; + /*mptoi( num, &a.num, 1 ); + mptoi( den, &a.den, 1 );*/ + gset(c.num, num); + gset(c.den, den); + + gclear(num); + gclear(den); + gclear(x); + gclear(y); + gclear(t); + + return c ; +} + +/* Returns the value of "a/b" */ +Rat ratdiv (Rat a, Rat b) +{ + return ratmult(a, ratinv(b) ); +} + +/* returns product a*b, normalized */ +Rat ratmult (Rat a, Rat b) +{ + Rat a1 = ratclone(a); + Rat b1 = ratclone(b); + gmpt x; + ginit(x); + + /* avoid overflow in intermediate product by cross-cancelling first + */ + /*x = a.num ; */ + gset(x, a.num); + /*a.num = b.num ;*/ + gset(a1.num, b.num); + /*b.num = x ;*/ + gset(b1.num, x); + a1 = ratreduce(a1); + b1 = ratreduce(b1); + /*a.num *= b.num;*/ + gmulint(a1.num, b1.num, x); + gset(a1.num, x); + /*a.den *= b.den;*/ + gmulint(a1.den, b1.den, x); + gset(a1.den, x); + + gclear(x); + ratclear(b1); + return ratreduce(a1); /* a or b might be non-normalized s*/ +} + +/* returns -a, normalized only if a normalized */ +Rat ratneg (Rat a) + /* returns -a */ +{ + /*a.num = - a.num;*/ + gchangesign(a.num); + return a; +} + +/* normalizes (make den>0, =1 if num==0) +* and reduces by gcd(num,den) +*/ + Rat ratreduce (Rat a) +{ + if (gzero(a.num)) + { + /*a.den = 1;*/ + gitomp(1, a.den); + } + else + { + gmpt div; + gmpt c; + ginit(div); + ginit(c); + if (gnegative(a.den)) + { + /*a.den = -a.den;*/ + gchangesign(a.den); + /*a.num = -a.num;*/ + gchangesign(a.num); + } + /*div = ratgcd(a.den, a.num);*/ + ratgcd(a.den, a.num, div); + /*a.num = a.num/div;*/ + gexactdivint(a.num, div, c); + gset(a.num, c); + /*a.den = a.den/div;*/ + gexactdivint(a.den, div, c); + gset(a.den, c); + gclear(div); + gclear(c); + } + return a; +} + +/* Computes the gcd of a and b and stores it in c */ +void ratgcd(gmpt a, gmpt b, gmpt c) +{ + gmpt d, e; + ginit(d); + ginit(e); + + gset(d, a); + gset(e, b); + mpz_gcd(c, d, e); + + gclear(d); + gclear(e); +} + +/* Inverts a rational number */ +Rat ratinv (Rat a) +{ + Rat a1 = ratclone(a); + + /*a.num = a.den ;*/ + gset(a1.num, a.den); + /*a.den = x ;*/ + gset(a1.den, a.num); + + return a1; +} + +/* returns Boolean condition that a==b +* a, b are assumed to be normalized +*/ + Bool ratiseq (Rat a, Rat b) +{ + /*return (a.num == b.num && a.den == b.den);*/ + Rat a1 = ratclone(a); + Rat b1 = ratclone(b); + Rat c = ratadd(a1, ratneg(b1)); + + int i = gzero(c.num); + + ratclear(a1); + ratclear(b1); + ratclear(c); + return i; +} + +/* returns Boolean condition that a > b */ +Bool ratgreat (Rat a, Rat b) +{ + Rat a1 = ratclone(a); + Rat b1 = ratclone(b); + Rat c = ratadd(a1, ratneg(b1)); + + int i = gpositive(c.num); + + ratclear(a1); + ratclear(b1); + ratclear(c); + return i; +} + +/* Returns the maximum element in an array of n Rat elements */ +Rat maxrow(Rat* rat, int n) +{ + int i; + Rat Mrow = ratfromi(0); + for(i = 0; i < n; ++i) + { + Mrow = ratgreat(Mrow,rat[i]) ? Mrow : rat[i]; + } + return Mrow; +} + +/* Returns the maximum element in an mxn matrix of Rat elements */ +Rat maxMatrix(Rat** rat, int m, int n) +{ + int i; + int tmpm = m; + int tmpn = n; + Rat M = ratfromi(0); + for(i = 0; i < tmpm; ++i) + { + Rat r = maxrow(rat[i], tmpn); + M = ratgreat(M, r) ? M : r; + } + return M; +} + +/* converts rational r to string s, omit den 1 +* s must be sufficiently long to contain result +* returns length of string +*/ +int rattoa (Rat r, char *s) +{ + char str[MAXSTR]; + int l, a; + /*l = sprintf(s, "%d", r.num);*/ + gmptoa(r.num, str); + l = sprintf(s, "%s", str); + /*if (r.den != 1)*/ + if(!gone(r.den)) + { + /*a = sprintf(s+l, "/%d", r.den);*/ + gmptoa(r.den, str); + a = sprintf(s+l, "/%s", str); + l += a + 1; + } + return l; +} + +/* converts rational a to double */ +double rattodouble(Rat a) +{ + int num, den; + gmptoi(a.num, &num, 1); + gmptoi(a.den, &den, 1); + /*return (double) a.num / (double) a.den ;*/ + return (double)num / (double)den; +} diff --git a/native-algo/lh-vector/inlemke.c b/native-algo/lh-vector/inlemke.c new file mode 100644 index 0000000..fd1f6ab --- /dev/null +++ b/native-algo/lh-vector/inlemke.c @@ -0,0 +1,200 @@ +/* inlemke.c + * Lemke direct + * 16 Apr 2000 + * options: + * -i run pivoting interactively, suggested with '-v' + * -v verbose: output tableau at every pivoting step + * Author: Bernhard von Stengel stengel@maths.lse.ac.uk + */ + +#include +#include + /* atoi */ +#include + /* strlen */ +#include + /* getopt(), optarg, optopt */ + +#include "alloc.h" +#include "col.h" +#include "rat.h" + +#include "lemke.h" + /* for lemke.h */ + +static int n; /* LCP dimension here */ + +/* max no of characters + 1 (for terminating '\0') + * of a string s declared as char s[MAXSTR] + * to be read from stdin by readstr + */ +#define MAXSTR 100 + +/*------------------ error message ----------------*/ +void notimpl (char *info) +{ + fflush(stdout); + fprintf(stderr, "Program terminated with error. %s\n", info); + exit(1); +} + +/*------------------ read-in routines --------------------------*/ +/* reads string s from stdin, to fit char s[MAXSTR] + * if length >= MAXSTR-1 a warning is sent to stderr + * returns EOF if EOF encountered, then s undefined + */ +int readstr (char *s) +{ + int tmp; + char fs[10]; /* MAXSTR must not exceed 7 decimal digits */ + sprintf (fs, "%%%ds",MAXSTR-1); /* generate format str */ + tmp = scanf (fs, s); + if (strlen(s)==MAXSTR-1) + { + fprintf(stderr, "Warning: input string\n%s\n", s); + fprintf(stderr, + "has max length %d, probably read incompletely\n", MAXSTR-1); + } + return tmp; /* is EOF if scanf encounters EOF */ +} + +/* s is a string of nonblank chars, which have to + * match in that order the next nonblank stdin chars + * readconf complains and terminates if not + */ +void readconf (const char *s) +{ + int i, len = strlen(s); + char a[MAXSTR]; + for (i=0; i +#include +#include +#include + /* atoi */ +#include + /* strlen */ +#include + /* getopt(), optarg, optopt */ + +#include "alloc.h" +#include "col.h" +#include "rat.h" + +#include "lemke.h" + /* for lemke.h */ + +static int n; /**< LCP dimension */ + +int m; /**< Number of rows in input matrix */ +int n1; /**< Number of columns in input matrix */ + +FILE* lcpout; /**< File to store the equivalent LCP */ + +/** max no of characters + 1 (for terminating '\0') +* of a string s declared as char s[MAXSTR] +* to be read from stdin by readstr +*/ +#define MAXSTR 100 + +/*------------------ error message ----------------*/ +/** + * Prints out a message and exits the program. + * + * \param info A string containing the error message. + */ +void notimpl (char *info) +{ + fflush(stdout); + fprintf(stderr, "Program terminated with error. %s\n", info); + exit(1); +} + +/*------------------ read-in routines --------------------------*/ +/** + * Reads in a string from the standard input. + * Reads string s from stdin, to fit char s[MAXSTR] + * if length >= MAXSTR-1 a warning is sent to stderr + * returns EOF if EOF encountered, then s undefined. + * + * \param s The string to be read in to from the stdin + * \returns EOF if EOF was encountered otherwise same return value as scanf + */ +int readstr (char *s) +{ + int tmp; + char fs[10]; /* MAXSTR must not exceed 7 decimal digits */ + sprintf (fs, "%%%ds",MAXSTR-1); /* generate format str */ + tmp = scanf (fs, s); + if (strlen(s)==MAXSTR-1) + { + fprintf(stderr, "Warning: input string\n%s\n", s); + fprintf(stderr, + "has max length %d, probably read incompletely\n", MAXSTR-1); + } + return tmp; /* is EOF if scanf encounters EOF */ +} + +/** + * Reads in a specific string. + * The input string is a string of nonblank chars which have to + * match in that order the next nonblank stdin chars otherwise + * readconf complains and terminates. + * + * \param s The string to be read and matched + */ +void readconf (const char *s) +{ + int i, len = strlen(s); + char a[MAXSTR]; + for (i=0; i m+1) + { + lcpM[i+2][j] = payoffA[i][j - (m+2)]; + } + else + { + lcpM[i+2][j] = ratfromi(0); + } + } + } + + for(i = 0; i < n1; ++i) + { + int j; + for(j = 0; j < 2+m+n1; ++j) + { + if(j == 1) + { + lcpM[i+2+m][j] = ratfromi(-1); + } + else if (j > 1 && j < 2+m) + { + lcpM[i+2+m][j] = payoffB[j - 2][i]; + } + else + { + lcpM[i+2+m][j] = ratfromi(0); + } + } + } +} + +/** + * Computes the LCP q vector + */ +void convertq() +{ + rhsq[0] = rhsq[1] = ratfromi(-1); + int i; + for(i = 0; i < m+n1; i++) + { + rhsq[i+2] = ratfromi(0); + } +} + +/** + * Compute the value of LCP d-vector + */ +void convertd() +{ + int i; + for(i = 0; i < 2+m+n1; i++) + { + if(i == k+1) + { + vecd[i] = ratfromi(0); + } + else + { + vecd[i] = ratfromi(1); + } + } +} + +/** + * Prints the lcpM to the output file lcpout + */ +void printlcpM() +{ + fprintf(lcpout, "n= %d\nM=\n", n); + int i; + for(i = 0; i < n; i++) + { + int j; + for(j = 0; j < n; j++) + { + char str[MAXSTR]; + rattoa(lcpM[i][j], str); + fprintf(lcpout, "%s ", str); + } + fprintf(lcpout, "\n"); + } +} + +/** + * Prints the RHS to the output file lcpout + */ +void printlcpq() +{ + fprintf(lcpout, "q= "); + int i; + for(i = 0; i < n; i++) + { + char str[MAXSTR]; + rattoa(rhsq[i], str); + fprintf(lcpout, "%s ", str); + } +} + +/** + * Prints the vecd to the output file lcpout + */ +void printlcpd() +{ + fprintf(lcpout, "\nd= "); + int i; + for(i = 0; i < n; i++) + { + char str[MAXSTR]; + rattoa(vecd[i], str); + fprintf(lcpout, "%s ", str); + } +} + +/** + * Prints the LCP to the output file lcpout + */ +void printLCP() +{ + printlcpM(); + printlcpq(); + printlcpd(); + fclose(lcpout); +} + +/** + * Converts the game to an equivalent LCP. + */ +void convert() +{ + /* Find the value of -A and -B using the method + * described in the report */ + Rat o = ratfromi(1); + + Rat ma = maxMatrix(payoffA, m, n1); + Rat a = ratfromi((int)ceil(rattodouble(ma))); + a = (ratiseq(a, ma)) ? ratadd(a, o) : a; + + o = ratfromi(1); + Rat mb = maxMatrix(payoffB, m, n1); + Rat b = ratfromi((int)ceil(rattodouble(mb))); + b = (ratiseq(b, mb)) ? ratadd(b, o) : b; + + complementMatrix(payoffA, a, m, n1); + complementMatrix(payoffB, b, m, n1); + nrows = m; + ncols = n1; + convertlcpM(); + convertq(); + convertd(); +} + +/* ---------------------- main ------------------------ */ +/** + * The main program. + * Reads in arguments from argv, and sets the flags for the + * Lemke-Howson algorithim accordingly. Reads the game from + * stdin, converts it to an equivalent LCP, and computes all + * reachable Nash Equilibria. + */ +int main(int argc, char *argv[]) +{ + int c; + k2 = 0; + Flagsrunlemke flags; + + flags.maxcount = 0; + flags.bdocupivot = 1; + flags.binitabl = 0; + flags.bouttabl = 0; + flags.boutsol = 0; + flags.binteract = 0; + flags.blexstats = 0; + flags.bouteq = 0; + flags.interactcount = 0; + flags.binitmethod = 1; + flags.boutinvAB = 0; + flags.boutpiv = 0; + flags.bisArtificial = 1; + /* parse options */ + while ( (c = getopt (argc, argv, "if:vVI:maep")) != -1) + switch (c) + { + case 'a': + flags.boutinvAB = 1; + break; + case 'e': + flags.bouteq = 1; + break; + case 'I': + flags.interactcount = atoi(optarg); + case 'i': + flags.binteract = 1; + printf("Interactive flag set.\n"); + break; + case 'f': + lcpout = fopen(optarg, "w+"); + break; + case 'V': + flags.bouttabl = 1; + flags.blexstats = 1; + printf("Verbose tableau output.\n"); + case 'v': + flags.binitabl = 1; + flags.boutpiv = 1; + flags.boutsol = 1; + flags.bouteq = 0; + break; + case 'm': + flags.binitmethod = 0; + break; + case 'p': + flags.boutpath = 1; + break; + case '?': + if (isprint (optopt)) + fprintf (stderr, "Unknown option `-%c'.\n", optopt); + else + fprintf (stderr, + "Unknown option character `\\x%x'.\n", + optopt); + return 1; + default: + abort (); + } + /* options are parsed and flags set */ + + readGame(); + k = 1; + convert(); + if(lcpout != NULL) + { + printLCP(); + } + computeEquilibria(flags); + freematrices(m); + return 0; +} diff --git a/native-algo/lh-vector/labelstest b/native-algo/lh-vector/labelstest new file mode 100755 index 0000000..fbe877d --- /dev/null +++ b/native-algo/lh-vector/labelstest @@ -0,0 +1,17 @@ +#!/bin/sh +echo "\n" > sample-output +M=`grep 'm=.*' sample-input | sed 's/m= \([0-9]*\)/\1/'` +N=`grep 'n=.*' sample-input | sed 's/n= \([0-9]*\)/\1/'` +C=`expr $M + $N` +for k in $(eval echo {1..$C}) +do + echo -n "Testing label $k: " + sed "s/k=.*/k=$k/" sample-input > tmp + mv tmp sample-input + ./inlh $1 < sample-input > tmp + cat sample-output tmp > tmp2 + mv tmp2 sample-output + S=`egrep 'Number of pivots:' tmp` + echo " "$S +done +rm -f tmp diff --git a/native-algo/lh-vector/lemke.c b/native-algo/lh-vector/lemke.c new file mode 100644 index 0000000..ffa9375 --- /dev/null +++ b/native-algo/lh-vector/lemke.c @@ -0,0 +1,1491 @@ +/** + * \file lemke.c + * LCP solver + * + * 13 July 2000 + * Author: Bernhard von Stengel stengel@maths.lse.ac.uk + * + * Edited: Tobenna Peter, Igwe ptigwe@gmail.com August, 2012 + */ + +#include +#include + /* free() */ +#include + /* strcpy */ + +#include "alloc.h" +#include "col.h" + +#include "lemke.h" + +#include "mp.h" +#include "equilibrium.h" + +/* used for tableau: */ +#define Z(i) (i) +#define W(i) (i+n) + /* VARS = 0..2n = Z(0) .. Z(n) W(1) .. W(n) */ + /* ROWCOL = 0..2n, 0 .. n-1: tabl rows (basic vars) */ + /* n .. 2n: tabl cols 0..n (cobasic) */ +#define RHS (n+1) /* q-column of tableau */ +#define TABCOL(v) (bascobas[v]-n) + /* v in VARS, v cobasic: TABCOL(v) is v's tableau col */ + /* v basic: TABCOL(v) < 0, TABCOL(v)+n is v's row */ + +/* LCP input */ +Rat **lcpM; +Rat *rhsq; +Rat *vecd; +int lcpdim = 0; /* set in setlcp */ +static int n; /* LCP dimension as used here */ + +/* LCP result */ +Rat *solz; +int pivotcount; + +/* tableau: */ +static mp **A; /**< tableau */ +static int *bascobas; /**< VARS -> ROWCOL */ +static int *whichvar; /**< ROWCOL -> VARS, inverse of bascobas */ + +/** scale factors for variables z. +* scfa[Z(0)] for d, scfa[RHS] for q +* scfa[Z(1..n)] for cols of M +* result variables to be multiplied with these +*/ +static mp *scfa; + +static mp det; /**< determinant */ + +static int *lextested, *lexcomparisons;/**< statistics for lexminvar */ + +static int *leavecand; + /**< should be local to lexminvar but defined globally for economy */ + +/* GSoC12: Tobenna Peter, Igwe */ +int nrows; +int ncols; +int k; +int k2; +Rat** payoffA; +Rat** payoffB; +mp** invAB; /**< Represents the inverse of AB */ +node* neg; +node* pos; + + +/*------------------ error message ----------------*/ +/** + * Prints out an error message and exits. + * + * \param info The error message + */ +void errexit (char *info) +{ + fflush(stdout); + fprintf(stderr, "Error: %s\n", info); + fprintf(stderr, "Lemke terminated unsuccessfully.\n"); + exit(1); +} + +/* declares */ +int assertbasic (int v, const char *info); + +/*------------------ memory allocation -------------------------*/ +/** + * Allocates memory for the LCP given its dimensions. + * If the LCP has been previously allocated, it frees the memory and + * reallocates it. If the dimension given for the LCP is < 0 or + * > MAXLCPDIM then it exits with an error. + * + * \param newn The dimension of the LCP. + */ +void setlcp (int newn) +{ + if (newn < 1 || newn > MAXLCPDIM) + { + fprintf(stderr, "Problem dimension n= %d not allowed. ", newn); + fprintf(stderr, "Minimum n is 1, maximum %d.\n", MAXLCPDIM); + exit(1); + } + if (lcpdim > 0) /* free previously used space */ + { + FREE2(lcpM, lcpdim); + free(rhsq); + free(vecd); + free(solz); + FREE2(A, lcpdim); + free(scfa); + free(bascobas); + free(whichvar); + free(leavecand); + FREE2(invAB, lcpdim); + } + n = lcpdim = newn; + /* LCP input/output data */ + T2ALLOC (lcpM, n, n, Rat); + rhsq = TALLOC(n, Rat); + vecd = TALLOC(n, Rat); + solz = TALLOC(n, Rat); + /* tableau */ + T2ALLOC (A, n, n+2, mp); + scfa = TALLOC (n+2, mp); + bascobas = TALLOC(2*n+1, int); + whichvar = TALLOC(2*n+1, int); + lextested = TALLOC(n+1, int); + lexcomparisons = TALLOC(n+1, int); + leavecand = TALLOC(n, int); + /* should be local to lexminvar but allocated here for economy */ + /* initialize all LCP entries to zero */ + { + int i,j; + Rat zero = ratfromi(0); + for (i=0; i= 0 and not q >= 0 (o/w trivial sol) +* and that q[i] < 0 implies d[i] > 0 +*/ +/* GSoC12: Tobenna Peter, Igwe (Edited)*/ +void isqdok (void) +{ + int i; + int isqpos = 1; + for (i=0; i=0. "); + printf("Trivial solution z=0.\n"); + exit(0); + } +} /* end of isqdok() */ + +/* ------------------- tableau setup ------------------ */ +/** + * Initialise tableau variables. + * Z(0)...Z(n) nonbasic, W(1)...W(n) basic + */ +void inittablvars (void) +{ + int i; + for (i=0; i<=n; i++) + { + bascobas[Z(i)] = n+i; + whichvar[n+i] = Z(i); + } + for (i=1; i<=n; i++) + { + bascobas[W(i)] = i-1; + whichvar[i-1] = W(i); + } +} /* end of inittablvars() */ + +/** + * Fill tableau from M, q, d + */ +/* GSoC12: Tobenna Peter, Igwe (Edited)*/ +void filltableau (void) +{ + int i,j; + mp den, num; + mp tmp, tmp2, tmp3; + for (j=0; j<=n+1; j++) + { + /* compute lcm scfa[j] of denominators for col j of A */ + itomp(ONE, scfa[j]); + for (i=0; i n) + return sprintf(s, "w%d", v-n); + else + return sprintf(s, "z%d", v); +} + +/** + * Output the current tableau, column-adjusted + */ +void outtabl (void) +{ + int i, j; + char s[INFOSTRINGLENGTH]; + char smp [DIG2DEC(MAX_DIGITS)+2]; /* string to print mp into */ + mptoa (det, smp); + printf("Determinant: %s\n", smp); + colset(n+3); + colleft(0); + colpr("var"); /* headers describing variables */ + for (j=0; j<=n+1; j++) + { + if (j==RHS) + colpr("RHS"); + else + { + vartoa(whichvar[j+n], s); + colpr(s); + } + } + colpr("scfa"); /* scale factors */ + for (j=0; j<=n+1; j++) + { + if (j==RHS) + mptoa(scfa[RHS], smp); + else if (whichvar[j+n] > n) /* col j is some W */ + sprintf(smp, "1"); + else /* col j is some Z: scfa */ + mptoa( scfa[whichvar[j+n]], smp); + colpr(smp); + } + colnl(); + for (i=0; i= n) + { + vartoa(v, s); + fprintf(stderr, "%s: Cobasic variable %s should be basic.\n", info, s); + /*errexit("");*/ + return -1; + } + return 0; +} + +/** + * Assert that v in VARS is a cobasic variable. + * If v is not cobasic, the program terminates with an error message + * + * \param v The variable to be asserted + * \param info Part of the error message + */ +int assertcobasic (int v, char *info) +{ + char s[INFOSTRINGLENGTH]; + if (TABCOL(v) < 0) + { + /* + vartoa(v, s); + fprintf(stderr, "%s: Basic variable %s should be cobasic.\n", info, s); + errexit("");*/ + return -1; + } + return 0; +} + +/** + * Document the current pivot. + * Asserts leave is basic and enter is cobasic, and + * print the current pivot + * + * \param leave The leaving variable + * \param enter The entering variable + */ +int docupivot (int leave, int enter, Flagsrunlemke flags) +{ + char s[INFOSTRINGLENGTH]; + + if(assertbasic(leave, "docupivot") < 0) + return -1; + + if(assertcobasic(enter, "docupivot") < 0) + return -1; + + if(flags.boutpiv) + { + vartoa(leave, s); + printf("leaving: %-4s ", s); + vartoa(enter, s); + printf("entering: %s\n", s); + } + return 0; +} /* end of docupivot */ + +/** + * Outputs an error message and exits when a ray termination + * occurs while trying to pivot in the entering variable. + * + * \param enter The entering variable. + */ +void raytermination (int enter) +{ + char s[INFOSTRINGLENGTH]; + vartoa(enter, s); + fprintf(stderr, "Ray termination when trying to enter %s\n", s); + outtabl(); + printf("Current basis, not an LCP solution:\n"); + outsol(); + errexit(""); +} + +/** + * Tests the tableau variables. If the tableau variables are wrong, + * output error and continue. + */ +void testtablvars(void) +{ + int i, j; + for (i=0; i<=2*n; i++) /* check if somewhere tableauvars wrong */ + if (bascobas[whichvar[i]]!=i || whichvar[bascobas[i]]!=i) + /* found an inconsistency, print everything */ + { + printf("Inconsistent tableau variables:\n"); + for (j=0; j<=2*n; j++) + { + printf("var j:%3d bascobas:%3d whichvar:%3d ", + j, bascobas[j], whichvar[j]); + printf(" b[w[j]]==j: %1d w[b[j]]==j: %1d\n", + bascobas[whichvar[j]]==j, whichvar[bascobas[j]]==j); + } + break; + } +} + +/* --------------- pivoting and related routines -------------- */ + +/** + * Complement of v in VARS. Error if v==Z(0). + * This is W(i) for Z(i) and vice versa, i=1...n. + * + * \param v The variable + * \returns The complement of v. Z(i) if v is W(i) and vice versa. + */ +int complement (int v) +{ + if (v==Z(0)) + errexit("Attempt to find complement of z0."); + return (v > n) ? Z(v-n) : W(v) ; +} /* end of complement (v) */ + +/** + * Initialize statistics for minimum ratio test + */ +void initstatistics(void) +{ + int i; + for (i=0; i<=n; i++) + lextested[i] = lexcomparisons[i] = 0; +} + +/** + * Output statistics of minimum ratio test + */ +void outstatistics(void) +{ + int i; + char s[LCPSTRL]; + + colset(n+2); + colleft(0); + colpr("lex-column"); + for (i=0; i<=n; i++) + colipr(i); + colnl(); + colpr("times tested"); + for (i=0; i<=n; i++) + colipr(lextested[i]); + colpr("% times tested"); + if (lextested[0] > 0) + { + colpr("100"); + for (i=1; i<=n; i++) + { + sprintf(s, "%2.0f", + (double) lextested[i] * 100.0 / (double) lextested[0]); + colpr(s); + } + } + else + colnl(); + colpr("avg comparisons"); + for (i=0; i<=n; i++) + if (lextested[i] > 0) + { + sprintf(s, "%1.1f", + (double) lexcomparisons[i] / (double) lextested[i]); + colpr(s); + } + else + colpr("-"); + colout(); +} + +/** + * Returns the leaving variable in VARS. This is given by lexmin row, + * when enter in VARS is entering variable + * only positive entries of entering column tested + * boolean *z0leave indicates back that z0 can leave the + * basis, but the lex-minratio test is performed fully, + * so the returned value might not be the index of z0. + * + * \param enter The entering variable + * \param z0leave Stores a boolean value stating if z0 can leave. + * \returns The leaving variable + */ +int lexminvar (int enter, int *z0leave) +{ + int col, i, j, testcol; + int numcand; + + assertcobasic(enter, "Lexminvar"); + col = TABCOL(enter); + numcand = 0; + /* leavecand [0..numcand-1] = candidates (rows) for leaving var */ + /* start with leavecand = { i | A[i][col] > 0 } */ + for (i=0; i 1; j++) + /* as long as there is more than one leaving candidate perform + * a minimum ratio test for the columns of j in RHS, W(1),... W(n) + * in the tableau. That test has an easy known result if + * the test column is basic or equal to the entering variable. + */ + { + if (j>n) /* impossible, perturbed RHS should have full rank */ + errexit("lex-minratio test failed"); + lextested[j] += 1 ; + lexcomparisons[j] += numcand ; + + testcol = (j==0) ? RHS : TABCOL(W(j)) ; + if (testcol != col) /* otherwise nothing will change */ + { + if (testcol >= 0) + /* not a basic testcolumn: perform minimum ratio tests */ + { + int sgn; + int newnum = 0; + /* leavecand[0..newnum] contains the new candidates */ + for (i=1; i < numcand; i++) + /* investigate remaining candidates */ + { + sgn = comprod(A[leavecand[0]][testcol], A[leavecand[i]][col], + A[leavecand[i]][testcol], A[leavecand[0]][col]); + /* sign of A[l_0,t] / A[l_0,col] - A[l_i,t] / A[l_i,col] */ + /* note only positive entries of entering column considered */ + if (sgn==0) /* new ratio is the same as before */ + leavecand[++newnum] = leavecand[i]; + else if (sgn==1) /* new smaller ratio detected */ + leavecand[newnum=0] = leavecand[i]; + } + numcand = newnum+1; + } + else + /* testcol < 0: W(j) basic, Eliminate its row from leavecand */ + /* since testcol is the jth unit column */ + for (i=0; i < numcand; i++) + if (leavecand[i] == bascobas[W(j)]) + { + leavecand[i] = leavecand[--numcand]; + /* shuffling of leavecand allowed */ + break; + } + } /* end of if(testcol != col) */ + + } /* end of for ( ... numcand > 1 ... ) */ + + *z0leave = (leavecand[0] == bascobas[Z(0)]); + return whichvar[leavecand[0]]; +} /* end of lexminvar (col, *z0leave); */ + +/** + * Returns the leaving variable in VARS as entered by user. + * When enter in VARS is entering variable + * only nonzero entries of entering column admitted + * boolean *z0leave indicates back that z0 has been + * entered as leaving variable, and then + * the returned value is the index of z0. + * + * \param enter The entering variable + * \param z0leave Stores a boolean value stating if z0 can leave. + * \returns The leaving variable + */ +int interactivevar (int enter, int *z0leave) +{ + char s[INFOSTRINGLENGTH], instring[2]; + + int inp, col, var; + int breject = 1; + assertcobasic(enter, "interactivevar"); + col = TABCOL(enter); + + vartoa(enter, s); + printf(" Entering variable (column): %s\n", s); + while (breject) + { + printf(" Leaving row (basic variable z.. or w..), "); + printf("or 't' for tableau:\n"); + strcpy(instring, "?"); + if (scanf("%1s", instring)==EOF) + { + printf ("Input terminated too early with EOF\n"); + exit(1); + } + if ( instring[0] == 't') + { + printf("\n"); + outtabl(); + vartoa(enter, s); + printf(" Entering variable (column): %s\n", s); + continue; + } + scanf("%d", &inp); + printf(" You typed %s%d\n", instring, inp); + if ( (inp < 0) || (inp > n)) + { + printf("Variable index %d outside 0..n=%d\n", + inp, n); + continue; + } + if ( instring[0] == 'w') + { + if (inp == 0) + { + printf("Variable w0 not allowed\n"); + continue; + } + var = inp + n; + } + else if ( instring[0] == 'z') + var = inp; + else + { + printf("Variable not starting with z or w\n"); + continue; + } + /* var == variable in VARS giving what has been input */ + if ( bascobas[var] >= n) + { + vartoa (var, s); + printf("Variable %s not basic\n", s); + continue; + } + if ( zero( A [bascobas[var]] [col] ) ) + { + vartoa (var, s); + printf("Row %s has zero pivot element, not allowed\n", s); + continue; + } + breject = 0; /* now everything ok */ + } /* end of while (breject) for input */ + *z0leave = (var == Z(0)); + return var; +} /* end of interactivevar (col, *z0leave); */ + +/** + * Negates tableau column col + * \param col The column of the tableau to be negated. + */ +void negcol(int col) +{ + int i; + for (i=0; i nrows) /* if l is p2's strategy*/ + { + l -= (nrows + 1); + int i; + for(i = 1; i < nrows; ++i) + { + if(ratgreat(payoffA[m][l], payoffA[i][l])) + m = i; + if(ratiseq(payoffA[m][l], payoffA[i][l])) + m = i; + } + m += 1; + } + else /* if l is p1's strategy */ + { + int i; + l -= 1; + for(i = 1; i < ncols; ++i) + { + if(ratgreat(payoffB[l][m], payoffB[l][i])) + m = i; + if(ratiseq(payoffB[l][m], payoffB[l][i])) + m = i; + } + m += (nrows + 1); + } + return m; +} + +/** +* Pivots the tableau given the values for the leaving +* and entering variables, and outputs data based on the +* flags. +* +* \param leave The leaving variable +* \param enter The entering variable +* \param flags The flags for running Lemke's algorithm +*/ +/* GSoC12: Tobenna Peter, Igwe */ +int fpivot(int leave, int enter, Flagsrunlemke flags) +{ + testtablvars(); + if (flags.bdocupivot) + { + if(docupivot (leave, enter, flags) < 0) + return -1; + } + pivot (leave, enter); + if (flags.bouttabl) + outtabl(); + pivotcount++; + + return 0; +} + +/** + * Initialise the LH algorithm with the first + * three pivots of method 1 as explained in the report. + */ +/* GSoC12: Tobenna Peter, Igwe */ +int initLH1(Flagsrunlemke flags) +{ + int enter, leave; + + enter = Z(0); + leave = (k > nrows) ? W(1) : W(2); + + fpivot(leave, enter, flags); + + enter = complement(leave); + leave = W(bestResponse(k) + 2); + fpivot(leave, enter, flags); + + enter = complement(leave); + leave = (k > nrows) ? W(2) : W(1); + + fpivot(leave, enter, flags); + + enter = complement(leave); + leave = W(k + 2); + fpivot(leave, enter, flags); + + return leave; +} + +/** + * Initialise the LH algorithm with the first + * three pivots of method 1 as explained in the report. + */ +/* GSoC12: Tobenna Peter, Igwe */ +int initLH2(Flagsrunlemke flags) +{ + int enter, leave; + + enter = Z(0); + leave = (k > nrows) ? W(2) : W(1); + + fpivot(leave, enter, flags); + + enter = complement(leave); + leave = W(k + 2); + + fpivot(leave, enter, flags); + + enter = complement(leave); + leave = (k > nrows) ? W(1) : W(2); + + fpivot(leave, enter, flags); + + enter = complement(leave); + leave = W(bestResponse(k) + 2); + + fpivot(leave, enter, flags); + + return leave; +} + +/** + * Initialise the LH pivots given the flags. + * It chooses to initialise the LH pivots using either + * method 1 or 2 as specified by the user in flags. + * + * \param flags The flags for running Lemke's algorithm + */ +/* GSoC12: Tobenna Peter, Igwe */ +int initLH(Flagsrunlemke flags) +{ + if(flags.bisArtificial) + return flags.binitmethod ? complement(initLH2(flags)) : complement(initLH1(flags)); + else + return Z(0); +} + +/** + * Computes the inverse of A_B. + */ +/* GSoC12: Tobenna Peter, Igwe */ +void getinvAB(int verbose) +{ + int i; + + for(i = 0; i < n; ++i) + { + if(bascobas[W(i + 1)] < n) /* If W(i) is basic */ + { + int j = bascobas[W(i + 1)]; /* Get it's row number */ + int k; + for(k = 0; k < n; ++k) + { + if(k == j) /* The jth row of the ith column is 1 other rows are 0 */ + { + copy(invAB[k][i], det); + } + else + { + itomp(0, invAB[k][i]); + } + } + } + else /* If W(i) is non-basic */ + { + int j = TABCOL(W(i + 1)); + int k; + for(k = 0; k < n; ++k) /* copy the column representing W(i) into the ith column */ + { + copy(invAB[k][i], A[k][j]); + } + } + } + + if(verbose) + { + printf("\nPrinting invAB:\n"); + colset(n); + + for(i = 0; i < n; ++i) + { + int j; + for(j = 0; j < n; ++j) + { + char str[MAXSTR]; + mptoa(invAB[i][j], str); + colpr(str); + } + } + colout(); + + colset(n); + printf("\nz0= "); + for(i = 0; i < n; ++i) + { + char str[MAXSTR]; + mptoa(A[i][TABCOL(Z(0))], str); + printf("%s ", str); + } + colout(); + printf("\n"); + } +} + +/* ------------------------------------------------------------ */ +/* GSoC12: Tobenna Peter, Igwe (Edited)*/ +int runlemke(Flagsrunlemke flags) +{ + int leave, enter, z0leave; + + pivotcount = 1; + + initstatistics(); + + if (flags.binitabl) + { + printf("After filltableau:\n"); + outtabl(); + } + + /* now give the entering q-col its correct sign */ + if(flags.bisArtificial)/*GSOC*/ + negcol (RHS); + + if (flags.bouttabl) + { + printf("After negcol:\n"); + outtabl(); + } + + /* z0 enters the basis to obtain lex-feasible solution, or use the initialization */ + /*enter = Z(0)*/ /*GSOC*/ + enter = flags.binteract ? Z(0) : initLH(flags); + leave = flags.binteract ? interactivevar(enter, &z0leave) : lexminvar(enter, &z0leave); + + if(leave < 0) + return -1; + + while (1) /* main loop of complementary pivoting */ + { + if(flags.interactcount) + flags.binteract = --flags.interactcount ? 1 : 0; + testtablvars(); + if (flags.bdocupivot) + { + if(docupivot (leave, enter, flags) < 0) + return -1; + } + pivot (leave, enter); + if (z0leave) + break; /* z0 will have value 0 but may still be basic. Amend? */ + if (flags.bouttabl) + outtabl(); + enter = complement(leave); + leave = flags.binteract ? interactivevar(enter, &z0leave) : lexminvar(enter, &z0leave); + if(leave < 0) + return -1; + + if (pivotcount++ == flags.maxcount) + { + printf("------- stop after %d pivoting steps --------\n", + flags.maxcount); + break; + } + } + + if (flags.binitabl) + { + printf("Final tableau:\n"); + outtabl(); + } + if (flags.boutsol) + outsol(); + if (flags.blexstats) + outstatistics(); + + notokcopysol(); + /*GSOC: For test purpose only */ + if(flags.boutinvAB) + getinvAB(flags.boutinvAB); + + return 0; +} + +/** + * Copy the tableau from the given equilibrium to be + * used for computation. + */ +/* GSoC12: Tobenna Peter, Igwe */ +void copyEquilibrium(Equilibrium eq) +{ + int i, j; + for(i = 0; i < n; ++i) + { + for(j = 0; j < n+2; ++j) + { + copy(A[i][j], eq.A[i][j]); + } + } + + for(i = 0; i < n+2; ++i) + { + copy(scfa[i], eq.scfa[i]); + } + + for(i = 0; i < 2*n+1; ++i) + { + bascobas[i] = eq.bascobas[i]; + whichvar[i] = eq.whichvar[i]; + } + copy(det, eq.det); +} + +/** + * Setup the covering vector for the Artificial Equilibrium. + * Calculates the new covering vector for the missing label k + * from the artificial equilibrium, and substitutes that in the + * tableau. + */ +/* GSoC12: Tobenna Peter, Igwe */ +void setupArtificial() +{ + int i; + /* Copy the new covering vector into the tableau */ + for(i = 0; i < n; ++i) + { + mp tmp; + if(i == k+1) + { + itomp(0, tmp); + } + else + { + itomp(1, tmp); + } + copy(A[i][TABCOL(Z(0))], tmp); + } +} + +/** + * Setup the tableau from the current equilibrium using k2 as the missing label. + * This involves calculating the inverse of A_B to find the new covering vector, + * and replacing it in the tableau. + */ +/* GSoC12: Tobenna Peter, Igwe */ +void setupEquilibrium(Flagsrunlemke flags) +{ + getinvAB(flags.boutinvAB); + /* vecd2 represents the covering vector when k2 is the missing label */ + mp* vecd2 = TALLOC(n, mp); + int i; + for(i = 0; i < n; ++i) + { + if(i == (k2 + 1)) + { + itomp(0, vecd2[i]); + } + else + { + itomp(1, vecd2[i]); + } + } + + /* sol represents the computed covering vector by multiplying + * invAB with vecd2, and multiplying the result by -1 */ + mp* sol = TALLOC(n, mp); + for(i = 0; i < n; ++i) + { + int j; + mp sum; + itomp(0, sum); + for(j = 0; j < n; ++j) + { + mp tmp; + mulint(invAB[i][j], vecd2[j], tmp); + linint(sum, 1, tmp, 1); + /*sum = ratadd(sum, tmp);*/ + } + changesign(sum); + copy(sol[i], sum); + } + + /* Copy the new covering vector into the tableau */ + for(i = 0; i < n; ++i) + { + /*A[i][TABCOL(Z(0))] = sol[i];*/ + copy(A[i][TABCOL(Z(0))], sol[i]); + } + if(flags.binitabl) + { + printf("\nTableau with new covering vector\n"); + outtabl(); + printf("\nRestarting with missing label: %d\n", k2); + } +} + +/** + * Compute the equilibria from the specified node. + * This computes all the equiibria directly reachable by + * dropping labels which do not have any equilibrium linked + * with from the current equilibrium. + * + * \param i Index position of the current equilibrium in the list + * \param isneg Boolean value indicating if the current equilibrium is + * a negatively indexed equilibrium. + * \param flags Flags for tunning Lemke's algorithm. + */ +/* GSoC12: Tobenna Peter, Igwe */ +void computeEquilibriafromnode(int i, int isneg, Flagsrunlemke flags) +{ + node* cur = (isneg) ? neg : pos; + node* res = (isneg) ? pos : neg; + + cur = getNodeat(cur, i); + Equilibrium eq; + int maxk = nrows + ncols; + for(k2 = 1; k2 <= maxk; ++k2) + { + if(cur->link[k2-1] != -1) + continue; + + copyEquilibrium(cur->eq); + if(flags.bisArtificial) + { + k = k2; + setupArtificial(); + } + else + { + setupEquilibrium(flags); + } + int err = runlemke(flags); + + if (err < 0) + continue; + + /* Create the equilibrium and add it to the list */ + eq = createEquilibrium(A, scfa, det, bascobas, whichvar, n, nrows, ncols); + int plength = listlength(res); + /* The equilibrium is at the index j in the list */ + int j = addEquilibrium(res, eq); + /* Label k links both equilibria together */ + cur->link[k2-1] = j; + node* p = getNodeat(res, j); + p->link[k2-1] = i; + + if(flags.bouteq && plength != listlength(res)) + { + colprEquilibrium(eq); + } + + if(flags.boutsol) + { + printEquilibrium(eq); + } + } +} + +/** + * Compute all equilibrium + */ +/* GSoC12: Tobenna Peter, Igwe */ +void computeEquilibria(Flagsrunlemke flags) +{ + int maxk = nrows + ncols; + int negi, posi; + + neg = newnode(n-2); + pos = newnode(n-2); + + isqdok(); + colset(n); + /* printf("LCP seems OK.\n"); */ + filltableau(); + /* printf("Tableau filled.\n"); */ + + /* Store the artificial equilibrium */ + Equilibrium eq = createEquilibrium(A, scfa, det, bascobas, whichvar, n, nrows, ncols); + neg->eq = eq; + + /* Compute and store the first equilibrium */ + runlemke(flags); + eq = createEquilibrium(A, scfa, det, bascobas, whichvar, n, nrows, ncols); + pos->eq = eq; + + if(flags.bouteq) + { + colprEquilibrium(eq); + } + if(flags.boutsol) + { + printEquilibrium(eq); + } + + /* Label 1 links the first equilibrium from both list */ + neg->link[0] = 0; + pos->link[0] = 0; + + computeEquilibriafromnode(0, 1, flags); + + flags.bisArtificial = 0; + negi = 1; + posi = 0; + int isneg = 0; + + while(1) + { + if(isneg) + { + while(negi < listlength(neg)) + { + computeEquilibriafromnode(negi, isneg, flags); + negi++; + } + } + else + { + while(posi < listlength(pos)) + { + computeEquilibriafromnode(posi, isneg, flags); + posi++; + } + } + isneg = !isneg; + if((negi == listlength(neg)) && (posi == listlength(pos))) + break; + } + + colout(); + if(flags.boutpath) + { + colset(n + 1); + int i; + for(i = 0; i < n + 1; ++i) + { + colleft(i); + } + char smp [2*DIG2DEC(MAX_DIGITS) + 4]; + + printf("\nEquilibria discovered: %d\n", (listlength(neg) - 1 + listlength(pos))); + sprintf(smp, "\n%d-ve index:", negi); + colpr(smp); + colnl(); + printlist(neg, 'N'); + sprintf(smp, "\n%d+ve index:", posi); + colpr(smp); + colnl(); + printlist(pos, 'P'); + colout(); + } +} + diff --git a/native-algo/lh-vector/lemke.h b/native-algo/lh-vector/lemke.h new file mode 100644 index 0000000..0c003ba --- /dev/null +++ b/native-algo/lh-vector/lemke.h @@ -0,0 +1,104 @@ +/** + * \file lemke.h + * Declarations for lcp solver. + * + * 16 Apr 2000 + * Author: Bernhard von Stengel stengel@maths.lse.ac.uk + * + * Edited: Tobenna Peter, Igwe ptigwe@gmail.com August, 2012 + */ + +/* #include before: rat.h */ +#include "list.h" +#include "rat.h" +#ifndef LEMKE_H +#define LEMKE_H + +#define MAXLCPDIM 2000 /**< max LCP dimension */ +#define INFOSTRINGLENGTH 8 /**< string naming vars, e.g. "z0", "w187" */ +#define LCPSTRL 60 /**< length of string containing LCP entry */ + +/* LCP input data */ +extern Rat **lcpM; /**< LCP Matrix */ +extern Rat *rhsq; /**< right hand side q */ +extern Rat *vecd; /**< LCP covering vector d */ +extern int lcpdim; /**< LCP dimension */ + +/* LCP result data */ +extern Rat *solz; /**< LCP solution z vector */ +/** Number of Lemke pivot iterations, including the first to pivot z0 in */ +extern int pivotcount; + +/*GSOC12*/ +/** Number of rows in the input matrix game */ +extern int nrows; +/** Number of columns in the input matrix game */ +extern int ncols; +/** The missing label from the artificial equilibrium */ +extern int k; +/** The missing label when restarting from a computed equilibrium */ +extern int k2; +/** The payoff matrix for player 1 */ +extern Rat** payoffA; +/** The payoff matrix for player 2 */ +extern Rat** payoffB; + +/** The list of negatively indexed equilibria*/ +extern node* neg; +/** The list of positively indexed equilibria*/ +extern node* pos; + +int vartoa(int v, char s[]); + +/** + * Allocate and initialise the LCP. + * Allocate and initialise with zero entries an LCP of dimension n + * this is the only method changing lcpdim + * exit with error if fails, e.g. if n not sensible + */ +void setlcp(int n); + +/** Output the LCP as given */ +void outlcp (void); + +/** Flags for runlemke */ +typedef struct +{ + int maxcount ; /**< Maximum number of iterations, infinity if 0 */ + int bdocupivot; /**< Y/N document pivot step */ + int binitabl ; /**< Y/N output entire tableau at beginning/end */ + int boutpiv ; /**< Y/N output current pivot step */ + int bouttabl ; /**< Y/N output entire tableau at each step */ + int boutsol ; /**< Y/N output solution */ + int binteract ; /**< Y/N interactive pivoting */ + int blexstats ; /**< Y/N statistics on lexminratio tests */ + int bouteq; /**< Y/N Immediately output equilibrium */ + int boutpath; /**< Y/N output the LH path */ + int interactcount;/**< Number of interactive entries *//* GSoC12: Tobenna Peter, Igwe */ + int binitmethod; /**< Used to select the initialisation method *//* GSoC12: Tobenna Peter, Igwe */ + int boutinvAB; /**< Y/N output inverse of A_B *//* GSoC12: Tobenna Peter, Igwe */ + int bisArtificial;/**< If the current equilibrium is artificial *//* GSoC12: Tobenna Peter, Igwe */ +}Flagsrunlemke; + +/** + * Solve LCP via Lemke's algorithm. + * Solution is stored in solz [0..lcpdim-1], exit with error if ray termination. + * This code initialises the tableau with prior pivots to ensure the + * Lemke-Howson path. + * + * \param flags The flags for running Lemke's algorithm. + */ +int runlemke(Flagsrunlemke flags); + +/** + * Compute all equilibria reachable by the Lemke-Howson algorithm. + * The complete bi-partite graph of reachable equilibria from the + * artificial equilibrium is stored in neg and pos, which represent + * the two different partitions of the graph. + * + * \param flags The flags for running Lemke's algorithm. + */ +/* GSoC12: Tobenna Peter, Igwe */ +void computeEquilibria(Flagsrunlemke flags); + +#endif \ No newline at end of file diff --git a/native-algo/lh-vector/list.c b/native-algo/lh-vector/list.c new file mode 100644 index 0000000..9fec5de --- /dev/null +++ b/native-algo/lh-vector/list.c @@ -0,0 +1,152 @@ +/** + * \file list.c + * A list of equilibrium. This is used to represent a group of + * equilibria, either the positively indexed equilibria or the + * negatively indexed equilibria. Nodes from one list are connected + * to the other list via their link variable, which enables the + * navigation of the bi-partite graph, of equilibria. + * + * Author: Tobenna Peter, Igwe ptigwe@gmail.com August, 2012 + * + * Note: This file generates both list.o and glist.o, + * to compile the file with gnump use the -DGLEMKE flag + */ + +#include "equilibrium.h" +#include "list.h" + +/* Creates a new node */ +node* newnode(int n) +{ + node* nd; + nd = malloc(sizeof(node)); + nd->link = malloc(n * sizeof(int)); + int i; + for(i = 0; i < n; ++i) + { + nd->link[i] = -1; + } + nd->next = NULL; + + return nd; +} + +/* Adds a new node with the given equilibrium to the list + * and returns its index position */ +int addNode(node* list, Equilibrium eq) +{ + int i = 0; + node* cur = list; + + while(cur->next != NULL) + { + cur = cur->next; + ++i; + } + + node* n = newnode(eq.lcpdim-2); + n->eq = eq; + cur->next = n; + ++i; + + return i; +} + +/*Finds and returns the location of an equilibrium in the list + Returns -1 if the equilibrium is not in the list*/ +int contains(node* list, Equilibrium eq) +{ + int result = -1; + int i = 0; + node* cur = list; + + while(cur != NULL) + { + if(equilibriumisEqual(cur->eq, eq)) + { + result = i; + break; + } + cur = cur->next; + ++i; + } + + return result; +} + +/* Adds the equilibrium to the list, and returns its index position + * in the list. If the equilibrium already exists, it returns the + * index where it is stoeed, and doesn't add it. */ +int addEquilibrium(node* list, Equilibrium eq) +{ + int result = contains(list, eq); + if(result == -1) + { + result = addNode(list, eq); + } + return result; +} + +/* Get node at index */ +int listlength(node* list) +{ + if(list == NULL) + return 0; + + int i = 1; + + node* next = list; + while(next->next != NULL) + { + ++i; + next = next->next; + } + + return i; +} + +/* Computes the number of elements in the list */ +node* getNodeat(node* list, int n) +{ + if(n >= listlength(list) || n < 0) + return NULL; + + int i = 0; + + node* cur = list; + for(i = 0; i < n; ++i) + { + cur = cur->next; + } + + return cur; +} + +/* Prints all the elements in the list */ +void printlist(node* list, char prefix) +{ + char smp [2*DIG2DEC(MAX_DIGITS) + 4]; + node* cur = list; + int i = 0; + while(cur != NULL) + { + sprintf(smp, "%cEq[%d]: ", prefix, i++); + colpr(smp); + colprEquilibrium(cur->eq); + int k; + colpr("Leads to: "); + colpr(""); + for(k = 0; k < cur->eq.nrows; ++k) + { + sprintf(smp, "%d->%d ", k+1, cur->link[k]); + colpr(smp); + } + colpr(""); + for(; k < cur->eq.lcpdim - 2; ++k) + { + sprintf(smp, "%d->%d ", k+1, cur->link[k]); + colpr(smp); + } + cur = cur->next; + } +} \ No newline at end of file diff --git a/native-algo/lh-vector/list.h b/native-algo/lh-vector/list.h new file mode 100644 index 0000000..d90fc94 --- /dev/null +++ b/native-algo/lh-vector/list.h @@ -0,0 +1,87 @@ +/** + * \file list.h + * A list of equilibrium. This is used to represent a group of + * equilibria, either the positively indexed equilibria or the + * negatively indexed equilibria. Nodes from one list are connected + * to the other list via their link variable, which enables the + * navigation of the bi-partite graph, of equilibria. + * + * Author: Tobenna Peter, Igwe ptigwe@gmail.com August, 2012 + */ +#include "equilibrium.h" +#ifndef LIST_H +#define LIST_H + +/** + * A node structure used to represent a linked list. + * Each node contains an Equilibrium which is unique to + * that list, i.e. no two nodes in the list have the same + * equilibrium. Each node also has a node element which + * connects it to the next node in the list. Finally, each + * node has an integer array link which connects the current + * node in the list to a node in the opposite list with a given + * label. For example if link[1] = 3, then this node is linked + * to the 4th element in the other list with the label 2. + * \sa Equilibrium + */ +typedef struct node_t +{ + Equilibrium eq; /**< The Equilibrium stored in the node */ + int* link; /**< The indexes of nodes it is connected to in the opposite list */ + struct node_t* next; /**< The next element in the list */ +}node; + +/** + * Creates a new node given the total number of labels. + * + * \param n Number of labels + * \returns A new node initialised for n labels + */ +node* newnode(int n); + +/** + * Returns the location of an equilibrium in the list. + * Returns -1 if the equilibrium is not in the list. + * + * \param list The list to be searched + * \param eq The equilibrium to search for + * \returns The index location of the equilibrium from 0 or + * -1 if not in the list + */ +int contains(node* list, Equilibrium eq); + +/** + * Adds the equilibrium to the end of a list. + * If the equilibrium already exists, it returns the + * index where it is stoeed, and doesn't add it. + * + * \param list The list to add an Equilibrium to. + * \param eq The equilibrium to be added. + * \returns The index location of the equilibrium + */ +int addEquilibrium(node* list, Equilibrium eq); + +/** + * Returns the node at the index of the specified list. + * If n is greater than or equal to the length of the list, + * it returns NULL. + * + * \param list The list + * \param n The index of the node in list + * \returns The node at the given index or NULL if there is no such index + */ +node* getNodeat(node* list, int n); + +/** + * Computes the number of elements in the list. + * + * \returns The length of the list + */ +int listlength(node* list); + +/** + * Prints all the elements in the list. + */ +void printlist(node* list, char prefix); + +#endif \ No newline at end of file diff --git a/native-algo/lh-vector/mp.c b/native-algo/lh-vector/mp.c new file mode 100644 index 0000000..ec08714 --- /dev/null +++ b/native-algo/lh-vector/mp.c @@ -0,0 +1,633 @@ +/* mp.c + * 27 Apr 2000 + * Author: Bernhard von Stengel stengel@maths.lse.ac.uk + */ + +#include +#include + /* atoi() */ +#include + /* INT_MAX, INT_MIN */ + +#include "mp.h" + +/*********************/ +/*global variables */ +/*********************/ + +long digits = MAX_DIGITS; +long record_digits; + +int mptoi(mp a, int *result, int bcomplain) +{ + char smp [DIG2DEC(MAX_DIGITS)+2]; /* string to print mp into */ + + mptoa(a, smp); + *result = atoi(smp); + if (*result == INT_MAX || *result == INT_MIN) + { + if (bcomplain) + { + printf("Warning: Long integer %s ", smp); + printf("overflown, replaced by %d\n", *result); + } + return 1; + } + else + return 0; +} + + +long readrat(mp Na, mp Da) + /* read a rational or integer and convert to mp with base BASE */ + /* returns true if denominator is not one */ +{ + char in[MAXINPUT],num[MAXINPUT],den[MAXINPUT]; + scanf("%s",in); + atoaa(in,num,den); /*convert rational to num/dem strings*/ + atomp(num,Na); + if (den[0]=='\0') + { + itomp(1L,Da); + return(FALSE); + } + atomp(den,Da); + return(TRUE); +} +void atomp(char s[], mp a) /*convert string to mp integer*/ +{ + mp mpone; + long diff,ten,i,sig; + itomp(1L,mpone); + ten=10L; + for (i=0; s[i]==' ' || s[i]=='\n' || s[i]=='\t'; i++); + /*skip white space*/ + sig=POS; + if( s[i] == '+' || s[i]=='-' ) /* sign */ + sig=(s[i++]=='+') ? POS : NEG; + itomp(0L,a); + while ( s[i] >= '0' && s[i] <= '9') + { diff=s[i] - '0'; + linint(a,ten,mpone,diff); + i++; + } + storesign(a,sig); +} /* end of atomp */ + +void readmp(mp a) /* read an integer and convert to mp with base BASE */ +{ + long in; + scanf("%ld",&in); + itomp(in,a); +} + +void itomp(long in, mp a) /* convert integer i to multiple precision with base BASE */ +{ + long i; + a[0]=2; /* initialize to zero */ + for(i=1;i=1;i--) printf(FORMAT,Nt[i]); + if( !(Dt[0]==2 && Dt[1]==1)) /* rational */ + { printf("/"); + if (sign(Dt)==NEG) printf("-"); + printf("%u",Dt[length(Dt)-1]); + for (i=length(Dt)-2;i>=1;i--) printf(FORMAT,Dt[i]); + } + printf(" "); +} + +/* get rid void pimat(long r,long s,mp Nt,char name[]) */ + /* print the long precision integer in row r col s of matrix A */ +/* of this { + int i; + if (s==0) printf("%s[%d][%d]=",name,B[r],C[s]); + else printf("[%d]=",C[s]); + if (sign(Nt)==NEG) printf("-"); + printf("%u",Nt[length(Nt)-1]); + for (i=length(Nt)-2;i>=1;i--) printf(FORMAT,Nt[i]); + +}*/ + +void pmp(char name[],mp a) /*print the long precision integer a*/ +{ + long i; + printf("%s",name); + if (sign(a)==NEG) printf("-"); + printf("%u",a[length(a)-1]); + for (i=length(a)-2;i>=1;i--) printf(FORMAT,a[i]); +} + +int mptoa(mp x, char s[]) + /* convert mp integer to string, returning length */ + /* s must be sufficiently long to contain result */ +{ +int i, pos=0; +if (sign(x)==NEG) + pos = sprintf(s, "-"); +pos += sprintf(&s[pos], "%u", x[length(x)-1] ); +for (i=length(x)-2; i>=1; i--) + pos += sprintf(&s[pos], FORMAT, x[i]); +return pos; +} + +/* + * Package of routines for multiple precision arithmetic + */ + +/* returns u=gcd(u,v) destroying v + * Euclid's algorithm. Knuth, II, p.320 + * modified to avoid copies r=u,u=v,v=r + * Switches to single precision when possible for greater speed + */ +void gcd(mp u, mp v) +{ + mp r; + unsigned long ul,vl; + long i; + static unsigned long maxspval=MAXD; + /* Max value for the last digit to guarantee */ + /* fitting into a single long integer. */ + + static long maxsplen; + /* Maximum digits for a number that will fit */ + /* into a single long integer. */ + + static long firstime=TRUE; + + if(firstime) /* initialize constants */ + { + for (maxsplen = 2; maxspval >= BASE; maxsplen++) + maxspval /= BASE; + firstime=FALSE; + } + if(greater(v,u)) goto bigv; + bigu: + if(zero(v)) + return; + if ((i=length(u))0; i--) + ul = BASE*ul + u[i]; + for (i=length(v)-1; i>0; i--) + vl = BASE*vl+v[i]; + if (ul>vl) + goto qv; + qu: + if (vl==0) + { + for (i=1;ul;i++) + { + u[i] = ul % BASE ; + ul = ul / BASE; + } + storelength(u,i); + return; + } + ul %= vl; + qv: + if (ul==0) + { + for (i=1;vl;i++) + { + u[i] = vl % BASE; + vl = vl / BASE; + } + storelength(u,i); + return; + } + vl %= ul; + goto qu; +} + + +void reduce(mp Na,mp Da) /* reduces Na Da by gcd(Na,Da) */ +{ + mp Nb,Db,Nc,Dc; + copy(Nb,Na); + copy(Db,Da); + storesign(Nb,POS); + storesign(Db, POS); + copy(Nc,Na); + copy(Dc,Da); + gcd(Nb,Db); /* Nb is the gcd(Na,Da) */ + divint(Nc,Nb,Na); + divint(Dc,Nb,Da); +} + +void lcm(mp a, mp b) + /* a = least common multiple of a, b; b is preserved */ +{ + mp u,v; + copy(u,a); + copy(v,b); + gcd(u,v); + divint(a,u,v); /* v=a/u a contains remainder = 0 */ + mulint(v,b,a); +} /* end of lcm */ + +long greater(mp a, mp b) /* tests if a > b and returns (TRUE=POS) */ +{ + long i; + + if(a[0] > b[0]) return(TRUE); + if(a[0] < b[0]) return(FALSE); + + for (i=length(a)-1;i>=1;i--) + { + if (a[i] < b[i]) + { + if(sign(a) == POS) + return 0 ; + else + return 1 ; + } + if(a[i] > b[i]) + { + if(sign(a) == NEG) + return 0 ; + else + return 1 ; + } + } + return 0 ; +} + +void copy(mp a, mp b) /* assigns a=b */ +{ + long i; + for (i=0; i<=length(b); i++) + a[i]=b[i]; +} + +/* compute a*ka+b*kb --> a + * Handbook of Algorithms and Data Structures P.239 + */ +void linint(mp a,long ka,mp b,long kb) +{ + long i,la,lb; + la = length(a); + lb = length(b); + for (i=1; ila) + { + storelength(a, lb); + for (i=la; i0) + { + a[i++]=cy%BASE; + cy/=BASE; + } + if(cy<0) + { + a[la-1]+=cy*BASE; + for (i=1;i2) + i--; + if ( i > record_digits) + { + if ( ( record_digits= i ) > digits) + digits_overflow(la); + }; + storelength(a,i); + if (i==2 && a[1]==0) + storesign(a,POS); +} /* end of normalize */ + +void mulint(mp a,mp b,mp c) /* multiply two integers a*b --> c */ + /***Handbook of Algorithms and Data Structures, p239 ***/ +{long nlength,i,j,la,lb; + /*** b and c may coincide ***/ + la=length(a); + lb=length(b); + nlength=la+lb-2; + if(nlength > digits ) + digits_overflow(nlength); + +for (i=0;i0;i--) { + for(j=2;j + MAXD-(BASE-1)*(BASE-1)-MAXD/BASE){ + c[i+j-1] -= (MAXD/BASE)*BASE; + c[i+j] += MAXD/BASE; + } + c[i] = b[i]*a[1]; + } +storelength(c,nlength); +storesign(c,sign(a)==sign(b) ? POS : NEG ); +normalize(c); +} /***end of mulint ***/ + +long comprod(mp Na,mp Nb,mp Nc,mp Nd) + /* +1 if Na*Nb > Nc*Nd */ + /* -1 if Na*Nb < Nc*Nd */ + /* 0 if Na*Nb = Nc*Nd */ +{ + mp mc,md; + mulint(Na,Nb,mc); + mulint(Nc,Nd,md); + linint(mc,ONE,md,-ONE); + if(positive(mc)) return (1); + if(negative(mc)) return (-1); + return(0); +} + +/********************************************************/ +/* Divide two multiple precision integers (c=a/b). */ +/* a is destroyed and contains the remainder on return. */ +/* From Knuth Vol.2 SemiNumerical Algorithms */ +/********************************************************/ +void divint(mp a, mp b, mp c ) + /* c=a/b, a contains remainder on return */ +{ + long cy, la, lb, lc, d1, s, t, sig; + long i, j, qh; + +/* figure out and save sign, do everything with positive numbers*/ + sig=sign(a)*sign(b); + + la = length(a); + lb = length(b); + lc = la-lb+2; + if ( la0; i--) { + cy = cy*BASE+a[i]; + a[i] = 0; + cy -= (c[i] = cy/t) * t; + } + a[1] = cy; + storesign(a,(cy==0) ? POS : sign(a)); + storelength(a,TWO); + /* set sign of c to sig (**mod**) */ + storesign(c,sig); + normalize(c); + return; + } + else + { + /* mp's are actually DIGITS+1 in length, so if length of a or b = */ + /* DIGITS, there will still be room after normalization. */ + /****************************************************/ + /* Step D1 - normalize numbers so b > floor(BASE/2) */ + d1 = BASE/(b[lb-1] + 1); + if (d1 > 1) + { + cy = 0; + for (i=1;i (s - qh*b[lb-1])*BASE + a[la-j-2]) + qh--; + } + /*******************************************************/ + /* Step D4 - divide through using qh as quotient digit */ + cy = 0; + for (i=1;i<=lb;i++) + { + s = qh*b[i] + cy; + a[la-j-lb+i] -= s%BASE; + cy = s/BASE; + if (a[la-j-lb+i] < 0) + { + a[la-j-lb+i] += BASE; + cy++; + } + } + /*****************************************************/ + /* Step D6 - adjust previous step if qh is 1 too big */ + if (cy) + { + qh--; + cy = 0; + for (i=1;i<=lb;i++) /* add a back in */ + { + a[la-j-lb+i] += b[i] + cy; + cy = a[la-j-lb+i]/BASE; + a[la-j-lb+i] %= BASE; + } + } + /***********************************************************************/ + /* Step D5 - write final value of qh. Saves calculating array indices */ + /* to do it here instead of before D6 */ + + c[la-lb-j+1] = qh; + + } + /**********************************************************************/ + /* Step D8 - unnormalize a and b to get correct remainder and divisor */ + + for (i=lc;c[i-1]==0 && i>2;i--); /* strip excess 0's from quotient */ + storelength(c,i); + if(i==2 && c[1]==0) storesign(c,POS); + cy = 0; + for (i=lb-1;i>=1;i--) + { + cy = (a[i]+=cy*BASE)%d1; + a[i] /= d1; + } + for (i=la;a[i-1]==0 && i>2;i--); /* strip excess 0's from quotient */ + storelength(a,i); + if(i==2 && a[1]==0) storesign(a,POS); + if (cy) printf("divide error"); + for (i=lb-1;i>=1;i--) + { + cy = (b[i]+=cy*BASE)%d1; + b[i] /= d1; + } + } +} + +/***************************************************************/ +/* */ +/* End of package for multiple precision arithmetic */ +/* */ +/***************************************************************/ + +void digits_overflow() +{ + printf("Overflow at digits=%d\n",DIG2DEC(digits)); + exit(1); +} + +/***************************************************************/ +/* */ +/* Package of routines for rational arithmetic */ +/* (Built on top of package for multiprecision arithmetic */ +/* Not currently used, but may be useful */ +/***************************************************************/ + + +linrat(Na,Da,ka,Nb,Db,kb,Nc,Dc) + /* computes Nc/Dc = ka*Na/Da +kb* Nb/Db + and reduces answer by gcd(Nc,Dc) */ +mp Na,Da,Nb,Db,Nc,Dc; +long ka,kb; +{ +mp c; +mulint(Na,Db,Nc); +mulint(Da,Nb,c); +linint(Nc,ka,c,kb); /* Nc = (ka*Na*Db)+(kb*Da*Nb) */ +mulint(Da,Db,Dc); /* Dc = Da*Db */ +reduce(Nc,Dc); +} + + +divrat(Na,Da,Nb,Db,Nc,Dc) + /* computes Nc/Dc = (Na/Da) / ( Nb/Db ) + and reduces answer by gcd(Nc,Dc) */ +mp Na,Da,Nb,Db,Nc,Dc; +{ +mulint(Na,Db,Nc); +mulint(Da,Nb,Dc); +reduce(Nc,Dc); +} + + +mulrat(Na,Da,Nb,Db,Nc,Dc) + /* computes Nc/Dc = Na/Da * Nb/Db + and reduces answer by gcd(Nc,Dc) */ +mp Na,Da,Nb,Db,Nc,Dc; +{ +mulint(Na,Nb,Nc); +mulint(Da,Db,Dc); +reduce(Nc,Dc); +} + +/***************************************************************/ +/* */ +/* End package of routines for rational arithmetic */ +/* */ +/***************************************************************/ + diff --git a/native-algo/lh-vector/mp.h b/native-algo/lh-vector/mp.h new file mode 100644 index 0000000..591da04 --- /dev/null +++ b/native-algo/lh-vector/mp.h @@ -0,0 +1,169 @@ +/** + * \file mp.h + * 13 July 2000 + * multiprecision routines taken from lrs + * Author: Bernhard von Stengel stengel@maths.lse.ac.uk + */ + +/***********/ +/* defines */ +/***********/ + +/**********MACHINE DEPENDENT CONSTANTS***********/ +/* MAXD is 2^(k-1)-1 where k=16,32,64 word size */ +/* MAXD must be at least 2*BASE^2 */ +/* If BASE is 10^k, use "%k.ku" for FORMAT */ +/* INTSIZE is number of bytes for integer */ +/* 32/64 bit machines */ +/***********************************************/ +#ifndef MP_H +#define MP_H +#ifndef B64 +/*32 bit machines */ +#define FORMAT "%4.4u" +#define MAXD 2147483647L +#define BASE 10000L +#define BASE_DIG 4 +#define INTSIZE 8L +#define BIT "32" +#else +/* 64 bit machines */ +#define MAXD 9223372036854775807L +#define BASE 1000000000L +#define FORMAT "%9.9u" +#define BASE_DIG 9 +#define INTSIZE 16L +#define BIT "64" +#endif + +#define MAXINPUT 1000 /*max length of any input rational*/ + +#define POS 1L +#define NEG -1L +#ifndef TRUE +#define TRUE 1L +#endif +#ifndef FALSE +#define FALSE 0L +#endif +#define ONE 1L +#define TWO 2L +#define ZERO 0L + +/********* MACROS ***********/ +#define positive(a) (((a)[0] < 2 || ((a)[0]==2 && (a)[1]==0))?FALSE:TRUE) +#define negative(a) (((a)[0] > -2 || ((a)[0]==-2 && (a)[1]==0))?FALSE:TRUE) +#define zero(a) ((((a)[0]==2 || (a)[0]==-2) && (a)[1]==0)?TRUE:FALSE) +#define one(a) (((a)[0]==2 && (a)[1]==1)?TRUE:FALSE) +#define length(a) (((a)[0] > 0) ? (a)[0] : -(a)[0]) +#define sign(a) (((a)[0] < 0) ? NEG : POS) +#define storesign(a,sa) a[0]=((a)[0] > 0) ? (sa)*((a)[0]) : -(sa)*((a)[0]) +#define changesign(a) a[0]= -(a)[0] +#define storelength(a,la) a[0]=((a)[0] > 0) ? (la) : -(la) + +/* + this is in decimal digits, you pay in memory if you increase this, + unless you override by a line with + digits n + before the begin line of your file. +*/ +#define DEFAULT_DIGITS 100L + +/* + this is number of longwords. Increasing this won't cost you that much + since only variables other than the A matrix are allocated this size. + Changing affects running time in small but not very predictable ways. +*/ + +/* +#define MAX_DIGITS 255L +#define MAX_DIGITS 50L +*/ +#define MAX_DIGITS 40L + +/* + * convert between decimal and machine (longword digits). Notice lovely + * implementation of ceiling function :-) + */ + +#define DEC2DIG(d) ( (d) % BASE_DIG ? (d)/BASE_DIG+1 : (d)/BASE_DIG) +#define DIG2DEC(d) ((d)*BASE_DIG) + +/*************/ +/* typedefs */ +/*************/ + +typedef long mp[MAX_DIGITS+1]; + /* type mp holds one multi-precision integer*/ + +/* bvs: not yet used */ + +typedef long * mp_t; +typedef long **mp_array; +typedef long ***mp_matrix; + +/*********************/ +/*global variables */ +/*********************/ + +/* max permitted, all checks in mp library assume that + * A is alloc. to this size + * - in fact an mp, even in A, is allocated size MAX_DIGITS + * - so set digits = MAX_DIGITS + */ +extern long digits; +/* this is the biggest achieved so far. */ +extern long record_digits; + +/* convert mp a back to integer in *result, + * bcomplain: give warning to stdout if overflow in conversion. + * return value: set to 1 if overflow, o/w 0 + */ +int mptoi(mp a, int *result, int bcomplain) ; + +/*********************************************************/ +/* Miscellaneous -arithmetic,etc should be hidden */ +/* taken from lrs3.2a, bvs beautified comments */ +/******************************************************* */ + +void atoaa(char in[], char num[], char den[]); + /**< convert rational string in to num/den strings */ +void atomp(char s[], mp a); + /**< convert string to mp integer */ +long comprod(mp Na,mp Nb,mp Nc,mp Nd); + /**< +1 if Na*Nb > Nc*Nd, -1 if Na*Nb < Nc*Nd else 0 */ +void copy(mp a, mp b); + /**< assigns a=b */ +void divint(mp a, mp b, mp c ); + /**< c=a/b, a contains remainder on return */ +void gcd(mp u, mp v); + /**< returns u=gcd(u,v) destroying v */ +long greater(mp a, mp b); + /**< tests if a > b and returns (TRUE=POS) */ +void itomp(long in, mp a); + /**< convert integer i to multiple precision with base BASE */ +void linint(mp a,long ka,mp b,long kb); + /**< compute a*ka+b*kb --> a */ +void lcm(mp a, mp b); + /**< a = least common multiple of a, b; b is preserved */ +int mptoa(mp a, char s[]); + /**< convert mp integer to string, return length */ +void mulint(mp a,mp b,mp c); + /**< multiply two integers a*b --> c */ +void normalize(mp a); + /**< normalize mp after computation */ +void pmp(char name[],mp a); + /**< print the long precision integer a */ +void prat(char name[],mp Nt,mp Dt); + /**< print the long precision rational Nt/Dt */ +void readmp(mp a) ; + /**< read an integer and convert to mp with base BASE */ +long readrat(mp Na, mp Da); + /**< read a rational or integer and convert to mp with base BASE */ +void reduce(mp Na,mp Da); + /**< reduces Na Da by gcd(Na,Da) */ + +void digits_overflow(); + +#endif +/* end of mp.h */ diff --git a/native-algo/lh-vector/path/Makefile b/native-algo/lh-vector/path/Makefile new file mode 100644 index 0000000..a6a98fa --- /dev/null +++ b/native-algo/lh-vector/path/Makefile @@ -0,0 +1,11 @@ +CC = gcc +CFLAGS = -ansi -Wall -O3 -g + +path: path.o + $(CC) path.o $(LDFLAGS) -o path + +path.o: path.c + $(CC) path.c -c $(CFLAGS) -o path.o + +clean: + rm -rf path.o path lh-* \ No newline at end of file diff --git a/native-algo/lh-vector/path/gen-path b/native-algo/lh-vector/path/gen-path new file mode 100755 index 0000000..23e81a9 --- /dev/null +++ b/native-algo/lh-vector/path/gen-path @@ -0,0 +1,11 @@ +#!/bin/sh + +./path < path-input > path-output +cat ../sample-input path-output > lh-input +rm path-output +../inlh -i $1 < lh-input > lh-output + +./path < path-input12 > path-output +cat ../sample-input path-output > lh-input12 +rm path-output +../inlh -i $1 < lh-input12 > lh-output12 \ No newline at end of file diff --git a/native-algo/lh-vector/path/path-input b/native-algo/lh-vector/path/path-input new file mode 100644 index 0000000..e435e4f --- /dev/null +++ b/native-algo/lh-vector/path/path-input @@ -0,0 +1,91 @@ +m= 6 +n= 6 +labels: +7 +6 +8 +4 +6 +5 +9 +7 +5 +6 +4 +8 +10 +4 +6 +5 +7 +6 +8 +2 +4 +8 +6 +7 +5 +3 +7 +6 +8 +4 +6 +5 +11 +9 +5 +6 +4 +8 +6 +7 +3 +5 +7 +6 +8 +4 +2 +8 +6 +7 +5 +6 +4 +10 +12 +4 +6 +5 +7 +6 +8 +2 +4 +8 +6 +7 +5 +3 +7 +6 +8 +4 +6 +5 +9 +7 +5 +6 +4 +8 +10 +4 +6 +5 +7 +6 +8 +1 \ No newline at end of file diff --git a/native-algo/lh-vector/path/path-input12 b/native-algo/lh-vector/path/path-input12 new file mode 100644 index 0000000..91c4659 --- /dev/null +++ b/native-algo/lh-vector/path/path-input12 @@ -0,0 +1,39 @@ +m= 6 +n= 6 +labels: +1 +7 +6 +8 +4 +6 +5 +9 +7 +5 +6 +4 +8 +10 +4 +6 +5 +7 +6 +8 +2 +4 +8 +6 +7 +5 +3 +7 +6 +8 +4 +6 +5 +11 +6 +12 \ No newline at end of file diff --git a/native-algo/lh-vector/path/path.c b/native-algo/lh-vector/path/path.c new file mode 100644 index 0000000..a652937 --- /dev/null +++ b/native-algo/lh-vector/path/path.c @@ -0,0 +1,200 @@ +/* + * path.c + * Converts the standard LH path to an equivalent path + * Author: Tobenna Peter, Igwe ptigwe@gmail.com + */ +#include +#include +#include +#include + +#define Z(i) (i) +#define W(i) (i + ndim) +#define MAXSTR 100 + +int ndim; +int m, n; + +int* basic; +int count; + +/* A list of integer values */ +struct node +{ + int value; + struct node* next; +} +node; + +struct node* root; + +void notimpl (char *info) +{ + fflush(stdout); + fprintf(stderr, "Program terminated with error. %s\n", info); + exit(1); +} + +void readconf (const char *s) +{ + int i, len = strlen(s); + char a[MAXSTR]; + for (i=0; inext->value) <= m) + { + printf("w2\n"); + pivot(var); + printf("w1\n"); + } + else + { + printf("w1\n"); + pivot(var); + printf("w2\n"); + } +} + +int main(int argc, char** argv) +{ + int swap = 1; + char c; + while((c = getopt(argc, argv, "m")) != -1) + { + switch (c) + { + case 'm': + swap = 0; + break; + } + } + readconf("m="); + scanf("%d", &m); + readconf("n="); + scanf("%d", &n); + readconf("labels:"); + ndim = 2+m+n; + + basic = (int*)malloc(ndim * sizeof(int)); + + /*Initialize the array of basic variables*/ + int i; + for(i = 0; i < 2+m+n; i++) + { + basic[i] = W(i+1); + } + + int var; + count = 0; + + /*Swap the last variable for the second*/ + struct node* sec; + + /*read the labels in and store them in a linked list*/ + root = malloc(sizeof(node)); + struct node* next = root; + struct node* prev = root; + while(scanf("%d", &var) != EOF) + { + next->value = var; + next->next = malloc(sizeof(node)); + if(count == swap) + { + /*Let the second element be empty*/ + prev = next; + sec = next; + next->next = malloc(sizeof(node)); + next = next->next; + next->value = var; + next->next = malloc(sizeof(node)); + } + prev = next; + next = next->next; + count++; + } + free(prev->next); + prev->next = NULL; + + sec->value = prev->value; + + /*Delete the last element in the list*/ + prev = root; + next = root; + while(next->next != NULL) + { + prev = next; + next = next->next; + } + free(prev->next); + prev->next = NULL; + + /*Convert and print the new sequence*/ + next = root; + count = 0; + while(next != NULL) + { + if(count == 0) + init(next->value); + else + pivot(next->value); + count++; + + next = next->next; + } + printf("z0\n"); + + free(basic); + return 0; +} \ No newline at end of file diff --git a/native-algo/lh-vector/rat.c b/native-algo/lh-vector/rat.c new file mode 100644 index 0000000..dde42ad --- /dev/null +++ b/native-algo/lh-vector/rat.c @@ -0,0 +1,359 @@ +/** \file rat.c + * + * For the computation of rational numbers. The rat.c file + * contains the implementation of the methods defined in rat.h + * which use mp. + * + * 27 Apr 2000 + * Author: Bernhard von Stengel stengel@maths.lse.ac.uk + * + * Edited: Tobenna Peter, Igwe ptigwe@gmail.com August 2012. + */ + +#include +#include +#include +#include + /* sprintf */ +#include "rat.h" + +/* Creates a rational number from two integers */ +Rat itorat(int num, int den) +{ + Rat r; + itomp(num, r.num); + itomp(den, r.den); + ratreduce(r); + return r; +} + +/* converts integer i to rational */ +/* GSoC12: Tobenna Peter, Igwe (Edited)*/ +Rat ratfromi(int i) +{ + Rat tmp; + /*tmp.num = i; */ + itomp(i, tmp.num); + /*tmp.den = 1; */ + itomp(1, tmp.den); + return tmp; +} + +/* Create a rational number from two mp numbers */ +/* GSoC12: Tobenna Peter, Igwe */ +Rat mptorat(mp num, mp den) +{ + Rat rat; + copy(rat.num, num); + copy(rat.den, den); + return rat; +} + +/* Create a rational number from one mp number */ +/* GSoC12: Tobenna Peter, Igwe */ +Rat ratfrommp(mp num) +{ + mp den; + itomp(1, den); + return mptorat(num, den); +} + +/* Parses a string that of the format "x" and "x/y" +* and returns the equivalent rational numbers */ +/* GSoC12: Tobenna Peter, Igwe */ + Rat parseRat(char* srat, const char* info, int j) +{ + char snum[MAXSTR], sden[MAXSTR]; + mp num, den; + + atoaa(srat, snum, sden); + atomp(snum, num); + if (sden[0]=='\0') + itomp(1, den); + else + { + atomp(sden, den); + if (negative(den) || zero(den)) + { + char str[MAXSTR]; + mptoa(den, str); + fprintf(stderr, "Warning: Denominator "); + fprintf(stderr, "%s of %s[%d] set to 1 since not positive\n", + str, info, j+1); + itomp(1, den); + } + } + Rat r = mptorat(num, den); + return r; +} + +/* Parses a string that of the format "x.y" +* and returns the equivalent rational numbers */ +/* GSoC12: Tobenna Peter, Igwe */ + Rat parseDecimal(char* srat, const char* info, int j) +{ + double x; + int count; + char* sub; + + sscanf(srat, "%lf", &x); + + sub = strchr(srat, '.'); + if(strchr(sub+1, '.') != NULL) + { + fprintf(stderr, "Error: Decimal "); + fprintf(stderr, "%s of %s[%d] has more than one decimal point\n", srat, info, j); + exit(1); + } + count = strlen(sub+1); + + char* str = strtok(srat, "."); + strcat(str, strtok(NULL, ".")); + + /*int num = floor(x * pow(10, count));*/ + mp num; + atomp(str, num); + /*int den = pow(10, count);*/ + int i; + strcpy(str, "10"); + for(i = 1; i < count; ++i) + { + strcat(str, "0"); + } + mp den; + atomp(str, den); + + Rat rat = mptorat(num, den); + return rat; +} + +/* Parses a string that of the format "x", "x/y" and "x.y" +* and returns the equivalent rational numbers */ +/* GSoC12: Tobenna Peter, Igwe */ + Rat ratfroma(char* srat, const char* info, int j) +{ + char* pos; + Rat rat; + + if((pos = strchr(srat, '.')) != NULL) + { + rat = parseDecimal(srat, info, j); + } + else + { + rat = parseRat(srat, info, j); + } + return rat; +} + +/* returns sum a+b, normalized */ +/* GSoC12: Tobenna Peter, Igwe (Edited) */ +Rat ratadd (Rat a, Rat b) +{ + /* + a.num = a.num * b.den + a.den * b.num; + a.den *= b.den; + return ratreduce(a); + */ + + mp num, den, x, y, t; + + /*itomp (a.num, num) ;*/ + copy(num, a.num); + /*itomp (a.den, den) ;*/ + copy(den, a.den); + /*itomp (b.num, x) ;*/ + copy(x, b.num); + /*itomp (b.den, y) ;*/ + copy(y, b.den); + mulint (y, num, t); + copy(num, t); + mulint (den, x, x); + linint (num, 1, x, 1); + mulint (y, den, den); + reduce(num, den) ; + /*mptoi( num, &a.num, 1 ); + mptoi( den, &a.den, 1 );*/ + copy(a.num, num); + copy(a.den, den); + return a ; +} + +/* returns quotient a/b, normalized */ +Rat ratdiv (Rat a, Rat b) +{ + return ratmult(a, ratinv(b) ); +} + +/* returns product a*b, normalized */ +/* GSoC12: Tobenna Peter, Igwe (Edited) */ +Rat ratmult (Rat a, Rat b) +{ + mp x; + + /* avoid overflow in intermediate product by cross-cancelling first + */ + /*x = a.num ; */ + copy(x, a.num); + /*a.num = b.num ;*/ + copy(a.num, b.num); + /*b.num = x ;*/ + copy(b.num, x); + a = ratreduce(a); + b = ratreduce(b); + /*a.num *= b.num;*/ + mulint(a.num, b.num, x); + copy(a.num, x); + /*a.den *= b.den;*/ + mulint(a.den, b.den, x); + copy(a.den, x); + return ratreduce(a); /* a or b might be non-normalized s*/ +} + +/* returns -a, normalized only if a normalized */ +/* GSoC12: Tobenna Peter, Igwe (Edited)*/ +Rat ratneg (Rat a) +{ + /*a.num = - a.num;*/ + changesign(a.num); + return a; +} + +/* normalizes (make den>0, =1 if num==0) +* and reduces by gcd(num,den) +*/ +/* GSoC12: Tobenna Peter, Igwe (Edited) */ +Rat ratreduce (Rat a) +{ + if (zero(a.num)) + { + /*a.den = 1;*/ + itomp(1, a.den); + } + else + { + mp div; + mp c; + if (negative(a.den)) + { + /*a.den = -a.den;*/ + changesign(a.den); + /*a.num = -a.num;*/ + changesign(a.num); + } + /*div = ratgcd(a.den, a.num);*/ + ratgcd(a.den, a.num, div); + /*a.num = a.num/div;*/ + divint(a.num, div, c); + copy(a.num, c); + /*a.den = a.den/div;*/ + divint(a.den, div, c); + copy(a.den, c); + } + return a; +} + +/* computes gcd of integers a and b, 0 if both 0 and stores the value in c*/ +void ratgcd(mp a, mp b, mp c) +{ + mp d; + copy(c, a); + copy(d, b); + gcd(c, d); +} + +/* GSoC12: Tobenna Peter, Igwe (Edited)*/ +Rat ratinv (Rat a) +{ + mp x; + + /*x = a.num ;*/ + copy(x, a.num); + /*a.num = a.den ;*/ + copy(a.num, a.den); + /*a.den = x ;*/ + copy(a.den, x); + return a; +} + +/* returns Boolean condition that a > b */ +Bool ratgreat (Rat a, Rat b) +{ + Rat c = ratadd(a, ratneg(b)); + return (positive(c.num)); +} + +/* returns Boolean condition that a==b +* a, b are assumed to be normalized +*/ +/* GSoC12: Tobenna Peter, Igwe (Edited) */ +Bool ratiseq (Rat a, Rat b) +{ + /*return (a.num == b.num && a.den == b.den);*/ + mp c; + itomp(1, c); + int x = comprod(a.num, c, b.num, c); + int y = comprod(a.den, c, b.den, c); + return ((x == 0) && (y == 0)); +} + +/* Returns the maximum element in an array of n Rat elements */ +/* GSoC12: Tobenna Peter, Igwe */ +Rat maxrow(Rat* rat, int n) +{ + int i; + Rat Mrow = ratfromi(0); + for(i = 0; i < n; ++i) + { + Mrow = ratgreat(Mrow,rat[i]) ? Mrow : rat[i]; + } + return Mrow; +} + +/* Returns the maximum element in an mxn matrix of Rat elements */ +/* GSoC12: Tobenna Peter, Igwe */ +Rat maxMatrix(Rat** rat, int m, int n) +{ + int i; + int tmpm = m; + int tmpn = n; + Rat M = ratfromi(0); + for(i = 0; i < tmpm; ++i) + { + Rat r = maxrow(rat[i], tmpn); + M = ratgreat(M, r) ? M : r; + } + return M; +} + +/* converts rational r to string s, omit den 1 +* s must be sufficiently long to contain result +* returns length of string +*/ +int rattoa (Rat r, char *s) +{ + char str[MAXSTR]; + int l, a; + /* GSoC12: Tobenna Peter, Igwe */ + mptoa(r.num, str); + l = sprintf(s, "%s", str); + if(!one(r.den)) + { + /*a = sprintf(s+l, "/%d", r.den);*/ + mptoa(r.den, str); + a = sprintf(s+l, "/%s", str); + l += a + 1; + } + return l; +} + +/* converts rational a to double */ +/* GSoC12: Tobenna Peter, Igwe (Edited) */ +double rattodouble(Rat a) +{ + /*return (double)a.num/(double)a.den*/ + int num, den; + mptoi(a.num, &num, 1); + mptoi(a.den, &den, 1); + return (double)num / (double)den; +} diff --git a/native-algo/lh-vector/rat.h b/native-algo/lh-vector/rat.h new file mode 100644 index 0000000..f406f29 --- /dev/null +++ b/native-algo/lh-vector/rat.h @@ -0,0 +1,295 @@ +/** \file rat.h + * For the computation of rational numbers. The .h file + * includes definitions for use with both mp and gmp. These + * definitions are seperated with the #ifdef GLEMKE directive + * to avoid a clash in names. + * + * 22 Apr 2000 + * Author: Bernhard von Stengel stengel@maths.lse.ac.uk + * + * Edited: Tobenna Peter, Igwe ptigwe@gmail.com August 2012. + */ +#ifndef RAT_H +#define RAT_H + +#ifdef GLEMKE + +#include "gmp.h" +#include "gmpwrap.h" + +#endif +#include "mp.h" + + +#define MAXSTR 100 + +#ifndef TRUE +#define TRUE 1L +#endif +#ifndef FALSE +#define FALSE 0L +#endif + +typedef int Bool; /* Boolean value 0/1 */ + +/** + * \brief A representation of rational numbers. + * + * A structure which is used to represent rational + * numbers. The numerator and denominator are + * stored as a multiple point precision integer + * using either mp (from mp.h) or gmpt (from gmp.h) + * + */ +typedef struct /* GSoC12: Tobenna Peter, Igwe (Edited) */ +{ + #ifdef GLEMKE + gmpt num; /*!< \brief Numerator. Used if GLEMKE is defined. */ + gmpt den; /*!< \brief Denominator. Used if GLEMKE is defined. */ + #else + mp num; /*!< \brief Numerator. Used if GLEMKE is not defined. */ + mp den; /*!< \brief Denominator. Used if GLEMKE is not defined. */ + #endif +} +Rat; + +#ifdef GLEMKE + +/** + * \brief Initialise a rational number and returns it. + * + * Creates a Rat and initialises the numerator + * and denominator. To be used when creating a rational + * number with gmp. + * This function is only available if GLEMKE is defined. + * + * \return The initialised Rat structure. + * \sa grat.c + */ +/* GSoC12: Tobenna Peter, Igwe */ +Rat ratinit(); + +/** + * \brief Clears the rational number. + * + * Clears the contents of the rational number which + * has gmp type numerator and denominator. + * + * \param rat The rational number to be cleared. + * \sa grat.c + */ +/* GSoC12: Tobenna Peter, Igwe */ +void ratclear(Rat rat); + +#endif + +/** + * Creates a rational number from two integers. + * + * \param num The numerator. + * \param den The denominator. + * \return The rational representation of the two integers + */ +Rat itorat(int num, int den); + +/** + * Converts integer to a rational number. + * This is equivalent to calling itorat(i, 1) + * + * \param i Integer to be converted + * \return The equivalent rational number + * \sa itorat() + */ +Rat ratfromi(int i); + +#ifdef GLEMKE + +/** + * Create a rational number from two gmp numbers. + * The values of numerator and denominator are copied + * over to a rational structure. + * + * \param num The numerator + * \param den The denominator + * \return The equivalent rational number + */ +/* GSoC12: Tobenna Peter, Igwe */ +Rat gmptorat(gmpt num, gmpt den); + +/** + * Create a rational number from one gmp number. + * + * \param a the gmp number to be converted. + * \return The equivalent rational number. + */ +/* GSoC12: Tobenna Peter, Igwe */ +Rat ratfromgmp(gmpt a); + +#else + +/** + * Create a rational number from two mp numbers. + * The values of numerator and denominator are copied + * over to a rational structure. + * + * \param num The numerator + * \param den The denominator + * \return The equivalent rational number + */ +/* GSoC12: Tobenna Peter, Igwe */ +Rat mptorat(mp num, mp den); + +/** + * Create a rational number from one mp number. + * + * \param a the gmp number to be converted. + * \return The equivalent rational number. + */ +/* GSoC12: Tobenna Peter, Igwe */ +Rat ratfrommp(mp a); +#endif + +/** + * Converts an array of characters to a Rat. + * Parses a string that of the format "x", "x/y" and "x.y" + * and returns the equivalent rational numbers. + * + * \param str The array of charcters. + * \param info Some information about str, to allow the + * function print out some information if there was an error. + * \param j The index of the array it is being read into + * so the correct information can be displayed if an error occurs. + */ +/* GSoC12: Tobenna Peter, Igwe */ +Rat ratfroma(char* str, const char* info, int j); + +/** + * Returns the normalised sum of a and b. + * + * \returns The normalised sum of a and b. + */ +Rat ratadd (Rat a, Rat b); + +/** + * Returns the normalised value of a/b. + * + * \returns The normalise value of a/b + */ +Rat ratdiv (Rat a, Rat b); + +/** + * Returns the normalised value of a*b. + * + * \returns The normalised value of a*b + */ +Rat ratmult (Rat a, Rat b); + +/** + * Returns -a. If a is normalised, then -a is normalised otherwise + * the returned value is not normalised. + * + * \returns The value of -a + */ +Rat ratneg (Rat a); + +/** + * Returns the normalised rational number. + * Normalizes (make den>0, =1 if num==0) + * and reduces by gcd(num,den). + * + * \param a Rational number to be normalised. + * \returns The normalised rational number. + */ +Rat ratreduce (Rat a); + +/* GSoC12: Tobenna Peter, Igwe */ +#ifdef GLEMKE +/** + * \brief Computes gcd of two integers. + * Computes the gcd of a and b, 0 if both 0 and stores the value in c. + * + * Note: Used if GLEMKE is defined. + * + * \param a First integer. + * \param b Second integer. + * \param c Destination to store the value of gcd(a,b) + */ +void ratgcd(gmpt a, gmpt b, gmpt c); +#else +/** + * \brief Computes gcd of two integers. + * Computes the gcd of a and b, 0 if both 0 and stores the value in c. + * + * Note: Used if GLEMKE is defined. + * + * \param a First integer. + * \param b Second integer. + * \param c Destination to store the value of gcd(a,b) + */ +void ratgcd(mp a, mp b, mp c); +#endif + +/** + * Returns the value of 1/a. This is normalised if a is normalised. + * + * \param a The rational number + * \returns The inverse of a + */ +Rat ratinv (Rat a); + +/** + * Returns Boolean condition that a > b. + * + * \returns TRUE if a > b otherwise FALSE + */ +Bool ratgreat (Rat a, Rat b); + +/** + * Returns Boolean condition that a==b. + * The values a and b are assumed to be normalized. + * + * \returns TRUE if a > b otherwise FALSE + */ +Bool ratiseq (Rat a, Rat b); + +/** + * Returns the maximum element in an array of n rational elements + * + * \param rat The array of rational numbers + * \param n The length of the array rat. + * \returns The maximum value in rat + */ +/* GSoC12: Tobenna Peter, Igwe */ +Rat maxrow(Rat* rat, int n); + +/** + * Returns the maximum element in an mxn matrix of Rat elements. + * + * \param rat The matrix of rational numbers + * \param m The number of rows + * \param n The number of columns + * \returns The maximum value in rat + */ +/* GSoC12: Tobenna Peter, Igwe */ +Rat maxMatrix(Rat** rat, int m, int n); + +/** + * Converts a rational to a string. + * Omit den == 1, s must be sufficiently long to contain result. + * + * \param r The rational number to be converted + * \param s The array of characters to store the result + * \returns The length of the string + */ +int rattoa (Rat r, char *s); + +/** + * Converts a rational to a double. If an overflow occurs, it is + * reported to the standard output. + * + * \param a The rational number to be converted + * \returns The double value of a + */ +double rattodouble (Rat a); + +#endif \ No newline at end of file diff --git a/native-algo/lh-vector/report/final.pdf b/native-algo/lh-vector/report/final.pdf new file mode 100644 index 0000000000000000000000000000000000000000..600f9e62ee8fc7e3289d93840366268d0a1919f5 GIT binary patch literal 139225 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 Iz!dTS1(l){MF0Q* literal 0 HcmV?d00001 diff --git a/native-algo/lh-vector/report/final/Makefile b/native-algo/lh-vector/report/final/Makefile new file mode 100644 index 0000000..a62a2e4 --- /dev/null +++ b/native-algo/lh-vector/report/final/Makefile @@ -0,0 +1,9 @@ + +all: report.tex + pdflatex report.tex + bibtex report + pdflatex report.tex + pdflatex report.tex + +clean: + -rm -rf *.dvi *.log *.dvi *.aux *.gz *.out *.pdf *.bbl *.blg *.pre \ No newline at end of file diff --git a/native-algo/lh-vector/report/final/computeall.tex b/native-algo/lh-vector/report/final/computeall.tex new file mode 100644 index 0000000..7af1c4e --- /dev/null +++ b/native-algo/lh-vector/report/final/computeall.tex @@ -0,0 +1,80 @@ +\begin{algorithm} + \caption{Compute Equilibria From Node}\label{compnode} + \begin{algorithmic}[1] + \Procedure{Compute Equilibria From Node}{$i, isneg$}\Comment{\small{Computes all equilibria from the current node $i$}} + \If{$isneg$} + \State $cur \gets neg$ \Comment{Set current list as the negatively indexed list} + \State $res \gets pos$ \Comment{Set result list as the positively indexed list} + \Else + \State $cur \gets pos$ \Comment{Set current list as the positively indexed list} + \State $res \gets neg$ \Comment{Set result list as the negatively indexed list} + \EndIf + \\ + \State $cur \gets getNodeAt(cur, i)$ \Comment{Gets the $i$th node in the list} + \State $maxK \gets nrows + ncols$ \Comment{The maximum possible value for the missing label} + \\ + \For{$k2 \gets 1, maxK$} + \If{$cur.link[k2-1] \not= -1$} \Comment{If the equilibrium it is linked with using label $k2$ is known} + \State \textbf{continue} + \EndIf + \\ + \State $copyEquilibrium(cur.eq)$ \Comment{Copy and setup the current equilibrium for computation} + \State $setupEquilibrium()$ + \State $runLemke()$ \Comment{Run Lemke's algorithm to find the next equilibrium} + \\ + \State $eq \gets createEquilibrium()$ \Comment{Create equilibrium using the current information in the tableau} + \State $j \gets addEquilibrium(res, eq)$ \Comment{Add the equilibrium to $res$ and return its location. If + $eq$ already exists in $res$, it returns its location but doesn't add it to $res$} + \\ + \State $cur.link[k2-1] \gets j$ \Comment{Link the two equilibria together using label $k2$} + \State $p \gets getNodeat(res, j)$ + \State $p.link[k2-1] \gets i$ + \EndFor + \EndProcedure + \end{algorithmic} +\end{algorithm} + +\begin{algorithm} + \caption{Compute all Equilibrium Reachable from the Artificial Equilibrium}\label{compall} + \begin{algorithmic}[1] + \Procedure{Compute All Equilibria}{} \Comment{\small{}} + \State $maxK \gets nrows + ncols$ + \State $neg = newnode(maxK)$ \Comment{Create the two lists with the total number of strategies} + \State $pos = newnode(maxK)$ + \State $isqdok()$ \Comment{Check if the LCP is valid and generate the tableau} + \State $filltableau()$ + \\ + \State $eq \gets createEquilibrium()$ \Comment{Create the Artificial Equilibrium from the current tableau} + \State $neg.eq \gets eq$ \Comment{Set $neg[0]$ to the Artificial Equilibrium} + \State $runLemke()$ \Comment{Run Lemke's algorithm to find the first positively indexed Equilibrium} + \State $eq \gets createEquilibrium()$ + \\ + \State $pos.eq \gets eq$ + \State $neg.link[0] \gets 0$ \Comment{Link the two equilibria using label 1} + \State $pos.link[0] \gets 0$ + \\ + \State $negi \gets 1$ \Comment{Stores its location in the list of negatively indexed Equilibria} + \State $posi \gets 1$ \Comment{Stores its location in the list of positively indexed Equilibria} + \State $isneg \gets \textbf{FALSE}$ \Comment{Stores if it is currently restarting from a negatively indexed Equilibrium} + \\ + \While{\textbf{TRUE}} + \If{$isneg$} + \While{$negi < listlength(neg)$} + \State $computeEquilibriaFromNode(negi, isneg)$ + \State $negi$++ + \EndWhile + \Else + \While{$posi < listlength(pos)$} + \State $computeEquilibriaFromNode(posi, isneg)$ + \State $posi$++ + \EndWhile + \EndIf + \State $isneg = !isneg$ + \\ + \If{$(negi == listlength(neg))$ \& $(posi == listlength(pos))$} + \State \textbf{break} + \EndIf + \EndWhile + \EndProcedure + \end{algorithmic} +\end{algorithm} \ No newline at end of file diff --git a/native-algo/lh-vector/report/final/img/img0.pdf b/native-algo/lh-vector/report/final/img/img0.pdf new file mode 100644 index 0000000000000000000000000000000000000000..6a0477a57635f37f28c0d252ee308eecc21d88e0 GIT binary patch literal 7562 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 literal 0 HcmV?d00001 diff --git a/native-algo/lh-vector/report/final/img/img1.pdf b/native-algo/lh-vector/report/final/img/img1.pdf new file mode 100644 index 0000000000000000000000000000000000000000..d596e5db16d4c1fd19d0ec975a98cb2594a9e8c0 GIT binary patch literal 8299 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 literal 0 HcmV?d00001 diff --git a/native-algo/lh-vector/report/final/implementation.tex b/native-algo/lh-vector/report/final/implementation.tex new file mode 100644 index 0000000..ee1e612 --- /dev/null +++ b/native-algo/lh-vector/report/final/implementation.tex @@ -0,0 +1,101 @@ +\section{Implementation} +\subsection{Restarting from an Equilibrium} +Once the first set of positively indexed equilibria has been +computed, the next step involves searching for other equilibria +from the already computed ones. This involves restarting from one of +the computed equilibrium, by choosing a covering vector and +pivoting in $z_0$. When an equilibrium has been computed, +the tableau column which represents the covering vector has +been changed and a new covering vector would need to be +computed which would be able to match the information in the +tableau. + +The method used to compute the new covering vector is the +first method which is explained by Berhnard in his documentation +of Lemke's algorithm \cite{doculemke}. +This involves the computation of +$A_B^{-1}$ for the set of basic variables in $B$, where $A$ is +the tableau which represents the current equilibrium. The column +$i$ in $A_B^{-1}$ is given by the column of $w_i$ if $w_i$ is +non-basic, or by the column $x$ such that: +$x = +\begin{pmatrix} + 0 & 0 & \cdots & det & \cdots & 0 & 0 & +\end{pmatrix}^\mathsf{T}$ +where $det$ is the determinant of the tableau, and $x[l]$ is +equal to $det$ if $l$ is the row of $w_i$, or 0 otherwise. + +The covering vector $d$ which represents a missing label $k$ is +given by +\[d = +\begin{pmatrix} + 1 & 1 & \cdots & 0 & \cdots & 1 & 1 & +\end{pmatrix}^\mathsf{T}\] +such that $d[i] = 0$ if $i = k$ otherwise $d[i] = 0$. Once the +values of $d$ and $A_B^{-1}$ have been computed, the new +covering vector $d'$ is calculated as $A_B^{-1}d$. The new +covering vector $d'$ can then be substituted in the tableau for +the column for $z_0$. + +\subsection{Bi-partite Graph} +The bi-partite graph containing the equilibria of a game is +represented in the program by two linked list, one containing +all the negatively indexed equilibria, and the second has as +its elements all the positively indexed equilibria. Each node in +a linked list stores three values; the equilibrium represented +at that node, the list of equilibria the current equilibria is +connected with a given missing label, and the next element in +the list. By storing each partition of the graph as a list, +we can easily get the $i$-th equilibrium in a list containing +$n$ elements, where $0 \leq i < n$, by using the value for +next in each node until the $i$-th node has been found. + +Each equilibrium found is stored as the tableau which represents +the equilibrium. By doing so the equilibrium for the given +node can be copied into the variables used for computation of the +new equilibrium. + +The list of equilibria which can be gotten from the current equilibria +using a set of missing labels is stored as an integer array \verb|link| +where the $k$-th element of the array $l$, is the location of the +equilibrium the current equilibrium is linked to in the opposite +list by the missing label $k-1$. + +The bi-partite graph is computed using an algorithm similar to the +Breadth First Search (BFS) to compute all equilibria reachable from +the artificial equilibrium which is listed in Algorithm \ref{compall}. +\input{computeall} + +Starting from the artificial equilibrium which is stored in \verb|neg[0]|, +it first computes the first positively indexed equilibrium by using the +missing label 1, stores the resulting equilibrium in \verb|pos[0]| and +and links both nodes by setting the first element of both links to 0 +(i.e. \verb|neg->link[0] = 0| and \verb|pos->link[0] = 0|). It then makes +a call to compute all the equilibrium from the first node of the negatively +indexed equilibria (i.e. the artificial equilibrium). Once all the first set +of positively linked equilibria have been calculated, it sets \verb|negi| to +1 and \verb|posi| to 0. The value of \verb|negi| is used to store the location +of the next negatively indexed equilibrium to restart from, the same goes for +\verb|posi| but for positively indexed equilibrium, \verb|isneg| is also set to +FALSE (0), to represent that we are going to be restarting from a positively indexed +equilibrium. + +The algorithm then loops through the following steps until the condition +that \verb|negi| equals the number of negatively indexed equilibria, and +\verb|posi| equals the number of positively indexed equilibria, indicating +that there are no longer any equilibria which can be found.found. + +If \verb|isneg| is FALSE, it loops through values of \verb|posi| until \verb|posi| +is equal to the length of \verb|pos|. For each value of \verb|posi| it computes +all the negatively indexed equilibria which are reachable from the \verb|posi|-th +positively indexed equilibrium, storing any new equilibrium found to \verb|neg| +and linking the current equilibrium with the equilibrium found using the label it +was found with. After each step, \verb|posi| is incremented by 1.found. + +If \verb|isneg| is TRUE, the process is the same as the above paragraph, but +with \verb|negi| instead of \verb|posi|, \verb|neg| instead of \verb|pos| and +\verb|pos| instead of \verb|neg|. + +Upon completion of the loop, the values of \verb|negi| and \verb|posi| would +store the number of negatively indexed and positively indexed equilibria found +respectively. \ No newline at end of file diff --git a/native-algo/lh-vector/report/final/intro.tex b/native-algo/lh-vector/report/final/intro.tex new file mode 100644 index 0000000..ad01931 --- /dev/null +++ b/native-algo/lh-vector/report/final/intro.tex @@ -0,0 +1,9 @@ +\section{Introduction} +The main aim of this report, is to show the progress made since the +midterm evaluations. By the midterm evaluations, the software was +able to compute the first set of positively indexed equilibrium gotten +from the artificial equilibrium. A complete report of the progress made +can be found at \url{http://www.csc.liv.ac.uk/~cs0tpi/GSOC/mideval.pdf}. +In this report, an explanation of the navigation of the bipartite graph +of all possible equilibria reachable is provided. Subsequent to these are +observations and testing. \ No newline at end of file diff --git a/native-algo/lh-vector/report/final/observ.tex b/native-algo/lh-vector/report/final/observ.tex new file mode 100644 index 0000000..8412da0 --- /dev/null +++ b/native-algo/lh-vector/report/final/observ.tex @@ -0,0 +1 @@ +\section{Observations} diff --git a/native-algo/lh-vector/report/final/ref.bib b/native-algo/lh-vector/report/final/ref.bib new file mode 100644 index 0000000..33b81b1 --- /dev/null +++ b/native-algo/lh-vector/report/final/ref.bib @@ -0,0 +1,15 @@ + +@url{doculemke, + Author = {Berhnard von Stengel}, + Date-Added = {2012-08-20 13:30:31 +0100}, + Date-Modified = {2012-08-20 13:31:51 +0100}, + Year = 2012, + Title = {Implementation of Lemke's algorithm \url{www.csc.liv.ac.uk/~cs0tpi/GSOC/doculemke.pdf}}} + +@phdthesis{rahul, + Author = {Rahul Savani}, + Date-Added = {2012-08-20 13:25:29 +0100}, + Date-Modified = {2012-08-20 13:30:21 +0100}, + School = {London School of Economics}, + Title = {Finding Nash Equilibria of Bimatrix Games}, + Year = {2006}} diff --git a/native-algo/lh-vector/report/final/report.tex b/native-algo/lh-vector/report/final/report.tex new file mode 100644 index 0000000..7948f7c --- /dev/null +++ b/native-algo/lh-vector/report/final/report.tex @@ -0,0 +1,45 @@ +% 26 May 2012 +\documentclass[a4paper,12pt]{article} %% important: a4paper first +% \pdfoutput=1 +\usepackage{mathptmx} +\usepackage{epsf} +\usepackage{amssymb} +\usepackage{amsmath} +\usepackage{bbold} +\usepackage{graphicx} +\usepackage{hyperref} +\usepackage{algorithm} +\usepackage{algpseudocode} +\usepackage{asymptote} +\usepackage{pict2e} +\usepackage{xcolor} + +\oddsidemargin=.46cm % A4 +\textwidth=15cm +\textheight=23.3cm +\topmargin=-1.3cm +\clubpenalty=10000 +\widowpenalty=10000 +\predisplaypenalty=1350 +\newdimen\einr +\einr2em + +\setlength\fboxrule{0pt} + +% \parindent0pt +\parskip1ex + +\title{Final Evaluation Report} + +\author{Tobenna Peter, Igwe\\ \small{\url{http://www.github.com/ptigwe/lh-vector}}} + +\date{\today} + +\begin{document} + \maketitle + \input{intro} + \input{implementation} + \input{testing} + \bibliography{ref} + \bibliographystyle{plain} +\end{document} \ No newline at end of file diff --git a/native-algo/lh-vector/report/final/testing.tex b/native-algo/lh-vector/report/final/testing.tex new file mode 100644 index 0000000..354878c --- /dev/null +++ b/native-algo/lh-vector/report/final/testing.tex @@ -0,0 +1,128 @@ +\section{Testing} +Bash scripts have been written to aid with the testing of the program, +which can be found in the \verb|test| folder. Some of the games are tested +by hand and cross-checked using existing pieces of software, and methods +such as best response diagrams. Amongst the games chosen for the test cases +are identity games (in \verb|test/identity|), $\Gamma(d \times d)$ and +$\Gamma(d \times 2d)$ dual cyclic polytopes, and some other games. + +Most of the automated tests for path and path lengths, have two similar +file names, \verb|*m1| and \verb|*m2| these files run the specified +test using method 1 and method 2 of initialisation for the Lemke's algorithm. + +For automated testing of identity matrix games, the size of the game to be tested +is required as an argument of the bash script which runs the test. The script then +generates the game, and the first set of paths from the artificial equilibrium, +and tests to see if the paths generated for the given missing labels, are the same +as the paths computed by the program. + +The same method for testing applies to $\Gamma(d\times d)$ dual-cyclic polytope +games, where the paths are generated and checked to see if it is the same +equivalent path which the program computed. The Maple script provided by Rahul +Savani used to generate +the dual-cyclic polytope games is available at \verb|test/dualcyclic/thesis.mws|. +Some sample games which were generated by the Maple script have also been provided, +and are used in the tests. In addition to testing the paths, another test case was +added to confirm that the equilibrium found by the program was a unique equilibrium. + +In testing the $\Gamma(d \times 2d)$ dual-cyclic polytope games, the path length of +the first couple of pivots from the artificial equilibrium was tested using already known +values for the length of the path \cite{rahul}. The paths of the $(2 \times 4)$ game was computed +using the manipulation of bit strings and is also provided +(\verb|test/dualcyclic/dx2d/2x4bit|). + +Other tests were carried out using best response diagrams to find the equilibria +reachable by Lemke-Howson, and compare with the results gotten from the program. +Some of these tests can be found in the figures that are attached below. + +The game in Figure \ref{uniqeq} contains exactly one equilibrium, which is +reached from the artificial equilibrium using all the strategies 1 through +6. The game shown in Figure \ref{oneeq} contains three different Nash +Equilibrium, but only one equilibrium the pure strategy +$ +\begin{pmatrix} + (0 & 0 & 1) &(0 & 0 & 1) +\end{pmatrix} +$ +\fbox{ +\begin{picture}(0,0) + \color{blue}\put(0,5){\circle*{7}} +\end{picture}} +is reachable with the Lemke-Howson algorithm. Finally, the game represented +in Figure \ref{multeq}, has 5 Nash Equilibria all of which can be found +with the Lemke-Howson algorithm. Using the missing labels 1 through 6 from +the artificial equilibrium, we get the following equilibria. +\begin{itemize} + \item Labels 1 and 4 leads to equilibrium + \fbox{ + \begin{picture}(0,0) + \color{red}\put(0,5){\circle*{7}} + \end{picture}} + \item Labels 2 and 5 leads to equilibrium + \fbox{ + \begin{picture}(0,0) + \color{green}\put(0,5){\circle*{7}} + \end{picture}} + \item Labels 3 and 6 leads to equilibrium + \fbox{ + \begin{picture}(0,0) + \color{yellow}\put(0,5){\circle*{7}} + \end{picture}} + \item Restarting from equilibrium + \fbox{ + \begin{picture}(0,0) + \color{red}\put(0,5){\circle*{7}} + \end{picture}} + with labels 2, 3, 5, 6 leads to + \fbox{ + \begin{picture}(0,0) + \color{blue}\put(0,5){\circle*{7}} + \end{picture}} + \item Restarting from equilibrium + \fbox{ + \begin{picture}(0,0) + \color{green}\put(0,5){\circle*{7}} + \end{picture}} + with labels 1, 4 leads to + \fbox{ + \begin{picture}(0,0) + \color{blue}\put(0,5){\circle*{7}} + \end{picture}} + \item Restarting from equilibrium + \fbox{ + \begin{picture}(0,0) + \color{green}\put(0,5){\circle*{7}} + \end{picture}} + with labels 3, 6 leads to + \fbox{ + \begin{picture}(0,0) + \color{purple}\put(0,5){\circle*{7}} + \end{picture}} + \item Restarting from equilibrium + \fbox{ + \begin{picture}(0,0) + \color{yellow}\put(0,5){\circle*{7}} + \end{picture}} + with labels 1, 2, 4, 5 leads to + \fbox{ + \begin{picture}(0,0) + \color{purple}\put(0,5){\circle*{7}} + \end{picture}} +\end{itemize} + +\begin{figure}[tbh] + \caption{$3 \times 3$ Game}\label{uniqeq} + \includegraphics[width=\textwidth]{img/img1.pdf} +\end{figure} + +\begin{center} + \begin{figure}[tbh] + \caption{$3 \times 3$ Game}\label{oneeq} + \includegraphics[width=\textwidth]{img/img0.pdf} + \end{figure} +\end{center} + +\begin{figure}[tbh] + \caption{$3 \times 3$ Game}\label{multeq} + \includegraphics[width=\textwidth]{img/img2.pdf} +\end{figure} diff --git a/native-algo/lh-vector/report/mideval.pdf b/native-algo/lh-vector/report/mideval.pdf new file mode 100644 index 0000000000000000000000000000000000000000..8b04a90b3ebab7a41ba17c36ece468bcab6e7704 GIT binary patch literal 130233 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%0D2!~5E3b9|^oiPk8tgtXPzX{9x=(Y=4U*}Q_ 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 BYMuZ9 literal 0 HcmV?d00001 diff --git a/native-algo/lh-vector/report/summary/Makefile b/native-algo/lh-vector/report/summary/Makefile new file mode 100644 index 0000000..37b161a --- /dev/null +++ b/native-algo/lh-vector/report/summary/Makefile @@ -0,0 +1,7 @@ + +all: summary.tex + pdflatex summary.tex + pdflatex summary.tex + +clean: + -rm -rf *.dvi *.log *.dvi *.aux *.gz *.out *.pdf *.bbl *.blg *.pre \ No newline at end of file diff --git a/native-algo/lh-vector/report/summary/summary.tex b/native-algo/lh-vector/report/summary/summary.tex new file mode 100644 index 0000000..c8ecc94 --- /dev/null +++ b/native-algo/lh-vector/report/summary/summary.tex @@ -0,0 +1,162 @@ +% 26 May 2012 +\documentclass[a4paper,12pt]{article} %% important: a4paper first +% \pdfoutput=1 +\usepackage{mathptmx} +\usepackage{epsf} +\usepackage{amssymb} +\usepackage{amsmath} +\usepackage{bbold} +\usepackage{graphicx} +\usepackage{hyperref} +\usepackage{algorithm} +\usepackage{algpseudocode} +\usepackage{asymptote} +\usepackage{pict2e} +\usepackage{xcolor} + +\oddsidemargin=.46cm % A4 +\textwidth=15cm +\textheight=23.3cm +\topmargin=-1.3cm +\clubpenalty=10000 +\widowpenalty=10000 +\predisplaypenalty=1350 +\newdimen\einr +\einr2em + +\setlength\fboxrule{0pt} + +% \parindent0pt +\parskip1ex + +\title{Summary Report} + +\author{Tobenna Peter, Igwe\\ \small{\url{http://www.github.com/ptigwe/lh-vector}}} + +\date{\today} + +\begin{document} + \maketitle + \section{Introduction} + Through out the course of this project, the computation of all equilibria reachable + from the artificial equilibrium with the Lemke-Howson algorithm using covering + vectors has been implemented. The project was built upon Berhnard von Stengel's + implementation of Lemke's algorithm in Linear Complementarity Problems (LCP) from + \url{http://www.github.com/stengel/ecta2002}. This + report provides a brief summary of how system that was implemented, and some of + the observations which were made. + + \section{Implementation} + Minor changes were made to the underlying implementation of Lemke's algorithm + which were mainly the way it represented rational numbers. The functionality + of computing rational numbers having the numerator and denominator integers + of large numbers was added using the GNUMP library as well as the multiple + precision (\verb|mp.h|) files provided by Berhnard. + + The algorithm used to navigate the bi-partite graph of equilibria, is similar + to the Breadth First Search(BFS) algorithm. Starting from the artificial + equilibrium, for each missing label $k$ in ${1 \cdots m+n}$ in a given + $m \times n$ game, it computes the equilibrium by computing the + value of the covering vector $d$ which represents the missing label and + following a set of pivoting rules. All computed equilibrium are stored as nodes + in the bi-partite graph, and the labels are used as the edges linking the two + equilibria (i.e the equilibrium started from and the computed equilibrium). + For every equilibrium $e$ found, the algorithm then tries to compute the + equilibria which can be found from $e$. When restarting from $e$, for all + missing labels $k'$ in ${1 \cdots m+n}$, if there is an an edge from $e$ to + an already computed equilibrium using $k'$, then restarting from $e$ using the + missing label $k'$ is skipped to avoid backward computation. Otherwise, the + covering vector $d'$ which represents $k'$ is computed and inserted into the + tableau, $z_0$ is pivoted, and Lemke's algorithm finds a new equilibrium, $e'$ + which is added to the graph and linked with $e$ using label $k'$. Note that + all equilibrium in the first set of equilibrium are restarted from before any + equilibrium in the second set, and so on. + + The algorithm terminates when there is a given set of equilibrium such that + no new equilibrium can be computed from it (i.e. when restarting from such + an equilibrium, for all missing labels $k'$, there exists a link from the + equilibrium to an already computed equilibrium). + + \section{Testing and Observations} + The test cases used can be found in the folder \verb|test|. These include + identity matrix games and dual-cyclic polytope games. It also includes testing + rational and decimal input system. A bash script which runs all the tests is + available at \verb|test/testall|, and accepts one argument, which is the + size of the identity matrix game to be tested. Some other test cases were + done using best response diagrams and can be found in the final report + (\url{http://www.csc.liv.ac.uk/~cs0tpi/GSOC/final.pdf}). + + While testing some of the games, it was noticed that in some cases the + path length ended up being had 4 extra pivots instead of 3 extra pivots to + the LH-path. This was mainly noticed with $\Gamma(d \times 2d)$ dual-cyclic + polytope games, for missing labels whose path lengths were odd numbers. + + \section{Input and Output} + \subsection{Input} + The program receives as its input a 2-player bi-matrix game in the format\\ + \[ + \begin{matrix} + m= & ?\\ + n= & ?\\ + A=\\ + &\ddots\\ + B=\\ + &\ddots\\ + \end{matrix}\] + where $A$ and $B$ are the payoff matrices for player 1 and 2 respectively. + For example, for a $2 \times 2$ identity matrix game, the input would be: + \[ + \begin{matrix} + m= & 2\\ + n= & 2\\ + A=\\ + 1 & 0\\ + 0 & 1\\ + B=\\ + 1 & 0\\ + 0 & 1\\ + \end{matrix} + \] + \subsection{Output} + The output provided can be split into two parts, the LH-path and the + bi-partite graph. + + As the program is computing the path from a given equilibrium, it + first prints out the tableau representing the current equilibrium + which it is starting from, followed by the set of pivot steps, and + finally the tableau representing the current equilibrium. If the + program is run with the verbose flag (\verb|-v|), it prints out + the tableau after every pivot step. + + Following the information of the LH-path, is the information of the + bipartite graph. This is of the following format: + \flushleft{ + \[ + \begin{matrix} + \textsf{Equilibria discovered:} & x\\ + \textsf{y-ve index:}\\ + \textsf{Eq[0]:}& \cdots\\ + \textsf{Leads to:} & \cdots k \verb|->| i \cdots\\ + \vdots\\ + \textsf{Eq[y-1]:} &\cdots\\ + \textsf{Leads to:} & \cdots k \verb|->| i \cdots\\ + \\ + \textsf{z-ve index:}\\ + \textsf{Eq[0]:}& \cdots\\ + \textsf{Leads to:} & \cdots k \verb|->| i \cdots\\ + \vdots\\ + \textsf{Eq[z-1]:} &\cdots\\ + \textsf{Leads to:} & \cdots k \verb|->| i \cdots\\ + \end{matrix} + \]} + where the program found $x$ equilibria excluding the artificial equilibrium, + of which $y$ have a negative index, and $z$ have a positive index. For each + equilibrium, the strategy is printed out in form of fractions, containing both + player 1 and 2's strategies. It also shows how the equilibria are linked together, + and for every value of the missing label $k$, it shows the current equilibrium + is linked to some other equilibrium with location $i$ in the opposite list. For + example, if we had $2 \verb|->| 1$, and the current equilibrium is \verb|Eq[2]|, + and it is negatively indexed, then the missing label 2 would lead us to the equilibrium + \verb|Eq[1]|. + +\end{document} \ No newline at end of file diff --git a/native-algo/lh-vector/sample-input b/native-algo/lh-vector/sample-input new file mode 100644 index 0000000..df11106 --- /dev/null +++ b/native-algo/lh-vector/sample-input @@ -0,0 +1,16 @@ +m= 6 +n= 6 +A= +-180 72 -333 297 -153 270 +-30 17 -33 42 -3 20 +-81 36 -126 126 -36 90 + 90 -36 126 -126 36 -81 + 20 -3 42 -33 17 -30 +270 -153 297 -333 72 -180 +B= + 72 36 17 -3 -36 -153 +-180 -81 -30 20 90 270 +297 126 42 -33 -126 -333 +-333 -126 -33 42 126 297 +270 90 20 -30 -81 -180 +-153 -36 -3 17 36 72 diff --git a/native-algo/lh-vector/sample-output b/native-algo/lh-vector/sample-output new file mode 100644 index 0000000..04f72b8 --- /dev/null +++ b/native-algo/lh-vector/sample-output @@ -0,0 +1,1047 @@ +After filltableau: +Determinant: -1 +var z0 z1 z2 z3 z4 z5 z6 z7 z8 z9 z10 z11 z12 z13 z14 RHS +scfa 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + +w1 1 . . 1 1 1 1 1 1 . . . . . . -1 +w2 1 . . . . . . . . 1 1 1 1 1 1 -1 +w3 . -1 . . . . . . . 478 226 631 1 451 28 . +w4 1 -1 . . . . . . . 328 281 331 256 301 278 . +w5 1 -1 . . . . . . . 379 262 424 172 334 208 . +w6 1 -1 . . . . . . . 208 334 172 424 262 379 . +w7 1 -1 . . . . . . . 278 301 256 331 281 328 . +w8 1 -1 . . . . . . . 28 451 1 631 226 478 . +w9 1 . -1 226 478 1 631 28 451 . . . . . . . +w10 1 . -1 262 379 172 424 208 334 . . . . . . . +w11 1 . -1 281 328 256 331 278 301 . . . . . . . +w12 1 . -1 301 278 331 256 328 281 . . . . . . . +w13 1 . -1 334 208 424 172 379 262 . . . . . . . +w14 1 . -1 451 28 631 1 478 226 . . . . . . . +-----------------end of tableau----------------- +leaving: w2 entering: z0 +leaving: w9 entering: z2 +leaving: w1 entering: z9 +leaving: w3 entering: z1 +leaving: w8 entering: z3 +leaving: w10 entering: z8 +leaving: w6 entering: z10 +leaving: z8 entering: z6 +leaving: w7 entering: w8 +leaving: w11 entering: z7 +leaving: z9 entering: z11 +leaving: z7 entering: w9 +leaving: w8 entering: w7 +leaving: z6 entering: z8 +leaving: z10 entering: w6 +leaving: w12 entering: w10 +leaving: w6 entering: z12 +leaving: z8 entering: z6 +leaving: w7 entering: w8 +leaving: w9 entering: z7 +leaving: w8 entering: z9 +leaving: w10 entering: z8 +leaving: w4 entering: z10 +leaving: z6 entering: z4 +leaving: z10 entering: w6 +leaving: z8 entering: w10 +leaving: z9 entering: w8 +leaving: z7 entering: w9 +leaving: w5 entering: w7 +leaving: w9 entering: z5 +leaving: w8 entering: z9 +leaving: w10 entering: z8 +leaving: w6 entering: z10 +leaving: z8 entering: z6 +leaving: w7 entering: w8 +leaving: w13 entering: z7 +leaving: z11 entering: z13 +leaving: z7 entering: w11 +leaving: w8 entering: w7 +leaving: z6 entering: z8 +leaving: z10 entering: w6 +leaving: z8 entering: w10 +leaving: z9 entering: w8 +leaving: z5 entering: w9 +leaving: w7 entering: w5 +leaving: w9 entering: z7 +leaving: w8 entering: z9 +leaving: w10 entering: z8 +leaving: w6 entering: z10 +leaving: z4 entering: z6 +leaving: z10 entering: w4 +leaving: z8 entering: w10 +leaving: z9 entering: w8 +leaving: z7 entering: w9 +leaving: w8 entering: w7 +leaving: z6 entering: z8 +leaving: z12 entering: w6 +leaving: w14 entering: w12 +leaving: w6 entering: z14 +leaving: z8 entering: z6 +leaving: w7 entering: w8 +leaving: w9 entering: z7 +leaving: w8 entering: z9 +leaving: w10 entering: z8 +leaving: w4 entering: z10 +leaving: z6 entering: z4 +leaving: z10 entering: w6 +leaving: z8 entering: w10 +leaving: z9 entering: w8 +leaving: z7 entering: w9 +leaving: w5 entering: w7 +leaving: w9 entering: z5 +leaving: w8 entering: z9 +leaving: w10 entering: z8 +leaving: w6 entering: z10 +leaving: z8 entering: z6 +leaving: w7 entering: w8 +leaving: w11 entering: z7 +leaving: z9 entering: z11 +leaving: z7 entering: w9 +leaving: w8 entering: w7 +leaving: z6 entering: z8 +leaving: z10 entering: w6 +leaving: w12 entering: w10 +leaving: w6 entering: z12 +leaving: z8 entering: z6 +leaving: w7 entering: w8 +leaving: w9 entering: z7 +leaving: w8 entering: z9 +leaving: w10 entering: z8 +leaving: z0 entering: z10 +Final tableau: +Determinant: 7473389062500 +var w2 w3 w13 w5 w10 w9 w12 w11 w14 w1 w4 w7 w6 w8 z0 RHS +scfa 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + +z13 -249112968750 -570191906250 . 4954580156250 . . . . . . -11110438406250 9815050968750 -3349185468750 260184656250 -321078937500 249112968750 +z10 -249112968750 260184656250 . -3349185468750 . . . . . . 9815050968750 -11110438406250 4954580156250 -570191906250 509297625000 249112968750 +z1 -2215859857031250 249112968750 . 1245564843750 . . . . . . 2242016718750 2242016718750 1245564843750 249112968750 2208635580937500 2215859857031250 +z12 -2242016718750 514833468750 . -5231372343750 . . . . . . 12106890281250 -10313276906250 3072393281250 -149467781250 2756850187500 2242016718750 +z9 -1245564843750 636622031250 . -7611785156250 . . . . . . 20676376406250 -21174602343750 8165369531250 -691980468750 1882186875000 1245564843750 +z14 -1245564843750 -691980468750 . 8165369531250 . . . . . . -21174602343750 20676376406250 -7611785156250 636622031250 553584375000 1245564843750 +z11 -2242016718750 -149467781250 . 3072393281250 . . . . . . -10313276906250 12106890281250 -5231372343750 514833468750 2092548937500 2242016718750 +z3 . . 4954580156250 . -3349185468750 260184656250 -11110438406250 9815050968750 -570191906250 -249112968750 . . . . 249112968750 249112968750 +z2 . . 1245564843750 . 1245564843750 249112968750 2242016718750 2242016718750 249112968750 -2215859857031250 . . . . 2208386467968750 2215859857031250 +z4 . . 8165369531250 . -7611785156250 636622031250 -21174602343750 20676376406250 -691980468750 -1245564843750 . . . . 1245564843750 1245564843750 +z5 . . 3072393281250 . -5231372343750 514833468750 -10313276906250 12106890281250 -149467781250 -2242016718750 . . . . 2242016718750 2242016718750 +z6 . . -5231372343750 . 3072393281250 -149467781250 12106890281250 -10313276906250 514833468750 -2242016718750 . . . . 2242016718750 2242016718750 +z7 . . -7611785156250 . 8165369531250 -691980468750 20676376406250 -21174602343750 636622031250 -1245564843750 . . . . 1245564843750 1245564843750 +z8 . . -3349185468750 . 4954580156250 -570191906250 9815050968750 -11110438406250 260184656250 -249112968750 . . . . 249112968750 249112968750 +-----------------end of tableau----------------- +basis= z1 z2 z3 z4 z5 z6 z7 z8 z9 z10 z11 z12 z13 z14 + z= 0 593/2 593/2 1/30 1/6 3/10 3/10 1/6 1/30 1/6 1/30 3/10 3/10 1/30 1/6 + w= 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + + Number of pivots: 91 +P1: 1/30 1/6 3/10 3/10 1/6 1/30 P2: 1/6 1/30 3/10 3/10 1/30 1/6 +After filltableau: +Determinant: -1 +var z0 z1 z2 z3 z4 z5 z6 z7 z8 z9 z10 z11 z12 z13 z14 RHS +scfa 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + +w1 1 . . 1 1 1 1 1 1 . . . . . . -1 +w2 1 . . . . . . . . 1 1 1 1 1 1 -1 +w3 1 -1 . . . . . . . 478 226 631 1 451 28 . +w4 . -1 . . . . . . . 328 281 331 256 301 278 . +w5 1 -1 . . . . . . . 379 262 424 172 334 208 . +w6 1 -1 . . . . . . . 208 334 172 424 262 379 . +w7 1 -1 . . . . . . . 278 301 256 331 281 328 . +w8 1 -1 . . . . . . . 28 451 1 631 226 478 . +w9 1 . -1 226 478 1 631 28 451 . . . . . . . +w10 1 . -1 262 379 172 424 208 334 . . . . . . . +w11 1 . -1 281 328 256 331 278 301 . . . . . . . +w12 1 . -1 301 278 331 256 328 281 . . . . . . . +w13 1 . -1 334 208 424 172 379 262 . . . . . . . +w14 1 . -1 451 28 631 1 478 226 . . . . . . . +-----------------end of tableau----------------- +leaving: w2 entering: z0 +leaving: w14 entering: z2 +leaving: w1 entering: z14 +leaving: w4 entering: z1 +leaving: w3 entering: z4 +leaving: w13 entering: z3 +leaving: w5 entering: z13 +leaving: w9 entering: z5 +leaving: w8 entering: z9 +leaving: w10 entering: z8 +leaving: w6 entering: z10 +leaving: z8 entering: z6 +leaving: w7 entering: w8 +leaving: w11 entering: z7 +leaving: z9 entering: z11 +leaving: z7 entering: w9 +leaving: w8 entering: w7 +leaving: z6 entering: z8 +leaving: z10 entering: w6 +leaving: w12 entering: w10 +leaving: w6 entering: z12 +leaving: z8 entering: z6 +leaving: w7 entering: w8 +leaving: w9 entering: z7 +leaving: w8 entering: z9 +leaving: w10 entering: z8 +leaving: z0 entering: z10 +Final tableau: +Determinant: 7473389062500 +var w2 w4 w14 w13 w3 w9 w10 w11 w12 w7 z0 w8 w6 w5 w1 RHS +scfa 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + +z14 -1245564843750 -21174602343750 . . -691980468750 . . . . 20676376406250 -19929037500000 636622031250 -7611785156250 8165369531250 . 1245564843750 +z10 -249112968750 9815050968750 . . 260184656250 . . . . -11110438406250 10064163937500 -570191906250 4954580156250 -3349185468750 . 249112968750 +z4 . . -691980468750 8165369531250 . 636622031250 -7611785156250 20676376406250 -21174602343750 . 1245564843750 . . . -1245564843750 1245564843750 +z1 -2215859857031250 2242016718750 . . 249112968750 . . . . 2242016718750 2210628484687500 249112968750 1245564843750 1245564843750 . 2215859857031250 +z13 -249112968750 -11110438406250 . . -570191906250 . . . . 9815050968750 -10861325437500 260184656250 -3349185468750 4954580156250 . 249112968750 +z12 -2242016718750 12106890281250 . . 514833468750 . . . . -10313276906250 14348907000000 -149467781250 3072393281250 -5231372343750 . 2242016718750 +z9 -1245564843750 20676376406250 . . 636622031250 . . . . -21174602343750 21921941250000 -691980468750 8165369531250 -7611785156250 . 1245564843750 +z11 -2242016718750 -10313276906250 . . -149467781250 . . . . 12106890281250 -8071260187500 514833468750 -5231372343750 3072393281250 . 2242016718750 +z5 . . -149467781250 3072393281250 . 514833468750 -5231372343750 12106890281250 -10313276906250 . 2242016718750 . . . -2242016718750 2242016718750 +z6 . . 514833468750 -5231372343750 . -149467781250 3072393281250 -10313276906250 12106890281250 . 2242016718750 . . . -2242016718750 2242016718750 +z7 . . 636622031250 -7611785156250 . -691980468750 8165369531250 -21174602343750 20676376406250 . 1245564843750 . . . -1245564843750 1245564843750 +z8 . . 260184656250 -3349185468750 . -570191906250 4954580156250 -11110438406250 9815050968750 . 249112968750 . . . -249112968750 249112968750 +z3 . . -570191906250 4954580156250 . 260184656250 -3349185468750 9815050968750 -11110438406250 . 249112968750 . . . -249112968750 249112968750 +z2 . . 249112968750 1245564843750 . 249112968750 1245564843750 2242016718750 2242016718750 . 2208386467968750 . . . -2215859857031250 2215859857031250 +-----------------end of tableau----------------- +basis= z1 z2 z3 z4 z5 z6 z7 z8 z9 z10 z11 z12 z13 z14 + z= 0 593/2 593/2 1/30 1/6 3/10 3/10 1/6 1/30 1/6 1/30 3/10 3/10 1/30 1/6 + w= 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + + Number of pivots: 27 +P1: 1/30 1/6 3/10 3/10 1/6 1/30 P2: 1/6 1/30 3/10 3/10 1/30 1/6 +After filltableau: +Determinant: -1 +var z0 z1 z2 z3 z4 z5 z6 z7 z8 z9 z10 z11 z12 z13 z14 RHS +scfa 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + +w1 1 . . 1 1 1 1 1 1 . . . . . . -1 +w2 1 . . . . . . . . 1 1 1 1 1 1 -1 +w3 1 -1 . . . . . . . 478 226 631 1 451 28 . +w4 1 -1 . . . . . . . 328 281 331 256 301 278 . +w5 . -1 . . . . . . . 379 262 424 172 334 208 . +w6 1 -1 . . . . . . . 208 334 172 424 262 379 . +w7 1 -1 . . . . . . . 278 301 256 331 281 328 . +w8 1 -1 . . . . . . . 28 451 1 631 226 478 . +w9 1 . -1 226 478 1 631 28 451 . . . . . . . +w10 1 . -1 262 379 172 424 208 334 . . . . . . . +w11 1 . -1 281 328 256 331 278 301 . . . . . . . +w12 1 . -1 301 278 331 256 328 281 . . . . . . . +w13 1 . -1 334 208 424 172 379 262 . . . . . . . +w14 1 . -1 451 28 631 1 478 226 . . . . . . . +-----------------end of tableau----------------- +leaving: w2 entering: z0 +leaving: w9 entering: z2 +leaving: w1 entering: z9 +leaving: w5 entering: z1 +leaving: w8 entering: z5 +leaving: w10 entering: z8 +leaving: w6 entering: z10 +leaving: z8 entering: z6 +leaving: w7 entering: w8 +leaving: w11 entering: z7 +leaving: z9 entering: z11 +leaving: z7 entering: w9 +leaving: w8 entering: w7 +leaving: z6 entering: z8 +leaving: z10 entering: w6 +leaving: w12 entering: w10 +leaving: w6 entering: z12 +leaving: z8 entering: z6 +leaving: w7 entering: w8 +leaving: w9 entering: z7 +leaving: w8 entering: z9 +leaving: w10 entering: z8 +leaving: w4 entering: z10 +leaving: w14 entering: z4 +leaving: w3 entering: z14 +leaving: w13 entering: z3 +leaving: z0 entering: z13 +Final tableau: +Determinant: 7473389062500 +var w2 w5 w9 w13 w14 w7 w10 w11 w12 w1 w4 w8 w6 z0 w3 RHS +scfa 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + +z11 -2242016718750 3072393281250 . . . 12106890281250 . . . . -10313276906250 514833468750 -5231372343750 5314410000000 -149467781250 2242016718750 +z13 -249112968750 4954580156250 . . . 9815050968750 . . . . -11110438406250 260184656250 -3349185468750 5203693125000 -570191906250 249112968750 +z14 -1245564843750 8165369531250 . . . 20676376406250 . . . . -21174602343750 636622031250 -7611785156250 9410934375000 -691980468750 1245564843750 +z10 -249112968750 -3349185468750 . . . -11110438406250 . . . . 9815050968750 -570191906250 4954580156250 -3100072500000 260184656250 249112968750 +z1 -2215859857031250 1245564843750 . . . 2242016718750 . . . . 2242016718750 249112968750 1245564843750 2209632032812500 249112968750 2215859857031250 +z12 -2242016718750 -5231372343750 . . . -10313276906250 . . . . 12106890281250 -149467781250 3072393281250 -2989355625000 514833468750 2242016718750 +z9 -1245564843750 -7611785156250 . . . -21174602343750 . . . . 20676376406250 -691980468750 8165369531250 -6366220312500 636622031250 1245564843750 +z5 . . 514833468750 3072393281250 -149467781250 . -5231372343750 12106890281250 -10313276906250 -2242016718750 . . . 2242016718750 . 2242016718750 +z2 . . 249112968750 1245564843750 249112968750 . 1245564843750 2242016718750 2242016718750 -2215859857031250 . . . 2208386467968750 . 2215859857031250 +z6 . . -149467781250 -5231372343750 514833468750 . 3072393281250 -10313276906250 12106890281250 -2242016718750 . . . 2242016718750 . 2242016718750 +z7 . . -691980468750 -7611785156250 636622031250 . 8165369531250 -21174602343750 20676376406250 -1245564843750 . . . 1245564843750 . 1245564843750 +z8 . . -570191906250 -3349185468750 260184656250 . 4954580156250 -11110438406250 9815050968750 -249112968750 . . . 249112968750 . 249112968750 +z3 . . 260184656250 4954580156250 -570191906250 . -3349185468750 9815050968750 -11110438406250 -249112968750 . . . 249112968750 . 249112968750 +z4 . . 636622031250 8165369531250 -691980468750 . -7611785156250 20676376406250 -21174602343750 -1245564843750 . . . 1245564843750 . 1245564843750 +-----------------end of tableau----------------- +basis= z1 z2 z3 z4 z5 z6 z7 z8 z9 z10 z11 z12 z13 z14 + z= 0 593/2 593/2 1/30 1/6 3/10 3/10 1/6 1/30 1/6 1/30 3/10 3/10 1/30 1/6 + w= 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + + Number of pivots: 27 +P1: 1/30 1/6 3/10 3/10 1/6 1/30 P2: 1/6 1/30 3/10 3/10 1/30 1/6 +After filltableau: +Determinant: -1 +var z0 z1 z2 z3 z4 z5 z6 z7 z8 z9 z10 z11 z12 z13 z14 RHS +scfa 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + +w1 1 . . 1 1 1 1 1 1 . . . . . . -1 +w2 1 . . . . . . . . 1 1 1 1 1 1 -1 +w3 1 -1 . . . . . . . 478 226 631 1 451 28 . +w4 1 -1 . . . . . . . 328 281 331 256 301 278 . +w5 1 -1 . . . . . . . 379 262 424 172 334 208 . +w6 . -1 . . . . . . . 208 334 172 424 262 379 . +w7 1 -1 . . . . . . . 278 301 256 331 281 328 . +w8 1 -1 . . . . . . . 28 451 1 631 226 478 . +w9 1 . -1 226 478 1 631 28 451 . . . . . . . +w10 1 . -1 262 379 172 424 208 334 . . . . . . . +w11 1 . -1 281 328 256 331 278 301 . . . . . . . +w12 1 . -1 301 278 331 256 328 281 . . . . . . . +w13 1 . -1 334 208 424 172 379 262 . . . . . . . +w14 1 . -1 451 28 631 1 478 226 . . . . . . . +-----------------end of tableau----------------- +leaving: w2 entering: z0 +leaving: w14 entering: z2 +leaving: w1 entering: z14 +leaving: w6 entering: z1 +leaving: w3 entering: z6 +leaving: w13 entering: z3 +leaving: w5 entering: z13 +leaving: z3 entering: z5 +leaving: w4 entering: w3 +leaving: w12 entering: z4 +leaving: z14 entering: z12 +leaving: z4 entering: w14 +leaving: w3 entering: w4 +leaving: z5 entering: z3 +leaving: z13 entering: w5 +leaving: w11 entering: w13 +leaving: w5 entering: z11 +leaving: z3 entering: z5 +leaving: w4 entering: w3 +leaving: w14 entering: z4 +leaving: w3 entering: z14 +leaving: w13 entering: z3 +leaving: w7 entering: z13 +leaving: w9 entering: z7 +leaving: w8 entering: z9 +leaving: w10 entering: z8 +leaving: z0 entering: z10 +Final tableau: +Determinant: 7473389062500 +var w2 w6 w14 w11 w12 w13 w4 w9 w10 w8 z0 w5 w3 w7 w1 RHS +scfa 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + +z12 -2242016718750 3072393281250 . . . . 12106890281250 . . -149467781250 5314410000000 -5231372343750 514833468750 -10313276906250 . 2242016718750 +z10 -249112968750 4954580156250 . . . . 9815050968750 . . -570191906250 5203693125000 -3349185468750 260184656250 -11110438406250 . 249112968750 +z6 . . 514833468750 -10313276906250 12106890281250 -5231372343750 . -149467781250 3072393281250 . 2242016718750 . . . -2242016718750 2242016718750 +z14 -1245564843750 -7611785156250 . . . . -21174602343750 . . 636622031250 -6366220312500 8165369531250 -691980468750 20676376406250 . 1245564843750 +z11 -2242016718750 -5231372343750 . . . . -10313276906250 . . 514833468750 -2989355625000 3072393281250 -149467781250 12106890281250 . 2242016718750 +z1 -2215859857031250 1245564843750 . . . . 2242016718750 . . 249112968750 2209632032812500 1245564843750 249112968750 2242016718750 . 2215859857031250 +z13 -249112968750 -3349185468750 . . . . -11110438406250 . . 260184656250 -3100072500000 4954580156250 -570191906250 9815050968750 . 249112968750 +z9 -1245564843750 8165369531250 . . . . 20676376406250 . . -691980468750 9410934375000 -7611785156250 636622031250 -21174602343750 . 1245564843750 +z7 . . 636622031250 -21174602343750 20676376406250 -7611785156250 . -691980468750 8165369531250 . 1245564843750 . . . -1245564843750 1245564843750 +z8 . . 260184656250 -11110438406250 9815050968750 -3349185468750 . -570191906250 4954580156250 . 249112968750 . . . -249112968750 249112968750 +z3 . . -570191906250 9815050968750 -11110438406250 4954580156250 . 260184656250 -3349185468750 . 249112968750 . . . -249112968750 249112968750 +z4 . . -691980468750 20676376406250 -21174602343750 8165369531250 . 636622031250 -7611785156250 . 1245564843750 . . . -1245564843750 1245564843750 +z5 . . -149467781250 12106890281250 -10313276906250 3072393281250 . 514833468750 -5231372343750 . 2242016718750 . . . -2242016718750 2242016718750 +z2 . . 249112968750 2242016718750 2242016718750 1245564843750 . 249112968750 1245564843750 . 2208386467968750 . . . -2215859857031250 2215859857031250 +-----------------end of tableau----------------- +basis= z1 z2 z3 z4 z5 z6 z7 z8 z9 z10 z11 z12 z13 z14 + z= 0 593/2 593/2 1/30 1/6 3/10 3/10 1/6 1/30 1/6 1/30 3/10 3/10 1/30 1/6 + w= 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + + Number of pivots: 27 +P1: 1/30 1/6 3/10 3/10 1/6 1/30 P2: 1/6 1/30 3/10 3/10 1/30 1/6 +After filltableau: +Determinant: -1 +var z0 z1 z2 z3 z4 z5 z6 z7 z8 z9 z10 z11 z12 z13 z14 RHS +scfa 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + +w1 1 . . 1 1 1 1 1 1 . . . . . . -1 +w2 1 . . . . . . . . 1 1 1 1 1 1 -1 +w3 1 -1 . . . . . . . 478 226 631 1 451 28 . +w4 1 -1 . . . . . . . 328 281 331 256 301 278 . +w5 1 -1 . . . . . . . 379 262 424 172 334 208 . +w6 1 -1 . . . . . . . 208 334 172 424 262 379 . +w7 . -1 . . . . . . . 278 301 256 331 281 328 . +w8 1 -1 . . . . . . . 28 451 1 631 226 478 . +w9 1 . -1 226 478 1 631 28 451 . . . . . . . +w10 1 . -1 262 379 172 424 208 334 . . . . . . . +w11 1 . -1 281 328 256 331 278 301 . . . . . . . +w12 1 . -1 301 278 331 256 328 281 . . . . . . . +w13 1 . -1 334 208 424 172 379 262 . . . . . . . +w14 1 . -1 451 28 631 1 478 226 . . . . . . . +-----------------end of tableau----------------- +leaving: w2 entering: z0 +leaving: w9 entering: z2 +leaving: w1 entering: z9 +leaving: w7 entering: z1 +leaving: w8 entering: z7 +leaving: w10 entering: z8 +leaving: w6 entering: z10 +leaving: w14 entering: z6 +leaving: w3 entering: z14 +leaving: w13 entering: z3 +leaving: w5 entering: z13 +leaving: z3 entering: z5 +leaving: w4 entering: w3 +leaving: w12 entering: z4 +leaving: z14 entering: z12 +leaving: z4 entering: w14 +leaving: w3 entering: w4 +leaving: z5 entering: z3 +leaving: z13 entering: w5 +leaving: w11 entering: w13 +leaving: w5 entering: z11 +leaving: z3 entering: z5 +leaving: w4 entering: w3 +leaving: w14 entering: z4 +leaving: w3 entering: z14 +leaving: w13 entering: z3 +leaving: z0 entering: z13 +Final tableau: +Determinant: 7473389062500 +var w2 w7 w9 w11 w12 w13 w14 w8 w10 w1 w6 w5 w3 z0 w4 RHS +scfa 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + +z9 -1245564843750 -21174602343750 . . . . . -691980468750 . . 8165369531250 -7611785156250 636622031250 -19929037500000 20676376406250 1245564843750 +z13 -249112968750 9815050968750 . . . . . 260184656250 . . -3349185468750 4954580156250 -570191906250 10064163937500 -11110438406250 249112968750 +z12 -2242016718750 -10313276906250 . . . . . -149467781250 . . 3072393281250 -5231372343750 514833468750 -8071260187500 12106890281250 2242016718750 +z14 -1245564843750 20676376406250 . . . . . 636622031250 . . -7611785156250 8165369531250 -691980468750 21921941250000 -21174602343750 1245564843750 +z11 -2242016718750 12106890281250 . . . . . 514833468750 . . -5231372343750 3072393281250 -149467781250 14348907000000 -10313276906250 2242016718750 +z10 -249112968750 -11110438406250 . . . . . -570191906250 . . 4954580156250 -3349185468750 260184656250 -10861325437500 9815050968750 249112968750 +z1 -2215859857031250 2242016718750 . . . . . 249112968750 . . 1245564843750 1245564843750 249112968750 2210628484687500 2242016718750 2215859857031250 +z7 . . -691980468750 -21174602343750 20676376406250 -7611785156250 636622031250 . 8165369531250 -1245564843750 . . . 1245564843750 . 1245564843750 +z2 . . 249112968750 2242016718750 2242016718750 1245564843750 249112968750 . 1245564843750 -2215859857031250 . . . 2208386467968750 . 2215859857031250 +z8 . . -570191906250 -11110438406250 9815050968750 -3349185468750 260184656250 . 4954580156250 -249112968750 . . . 249112968750 . 249112968750 +z3 . . 260184656250 9815050968750 -11110438406250 4954580156250 -570191906250 . -3349185468750 -249112968750 . . . 249112968750 . 249112968750 +z4 . . 636622031250 20676376406250 -21174602343750 8165369531250 -691980468750 . -7611785156250 -1245564843750 . . . 1245564843750 . 1245564843750 +z5 . . 514833468750 12106890281250 -10313276906250 3072393281250 -149467781250 . -5231372343750 -2242016718750 . . . 2242016718750 . 2242016718750 +z6 . . -149467781250 -10313276906250 12106890281250 -5231372343750 514833468750 . 3072393281250 -2242016718750 . . . 2242016718750 . 2242016718750 +-----------------end of tableau----------------- +basis= z1 z2 z3 z4 z5 z6 z7 z8 z9 z10 z11 z12 z13 z14 + z= 0 593/2 593/2 1/30 1/6 3/10 3/10 1/6 1/30 1/6 1/30 3/10 3/10 1/30 1/6 + w= 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + + Number of pivots: 27 +P1: 1/30 1/6 3/10 3/10 1/6 1/30 P2: 1/6 1/30 3/10 3/10 1/30 1/6 +After filltableau: +Determinant: -1 +var z0 z1 z2 z3 z4 z5 z6 z7 z8 z9 z10 z11 z12 z13 z14 RHS +scfa 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + +w1 1 . . 1 1 1 1 1 1 . . . . . . -1 +w2 1 . . . . . . . . 1 1 1 1 1 1 -1 +w3 1 -1 . . . . . . . 478 226 631 1 451 28 . +w4 1 -1 . . . . . . . 328 281 331 256 301 278 . +w5 1 -1 . . . . . . . 379 262 424 172 334 208 . +w6 1 -1 . . . . . . . 208 334 172 424 262 379 . +w7 1 -1 . . . . . . . 278 301 256 331 281 328 . +w8 . -1 . . . . . . . 28 451 1 631 226 478 . +w9 1 . -1 226 478 1 631 28 451 . . . . . . . +w10 1 . -1 262 379 172 424 208 334 . . . . . . . +w11 1 . -1 281 328 256 331 278 301 . . . . . . . +w12 1 . -1 301 278 331 256 328 281 . . . . . . . +w13 1 . -1 334 208 424 172 379 262 . . . . . . . +w14 1 . -1 451 28 631 1 478 226 . . . . . . . +-----------------end of tableau----------------- +leaving: w2 entering: z0 +leaving: w14 entering: z2 +leaving: w1 entering: z14 +leaving: w8 entering: z1 +leaving: w3 entering: z8 +leaving: w13 entering: z3 +leaving: w5 entering: z13 +leaving: z3 entering: z5 +leaving: w4 entering: w3 +leaving: w12 entering: z4 +leaving: z14 entering: z12 +leaving: z4 entering: w14 +leaving: w3 entering: w4 +leaving: z5 entering: z3 +leaving: z13 entering: w5 +leaving: w11 entering: w13 +leaving: w5 entering: z11 +leaving: z3 entering: z5 +leaving: w4 entering: w3 +leaving: w14 entering: z4 +leaving: w3 entering: z14 +leaving: w13 entering: z3 +leaving: w7 entering: z13 +leaving: z5 entering: z7 +leaving: z13 entering: w5 +leaving: z3 entering: w13 +leaving: z14 entering: w3 +leaving: z4 entering: w14 +leaving: w6 entering: w4 +leaving: w14 entering: z6 +leaving: w3 entering: z14 +leaving: w13 entering: z3 +leaving: w5 entering: z13 +leaving: z3 entering: z5 +leaving: w4 entering: w3 +leaving: w10 entering: z4 +leaving: z12 entering: z10 +leaving: z4 entering: w12 +leaving: w3 entering: w4 +leaving: z5 entering: z3 +leaving: z13 entering: w5 +leaving: z3 entering: w13 +leaving: z14 entering: w3 +leaving: z6 entering: w14 +leaving: w4 entering: w6 +leaving: w14 entering: z4 +leaving: w3 entering: z14 +leaving: w13 entering: z3 +leaving: w5 entering: z13 +leaving: z7 entering: z5 +leaving: z13 entering: w7 +leaving: z3 entering: w13 +leaving: z14 entering: w3 +leaving: z4 entering: w14 +leaving: w3 entering: w4 +leaving: z5 entering: z3 +leaving: z11 entering: w5 +leaving: w9 entering: w11 +leaving: w5 entering: z9 +leaving: z3 entering: z5 +leaving: w4 entering: w3 +leaving: w14 entering: z4 +leaving: w3 entering: z14 +leaving: w13 entering: z3 +leaving: w7 entering: z13 +leaving: z5 entering: z7 +leaving: z13 entering: w5 +leaving: z3 entering: w13 +leaving: z14 entering: w3 +leaving: z4 entering: w14 +leaving: w6 entering: w4 +leaving: w14 entering: z6 +leaving: w3 entering: z14 +leaving: w13 entering: z3 +leaving: w5 entering: z13 +leaving: z3 entering: z5 +leaving: w4 entering: w3 +leaving: w12 entering: z4 +leaving: z14 entering: z12 +leaving: z4 entering: w14 +leaving: w3 entering: w4 +leaving: z5 entering: z3 +leaving: z13 entering: w5 +leaving: w11 entering: w13 +leaving: w5 entering: z11 +leaving: z3 entering: z5 +leaving: w4 entering: w3 +leaving: w14 entering: z4 +leaving: w3 entering: z14 +leaving: w13 entering: z3 +leaving: z0 entering: z13 +Final tableau: +Determinant: 7473389062500 +var w2 w8 w10 w9 w12 w11 w14 w13 w6 z0 w3 w5 w4 w7 w1 RHS +scfa 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + +z10 -249112968750 -570191906250 . . . . . . 4954580156250 -321078937500 260184656250 -3349185468750 9815050968750 -11110438406250 . 249112968750 +z13 -249112968750 260184656250 . . . . . . -3349185468750 509297625000 -570191906250 4954580156250 -11110438406250 9815050968750 . 249112968750 +z8 . . 4954580156250 -570191906250 9815050968750 -11110438406250 260184656250 -3349185468750 . 249112968750 . . . . -249112968750 249112968750 +z12 -2242016718750 -149467781250 . . . . . . 3072393281250 2092548937500 514833468750 -5231372343750 12106890281250 -10313276906250 . 2242016718750 +z9 -1245564843750 -691980468750 . . . . . . 8165369531250 553584375000 636622031250 -7611785156250 20676376406250 -21174602343750 . 1245564843750 +z14 -1245564843750 636622031250 . . . . . . -7611785156250 1882186875000 -691980468750 8165369531250 -21174602343750 20676376406250 . 1245564843750 +z11 -2242016718750 514833468750 . . . . . . -5231372343750 2756850187500 -149467781250 3072393281250 -10313276906250 12106890281250 . 2242016718750 +z1 -2215859857031250 249112968750 . . . . . . 1245564843750 2208635580937500 249112968750 1245564843750 2242016718750 2242016718750 . 2215859857031250 +z3 . . -3349185468750 260184656250 -11110438406250 9815050968750 -570191906250 4954580156250 . 249112968750 . . . . -249112968750 249112968750 +z4 . . -7611785156250 636622031250 -21174602343750 20676376406250 -691980468750 8165369531250 . 1245564843750 . . . . -1245564843750 1245564843750 +z5 . . -5231372343750 514833468750 -10313276906250 12106890281250 -149467781250 3072393281250 . 2242016718750 . . . . -2242016718750 2242016718750 +z6 . . 3072393281250 -149467781250 12106890281250 -10313276906250 514833468750 -5231372343750 . 2242016718750 . . . . -2242016718750 2242016718750 +z7 . . 8165369531250 -691980468750 20676376406250 -21174602343750 636622031250 -7611785156250 . 1245564843750 . . . . -1245564843750 1245564843750 +z2 . . 1245564843750 249112968750 2242016718750 2242016718750 249112968750 1245564843750 . 2208386467968750 . . . . -2215859857031250 2215859857031250 +-----------------end of tableau----------------- +basis= z1 z2 z3 z4 z5 z6 z7 z8 z9 z10 z11 z12 z13 z14 + z= 0 593/2 593/2 1/30 1/6 3/10 3/10 1/6 1/30 1/6 1/30 3/10 3/10 1/30 1/6 + w= 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + + Number of pivots: 91 +P1: 1/30 1/6 3/10 3/10 1/6 1/30 P2: 1/6 1/30 3/10 3/10 1/30 1/6 +After filltableau: +Determinant: -1 +var z0 z1 z2 z3 z4 z5 z6 z7 z8 z9 z10 z11 z12 z13 z14 RHS +scfa 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + +w1 1 . . 1 1 1 1 1 1 . . . . . . -1 +w2 1 . . . . . . . . 1 1 1 1 1 1 -1 +w3 1 -1 . . . . . . . 478 226 631 1 451 28 . +w4 1 -1 . . . . . . . 328 281 331 256 301 278 . +w5 1 -1 . . . . . . . 379 262 424 172 334 208 . +w6 1 -1 . . . . . . . 208 334 172 424 262 379 . +w7 1 -1 . . . . . . . 278 301 256 331 281 328 . +w8 1 -1 . . . . . . . 28 451 1 631 226 478 . +w9 . . -1 226 478 1 631 28 451 . . . . . . . +w10 1 . -1 262 379 172 424 208 334 . . . . . . . +w11 1 . -1 281 328 256 331 278 301 . . . . . . . +w12 1 . -1 301 278 331 256 328 281 . . . . . . . +w13 1 . -1 334 208 424 172 379 262 . . . . . . . +w14 1 . -1 451 28 631 1 478 226 . . . . . . . +-----------------end of tableau----------------- +leaving: w1 entering: z0 +leaving: w8 entering: z1 +leaving: w2 entering: z8 +leaving: w9 entering: z2 +leaving: w14 entering: z9 +leaving: w3 entering: z14 +leaving: w13 entering: z3 +leaving: w5 entering: z13 +leaving: z3 entering: z5 +leaving: w4 entering: w3 +leaving: w12 entering: z4 +leaving: z14 entering: z12 +leaving: z4 entering: w14 +leaving: w3 entering: w4 +leaving: z5 entering: z3 +leaving: z13 entering: w5 +leaving: w11 entering: w13 +leaving: w5 entering: z11 +leaving: z3 entering: z5 +leaving: w4 entering: w3 +leaving: w14 entering: z4 +leaving: w3 entering: z14 +leaving: w13 entering: z3 +leaving: w7 entering: z13 +leaving: z5 entering: z7 +leaving: z13 entering: w5 +leaving: z3 entering: w13 +leaving: z14 entering: w3 +leaving: z4 entering: w14 +leaving: w6 entering: w4 +leaving: w14 entering: z6 +leaving: w3 entering: z14 +leaving: w13 entering: z3 +leaving: w5 entering: z13 +leaving: z3 entering: z5 +leaving: w4 entering: w3 +leaving: w10 entering: z4 +leaving: w3 entering: z10 +leaving: z0 entering: z3 +Final tableau: +Determinant: 7473389062500 +var w1 w8 w9 w11 w12 w13 w14 z0 w2 w10 w3 w5 w4 w7 w6 RHS +scfa 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + +z3 -249112968750 . 260184656250 9815050968750 -11110438406250 4954580156250 -570191906250 509297625000 . -3349185468750 . . . . . 249112968750 +z8 -249112968750 . -570191906250 -11110438406250 9815050968750 -3349185468750 260184656250 -321078937500 . 4954580156250 . . . . . 249112968750 +z12 . -149467781250 . . . . . 2242016718750 -2242016718750 . 514833468750 -5231372343750 12106890281250 -10313276906250 3072393281250 2242016718750 +z14 . 636622031250 . . . . . 1245564843750 -1245564843750 . -691980468750 8165369531250 -21174602343750 20676376406250 -7611785156250 1245564843750 +z11 . 514833468750 . . . . . 2242016718750 -2242016718750 . -149467781250 3072393281250 -10313276906250 12106890281250 -5231372343750 2242016718750 +z10 . -570191906250 . . . . . 249112968750 -249112968750 . 260184656250 -3349185468750 9815050968750 -11110438406250 4954580156250 249112968750 +z13 . 260184656250 . . . . . 249112968750 -249112968750 . -570191906250 4954580156250 -11110438406250 9815050968750 -3349185468750 249112968750 +z1 . 249112968750 . . . . . 2208386467968750 -2215859857031250 . 249112968750 1245564843750 2242016718750 2242016718750 1245564843750 2215859857031250 +z2 -2215859857031250 . 249112968750 2242016718750 2242016718750 1245564843750 249112968750 2208635580937500 . 1245564843750 . . . . . 2215859857031250 +z4 -1245564843750 . 636622031250 20676376406250 -21174602343750 8165369531250 -691980468750 1882186875000 . -7611785156250 . . . . . 1245564843750 +z5 -2242016718750 . 514833468750 12106890281250 -10313276906250 3072393281250 -149467781250 2756850187500 . -5231372343750 . . . . . 2242016718750 +z6 -2242016718750 . -149467781250 -10313276906250 12106890281250 -5231372343750 514833468750 2092548937500 . 3072393281250 . . . . . 2242016718750 +z7 -1245564843750 . -691980468750 -21174602343750 20676376406250 -7611785156250 636622031250 553584375000 . 8165369531250 . . . . . 1245564843750 +z9 . -691980468750 . . . . . 1245564843750 -1245564843750 . 636622031250 -7611785156250 20676376406250 -21174602343750 8165369531250 1245564843750 +-----------------end of tableau----------------- +basis= z1 z2 z3 z4 z5 z6 z7 z8 z9 z10 z11 z12 z13 z14 + z= 0 593/2 593/2 1/30 1/6 3/10 3/10 1/6 1/30 1/6 1/30 3/10 3/10 1/30 1/6 + w= 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + + Number of pivots: 39 +P1: 1/30 1/6 3/10 3/10 1/6 1/30 P2: 1/6 1/30 3/10 3/10 1/30 1/6 +After filltableau: +Determinant: -1 +var z0 z1 z2 z3 z4 z5 z6 z7 z8 z9 z10 z11 z12 z13 z14 RHS +scfa 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + +w1 1 . . 1 1 1 1 1 1 . . . . . . -1 +w2 1 . . . . . . . . 1 1 1 1 1 1 -1 +w3 1 -1 . . . . . . . 478 226 631 1 451 28 . +w4 1 -1 . . . . . . . 328 281 331 256 301 278 . +w5 1 -1 . . . . . . . 379 262 424 172 334 208 . +w6 1 -1 . . . . . . . 208 334 172 424 262 379 . +w7 1 -1 . . . . . . . 278 301 256 331 281 328 . +w8 1 -1 . . . . . . . 28 451 1 631 226 478 . +w9 1 . -1 226 478 1 631 28 451 . . . . . . . +w10 . . -1 262 379 172 424 208 334 . . . . . . . +w11 1 . -1 281 328 256 331 278 301 . . . . . . . +w12 1 . -1 301 278 331 256 328 281 . . . . . . . +w13 1 . -1 334 208 424 172 379 262 . . . . . . . +w14 1 . -1 451 28 631 1 478 226 . . . . . . . +-----------------end of tableau----------------- +leaving: w1 entering: z0 +leaving: w3 entering: z1 +leaving: w2 entering: z3 +leaving: w10 entering: z2 +leaving: w9 entering: z10 +leaving: w5 entering: z9 +leaving: z3 entering: z5 +leaving: w4 entering: w3 +leaving: w14 entering: z4 +leaving: w3 entering: z14 +leaving: w13 entering: z3 +leaving: w7 entering: z13 +leaving: z5 entering: z7 +leaving: z13 entering: w5 +leaving: z3 entering: w13 +leaving: z14 entering: w3 +leaving: z4 entering: w14 +leaving: w6 entering: w4 +leaving: w14 entering: z6 +leaving: w3 entering: z14 +leaving: w13 entering: z3 +leaving: w5 entering: z13 +leaving: z3 entering: z5 +leaving: w4 entering: w3 +leaving: w12 entering: z4 +leaving: z14 entering: z12 +leaving: z4 entering: w14 +leaving: w3 entering: w4 +leaving: z5 entering: z3 +leaving: z13 entering: w5 +leaving: w11 entering: w13 +leaving: w5 entering: z11 +leaving: z3 entering: z5 +leaving: w4 entering: w3 +leaving: w14 entering: z4 +leaving: w3 entering: z14 +leaving: w13 entering: z3 +leaving: w8 entering: z13 +leaving: z0 entering: z8 +Final tableau: +Determinant: 7473389062500 +var w1 w6 w10 w2 w12 w11 w14 w13 z0 w8 w9 w5 w3 w7 w4 RHS +scfa 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + +z8 -249112968750 . 4954580156250 . 9815050968750 -11110438406250 260184656250 -3349185468750 5203693125000 . -570191906250 . . . . 249112968750 +z7 -1245564843750 . 8165369531250 . 20676376406250 -21174602343750 636622031250 -7611785156250 9410934375000 . -691980468750 . . . . 1245564843750 +z1 . 1245564843750 . -2215859857031250 . . . . 2208386467968750 249112968750 . 1245564843750 249112968750 2242016718750 2242016718750 2215859857031250 +z12 . 3072393281250 . -2242016718750 . . . . 2242016718750 -149467781250 . -5231372343750 514833468750 -10313276906250 12106890281250 2242016718750 +z9 . 8165369531250 . -1245564843750 . . . . 1245564843750 -691980468750 . -7611785156250 636622031250 -21174602343750 20676376406250 1245564843750 +z14 . -7611785156250 . -1245564843750 . . . . 1245564843750 636622031250 . 8165369531250 -691980468750 20676376406250 -21174602343750 1245564843750 +z11 . -5231372343750 . -2242016718750 . . . . 2242016718750 514833468750 . 3072393281250 -149467781250 12106890281250 -10313276906250 2242016718750 +z13 . -3349185468750 . -249112968750 . . . . 249112968750 260184656250 . 4954580156250 -570191906250 9815050968750 -11110438406250 249112968750 +z10 . 4954580156250 . -249112968750 . . . . 249112968750 -570191906250 . -3349185468750 260184656250 -11110438406250 9815050968750 249112968750 +z2 -2215859857031250 . 1245564843750 . 2242016718750 2242016718750 249112968750 1245564843750 2209632032812500 . 249112968750 . . . . 2215859857031250 +z3 -249112968750 . -3349185468750 . -11110438406250 9815050968750 -570191906250 4954580156250 -3100072500000 . 260184656250 . . . . 249112968750 +z4 -1245564843750 . -7611785156250 . -21174602343750 20676376406250 -691980468750 8165369531250 -6366220312500 . 636622031250 . . . . 1245564843750 +z5 -2242016718750 . -5231372343750 . -10313276906250 12106890281250 -149467781250 3072393281250 -2989355625000 . 514833468750 . . . . 2242016718750 +z6 -2242016718750 . 3072393281250 . 12106890281250 -10313276906250 514833468750 -5231372343750 5314410000000 . -149467781250 . . . . 2242016718750 +-----------------end of tableau----------------- +basis= z1 z2 z3 z4 z5 z6 z7 z8 z9 z10 z11 z12 z13 z14 + z= 0 593/2 593/2 1/30 1/6 3/10 3/10 1/6 1/30 1/6 1/30 3/10 3/10 1/30 1/6 + w= 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + + Number of pivots: 39 +P1: 1/30 1/6 3/10 3/10 1/6 1/30 P2: 1/6 1/30 3/10 3/10 1/30 1/6 +After filltableau: +Determinant: -1 +var z0 z1 z2 z3 z4 z5 z6 z7 z8 z9 z10 z11 z12 z13 z14 RHS +scfa 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + +w1 1 . . 1 1 1 1 1 1 . . . . . . -1 +w2 1 . . . . . . . . 1 1 1 1 1 1 -1 +w3 1 -1 . . . . . . . 478 226 631 1 451 28 . +w4 1 -1 . . . . . . . 328 281 331 256 301 278 . +w5 1 -1 . . . . . . . 379 262 424 172 334 208 . +w6 1 -1 . . . . . . . 208 334 172 424 262 379 . +w7 1 -1 . . . . . . . 278 301 256 331 281 328 . +w8 1 -1 . . . . . . . 28 451 1 631 226 478 . +w9 1 . -1 226 478 1 631 28 451 . . . . . . . +w10 1 . -1 262 379 172 424 208 334 . . . . . . . +w11 . . -1 281 328 256 331 278 301 . . . . . . . +w12 1 . -1 301 278 331 256 328 281 . . . . . . . +w13 1 . -1 334 208 424 172 379 262 . . . . . . . +w14 1 . -1 451 28 631 1 478 226 . . . . . . . +-----------------end of tableau----------------- +leaving: w1 entering: z0 +leaving: w8 entering: z1 +leaving: w2 entering: z8 +leaving: w11 entering: z2 +leaving: w14 entering: z11 +leaving: w3 entering: z14 +leaving: w13 entering: z3 +leaving: w5 entering: z13 +leaving: z3 entering: z5 +leaving: w4 entering: w3 +leaving: w12 entering: z4 +leaving: w6 entering: z12 +leaving: z8 entering: z6 +leaving: w7 entering: w8 +leaving: w9 entering: z7 +leaving: w8 entering: z9 +leaving: w10 entering: z8 +leaving: w3 entering: z10 +leaving: z0 entering: z3 +Final tableau: +Determinant: 7473389062500 +var w1 w7 w11 w13 w12 z0 w10 w9 w2 w8 w3 w14 w6 w5 w4 RHS +scfa 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + +z3 -249112968750 . 9815050968750 4954580156250 -11110438406250 10064163937500 -3349185468750 260184656250 . . . -570191906250 . . . 249112968750 +z6 -2242016718750 . -10313276906250 -5231372343750 12106890281250 -8071260187500 3072393281250 -149467781250 . . . 514833468750 . . . 2242016718750 +z14 . 20676376406250 . . . 1245564843750 . . -1245564843750 636622031250 -691980468750 . -7611785156250 8165369531250 -21174602343750 1245564843750 +z10 . -11110438406250 . . . 249112968750 . . -249112968750 -570191906250 260184656250 . 4954580156250 -3349185468750 9815050968750 249112968750 +z13 . 9815050968750 . . . 249112968750 . . -249112968750 260184656250 -570191906250 . -3349185468750 4954580156250 -11110438406250 249112968750 +z12 . -10313276906250 . . . 2242016718750 . . -2242016718750 -149467781250 514833468750 . 3072393281250 -5231372343750 12106890281250 2242016718750 +z9 . -21174602343750 . . . 1245564843750 . . -1245564843750 -691980468750 636622031250 . 8165369531250 -7611785156250 20676376406250 1245564843750 +z1 . 2242016718750 . . . 2208386467968750 . . -2215859857031250 249112968750 249112968750 . 1245564843750 1245564843750 2242016718750 2215859857031250 +z7 -1245564843750 . -21174602343750 -7611785156250 20676376406250 -19929037500000 8165369531250 -691980468750 . . . 636622031250 . . . 1245564843750 +z8 -249112968750 . -11110438406250 -3349185468750 9815050968750 -10861325437500 4954580156250 -570191906250 . . . 260184656250 . . . 249112968750 +z2 -2215859857031250 . 2242016718750 1245564843750 2242016718750 2210628484687500 1245564843750 249112968750 . . . 249112968750 . . . 2215859857031250 +z4 -1245564843750 . 20676376406250 8165369531250 -21174602343750 21921941250000 -7611785156250 636622031250 . . . -691980468750 . . . 1245564843750 +z5 -2242016718750 . 12106890281250 3072393281250 -10313276906250 14348907000000 -5231372343750 514833468750 . . . -149467781250 . . . 2242016718750 +z11 . 12106890281250 . . . 2242016718750 . . -2242016718750 514833468750 -149467781250 . -5231372343750 3072393281250 -10313276906250 2242016718750 +-----------------end of tableau----------------- +basis= z1 z2 z3 z4 z5 z6 z7 z8 z9 z10 z11 z12 z13 z14 + z= 0 593/2 593/2 1/30 1/6 3/10 3/10 1/6 1/30 1/6 1/30 3/10 3/10 1/30 1/6 + w= 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + + Number of pivots: 19 +P1: 1/30 1/6 3/10 3/10 1/6 1/30 P2: 1/6 1/30 3/10 3/10 1/30 1/6 +After filltableau: +Determinant: -1 +var z0 z1 z2 z3 z4 z5 z6 z7 z8 z9 z10 z11 z12 z13 z14 RHS +scfa 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + +w1 1 . . 1 1 1 1 1 1 . . . . . . -1 +w2 1 . . . . . . . . 1 1 1 1 1 1 -1 +w3 1 -1 . . . . . . . 478 226 631 1 451 28 . +w4 1 -1 . . . . . . . 328 281 331 256 301 278 . +w5 1 -1 . . . . . . . 379 262 424 172 334 208 . +w6 1 -1 . . . . . . . 208 334 172 424 262 379 . +w7 1 -1 . . . . . . . 278 301 256 331 281 328 . +w8 1 -1 . . . . . . . 28 451 1 631 226 478 . +w9 1 . -1 226 478 1 631 28 451 . . . . . . . +w10 1 . -1 262 379 172 424 208 334 . . . . . . . +w11 1 . -1 281 328 256 331 278 301 . . . . . . . +w12 . . -1 301 278 331 256 328 281 . . . . . . . +w13 1 . -1 334 208 424 172 379 262 . . . . . . . +w14 1 . -1 451 28 631 1 478 226 . . . . . . . +-----------------end of tableau----------------- +leaving: w1 entering: z0 +leaving: w3 entering: z1 +leaving: w2 entering: z3 +leaving: w12 entering: z2 +leaving: w9 entering: z12 +leaving: w8 entering: z9 +leaving: w10 entering: z8 +leaving: w6 entering: z10 +leaving: z8 entering: z6 +leaving: w7 entering: w8 +leaving: w11 entering: z7 +leaving: w5 entering: z11 +leaving: z3 entering: z5 +leaving: w4 entering: w3 +leaving: w14 entering: z4 +leaving: w3 entering: z14 +leaving: w13 entering: z3 +leaving: w8 entering: z13 +leaving: z0 entering: z8 +Final tableau: +Determinant: 7473389062500 +var w1 w4 w12 w2 w14 w13 z0 w11 w10 w7 w6 w5 w9 w8 w3 RHS +scfa 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + +z8 -249112968750 . 9815050968750 . 260184656250 -3349185468750 10064163937500 -11110438406250 4954580156250 . . . -570191906250 . . 249112968750 +z5 -2242016718750 . -10313276906250 . -149467781250 3072393281250 -8071260187500 12106890281250 -5231372343750 . . . 514833468750 . . 2242016718750 +z1 . 2242016718750 . -2215859857031250 . . 2208386467968750 . . 2242016718750 1245564843750 1245564843750 . 249112968750 249112968750 2215859857031250 +z14 . -21174602343750 . -1245564843750 . . 1245564843750 . . 20676376406250 -7611785156250 8165369531250 . 636622031250 -691980468750 1245564843750 +z11 . -10313276906250 . -2242016718750 . . 2242016718750 . . 12106890281250 -5231372343750 3072393281250 . 514833468750 -149467781250 2242016718750 +z10 . 9815050968750 . -249112968750 . . 249112968750 . . -11110438406250 4954580156250 -3349185468750 . -570191906250 260184656250 249112968750 +z13 . -11110438406250 . -249112968750 . . 249112968750 . . 9815050968750 -3349185468750 4954580156250 . 260184656250 -570191906250 249112968750 +z9 . 20676376406250 . -1245564843750 . . 1245564843750 . . -21174602343750 8165369531250 -7611785156250 . -691980468750 636622031250 1245564843750 +z12 . 12106890281250 . -2242016718750 . . 2242016718750 . . -10313276906250 3072393281250 -5231372343750 . -149467781250 514833468750 2242016718750 +z6 -2242016718750 . 12106890281250 . 514833468750 -5231372343750 14348907000000 -10313276906250 3072393281250 . . . -149467781250 . . 2242016718750 +z7 -1245564843750 . 20676376406250 . 636622031250 -7611785156250 21921941250000 -21174602343750 8165369531250 . . . -691980468750 . . 1245564843750 +z2 -2215859857031250 . 2242016718750 . 249112968750 1245564843750 2210628484687500 2242016718750 1245564843750 . . . 249112968750 . . 2215859857031250 +z3 -249112968750 . -11110438406250 . -570191906250 4954580156250 -10861325437500 9815050968750 -3349185468750 . . . 260184656250 . . 249112968750 +z4 -1245564843750 . -21174602343750 . -691980468750 8165369531250 -19929037500000 20676376406250 -7611785156250 . . . 636622031250 . . 1245564843750 +-----------------end of tableau----------------- +basis= z1 z2 z3 z4 z5 z6 z7 z8 z9 z10 z11 z12 z13 z14 + z= 0 593/2 593/2 1/30 1/6 3/10 3/10 1/6 1/30 1/6 1/30 3/10 3/10 1/30 1/6 + w= 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + + Number of pivots: 19 +P1: 1/30 1/6 3/10 3/10 1/6 1/30 P2: 1/6 1/30 3/10 3/10 1/30 1/6 +After filltableau: +Determinant: -1 +var z0 z1 z2 z3 z4 z5 z6 z7 z8 z9 z10 z11 z12 z13 z14 RHS +scfa 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + +w1 1 . . 1 1 1 1 1 1 . . . . . . -1 +w2 1 . . . . . . . . 1 1 1 1 1 1 -1 +w3 1 -1 . . . . . . . 478 226 631 1 451 28 . +w4 1 -1 . . . . . . . 328 281 331 256 301 278 . +w5 1 -1 . . . . . . . 379 262 424 172 334 208 . +w6 1 -1 . . . . . . . 208 334 172 424 262 379 . +w7 1 -1 . . . . . . . 278 301 256 331 281 328 . +w8 1 -1 . . . . . . . 28 451 1 631 226 478 . +w9 1 . -1 226 478 1 631 28 451 . . . . . . . +w10 1 . -1 262 379 172 424 208 334 . . . . . . . +w11 1 . -1 281 328 256 331 278 301 . . . . . . . +w12 1 . -1 301 278 331 256 328 281 . . . . . . . +w13 . . -1 334 208 424 172 379 262 . . . . . . . +w14 1 . -1 451 28 631 1 478 226 . . . . . . . +-----------------end of tableau----------------- +leaving: w1 entering: z0 +leaving: w8 entering: z1 +leaving: w2 entering: z8 +leaving: w13 entering: z2 +leaving: w14 entering: z13 +leaving: w6 entering: z14 +leaving: z8 entering: z6 +leaving: w7 entering: w8 +leaving: w9 entering: z7 +leaving: w8 entering: z9 +leaving: w10 entering: z8 +leaving: w4 entering: z10 +leaving: z6 entering: z4 +leaving: z10 entering: w6 +leaving: z8 entering: w10 +leaving: z9 entering: w8 +leaving: z7 entering: w9 +leaving: w5 entering: w7 +leaving: w9 entering: z5 +leaving: w8 entering: z9 +leaving: w10 entering: z8 +leaving: w6 entering: z10 +leaving: z8 entering: z6 +leaving: w7 entering: w8 +leaving: w11 entering: z7 +leaving: z9 entering: z11 +leaving: z7 entering: w9 +leaving: w8 entering: w7 +leaving: z6 entering: z8 +leaving: z10 entering: w6 +leaving: w12 entering: w10 +leaving: w6 entering: z12 +leaving: z8 entering: z6 +leaving: w7 entering: w8 +leaving: w9 entering: z7 +leaving: w8 entering: z9 +leaving: w10 entering: z8 +leaving: w3 entering: z10 +leaving: z0 entering: z3 +Final tableau: +Determinant: 7473389062500 +var w1 w5 w13 z0 w10 w9 w12 w11 w2 w7 w4 w8 w6 w14 w3 RHS +scfa 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + +z3 -249112968750 . 4954580156250 5203693125000 -3349185468750 260184656250 -11110438406250 9815050968750 . . . . . -570191906250 . 249112968750 +z4 -1245564843750 . 8165369531250 9410934375000 -7611785156250 636622031250 -21174602343750 20676376406250 . . . . . -691980468750 . 1245564843750 +z10 . -3349185468750 . 249112968750 . . . . -249112968750 -11110438406250 9815050968750 -570191906250 4954580156250 . 260184656250 249112968750 +z12 . -5231372343750 . 2242016718750 . . . . -2242016718750 -10313276906250 12106890281250 -149467781250 3072393281250 . 514833468750 2242016718750 +z9 . -7611785156250 . 1245564843750 . . . . -1245564843750 -21174602343750 20676376406250 -691980468750 8165369531250 . 636622031250 1245564843750 +z14 . 8165369531250 . 1245564843750 . . . . -1245564843750 20676376406250 -21174602343750 636622031250 -7611785156250 . -691980468750 1245564843750 +z11 . 3072393281250 . 2242016718750 . . . . -2242016718750 12106890281250 -10313276906250 514833468750 -5231372343750 . -149467781250 2242016718750 +z1 . 1245564843750 . 2208386467968750 . . . . -2215859857031250 2242016718750 2242016718750 249112968750 1245564843750 . 249112968750 2215859857031250 +z5 -2242016718750 . 3072393281250 5314410000000 -5231372343750 514833468750 -10313276906250 12106890281250 . . . . . -149467781250 . 2242016718750 +z6 -2242016718750 . -5231372343750 -2989355625000 3072393281250 -149467781250 12106890281250 -10313276906250 . . . . . 514833468750 . 2242016718750 +z7 -1245564843750 . -7611785156250 -6366220312500 8165369531250 -691980468750 20676376406250 -21174602343750 . . . . . 636622031250 . 1245564843750 +z8 -249112968750 . -3349185468750 -3100072500000 4954580156250 -570191906250 9815050968750 -11110438406250 . . . . . 260184656250 . 249112968750 +z2 -2215859857031250 . 1245564843750 2209632032812500 1245564843750 249112968750 2242016718750 2242016718750 . . . . . 249112968750 . 2215859857031250 +z13 . 4954580156250 . 249112968750 . . . . -249112968750 9815050968750 -11110438406250 260184656250 -3349185468750 . -570191906250 249112968750 +-----------------end of tableau----------------- +basis= z1 z2 z3 z4 z5 z6 z7 z8 z9 z10 z11 z12 z13 z14 + z= 0 593/2 593/2 1/30 1/6 3/10 3/10 1/6 1/30 1/6 1/30 3/10 3/10 1/30 1/6 + w= 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + + Number of pivots: 39 +P1: 1/30 1/6 3/10 3/10 1/6 1/30 P2: 1/6 1/30 3/10 3/10 1/30 1/6 +After filltableau: +Determinant: -1 +var z0 z1 z2 z3 z4 z5 z6 z7 z8 z9 z10 z11 z12 z13 z14 RHS +scfa 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + +w1 1 . . 1 1 1 1 1 1 . . . . . . -1 +w2 1 . . . . . . . . 1 1 1 1 1 1 -1 +w3 1 -1 . . . . . . . 478 226 631 1 451 28 . +w4 1 -1 . . . . . . . 328 281 331 256 301 278 . +w5 1 -1 . . . . . . . 379 262 424 172 334 208 . +w6 1 -1 . . . . . . . 208 334 172 424 262 379 . +w7 1 -1 . . . . . . . 278 301 256 331 281 328 . +w8 1 -1 . . . . . . . 28 451 1 631 226 478 . +w9 1 . -1 226 478 1 631 28 451 . . . . . . . +w10 1 . -1 262 379 172 424 208 334 . . . . . . . +w11 1 . -1 281 328 256 331 278 301 . . . . . . . +w12 1 . -1 301 278 331 256 328 281 . . . . . . . +w13 1 . -1 334 208 424 172 379 262 . . . . . . . +w14 . . -1 451 28 631 1 478 226 . . . . . . . +-----------------end of tableau----------------- +leaving: w1 entering: z0 +leaving: w3 entering: z1 +leaving: w2 entering: z3 +leaving: w14 entering: z2 +leaving: w9 entering: z14 +leaving: w8 entering: z9 +leaving: w10 entering: z8 +leaving: w6 entering: z10 +leaving: z8 entering: z6 +leaving: w7 entering: w8 +leaving: w11 entering: z7 +leaving: z9 entering: z11 +leaving: z7 entering: w9 +leaving: w8 entering: w7 +leaving: z6 entering: z8 +leaving: z10 entering: w6 +leaving: w12 entering: w10 +leaving: w6 entering: z12 +leaving: z8 entering: z6 +leaving: w7 entering: w8 +leaving: w9 entering: z7 +leaving: w8 entering: z9 +leaving: w10 entering: z8 +leaving: w4 entering: z10 +leaving: z6 entering: z4 +leaving: z10 entering: w6 +leaving: z8 entering: w10 +leaving: z9 entering: w8 +leaving: z7 entering: w9 +leaving: w5 entering: w7 +leaving: w9 entering: z5 +leaving: w8 entering: z9 +leaving: w10 entering: z8 +leaving: w6 entering: z10 +leaving: z8 entering: z6 +leaving: w7 entering: w8 +leaving: w13 entering: z7 +leaving: w8 entering: z13 +leaving: z0 entering: z8 +Final tableau: +Determinant: 7473389062500 +var w1 w3 w14 w2 z0 w9 w10 w11 w12 w5 w4 w7 w6 w8 w13 RHS +scfa 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + +z8 -249112968750 . 260184656250 . 509297625000 -570191906250 4954580156250 -11110438406250 9815050968750 . . . . . -3349185468750 249112968750 +z3 -249112968750 . -570191906250 . -321078937500 260184656250 -3349185468750 9815050968750 -11110438406250 . . . . . 4954580156250 249112968750 +z1 . 249112968750 . -2215859857031250 2208386467968750 . . . . 1245564843750 2242016718750 2242016718750 1245564843750 249112968750 . 2215859857031250 +z10 . 260184656250 . -249112968750 249112968750 . . . . -3349185468750 9815050968750 -11110438406250 4954580156250 -570191906250 . 249112968750 +z13 . -570191906250 . -249112968750 249112968750 . . . . 4954580156250 -11110438406250 9815050968750 -3349185468750 260184656250 . 249112968750 +z12 . 514833468750 . -2242016718750 2242016718750 . . . . -5231372343750 12106890281250 -10313276906250 3072393281250 -149467781250 . 2242016718750 +z9 . 636622031250 . -1245564843750 1245564843750 . . . . -7611785156250 20676376406250 -21174602343750 8165369531250 -691980468750 . 1245564843750 +z11 . -149467781250 . -2242016718750 2242016718750 . . . . 3072393281250 -10313276906250 12106890281250 -5231372343750 514833468750 . 2242016718750 +z14 . -691980468750 . -1245564843750 1245564843750 . . . . 8165369531250 -21174602343750 20676376406250 -7611785156250 636622031250 . 1245564843750 +z4 -1245564843750 . -691980468750 . 553584375000 636622031250 -7611785156250 20676376406250 -21174602343750 . . . . . 8165369531250 1245564843750 +z5 -2242016718750 . -149467781250 . 2092548937500 514833468750 -5231372343750 12106890281250 -10313276906250 . . . . . 3072393281250 2242016718750 +z6 -2242016718750 . 514833468750 . 2756850187500 -149467781250 3072393281250 -10313276906250 12106890281250 . . . . . -5231372343750 2242016718750 +z7 -1245564843750 . 636622031250 . 1882186875000 -691980468750 8165369531250 -21174602343750 20676376406250 . . . . . -7611785156250 1245564843750 +z2 -2215859857031250 . 249112968750 . 2208635580937500 249112968750 1245564843750 2242016718750 2242016718750 . . . . . 1245564843750 2215859857031250 +-----------------end of tableau----------------- +basis= z1 z2 z3 z4 z5 z6 z7 z8 z9 z10 z11 z12 z13 z14 + z= 0 593/2 593/2 1/30 1/6 3/10 3/10 1/6 1/30 1/6 1/30 3/10 3/10 1/30 1/6 + w= 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + + Number of pivots: 39 +P1: 1/30 1/6 3/10 3/10 1/6 1/30 P2: 1/6 1/30 3/10 3/10 1/30 1/6 +P1: 1/30 1/6 3/10 3/10 1/6 1/30 P2: 1/6 1/30 3/10 3/10 1/30 1/6 + +Equilibria discovered: 1 + +1-ve index: +Eq[0]: P1: 0 0 0 0 0 0 P2: 0 0 0 0 0 0 +Leads to: 1->0 2->0 3->0 4->0 5->0 6->0 7->0 8->0 9->0 10->0 11->0 12->0 + +1+ve index: +Eq[0]: P1: 1/30 1/6 3/10 3/10 1/6 1/30 P2: 1/6 1/30 3/10 3/10 1/30 1/6 +Leads to: 1->0 2->0 3->0 4->0 5->0 6->0 7->0 8->0 9->0 10->0 11->0 12->0 diff --git a/native-algo/lh-vector/summary.pdf b/native-algo/lh-vector/summary.pdf new file mode 100644 index 0000000000000000000000000000000000000000..fea0d33e8db068ada1bdf3b33ce2562c9b305d8d GIT binary patch literal 87613 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 BYMuZ9 literal 0 HcmV?d00001 diff --git a/native-algo/lh-vector/test/dualcyclic/dx2d/2x4 b/native-algo/lh-vector/test/dualcyclic/dx2d/2x4 new file mode 100644 index 0000000..daf8973 --- /dev/null +++ b/native-algo/lh-vector/test/dualcyclic/dx2d/2x4 @@ -0,0 +1,8 @@ +m= 2 +n= 4 +A= +73 85 78 82 +109 49 82 64 +B= +109 89 79 73 +1 61 81 91 diff --git a/native-algo/lh-vector/test/dualcyclic/dx2d/2x4bit b/native-algo/lh-vector/test/dualcyclic/dx2d/2x4bit new file mode 100644 index 0000000..4c73cc2 --- /dev/null +++ b/native-algo/lh-vector/test/dualcyclic/dx2d/2x4bit @@ -0,0 +1,63 @@ +1 2 3 4 5 6 K=1 1 2 4 3 6 5 +1 1 0 0 0 0 0 0 1 1 1 1 +0 1 1 0 0 0 0 1 1 0 1 1 +0 0 1 1 0 0 E1 1 1 0 0 1 1 + +1 2 3 4 5 6 K=2 1 2 4 3 6 5 +1 1 0 0 0 0 0 0 1 1 1 1 +1 0 0 0 0 1 1 0 1 1 0 1 +0 0 0 0 1 1 E2 1 1 1 1 0 0 + +1 2 3 4 5 6 K=3 1 2 4 3 6 5 +1 1 0 0 0 0 0 0 1 1 1 1 +1 0 0 0 0 1 0 1 1 0 1 1 +0 0 0 0 1 1 1 1 1 0 0 1 + E2 1 1 1 1 0 0 + +1 2 3 4 5 6 K=4 1 2 4 3 6 5 +1 1 0 0 0 0 0 0 1 1 1 1 +0 1 1 0 0 0 1 0 0 1 1 1 +0 0 1 1 0 0 E1 1 1 0 0 1 1 + +1 2 3 4 5 6 K=5 1 2 4 3 6 5 +1 1 0 0 0 0 0 0 1 1 1 1 +1 0 0 0 0 1 0 1 1 1 1 0 +0 0 0 0 1 1 E2 1 1 1 1 0 0 + +1 2 3 4 5 6 K=6 1 2 4 3 6 5 +1 1 0 0 0 0 0 0 1 1 1 1 +0 1 1 0 0 0 1 0 1 1 0 1 +0 0 1 1 0 0 1 1 1 0 0 1 + E1 1 1 0 0 1 1 + +0 0 1 1 0 0 E1 1 1 0 0 1 1 + 1 4 6 + +1 2 3 4 5 6 K=2 1 2 4 3 6 5 +0 0 1 1 0 0 1 1 0 0 1 1 +0 0 0 1 1 0 1 0 0 1 1 1 + E3 1 1 0 1 1 0 + +1 2 3 4 5 6 K=3 1 2 4 3 6 5 +0 0 1 1 0 0 1 1 0 0 1 1 +0 0 0 1 1 0 E3 1 1 0 1 1 0 + +1 2 3 4 5 6 K=5 1 2 4 3 6 5 +0 0 1 1 0 0 1 1 0 0 1 1 +0 0 0 1 1 0 E3 1 1 0 1 1 0 + +0 0 0 0 1 1 E2 1 1 1 1 0 0 + 2 3 5 + +1 2 3 4 5 6 K=1 1 2 4 3 6 5 +0 0 0 0 1 1 1 1 1 1 0 0 +0 0 0 1 1 0 0 1 1 1 1 0 + E3 1 1 0 1 1 0 + +1 2 3 4 5 6 K=4 1 2 4 3 6 5 +0 0 0 0 1 1 1 1 1 1 0 0 +0 0 0 1 1 0 E3 1 1 0 1 1 0 + +1 2 3 4 5 6 K=6 1 2 4 3 6 5 +0 0 0 0 1 1 1 1 1 1 0 0 +0 0 0 1 1 0 E3 1 1 0 1 1 0 diff --git a/native-algo/lh-vector/test/dualcyclic/dx2d/2x4path b/native-algo/lh-vector/test/dualcyclic/dx2d/2x4path new file mode 100644 index 0000000..7cdf8a7 --- /dev/null +++ b/native-algo/lh-vector/test/dualcyclic/dx2d/2x4path @@ -0,0 +1,6 @@ +k= 1 length= 4 +k= 2 length= 4 +k= 3 length= 5 +k= 4 length= 4 +k= 5 length= 4 +k= 6 length= 5 \ No newline at end of file diff --git a/native-algo/lh-vector/test/dualcyclic/dx2d/4x8 b/native-algo/lh-vector/test/dualcyclic/dx2d/4x8 new file mode 100644 index 0000000..87dcb33 --- /dev/null +++ b/native-algo/lh-vector/test/dualcyclic/dx2d/4x8 @@ -0,0 +1,12 @@ +m= 4 +n= 8 +A= +194041 203281 184801 215601 195709 213676 201216 202896 +251534 187881 308001 107801 236776 123842 202460 192116 +215601 198147 236134 172481 213676 175176 201776 198104 +323401 157081 415801 1 267576 51976 203316 184416 +B= +217561 212017 208321 205681 203701 202161 200929 199921 +129361 157081 173713 184801 192721 198661 203281 206977 +323401 267961 240241 223609 212521 204601 198661 194041 +107801 163241 181721 190961 196505 200201 202841 204821 diff --git a/native-algo/lh-vector/test/dualcyclic/dx2d/4x8path b/native-algo/lh-vector/test/dualcyclic/dx2d/4x8path new file mode 100644 index 0000000..8d07d5d --- /dev/null +++ b/native-algo/lh-vector/test/dualcyclic/dx2d/4x8path @@ -0,0 +1,12 @@ +k= 1 length= 20 +k= 2 length= 8 +k= 3 length= 8 +k= 4 length= 20 +k= 5 length= 21 +k= 6 length= 10 +k= 7 length= 21 +k= 8 length= 10 +k= 9 length= 10 +k= 10 length= 21 +k= 11 length= 10 +k= 12 length= 21 \ No newline at end of file diff --git a/native-algo/lh-vector/test/dualcyclic/dx2d/6x12 b/native-algo/lh-vector/test/dualcyclic/dx2d/6x12 new file mode 100644 index 0000000..bebcc42 --- /dev/null +++ b/native-algo/lh-vector/test/dualcyclic/dx2d/6x12 @@ -0,0 +1,16 @@ +m= 6 +n= 12 +A= +415507144 417077944 405187861 421986694 395841601 435425761 406414293 434326201 415607501 421367101 416876846 417119396 +423800968 415978384 474303061 391748794 518992321 326569321 467313001 332726857 423050676 395448901 416980334 415823486 +418962904 416638120 435425761 409027594 451259425 387045121 434326201 388144681 419063261 409404854 416925356 416514638 +443153224 412679704 598710421 331272994 712514881 145141921 555277801 180327841 433200461 359163421 417115664 414095606 +431058064 414878824 526139461 367558474 603658441 248814721 506897161 264993961 427702661 378955501 417043166 415026002 +467343544 406082344 707566861 270797194 857656801 1 615753601 71471401 439797821 334973101 417200246 412996046 +B= +419390639 418807199 418369619 418029279 417757007 417534239 417348599 417191519 417056879 416940191 416838089 416747999 +400892159 404976239 407893439 410081339 411783039 413144399 414258239 415186439 415971839 416645039 417228479 417738989 +459856064 447603824 439435664 433601264 429225464 425822064 423099344 420871664 419015264 417444464 416098064 414931184 +355031344 375451744 387703984 395872144 401706544 406082344 409485744 412208464 414436144 416292544 417863344 419209744 +467343544 446923144 436712944 430586824 426502744 423585544 421397644 419695944 418334584 417220744 416292544 415507144 +394772584 407024824 411108904 413150944 414376168 415192984 415776424 416214004 416554344 416826616 417049384 417235024 diff --git a/native-algo/lh-vector/test/dualcyclic/dx2d/6x12path b/native-algo/lh-vector/test/dualcyclic/dx2d/6x12path new file mode 100644 index 0000000..6489942 --- /dev/null +++ b/native-algo/lh-vector/test/dualcyclic/dx2d/6x12path @@ -0,0 +1,18 @@ +k= 1 length= 88 +k= 2 length= 24 +k= 3 length= 24 +k= 4 length= 24 +k= 5 length= 24 +k= 6 length= 88 +k= 7 length= 89 +k= 8 length= 36 +k= 9 length= 89 +k= 10 length= 16 +k= 11 length= 89 +k= 12 length= 36 +k= 13 length= 36 +k= 14 length= 89 +k= 15 length= 16 +k= 16 length= 89 +k= 17 length= 36 +k= 18 length= 89 \ No newline at end of file diff --git a/native-algo/lh-vector/test/dualcyclic/dx2d/out b/native-algo/lh-vector/test/dualcyclic/dx2d/out new file mode 100644 index 0000000..ef9cc19 --- /dev/null +++ b/native-algo/lh-vector/test/dualcyclic/dx2d/out @@ -0,0 +1,12 @@ +n= 8 +M= +0 0 1 1 0 0 0 0 +0 0 0 0 1 1 1 1 +-1 0 0 0 8 7 6 5 +-1 0 0 0 4 3 2 1 +0 -1 6 2 0 0 0 0 +0 -1 5 1 0 0 0 0 +0 -1 4 -0 0 0 0 0 +0 -1 3 -1 0 0 0 0 +q= -1 -1 0 0 0 0 0 0 +d= 1 1 0 1 1 1 1 1 \ No newline at end of file diff --git a/native-algo/lh-vector/test/dualcyclic/dx2d/pathlengthtestm1 b/native-algo/lh-vector/test/dualcyclic/dx2d/pathlengthtestm1 new file mode 100755 index 0000000..411b43a --- /dev/null +++ b/native-algo/lh-vector/test/dualcyclic/dx2d/pathlengthtestm1 @@ -0,0 +1,27 @@ +#!/bin/sh +echo "\n" > sample-output +for M in $(eval echo 2 4 6) +do + N=$((2*$M)) + F=$M"x"$N + echo "Testing $F" + #Compute and get the path lengths for the pivots from the artificial equilibrium + ../../../inlh < $F | grep "Number of pivots: " | grep "Number of pivots: " -n | head -n "$(($M+$N))" > tmp + for k in $(eval echo {1..$(($N+$M))}) + do + echo -n "Testing label $k: " + C=`egrep "$k: Number of pivots:" tmp | sed 's/.* Number of pivots:[ ]* \([0-9]*\)/\1/' | head -n 1` + G=`sed -n ''"$k,$k p"'' "$F"path | sed "s/.*length=\([0-9]*\)/\1/"` + B=$(($G+3)) + D=$(($G+4)) + T1=`[ $C -eq $B ]` + T2=`[ $C -eq $D ]` + if [ $T1 -o $T2 ] + then + echo "Passed" + else + echo "Failed" + fi + done +done +rm -f tmp \ No newline at end of file diff --git a/native-algo/lh-vector/test/dualcyclic/dx2d/pathlengthtestm2 b/native-algo/lh-vector/test/dualcyclic/dx2d/pathlengthtestm2 new file mode 100755 index 0000000..4d6f9b1 --- /dev/null +++ b/native-algo/lh-vector/test/dualcyclic/dx2d/pathlengthtestm2 @@ -0,0 +1,27 @@ +#!/bin/sh +echo "\n" > sample-output +for M in $(eval echo 2 4 6) +do + N=$((2*$M)) + F=$M"x"$N + echo "Testing $F" + #Compute and get the path lengths for the pivots from the artificial equilibrium + ../../../inlh -m < $F | grep "Number of pivots: " | grep "Number of pivots: " -n | head -n "$(($M+$N))" > tmp + for k in $(eval echo {1..$(($N+$M))}) + do + echo -n "Testing label $k: " + C=`egrep "$k: Number of pivots:" tmp | sed 's/.* Number of pivots:[ ]* \([0-9]*\)/\1/' | head -n 1` + G=`sed -n ''"$k,$k p"'' "$F"path | sed "s/.*length=\([0-9]*\)/\1/"` + B=$(($G+3)) + D=$(($G+4)) + T1=`[ $C -eq $B ]` + T2=`[ $C -eq $D ]` + if [ $T1 -o $T2 ] + then + echo "Passed" + else + echo "Failed" + fi + done +done +rm -f tmp \ No newline at end of file diff --git a/native-algo/lh-vector/test/dualcyclic/dxd/2x2 b/native-algo/lh-vector/test/dualcyclic/dxd/2x2 new file mode 100644 index 0000000..06c3db5 --- /dev/null +++ b/native-algo/lh-vector/test/dualcyclic/dxd/2x2 @@ -0,0 +1,8 @@ +m= 2 +n= 2 +A= +-3 3 +3 1 +B= +3 1 +-3 3 diff --git a/native-algo/lh-vector/test/dualcyclic/dxd/4x4 b/native-algo/lh-vector/test/dualcyclic/dxd/4x4 new file mode 100644 index 0000000..7340e61 --- /dev/null +++ b/native-algo/lh-vector/test/dualcyclic/dxd/4x4 @@ -0,0 +1,12 @@ +m= 4 +n= 4 +A= +-735 165 -1155 1365 +-63 25 -35 105 +-315 81 -315 525 +105 -15 105 -147 +B= +165 81 25 -15 +-735 -315 -63 105 +1365 525 105 -147 +-1155 -315 -35 105 diff --git a/native-algo/lh-vector/test/dualcyclic/dxd/6x6 b/native-algo/lh-vector/test/dualcyclic/dxd/6x6 new file mode 100644 index 0000000..df11106 --- /dev/null +++ b/native-algo/lh-vector/test/dualcyclic/dxd/6x6 @@ -0,0 +1,16 @@ +m= 6 +n= 6 +A= +-180 72 -333 297 -153 270 +-30 17 -33 42 -3 20 +-81 36 -126 126 -36 90 + 90 -36 126 -126 36 -81 + 20 -3 42 -33 17 -30 +270 -153 297 -333 72 -180 +B= + 72 36 17 -3 -36 -153 +-180 -81 -30 20 90 270 +297 126 42 -33 -126 -333 +-333 -126 -33 42 126 297 +270 90 20 -30 -81 -180 +-153 -36 -3 17 36 72 diff --git a/native-algo/lh-vector/test/dualcyclic/dxd/8x8 b/native-algo/lh-vector/test/dualcyclic/dxd/8x8 new file mode 100644 index 0000000..d393ebb --- /dev/null +++ b/native-algo/lh-vector/test/dualcyclic/dxd/8x8 @@ -0,0 +1,20 @@ +m= 8 +n= 8 +A= +-1355823 157689 -11168703 5130657 -13576563 15317757 -2477475 7612605 +-715183 85617 -5402943 2608137 -5504499 6909357 -555555 2567565 +-995463 117649 -7805343 3689217 -8531523 10272717 -1036035 4249245 +-307503 37569 -2199743 1094625 -2045043 2705157 -171171 885885 +-490959 59409 -3601143 1767297 -3486483 4506957 -315315 1558557 +-25263 3249 -161343 85617 -123123 182637 -6435 45045 +-154623 19089 -1078623 544257 -963963 1303757 -75075 405405 +85617 -10479 603057 -302463 549549 -734643 45045 -235235 +B= +157689 117649 85617 59409 37569 19089 3249 -10479 +-1355823 -995463 -715183 -490959 -307503 -154623 -25263 85617 +5130657 3689217 2608137 1767297 1094625 544257 85617 -302463 +-11168703 -7805343 -5402943 -3601143 -2199743 -1078623 -161343 603057 +15317757 10272717 6909357 4506957 2705157 1303757 182637 -734643 +-13576563 -8531523 -5504499 -3486483 -2045043 -963963 -123123 549549 +7612605 4249245 2567565 1558557 885885 405405 45045 -235235 +-2477475 -1036035 -555555 -315315 -171171 -75075 -6435 45045 diff --git a/native-algo/lh-vector/test/dualcyclic/dxd/Makefile b/native-algo/lh-vector/test/dualcyclic/dxd/Makefile new file mode 100644 index 0000000..1f7c222 --- /dev/null +++ b/native-algo/lh-vector/test/dualcyclic/dxd/Makefile @@ -0,0 +1,11 @@ +CC = gcc +CFLAGS = -Wall -O3 -g + +lh-label: lh-label.o + $(CC) lh-label.o $(LDFLAGS) -o lh-label + +lh-label.o: lh-label.c + $(CC) lh-label.c -c $(CFLAGS) -o lh-label.o + +clean: + rm -rf *.o lh-label lh-label \ No newline at end of file diff --git a/native-algo/lh-vector/test/dualcyclic/dxd/dualcyclictest b/native-algo/lh-vector/test/dualcyclic/dxd/dualcyclictest new file mode 100755 index 0000000..1b73dcd --- /dev/null +++ b/native-algo/lh-vector/test/dualcyclic/dxd/dualcyclictest @@ -0,0 +1,22 @@ +#!/bin/sh +#Test identity matrices using the first method for converting to an equivalent path + +for N in $(eval echo 2 4 6 8) +do + echo "Testing "$N"x"$N + ../../../inlh $2 < $N"x"$N > output + s1=`cat output | grep "Equilibria discovered"` + C1=`echo $s1 | sed 's/.* \([0-9]*\)/\1/'` + s2=`cat output | grep "Leads to: "` + C2=`echo $s2 | grep -o "\->0" | wc -l | sed s/\ //g` + E1=1 + E2=$(($N*2)) + T1=`[ "$C1" -eq "$E1" ]` + T2=`[ "$C2" -eq "$E2" ]` + if [ T1 -a T2 ] + then + echo "Passed" + else + echo "Failed" + fi +done \ No newline at end of file diff --git a/native-algo/lh-vector/test/dualcyclic/dxd/dualcyclictestm1 b/native-algo/lh-vector/test/dualcyclic/dxd/dualcyclictestm1 new file mode 100755 index 0000000..d985002 --- /dev/null +++ b/native-algo/lh-vector/test/dualcyclic/dxd/dualcyclictestm1 @@ -0,0 +1,45 @@ +#!/bin/sh +#Test identity matrices using the first method for converting to an equivalent path + +for N in $(eval echo 2 4 6 8) +do + echo "Testing "$N"x"$N + ../../../inlh < $N"x"$N > output + + for k in $(eval echo {1..$((2*N))}) + do + echo -n "Testing label $k: " + ./lh-label -d $N -l $k > gpath + grep "newlabel .*" gpath | sed 's/newlabel \([0-9]*\)/\1/' > tmp + mv tmp gpath + cat sample gpath > tmp + mv tmp gpath + sed "s/m=.*/m=$N/" gpath > tmp + mv tmp gpath + sed "s/n=.*/n=$N/" gpath > tmp + mv tmp gpath + ../../../path/path < gpath > tmp + mv tmp gpath + + grep -n "Number of pivots:" output | head -n 1 > line + L=`cat line | sed "s/\([0-9\]*\):.*/\1/"` + head -n $L output > cpath + R=$(($L-`wc -l output | sed 's/[ ]*\([0-9]*\) output/\1/'`)) + tail -n $R output > tmp + mv tmp output + + grep -x 'leaving:.*' cpath > tmp + mv tmp cpath + sed 's/leaving: \([a-z0-9]*\).*/\1/' cpath > tmp + mv tmp cpath + + S=`diff cpath gpath` + if [ -z $S ] + then + echo "Passed" + else + echo "Failed" + fi + done +done +rm cpath gpath line output \ No newline at end of file diff --git a/native-algo/lh-vector/test/dualcyclic/dxd/dualcyclictestm2 b/native-algo/lh-vector/test/dualcyclic/dxd/dualcyclictestm2 new file mode 100755 index 0000000..d006051 --- /dev/null +++ b/native-algo/lh-vector/test/dualcyclic/dxd/dualcyclictestm2 @@ -0,0 +1,45 @@ +#!/bin/sh +#Test identity matrices using the first method for converting to an equivalent path + +for N in $(eval echo 2 4 6 8) +do + echo "Testing "$N"x"$N + ../../../inlh -m < $N"x"$N > output + + for k in $(eval echo {1..$((2*N))}) + do + echo -n "Testing label $k: " + ./lh-label -d $N -l $k > gpath + grep "newlabel .*" gpath | sed 's/newlabel \([0-9]*\)/\1/' > tmp + mv tmp gpath + cat sample gpath > tmp + mv tmp gpath + sed "s/m=.*/m=$N/" gpath > tmp + mv tmp gpath + sed "s/n=.*/n=$N/" gpath > tmp + mv tmp gpath + ../../../path/path -m < gpath > tmp + mv tmp gpath + + grep -n "Number of pivots:" output | head -n 1 > line + L=`cat line | sed "s/\([0-9\]*\):.*/\1/"` + head -n $L output > cpath + R=$(($L-`wc -l output | sed 's/[ ]*\([0-9]*\) output/\1/'`)) + tail -n $R output > tmp + mv tmp output + + grep -x 'leaving:.*' cpath > tmp + mv tmp cpath + sed 's/leaving: \([a-z0-9]*\).*/\1/' cpath > tmp + mv tmp cpath + + S=`diff cpath gpath` + if [ -z $S ] + then + echo "Passed" + else + echo "Failed" + fi + done +done +rm cpath gpath line output \ No newline at end of file diff --git a/native-algo/lh-vector/test/dualcyclic/dxd/lh-label.c b/native-algo/lh-vector/test/dualcyclic/dxd/lh-label.c new file mode 100644 index 0000000..73471cc --- /dev/null +++ b/native-algo/lh-vector/test/dualcyclic/dxd/lh-label.c @@ -0,0 +1,231 @@ +/* LH-paths on cyclic polytopes + * Bellairs 15 March 2003 + * LSE 18 March 2003 + * + * options: + * -d # dimension, must be even + * -l # only dropping this label (default: all) + * -o output bitstrings (default not) + */ + +#include +#include /* isprint() */ +#include /* atoi() */ +#include + /* getopt(), optarg, optopt, optind */ + +#define MAXD 100 /* max dimension */ +#define MAXN 2*MAXD + +/*-------- global variables --------*/ +int perm[MAXN]; // permutation of second polytope +int invperm[MAXN]; // inverse permutation +int vertex1[MAXN]; // gale evenness representation of first vertex +int vertex2[MAXN]; // gale evenness representation of second vertex +int parity1[MAXN]; // parity of 1's in first vertex +int parity2[MAXN]; // parity of 2's in first vertex +int d=6; // dimension +int n; // 2 times dimension, = number of facets +int bout=0; // output vertices + +void genarteq(void) // generate artificial equilibrium +{ + int i; + for (i=0; i=n ) whichbit -= n; + if (whichbit < 0 ) whichbit += n; + // printf("whichbit %d\n",whichbit); + if (vertex[whichbit] == 0) break; + prevparity = parity[whichbit] = 1 - parity[whichbit]; + } + parity[whichbit] = 1 - prevparity; + vertex[whichbit] = 1; // set new bit to one + return whichbit; +} + +void testparity(void) + // outputs both vertices and their parity: +{ + printf("Vertex 1:\n"); + outbits(vertex1); + printf("\n"); + outbits(parity1); + printf("\n"); + /* + printf("Vertex 2:\n"); + outbits(vertex2); + printf("\n"); + outbits(parity2); + printf("\n"); + */ + printf("\n"); +} + +double lhpath(int droplabel) + // compute lemke-howson path when dropping label droplabel + // return length of path +{ + double length=0.0; // length of path + int newlabel; + if (droplabel < d) // start in vertex 1 + { + newlabel = invperm[adjvertex(vertex1, parity1, droplabel)]; + if (bout) { outbits(vertex1) ; printf(" "); outbits(vertex2); printf("\n");} + // if (bout) { outbits(vertex1); printf(" ");} + printf("newlabel %d\n", invperm[newlabel]+1); + length += 1.0; + } + else { + newlabel = invperm[droplabel]; // start in vertex 2 // EDIT BY RAHUL 1 July 2012 + //newlabel = droplabel; // start in vertex 2 + } + while(1) + { + // vertex 2 to move + newlabel = perm[adjvertex(vertex2, parity2, newlabel)]; + if (bout) { outbits(vertex1) ; printf(" "); outbits(vertex2); printf("\n");} + /*if (bout) { outbits(vertex2); printf("\n");}*/ + printf("newlabel %d\n", newlabel+1); + length += 1.0; + if (newlabel==droplabel) break; + // vertex 1 to move + newlabel = invperm[adjvertex(vertex1, parity1, newlabel)]; + if (bout) { outbits(vertex1) ; printf(" "); outbits(vertex2); printf("\n");} + //if (bout) { outbits(vertex1); printf(" ");} + printf("newlabel %d\n", invperm[newlabel]+1); + length += 1.0; + //if (newlabel==droplabel) break; + if (newlabel==invperm[droplabel]) break; // EDIT BY RAHUL 1 July 2012 + } + if (bout) printf("\n"); + return(length); +} + +/*================ main ==============*/ +int main(int argc, char *argv[]) +{ + int c; + int dl = -1 ; // droplabel + /* parse options */ + while ( (c = getopt (argc, argv, "d:l:o")) != -1) + switch (c) + { + int x; + case 'd': + x = atoi(optarg); + x = 2*(x/2); + if (x <= MAXD && x > 0 ) + d = x ; + else + { + fprintf(stderr, "Entered dimension %d ", x); + fprintf(stderr, "not OK.\n"); + return 1; + } + break; + case 'l': + dl = atoi(optarg)-1 ; + if (dl >= 0 && dl < 2*d) + break; + fprintf(stderr, "Dropped label %d ", dl); + fprintf(stderr, "not in range 1 .. %d, not OK.\n", + d+1); + return 1; + case 'o': + bout = 1; + break; + case '?': + if (isprint (optopt)) + fprintf (stderr, "Unknown option `-%c'.\n", optopt); + else + fprintf (stderr, + "Unknown option character `\\x%x'.\n", + optopt); + return 1; + default: + abort (); + } + /* options have been input */ + { + int i , fromlabel, tolabel; + double l,old =1.0; + n = 2*d; + if (dl<0) + { fromlabel = 0; tolabel =n;} + else + { fromlabel = dl; tolabel = dl+1;} + genperm(); + outperm(); + printf("Dimension %2d: \n", d); + + for (i=fromlabel; i [ seq(x^i, i=1..d)]; + L:=[seq(g(k), k=-d+1..d)]; + mu := add (L[i]/(2*d), i=1..2*d); + K := [seq( L[i]-mu, i=1..2*d)]; + C:= matrix([seq (K[i], i=1..d)]); + Cinv := inverse(C); + Dmat:= matrix([seq (K[i], i=d+1..2*d)]); + one := [seq(1, i=1..d)]; + r := evalm( one - evalm (Dmat &* evalm (Cinv &* one))); + S := matrix (d,d,0); + for i to d do S[i,i] := 1/r[i] od; + Btrans:= evalm(-S &* Dmat &* Cinv); + B:=transpose(Btrans); + perm := i -> i - 1 + 2*(i mod 2); + A := matrix (d,d,0); + for i to d do for j to d do A[perm(i),perm(j+d)-d] := Btrans[i,j] od od; + comm := 1 ; + for i to d do for j to d do comm:= lcm(comm, denom(A[i,j])) od od; + writedata( A, evalm(comm * A), integer); + print("Wrote payoff matrix A to file A"); + writedata( B, evalm(comm * B), integer); + print("Wrote payoff matrix B to file B"); +end proc; + +square:= proc (d) + g := x -> [ seq(x^i, i=1..d)]; + L:=[seq(g(k), k=-d+1..d)]; + mu := add (L[i]/(2*d), i=1..2*d); + K := [seq( L[i]-mu, i=1..2*d)]; + C:= matrix([seq (K[i], i=1..d)]); + Cinv := inverse(C); + Dmat:= matrix([seq (K[i], i=d+1..2*d)]); + one := [seq(1, i=1..d)]; + r := evalm( one - evalm (Dmat &* evalm (Cinv &* one))); + S := matrix (d,d,0); + for i to d do S[i,i] := 1/r[i] od; + Btrans:= evalm(-S &* Dmat &* Cinv); + B:=transpose(Btrans); + perm := i -> if i=1 then i else if i=d then d else if i [ seq(x^i, i=1..d)]; + threed := 3*d/2; + L:=[seq(g(k), k=-threed+1..threed)]; + mu := add (L[i]/(3*d), i=1..3*d); + K := [seq( L[i]-mu, i=1..3*d)]; + C:= matrix([seq (K[i], i=1..d)]); + Cinv := inverse(C); + Dmat:= matrix([seq (K[i], i=d+1..3*d)]); + one := [seq(1, i=1..d)]; + twoone := [seq(1, i=1..2*d)]; + r := evalm( twoone - evalm (Dmat &* evalm (Cinv &* one))); + S := matrix (2*d,2*d,0); + for i to 2*d do S[i,i] := 1/r[i] od; + Btrans:= evalm(-S &* Dmat &* Cinv); + B:=transpose(Btrans); + perm := i -> if i=1 then i else if i=d then d else if i [ seq(x^i, i=1..2*d)]; + LL:=[seq(gg(k), k=-threed+1..threed)]; + mumu := add ( LL[i]/(3*d), i=1..3*d); + KK := [seq( LL[i]-mumu, i=1..3*d)]; + Kperm := [seq ( KK[perm(i)], i=1..3*d)]; + + CC:= matrix([seq (Kperm[i], i=d+1..3*d)]); + CCinv := inverse(CC); + DD := matrix([seq (Kperm[i], i=1..d)]); + + rr := evalm( one - evalm (DD &* evalm (CCinv &* twoone))); + SS := matrix (d,d,0); + for i to d do SS[i,i] := 1/rr[i] od; + A := evalm(-SS &* DD &* CCinv); + + comm := 1 ; + for i to d do for j to 2*d do comm:= lcm(comm, denom(A[i,j])) od od; + writedata( A, evalm(comm * A), integer); + + comm := 1 ; + for i to d do for j to 2*d do comm:= lcm(comm, denom(B[i,j])) od od; + + Aint := evalm(comm * A); + Bint := evalm(comm * B); + # + + min := 0; + for i to d do + for j to 2*d do + if Aint[i,j]< min then min:= Aint[i,j] fi; + if Bint[i,j]< min then min:= Bint[i,j] fi; + od; + od; + # find smallest entry - could do seperately for A and B + + if min<0 then + for i to d do + for j to 2*d do + Aint[i,j]:= Aint[i,j] - min + 1; + Bint[i,j]:= Bint[i,j] - min + 1; + od; + od; + fi; + # now positive + + #max := 0; + #for i to d do + # for j to 2*d do + # if Aint[i,j]> max then max:= Aint[i,j] fi; + # if Bint[i,j]> max then max:= Bint[i,j] fi; + # od; + #od; + + #M:= matrix(3*d,3*d,max+1); + M:= matrix(3*d,3*d,0); + + for i to d do + for j to 2*d do + M[i,j+d]:= Aint[i,j]; + od; + od; + + for i to 2*d do + for j to d do + M[i+d,j]:= Bint[j,i]; + od; + od; + + writedata( A, evalm(Aint), integer); + print("Wrote payoff matrix A to file A"); + writedata( B, evalm(Bint), integer); + print("Wrote payoff matrix B to file B"); + writedata( M, M, integer); + print("Wrote min to file M"); +end proc; + + +chall_cost := proc (d) + g := x -> [ seq(x^i, i=1..d)]; + threed := 3*d/2; + L:=[seq(g(k), k=-threed+1..threed)]; + mu := add (L[i]/(3*d), i=1..3*d); + K := [seq( L[i]-mu, i=1..3*d)]; + C:= matrix([seq (K[i], i=1..d)]); + Cinv := inverse(C); + Dmat:= matrix([seq (K[i], i=d+1..3*d)]); + one := [seq(1, i=1..d)]; + twoone := [seq(1, i=1..2*d)]; + r := evalm( twoone - evalm (Dmat &* evalm (Cinv &* one))); + S := matrix (2*d,2*d,0); + for i to 2*d do S[i,i] := 1/r[i] od; + Btrans:= evalm(-S &* Dmat &* Cinv); + B:=transpose(Btrans); + perm := i -> if i=1 then i else if i=d then d else if i [ seq(x^i, i=1..2*d)]; + LL:=[seq(gg(k), k=-threed+1..threed)]; + mumu := add ( LL[i]/(3*d), i=1..3*d); + KK := [seq( LL[i]-mumu, i=1..3*d)]; + Kperm := [seq ( KK[perm(i)], i=1..3*d)]; + + CC:= matrix([seq (Kperm[i], i=d+1..3*d)]); + CCinv := inverse(CC); + DD := matrix([seq (Kperm[i], i=1..d)]); + + rr := evalm( one - evalm (DD &* evalm (CCinv &* twoone))); + SS := matrix (d,d,0); + for i to d do SS[i,i] := 1/rr[i] od; + A := evalm(-SS &* DD &* CCinv); + + comm := 1 ; + for i to d do for j to 2*d do comm:= lcm(comm, denom(A[i,j])) od od; + + comm := 1 ; + for i to d do for j to 2*d do comm:= lcm(comm, denom(B[i,j])) od od; + + Aint := evalm(-comm * A); + Bint := evalm(-comm * B); + # now costs + + min := 0; + for i to d do + for j to 2*d do + if Aint[i,j]< min then min:= Aint[i,j] fi; + if Bint[i,j]< min then min:= Bint[i,j] fi; + od; + od; + # find smallest entry - could do seperately for A and B + + if min<0 then + for i to d do + for j to 2*d do + Aint[i,j]:= Aint[i,j] - min + 1; + Bint[i,j]:= Bint[i,j] - min + 1; + od; + od; + fi; + # costs now positive + + max := 0; + for i to d do + for j to 2*d do + if Aint[i,j]> max then max:= Aint[i,j] fi; + if Bint[i,j]> max then max:= Bint[i,j] fi; + od; + od; + + M:= matrix(3*d,3*d,max+1); + + for i to d do + for j to 2*d do + M[i,j+d]:= Aint[i,j]; + od; + od; + + for i to 2*d do + for j to d do + M[i+d,j]:= Bint[j,i]; + od; + od; + + writedata( A, evalm(comm * A), integer); + print("Wrote payoff matrix A to file A"); + writedata( B, evalm(comm * B), integer); + print("Wrote payoff matrix B to file B"); + writedata( M, M, integer); + print("Wrote min to file M"); +end proc; + + diff --git a/native-algo/lh-vector/test/identity/Makefile b/native-algo/lh-vector/test/identity/Makefile new file mode 100644 index 0000000..1f9b7ec --- /dev/null +++ b/native-algo/lh-vector/test/identity/Makefile @@ -0,0 +1,19 @@ +CC = gcc +CFLAGS = -ansi -Wall -O3 -g + +all: genidentity genidenpath + +genidentity: genidentity.o + $(CC) genidentity.o $(LDFLAGS) -o genidentity + +genidentity.o: genidentity.c + $(CC) genidentity.c -c $(CFLAGS) -o genidentity.o + +genidenpath: genidenpath.o + $(CC) genidenpath.o $(LDFLAGS) -o genidenpath + +genidenpath.o: genidenpath.c + $(CC) genidenpath.c -c $(CFLAGS) -o genidenpath.o + +clean: + rm -rf *.o genidentity genidenpath \ No newline at end of file diff --git a/native-algo/lh-vector/test/identity/genidenpath.c b/native-algo/lh-vector/test/identity/genidenpath.c new file mode 100644 index 0000000..6c34851 --- /dev/null +++ b/native-algo/lh-vector/test/identity/genidenpath.c @@ -0,0 +1,30 @@ +/* + * genidentity.c + * Generates the path of an identity matrix from the + * artificial equilibrium using a given missing label + * Author: Tobenna Peter, Igwe ptigwe@gmail.com + */ +#include +#include + +int main(int argc, char** argv) +{ + if(argc < 2) + return 1; + + int n = atoi(argv[1]); + int k = atoi(argv[2]); + + printf("m= %d\nn= %d\n", n, n); + printf("labels:\n"); + if(k <= n) + { + printf("%d\n%d\n", k+n, k); + } + else + { + printf("%d\n%d\n", k-n, k); + } + + return 0; +} \ No newline at end of file diff --git a/native-algo/lh-vector/test/identity/genidentity.c b/native-algo/lh-vector/test/identity/genidentity.c new file mode 100644 index 0000000..57f2703 --- /dev/null +++ b/native-algo/lh-vector/test/identity/genidentity.c @@ -0,0 +1,43 @@ +/* + * genidentity.c + * Generates an identity matrix game + * Author: Tobenna Peter, Igwe ptigwe@gmail.com + */ +#include +#include + +int main(int argc, char** argv) +{ + if(argc < 1) + return 1; + int n = atoi(argv[1]); + printf("m= %d\n", n); + printf("n= %d\n", n); + printf("A=\n"); + int i, j; + for(i = 0; i < n; ++i) + { + for(j = 0; j < n; ++j) + { + if(i == j) + printf("1 "); + else + printf("0 "); + } + printf("\n"); + } + + printf("B=\n"); + for(i = 0; i < n; ++i) + { + for(j = 0; j < n; ++j) + { + if(i == j) + printf("1 "); + else + printf("0 "); + } + printf("\n"); + } + return 0; +} \ No newline at end of file diff --git a/native-algo/lh-vector/test/identity/identitytestm1 b/native-algo/lh-vector/test/identity/identitytestm1 new file mode 100755 index 0000000..7507e47 --- /dev/null +++ b/native-algo/lh-vector/test/identity/identitytestm1 @@ -0,0 +1,31 @@ +#!/bin/sh +#Test identity matrices using the first method for converting to an equivalent path +N=$1 +./genidentity $N > input +../../inlh < input > output +for k in $(eval echo {1..$((2*N))}) +do + echo -n "Testing label $k: " + ./genidenpath $N $k > tmp + ../../path/path < tmp > gpath + + grep -n "Number of pivots:" output | head -n 1 > line + L=`cat line | sed "s/\([0-9\]*\):.*/\1/"` + head -n $L output > cpath + R=$(($L-`wc -l output | sed 's/[ ]*\([0-9]*\) output/\1/'`)) + tail -n $R output > tmp + mv tmp output + + grep -x 'leaving:.*' cpath > tmp + mv tmp cpath + sed 's/leaving: \([a-z0-9]*\).*/\1/' cpath > tmp + mv tmp cpath + S=`diff cpath gpath` + if [ -z $S ] + then + echo "Passed" + else + echo "Failed" + fi +done +rm input cpath gpath \ No newline at end of file diff --git a/native-algo/lh-vector/test/identity/identitytestm2 b/native-algo/lh-vector/test/identity/identitytestm2 new file mode 100755 index 0000000..289c569 --- /dev/null +++ b/native-algo/lh-vector/test/identity/identitytestm2 @@ -0,0 +1,31 @@ +#!/bin/sh +#Test identity matrices using the first method for converting to an equivalent path +N=$1 +./genidentity $N > input +../../inlh -m < input > output +for k in $(eval echo {1..$((2*N))}) +do + echo -n "Testing label $k: " + ./genidenpath $N $k > tmp + ../../path/path -m < tmp > gpath + + grep -n "Number of pivots:" output | head -n 1 > line + L=`cat line | sed "s/\([0-9\]*\):.*/\1/"` + head -n $L output > cpath + R=$(($L-`wc -l output | sed 's/[ ]*\([0-9]*\) output/\1/'`)) + tail -n $R output > tmp + mv tmp output + + grep -x 'leaving:.*' cpath > tmp + mv tmp cpath + sed 's/leaving: \([a-z0-9]*\).*/\1/' cpath > tmp + mv tmp cpath + S=`diff cpath gpath` + if [ -z $S ] + then + echo "Passed" + else + echo "Failed" + fi +done +rm input cpath gpath \ No newline at end of file diff --git a/native-algo/lh-vector/test/invAB/Makefile b/native-algo/lh-vector/test/invAB/Makefile new file mode 100644 index 0000000..15c0d6e --- /dev/null +++ b/native-algo/lh-vector/test/invAB/Makefile @@ -0,0 +1,11 @@ +CC = gcc +CFLAGS = -ansi -Wall -O3 -g + +invABdtest: invABdtest.o ../../rat.o ../../alloc.o ../../mp.o + $(CC) invABdtest.o $(LDFLAGS) -lm ../../rat.o ../../alloc.o ../../mp.o -o invABdtest + +invABdtest.o: invABdtest.c + $(CC) invABdtest.c -c $(CFLAGS) -o invABdtest.o + +clean: + rm -rf *.o invABdtest diff --git a/native-algo/lh-vector/test/invAB/invABdtest.c b/native-algo/lh-vector/test/invAB/invABdtest.c new file mode 100644 index 0000000..cbdccba --- /dev/null +++ b/native-algo/lh-vector/test/invAB/invABdtest.c @@ -0,0 +1,165 @@ +/* +* invABdtest.c +* Used to test the validity of the computation of +* the inverse of A_B. +* Author: Tobenna Peter, Igwe +*/ +#include +#include +#include "../../mp.h" +#include "../../alloc.h" + +#define MAXSTR 100 + +int n; +mp* vecd; +mp* sol; +mp** invAB; + +/*------------------ error message ----------------*/ +void notimpl (char *info) +{ + fflush(stdout); + fprintf(stderr, "Program terminated with error. %s\n", info); + exit(1); +} + +/*------------------ read-in routines --------------------------*/ +/* reads string s from stdin, to fit char s[MAXSTR] +* if length >= MAXSTR-1 a warning is sent to stderr +* returns EOF if EOF encountered, then s undefined +*/ +int readstr (char *s) +{ + int tmp; + char fs[10]; /* MAXSTR must not exceed 7 decimal digits */ + sprintf (fs, "%%%ds",MAXSTR-1); /* generate format str */ + tmp = scanf (fs, s); + if (strlen(s)==MAXSTR-1) + { + fprintf(stderr, "Warning: input string\n%s\n", s); + fprintf(stderr, + "has max length %d, probably read incompletely\n", MAXSTR-1); + } + return tmp; /* is EOF if scanf encounters EOF */ +} + +/* s is a string of nonblank chars, which have to +* match in that order the next nonblank stdin chars +* readconf complains and terminates if not +*/ +void readconf (const char *s) +{ + int i, len = strlen(s); + char a[MAXSTR]; + for (i=0; i sample-output +M=`grep 'm=.*' sample-input | sed 's/m= \([0-9]*\)/\1/'` +N=`grep 'n=.*' sample-input | sed 's/n= \([0-9]*\)/\1/'` +C=`expr $M + $N` +../../inlh -a $1 < sample-input > sample-output +for k in $(eval echo {1..$C}) +do + echo -n "Testing label $k: " + S=`grep -n 'Printing invAB:' sample-output | sed 's/\([0-9]*\).*/\1/' | head -1` + echo "n= `expr $C + 2`" > tmp + echo "k= $k" > tmp2 + cat tmp tmp2 > tmp3 + echo "invAB=" > tmp2 + cat tmp3 tmp2 > tmp + L=$(($S+$C+2)) + head -$L sample-output | tail -$((C+2)) > tmp2 + cat tmp tmp2 > tmp3 + R=$((`wc -l sample-output | sed 's/[ ]*\([0-9]*\) sample-output/\1/'`-$L)) + tail -$R sample-output > tmp + mv tmp sample-output + ./invABdtest < tmp3 > tmp + G=`grep "z0= .*" tmp | sed 's/z0= \([0-9^ ]*\)/\1/'` + E=`grep "z0= .*" sample-output | sed 's/z0= \([0-9^ ]*\)/\1/' | head -1` + + if [ "$E" = "$G" ] + then + echo "Passed" + else + echo "Failed" + exit + fi +done +rm tmp* \ No newline at end of file diff --git a/native-algo/lh-vector/test/invAB/sample-input b/native-algo/lh-vector/test/invAB/sample-input new file mode 100644 index 0000000..df11106 --- /dev/null +++ b/native-algo/lh-vector/test/invAB/sample-input @@ -0,0 +1,16 @@ +m= 6 +n= 6 +A= +-180 72 -333 297 -153 270 +-30 17 -33 42 -3 20 +-81 36 -126 126 -36 90 + 90 -36 126 -126 36 -81 + 20 -3 42 -33 17 -30 +270 -153 297 -333 72 -180 +B= + 72 36 17 -3 -36 -153 +-180 -81 -30 20 90 270 +297 126 42 -33 -126 -333 +-333 -126 -33 42 126 297 +270 90 20 -30 -81 -180 +-153 -36 -3 17 36 72 diff --git a/native-algo/lh-vector/test/rat_dec/rat_dectestm1 b/native-algo/lh-vector/test/rat_dec/rat_dectestm1 new file mode 100755 index 0000000..256781c --- /dev/null +++ b/native-algo/lh-vector/test/rat_dec/rat_dectestm1 @@ -0,0 +1,32 @@ +#!/bin/sh +#Test identity matrices using the first method for converting to an equivalent path +N=$1 +for i in $(eval echo {1..10}) +do + echo -n "Testing $i/10" + d="0.$i" + r="$i\/10" + ../identity/genidentity $N > input + sed 's/1 0/'"$r"' 0/' input | sed 's/0 1/0 '"$r"'/' > rinput + sed 's/1 0/'"$d"' 0/' input | sed 's/0 1/0 '"$d"'/' > dinput + ../../inlh < rinput > rpath + ../../inlh < dinput > dpath + + grep -x 'leaving:.*' rpath > tmp + mv tmp rpath + sed 's/leaving: \([a-z0-9]*\).*/\1/' rpath > tmp + mv tmp rpath + + grep -x 'leaving:.*' dpath > tmp + mv tmp dpath + sed 's/leaving: \([a-z0-9]*\).*/\1/' dpath > tmp + mv tmp dpath + S=`diff dpath rpath` + if [ -z $S ] + then + echo "Passed" + else + echo "Failed" + fi +done +rm *input dpath rpath \ No newline at end of file diff --git a/native-algo/lh-vector/test/rat_dec/rat_dectestm2 b/native-algo/lh-vector/test/rat_dec/rat_dectestm2 new file mode 100755 index 0000000..00af87c --- /dev/null +++ b/native-algo/lh-vector/test/rat_dec/rat_dectestm2 @@ -0,0 +1,32 @@ +#!/bin/sh +#Test identity matrices using the first method for converting to an equivalent path +N=$1 +for i in $(eval echo {1..10}) +do + echo -n "Testing $i/10" + d="0.$i" + r="$i\/10" + ../identity/genidentity $N > input + sed 's/1 0/'"$r"' 0/' input | sed 's/0 1/0 '"$r"'/' > rinput + sed 's/1 0/'"$d"' 0/' input | sed 's/0 1/0 '"$d"'/' > dinput + ../../inlh -m < rinput > rpath + ../../inlh -m < dinput > dpath + + grep -x 'leaving:.*' rpath > tmp + mv tmp rpath + sed 's/leaving: \([a-z0-9]*\).*/\1/' rpath > tmp + mv tmp rpath + + grep -x 'leaving:.*' dpath > tmp + mv tmp dpath + sed 's/leaving: \([a-z0-9]*\).*/\1/' dpath > tmp + mv tmp dpath + S=`diff dpath rpath` + if [ -z $S ] + then + echo "Passed" + else + echo "Failed" + fi +done +rm *input dpath rpath \ No newline at end of file diff --git a/native-algo/lh-vector/test/testall b/native-algo/lh-vector/test/testall new file mode 100755 index 0000000..eb176cd --- /dev/null +++ b/native-algo/lh-vector/test/testall @@ -0,0 +1,37 @@ +#!/bin/sh + +echo "\nTesting identity matrix $1 with method 1\n" +cd ./identity +./identitytestm1 $1 + +echo "\nTesting identity matrix $1 with method 2\n" +./identitytestm2 $1 +cd ../ + +echo "\nTesting Rational and decimal input with method 1\n" +cd ./rat_dec +./rat_dectestm1 $1 + +echo "\nTesting Rational and decimal input with method 2\n" +./rat_dectestm2 $1 +cd ../ + +echo "\nTesting (d,d) dual cyclic polytopes for unique equilibrium\n" +cd ./dualcyclic/dxd +./dualcyclictest + +echo "\nTesting (d,d) dual cyclic polytopes with method 1\n" +cd ./dualcyclic/dxd +./dualcyclictestm1 + +echo "\nTesting (d,d) dual cyclic polytopes with method 2\n" +./dualcyclictestm1 +cd ../../ + +echo "\nTesting (d,2d) dual cyclic polytopes with method 1\n" +cd ./dualcyclic/dx2d +./pathlengthtestm1 + +echo "\nTesting (d,2d) dual cyclic polytopes with method 2\n" +./pathlengthtestm2 +cd ../../ \ No newline at end of file diff --git a/web-service/src/lse/math/games/web/LHServlet.java b/web-service/src/lse/math/games/web/LHServlet.java new file mode 100644 index 0000000..60cf92d --- /dev/null +++ b/web-service/src/lse/math/games/web/LHServlet.java @@ -0,0 +1,367 @@ +package lse.math.games.web; + +import java.io.BufferedReader; +import java.io.BufferedWriter; + +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.File; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.io.OutputStream; +import java.io.OutputStreamWriter; + +import java.util.Arrays; +import java.util.LinkedList; +import java.util.Vector; + +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import lse.math.games.Rational; +import lse.math.games.matrix.Bimatrix; +import lse.math.games.io.ColumnTextWriter; + + + +/** +* @author Martin Prause +* adapted by Tobenna Peter, Igwe +*/ +@SuppressWarnings("serial") +public class LHServlet extends AbstractRESTServlet +{ + private static final Logger log = Logger.getLogger(LHServlet.class.getName()); + final static String lineSeparator = System.getProperty("line.separator"); + + private String os; + //program1=Create H-representation + private String program="inlh"; + + + public void init(ServletConfig config) + throws ServletException + { + super.init(config); + os=System.getProperty("os.name"); + if (os.startsWith("Windows")){ + program += ".exe"; + } + outputPath = Paths.get(System.getProperty("user.dir")).resolve("game-output"); + } + + /** + * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) + */ + protected void doGet(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException + { + doPost(request, response); + } + + /** + * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) + */ + protected void doPost(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException + { + response.setContentType("text/plain"); + log.info("Processing new request"); + + Bimatrix game = null; + File f; + String consoleOutput=""; + + int estimate=Integer.parseInt(request.getParameter("es")); + Rational[][] a = parseMultiRowRatParam(request, "a"); + Rational[][] b = parseMultiRowRatParam(request, "b"); + String[] rowNames = request.getParameter("r") != null ? request.getParameter("r").split(" ") : null; + String[] colNames = request.getParameter("c") != null ? request.getParameter("c").split(" ") : null; + String algo = request.getParameter("algo"); + String pathToAlgo=request.getParameter("d"); + String maxSeconds=request.getParameter("ms"); + int nrows = 0; + int ncols = 0; + + //Check payoff matrix + if (a != null) { + nrows = a.length; + ncols = a.length > 0 ? a[0].length : 0; + + log.info("Processing bimatrix with nrows " + nrows + " and ncols " + ncols); + + if(!checkDimensions(a, nrows, ncols)) { + addError(request, "A (" + nrows + "x" + ncols + ") is incomplete: " + request.getParameter("a")); + } + } else { + addError(request, "Unable to parse A: " + request.getParameter("a")); + } + + if (b != null && a != null) { + if(!checkDimensions(b, nrows, ncols)) { + int nrowsb = a.length; + int ncolsb = a.length > 0 ? a[0].length : 0; + addError(request, "Dimensions of B (" + nrowsb + "x" + ncolsb + ") do not match A"); + } + } else { + addError(request, "Unable to parse B: " + request.getParameter("b")); + } + + if (!this.hasErrors(request)) + { + game = new Bimatrix(new String[]{"A" , "B"}, a, b, rowNames, colNames); + + try { + f = new File(pathToAlgo+program); + Runtime rt=Runtime.getRuntime(); + Process p=null; + String[] cmdArray = null; + + //Call external program and create H-Representation + if(estimate == 0) + cmdArray = new String[]{f.getCanonicalPath(), "-e"}; + else if(estimate == 1) + cmdArray = new String[]{f.getCanonicalPath(), "-p"}; + p = rt.exec(cmdArray); + + BufferedWriter out = new BufferedWriter(new OutputStreamWriter(p.getOutputStream())); + BufferedReader bri = new BufferedReader(new InputStreamReader(p.getInputStream())); + out.write("m= " + nrows + " n= " + ncols); + out.write("A= " + processMatrix(a)); + out.write("B= " + processMatrix(b)); + out.flush(); + out.close(); + + p.waitFor(); + + //Read consoleOutput + String line; + String lineSeparator = System.getProperty("line.separator"); + while ((line = bri.readLine()) != null) { + consoleOutput+=line+lineSeparator; + } + bri.close(); + log.info(consoleOutput); + p.waitFor(); + } catch (IOException e1){ + addError(request, e1.getMessage()); + log.log(Level.SEVERE,e1.toString()); + } catch(Throwable e2) { + addError(request, e2.getMessage()); + log.log(Level.SEVERE,e2.toString()); + } + try { + this.writeResponseHeader(request, response); + if (game != null) { + StringBuilder outStrBuilder=new StringBuilder(); + outStrBuilder.append("Strategic form: "); + outStrBuilder.append(lineSeparator); + outStrBuilder.append(lineSeparator); + outStrBuilder.append(game.printFormatHTML()); + outStrBuilder.append(lineSeparator); + outStrBuilder.append(lineSeparator); + outStrBuilder.append("EE = Extreme Equilibrium, EP = Expected Payoffs"); + outStrBuilder.append(lineSeparator); + outStrBuilder.append(lineSeparator); + outStrBuilder.append("Rational:"); + outStrBuilder.append(lineSeparator); + outStrBuilder.append(formatOutput(processOutput(consoleOutput, true, rowNames, colNames), estimate)); + outStrBuilder.append(lineSeparator); + outStrBuilder.append("Decimal:"); + outStrBuilder.append(lineSeparator); + outStrBuilder.append(formatOutput(processOutput(consoleOutput, false, rowNames, colNames), estimate)); + + response.getWriter().println(outStrBuilder.toString()); + } + } catch (Exception ex) { + ex.printStackTrace(); + response.getWriter().println(ex.getStackTrace()); + } + + } + } + + private String processMatrix(Rational[][] A) + { + String s = ""; + String lineSeparator = System.getProperty("line.separator"); + + for (int i=0; i < A.length; i++) + { + for (int j=0; j < A[i].length; j++) + { + s += " " + A[i][j]; + } + s += lineSeparator; + } + return s; + } + + private boolean checkDimensions(T[][] mat, int row, int col) + { + if (mat.length != row) return false; + for (int i = 0; i < row; ++i) + { + if (mat[i].length != col) return false; + } + return true; + } + + private Rational[][] parseMultiRowRatParam(HttpServletRequest request, String name) + { + String matStr = request.getParameter(name); + if (matStr != null) { + try { + return parseRatMatrix(matStr); + } catch (NumberFormatException ex) { + addError(request, name + " matrix has invalid entries: " + ex.getMessage() + "\r\n" + matStr); + } + } + return null; + } + + + private Rational[][] parseRatMatrix(String matStr) + { + String[] vecStrArr = matStr.trim().split("\\r\\n"); + Rational[][] mat = new Rational[vecStrArr.length][]; + for (int i = 0; i < mat.length; ++i) + { + mat[i] = parseRatVector(vecStrArr[i].trim()); + } + return mat; + } + + private Rational[] parseRatVector(String vecStr) + { + String[] strArr = vecStr.split(",?\\s+"); + Rational[] vec = new Rational[strArr.length]; + for (int i = 0; i < vec.length; ++i) + { + vec[i] = Rational.valueOf(strArr[i]); + } + return vec; + } + + public static void printRow(String name, Rational value, ColumnTextWriter colpp, boolean excludeZero) + { + Rational.printRow(name, value, colpp, excludeZero); + } + + private String processOutput(String s, Boolean rational, String[] rowNames, String[] colNames) + { + StringBuilder output = new StringBuilder(); + String lines[] = s.split("\\r?\\n"); + String lineSeparator = System.getProperty("line.separator"); + + for (int i = 0; i < lines.length; ++i) + { + output.append(processLine(lines[i], rational, rowNames, colNames)); + output.append(lineSeparator); + } + + return output.toString(); + } + + private String processLine(String l, Boolean rational, String[] rowNames, String[] colNames) + { + StringBuilder output = new StringBuilder(); + String entries[] = l.split("\\s+"); + + if (entries[0].contains("P") || entries[0].contains("E")) + { + output.append(entries[0] + " "); + for (int i = 1; i < entries.length; ++i) + { + if (entries[i].contains("P") || entries[i].contains("E") || entries[i].contains("d")) + { + output.append(entries[i] + " "); + continue; + } + if (rational) + { + output.append(entries[i] + " "); + } + else + { + String ts = Double.toString((Math.round(Rational.valueOf(entries[i]).doubleValue() *100000.)/100000.)); + if (ts.equals("0.0")) { + ts="0"; + } + output.append(ts + " "); + } + } + } + else if (entries[0].contains("L")) + { + output.append(entries[0] + " "); + output.append(entries[1] + " "); + + for (int i = 2; i < entries.length; ++i) + { + if (i >= rowNames.length + colNames.length + 2) + break; + String label = (i - 2 < rowNames.length) ? rowNames[i - 2] : colNames[i - rowNames.length - 2]; + output.append(entries[i].replace((i - 1) + "->", label + "->") + " "); + } + } + + return output.toString(); + } + + private String formatOutput(String s, int estimate) + { + String lines[] = s.split("\\r?\\n"); + Vector l=new Vector(); + if (estimate == 1) + { + String p1[] = lines[4].split("\\s+"); + for (int j = 0; j < p1.length; j++) + { + l.add(p1[j].length()); + } + } + for (int i=0;iNative lse.math.games.web.NativeServlet + + LH + lse.math.games.web.LHServlet + Native /native/servlet + + + LH + /lh/servlet + LrsC diff --git a/web-service/war/builder/webservices.xml b/web-service/war/builder/webservices.xml index b17b4fb..ad6fda9 100644 --- a/web-service/war/builder/webservices.xml +++ b/web-service/war/builder/webservices.xml @@ -23,6 +23,26 @@ --> + + 1 + Lemke-Howson using covering vectors + /gte/lh/ + nf + native-algo/lh-vector/ + 0 + 600 + + + + 1 + Lemke-Howson using covering vectors + /gte/lh/ + nf + native-algo/lh-vector/ + 1 + 600 + + 1 Lemke Find One Equilibrium (Strategic Form) @@ -32,8 +52,7 @@ 600 - - + 1 Lemke Find One Equilibrium (Sequence Form) /gte/tree/ diff --git a/web-service/war/lh/index.jsp b/web-service/war/lh/index.jsp new file mode 100644 index 0000000..5655686 --- /dev/null +++ b/web-service/war/lh/index.jsp @@ -0,0 +1,3 @@ + +<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> + \ No newline at end of file diff --git a/web-service/war/lh/servlet/hidden.txt b/web-service/war/lh/servlet/hidden.txt new file mode 100644 index 0000000..019adf0 --- /dev/null +++ b/web-service/war/lh/servlet/hidden.txt @@ -0,0 +1 @@ +Files in this folder are accessible to the server but not to a browser \ No newline at end of file From c64c7437c52437afb9791aa37457952d334c20a6 Mon Sep 17 00:00:00 2001 From: "Tobenna P. Igwe" Date: Thu, 7 May 2015 14:20:22 +0100 Subject: [PATCH 2/4] Minor indentation changes to results of LH --- web-service/src/lse/math/games/web/LHServlet.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/web-service/src/lse/math/games/web/LHServlet.java b/web-service/src/lse/math/games/web/LHServlet.java index 60cf92d..32c4da1 100644 --- a/web-service/src/lse/math/games/web/LHServlet.java +++ b/web-service/src/lse/math/games/web/LHServlet.java @@ -308,6 +308,10 @@ else if (entries[0].contains("L")) { if (i >= rowNames.length + colNames.length + 2) break; + + if (i == rowNames.length + 2) + output.append(" - "); + String label = (i - 2 < rowNames.length) ? rowNames[i - 2] : colNames[i - rowNames.length - 2]; output.append(entries[i].replace((i - 1) + "->", label + "->") + " "); } From 2e3263655b1ded576aaefd2b50c66d51e7c45a9d Mon Sep 17 00:00:00 2001 From: "Tobenna P. Igwe" Date: Thu, 7 May 2015 14:21:16 +0100 Subject: [PATCH 3/4] Changed 'NEq' and 'PEq' to 'Eq-' and 'Eq+' respectively --- native-algo/lh-vector/glemke.c | 4 ++-- native-algo/lh-vector/lemke.c | 4 ++-- native-algo/lh-vector/list.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/native-algo/lh-vector/glemke.c b/native-algo/lh-vector/glemke.c index c83cf15..ab27f4a 100644 --- a/native-algo/lh-vector/glemke.c +++ b/native-algo/lh-vector/glemke.c @@ -1536,11 +1536,11 @@ void computeEquilibria(Flagsrunlemke flags) sprintf(smp, "\n%d-ve index:", negi); colpr(smp); colnl(); - printlist(neg, 'N'); + printlist(neg, '-'); sprintf(smp, "\n%d+ve index:", posi); colpr(smp); colnl(); - printlist(pos, 'P'); + printlist(pos, '+'); colout(); } } diff --git a/native-algo/lh-vector/lemke.c b/native-algo/lh-vector/lemke.c index ffa9375..1a2251f 100644 --- a/native-algo/lh-vector/lemke.c +++ b/native-algo/lh-vector/lemke.c @@ -1480,11 +1480,11 @@ void computeEquilibria(Flagsrunlemke flags) sprintf(smp, "\n%d-ve index:", negi); colpr(smp); colnl(); - printlist(neg, 'N'); + printlist(neg, '-'); sprintf(smp, "\n%d+ve index:", posi); colpr(smp); colnl(); - printlist(pos, 'P'); + printlist(pos, '+'); colout(); } } diff --git a/native-algo/lh-vector/list.c b/native-algo/lh-vector/list.c index 9fec5de..7f282c9 100644 --- a/native-algo/lh-vector/list.c +++ b/native-algo/lh-vector/list.c @@ -130,7 +130,7 @@ void printlist(node* list, char prefix) int i = 0; while(cur != NULL) { - sprintf(smp, "%cEq[%d]: ", prefix, i++); + sprintf(smp, "Eq%c[%d]: ", prefix, i++); colpr(smp); colprEquilibrium(cur->eq); int k; From 8222f887b938bd476831f681fa1807bb03d260eb Mon Sep 17 00:00:00 2001 From: "Tobenna P. Igwe" Date: Thu, 7 May 2015 21:29:32 +0100 Subject: [PATCH 4/4] Reset the matrix viewer when loading a game. If the matrix viewer is set to either zero-sum or symmetric game, then GTE loads a the first matrix and sets the second based on the current setting. --- gui-builder/src/lse/math/games/builder/view/Main.mxml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gui-builder/src/lse/math/games/builder/view/Main.mxml b/gui-builder/src/lse/math/games/builder/view/Main.mxml index 9eaa586..2510eb6 100644 --- a/gui-builder/src/lse/math/games/builder/view/Main.mxml +++ b/gui-builder/src/lse/math/games/builder/view/Main.mxml @@ -1311,7 +1311,7 @@ - +