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/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 @@ - + 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..ab27f4a --- /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, '-'); + sprintf(smp, "\n%d+ve index:", posi); + colpr(smp); + colnl(); + printlist(pos, '+'); + 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..1a2251f --- /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, '-'); + sprintf(smp, "\n%d+ve index:", posi); + colpr(smp); + colnl(); + printlist(pos, '+'); + 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..7f282c9 --- /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, "Eq%c[%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 0000000..600f9e6 Binary files /dev/null and b/native-algo/lh-vector/report/final.pdf differ 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 0000000..6a0477a Binary files /dev/null and b/native-algo/lh-vector/report/final/img/img0.pdf differ 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 0000000..d596e5d Binary files /dev/null and b/native-algo/lh-vector/report/final/img/img1.pdf differ diff --git a/native-algo/lh-vector/report/final/img/img2.pdf b/native-algo/lh-vector/report/final/img/img2.pdf new file mode 100644 index 0000000..fa04a9c Binary files /dev/null and b/native-algo/lh-vector/report/final/img/img2.pdf differ 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 0000000..8b04a90 Binary files /dev/null and b/native-algo/lh-vector/report/mideval.pdf differ diff --git a/native-algo/lh-vector/report/summary.pdf b/native-algo/lh-vector/report/summary.pdf new file mode 100644 index 0000000..fea0d33 Binary files /dev/null and b/native-algo/lh-vector/report/summary.pdf differ 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 0000000..fea0d33 Binary files /dev/null and b/native-algo/lh-vector/summary.pdf differ 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..32c4da1 --- /dev/null +++ b/web-service/src/lse/math/games/web/LHServlet.java @@ -0,0 +1,371 @@ +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; + + 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 + "->") + " "); + } + } + + 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