remove lpsolve

release/4.3a0
thduynguyen 2014-12-16 11:27:20 -05:00
parent 44477e12f2
commit b39d14872a
160 changed files with 13 additions and 109651 deletions

View File

@ -1,169 +0,0 @@
CC= gcc
MINGW_EXTRA = c:/cygwin/mingw
MINGW_INCDIR = $(MINGW_EXTRA)/include
MINGW_LIBDIR = $(MINGW_EXTRA)/lib
AS = as
DLLTOOL = dlltool
DLLWRAP = dllwrap
DLLWRAP_FLAGS = --dlltool-name=$(DLLTOOL) --as=$(AS) --driver-name=$(CC) \
--target=i386-mingw32
DLL_LDFLAGS = -L$(MINGW_LIBDIR) -mno-cygwin -mwindows
DLL_LDLIBS = liblpk.a
#
# Beginning of supplied stuff
#
#should be OK in most situations:
#CFLAGS= -O
# HP/UX 9.0X optimized code
#CFLAGS= +O3 +Oaggressive +Olibcalls -Aa -D_POSIX_SOURCE -DCHECK +FP VZOUiD
# HP/UX 9.0X debugging
#CFLAGS= -g -Aa -D_POSIX_SOURCE -DCHECK +FP VZOUiD
# nice for gcc
CFLAGS= -O3 -Wall -pedantic -ansi -mrtd
#CFLAGS= -g -Wall -pedantic -ansi
INCLUDE=-Ibfp -Ibfp/bfp_etaPFI -I. -Icolamd -Ishared
CFLAGS= -O3 -Wall -pedantic -ansi -mrtd -mno-cygwin -I$(MINGW_INCDIR)\
-DINTEGERTIME -DPARSER_LP -DYY_INTERACTIVE -DWIN32 $(INCLUDE) \
-DBUILDING_FOR_R -DWIN32 -g
# Option -DCHECK checks for numerical problems during rounding of numbers.
# It will slow things down a bit.
# You can add a -DREAL=<float type> to the CFLAGS, to change the default float
# type used in lp_solve (double) to float or 'long double'. However, type float
# might be fast on your computer, but it is not accurate enough to solve even
# moderately sized problems without running into numerical problems.
# The use of long doubles does increase the numerical stability of lp_solve,
# if your compiler actually implements them with more bits than a double. But
# it slows down things quite a bit.
# Choose your favorite or available version of lex and yacc
#YACC= yacc
#especially for linux:
YACC= bison -y
#LEX= lex
#especially for linux:
LEX= flex -l
#LEXLIB= -ll
#especially for linux:
LEXLIB= -lfl
#ANSI math lib
#MATHLIB= -lM
#non-ANSI math lib, should also work
MATHLIB= -lm
LPKSRC.c= $(wildcard *.c) lp_MDO.c \
colamd/colamd.c shared/commonlib.c shared/myblas.c
LEXFILE.l= lp_rlp.l
YACCFILE.y= lp_rlp.y
LPKLIB=liblpk.a
LEXFILE.c= $(LEXFILE.l:.l=.c)
YACCFILE.c= $(YACCFILE.y:.y=.c)
YACCFILE.o= $(YACCFILE.y:.y=.o)
CSOURCES=$(LEXFILE.c) $(YACCFILE.c) $(wildcard *.c)
# commonlib.c fortify.c lp_Hash.c \
# lp_LUMOD.c lp_MPS.c lp_SOS.c lp_crash.c lp_lib.c lp_matrix.c lp_mipbb.c \
# lp_presolve.c lp_price.c lp_pricePSE.c lp_report.c lp_rlp.c lp_scale.c \
# lp_simplex.c lp_solveDLL.c lp_utils.c lp_wlp.c lpslink.c myblas.c \
# yacc_read.c
COBJ=$(CSOURCES:.c=.o)
LPKSRC= $(LPKSRC.c) $(YACCFILE.c)
LPKOBJ= $(LPKSRC:.c=.o)
HEADERS=*.h
all: lpslink.dll
q8.exe: q8.o
$(CC) -o q8.exe $(CFLAGS) \
--allow-multiple-definition \
q8.o colamd/colamd.o shared/commonlib.o \
fortify.o ini.o \
lp_Hash.o lp_LUSOL.o lp_MDO.o lp_MPS.o lp_SOS.o lp_crash.o lp_lib.o \
lp_matrix.o lp_mipbb.o lp_params.o lp_presolve.o lp_price.o lp_pricePSE.o \
lp_report.o lp_rlp.o lp_scale.o lp_simplex.o lp_utils.o lp_wlp.o lpslink.o \
lusol.o mmio.o shared/myblas.o yacc_read.o \
$(MATHLIB) $(LPKLIB) \
-Wl,--allow-multiple-definition
$(COBJ): $(HEADERS)
purify: lp_solve.o $(LPKLIB)
purify $(CC) -o $(TARGET) $(CFLAGS) lp_solve.o $(LPKLIB) $(LEXLIB) $(MATHLIB)
quantify: lp_solve.o $(LPKLIB)
quantify $(CC) -o $(TARGET) $(CFLAGS) lp_solve.o $(LPKLIB) $(LEXLIB) $(MATHLIB)
$(LPKLIB): $(LPKOBJ)
ar rv $@ $(LPKOBJ)
ranlib $(LPKLIB)
$(YACCFILE.o): $(LEXFILE.c)
$(LEXFILE.c): $(LEXFILE.l)
$(LEX) $(LEXFILE.l)
mv lex.yy.c $(LEXFILE.c)
$(YACCFILE.c): $(YACCFILE.y)
$(YACC) $(YACCFILE.y)
mv y.tab.c $(YACCFILE.c)
# liblpk.def: lpslink.o
# dlltool -z liblpk.def -e exports.o -l liblpk.lib lpslink.o
lpslink.dll: lpslink.o liblpk.def liblpk.a
$(DLLWRAP) $(DLLWRAP_FLAGS) -o $@ --def liblpk.def \
lpslink.o $(DLL_LDFLAGS) $(DLL_LDLIBS)
test:
-for i in $(TESTFILES1); do\
./$(TARGET) -s -S3 -time < $$i > xxx.tmp;\
if diff xxx.tmp lp_examples/`basename $$i .lp`.out > /dev/null; then\
echo "$$i gives the correct result";\
else\
echo "*** $$i gives different result, please check ***";\
fi;\
done;\
for i in $(TESTFILES2); do\
./$(TARGET) -mps -s -S3 -time < $$i > xxx.tmp;\
if diff xxx.tmp lp_examples/`basename $$i .mps`.out > /dev/null; then\
echo "$$i gives the correct result";\
else\
echo "*** $$i gives different result, please check ***";\
fi;\
done;\
rm xxx.tmp
mktest:
-for i in $(TESTFILES1); do\
./$(TARGET) -s -S3 -time < $$i > lp_examples/`basename $$i .lp`.out;\
done;\
for i in $(TESTFILES2); do\
./$(TARGET) -mps -s -S3 -time < $$i > lp_examples/`basename $$i .mps`.out;\
done;\
$(TARGET).man: $(TARGET).1
nroff -man $(TARGET).1 > $(TARGET).man
MANIFEST: clean
ls -lR > MANIFEST; ls -lR > MANIFEST
clean:
rm -f *.a *.o TAGS $(LEXFILE.c) $(YACCFILE.c) demo $(TARGET) lp2mps mps2lp .pure .softdebughist datafile
TAGS:
etags *.[chyl]

View File

@ -1,83 +0,0 @@
#
# Makefile for building lp_solve using GNU Make
# Usage:
# make -f Makefile.Linux [all | bin | lib | clean]
#
# $Revision: 1.1 $
#
AR = ar
ARFLAGS = rv
CC = gcc
LEX = flex
YACC = bison
INCLUDE = -I. -Ibfp -Ibfp/bfp_LUSOL -Ibfp/bfp_LUSOL/LUSOL -Icolamd -Ishared
# Uncomment any of the following two depending on your profile
#DEBUG = -g -pg
DEBUG = -O2
DEFINE = -DYY_NEVER_INTERACTIVE -DPARSER_LP -DINVERSE_ACTIVE=INVERSE_LUSOL -DRoleIsExternalInvEngine
# Uncomment any of the following two depending on how easily compiler messages scare you
#CFLAGS= $(INCLUDE) $(DEBUG) $(DEFINE) -fpic -Wall -pedantic -trigraphs
CFLAGS= $(INCLUDE) $(DEBUG) $(DEFINE) -fpic
LFLAGS = -L -l
YFLAGS = --no-lines -y
LDFLAGS = -lm -ldl
LUSOLSRC = bfp/bfp_LUSOL/lp_LUSOL.c bfp/bfp_LUSOL/LUSOL/lusol.c
LUSOLOBJS = bfp/bfp_LUSOL/lp_LUSOL.o bfp/bfp_LUSOL/LUSOL/lusol.o
OBJECTS = $(LUSOLOBJS) lp_MDO.o shared/commonlib.o colamd/colamd.o \
shared/mmio.o shared/myblas.o ini.o fortify.o lp_rlp.o lp_crash.o \
lp_Hash.o lp_lib.o lp_wlp.o lp_matrix.o lp_mipbb.o lp_MPS.o \
lp_params.o lp_presolve.o lp_price.o lp_pricePSE.o lp_report.o \
lp_scale.o lp_simplex.o lp_SOS.o lp_utils.o yacc_read.o
SRC = $(LUSOLSRC) lp_MDO.c shared/commonlib.c colamd/colamd.c \
shared/mmio.c shared/myblas.c ini.c fortify.c lp_rlp.c lp_crash.c \
lp_Hash.c lp_lib.c lp_wlp.c lp_matrix.c lp_mipbb.c lp_MPS.c \
lp_params.c lp_presolve.c lp_price.c lp_pricePSE.c lp_report.c \
lp_scale.c lp_simplex.c lp_SOS.c lp_utils.c yacc_read.c
LIBRARIES = liblpsolve55.a liblpsolve55.so
BINARIES = lp_solve demo
ALL = $(BINARIES) $(DEMOS) $(LIBRARIES)
.PHONY=clean lp_solve
all: $(ALL)
lib: $(LIBRARIES)
bin: $(BINARIES)
objects: $(OBJECTS)
lp_rlp.o: lp_rlp.l lp_rlp.y
$(LEX) $(LFLAGS) lp_rlp.l
sed -e "s/yy/lp_yy/g" lex.yy.c >lp_rlp.h
rm -f lex.yy.c
$(YACC) $(YFLAGS) lp_rlp.y
sed -e "s/yy/lp_yy/g" y.tab.c >lp_rlp.c
rm -f y.tab.c
$(CC) $(CFLAGS) $(DEBUG) $(DEFINE) $(INCLUDE) -c $*.c
lp_solve: lp_solve/lp_solve.c $(OBJECTS)
$(CC) $(CFLAGS) $(DEBUG) $(DEFINE) $(INCLUDE) $< $(OBJECTS) -o lp_solve/lp_solve $(LDFLAGS)
demo: demo/demo.c $(OBJECTS)
$(CC) $(CFLAGS) $(DEBUG) $(DEFINE) $(INCLUDE) $< $(OBJECTS) -o demo/demo $(LDFLAGS)
liblpsolve55.a: $(OBJECTS)
$(AR) $(ARFLAGS) lpsolve55/$@ `echo $(SRC)|sed 's/[.]c/.o/g'`
ranlib lpsolve55/$@
liblpsolve55.so: $(OBJECTS)
$(CC) -fpic -shared -Wl,-Bsymbolic -Wl,-soname,$@ -o lpsolve55/$@ `echo $(SRC)|sed 's/[.]c/.o/g'` $(LDFLAGS)
clean:
rm -f $(OBJECTS) *.so *.a lp_solve/lp_solve demo/demo lpsolve55/*.so lpsolve55/*.a

View File

@ -1,131 +0,0 @@
PACKAGE_NAME=@PACKAGE_NAME@
PACKAGE_STRING=@PACKAGE_NAME@_@PACKAGE_VERSION@
CCSHARED=@CCSHARED@
prefix = @prefix@
includedir = @includedir@/lpsolve
libdir = @libdir@
CFLAGS=@CFLAGS@
INCLUDES=-I. -I./shared -I./bfp -I./bfp/bfp_LUSOL -I./bfp/bfp_LUSOL/LUSOL -I./colamd
DEFINES=-DYY_NEVER_INTERACTIVE -DPARSER_LP -DINVERSE_ACTIVE=INVERSE_LUSOL -DRoleIsExternalInvEngine @DEF@
LIBS=-lc -lm -ldl
INSTALL_DATA = ${INSTALL} -m 644
INSTALL_PROGRAM = ${INSTALL}
INSTALL_SCRIPT = ${INSTALL}
INSTALL = @INSTALL@
mkdir_p = mkdir -p
HEADERS = \
declare.h \
fortify.h \
ini.h \
lp_crash.h \
lp_explicit.h \
lp_fortify.h \
lp_Hash.h \
lpkit.h \
lp_lib.h \
lp_matrix.h \
lp_MDO.h \
lp_mipbb.h \
lp_MPS.h \
lp_presolve.h \
lp_price.h \
lp_pricePSE.h \
lp_report.h \
lp_rlp.h \
lp_scale.h \
lp_simplex.h \
lp_solveDLL.h \
lpsolve.h \
lp_SOS.h \
lp_types.h \
lp_utils.h \
lp_wlp.h \
ufortify.h \
yacc_read.h
SOURCES = lp_MDO.c \
shared/commonlib.c \
shared/mmio.c \
shared/myblas.c \
ini.c \
fortify.c \
colamd/colamd.c \
lp_rlp.c \
lp_crash.c \
bfp/bfp_LUSOL/lp_LUSOL.c \
bfp/bfp_LUSOL/LUSOL/lusol.c \
lp_Hash.c \
lp_lib.c \
lp_wlp.c \
lp_matrix.c \
lp_mipbb.c \
lp_MPS.c \
lp_params.c \
lp_presolve.c \
lp_price.c \
lp_pricePSE.c \
lp_report.c \
lp_scale.c \
lp_simplex.c \
lp_SOS.c \
lp_utils.c \
yacc_read.c
all: liblpsolve55.a @SHARED_LIB@
# OBJECTS = $(patsubst %.c,%.o,$(SOURCES))
#.c.o:
# $(CC) -s -c $(INCLUDES) $(CFLAGS) $(DEFINES) $(SOURCES)
liblpsolve55.a: $(SOURCES)
$(CC) -s -c $(INCLUDES) $(CFLAGS) $(DEFINES) $(SOURCES)
ar rv $@ `echo $(SOURCES)|sed s/[.]c/.o/g|sed 's/[^ ]*\///g'`
ranlib $@
liblpsolve55@SO@: $(SOURCES)
$(CC) $(CCSHARED) -s -c $(INCLUDES) $(CFLAGS) $(DEFINES) $(SOURCES)
$(CC) -shared -Wl,-Bsymbolic -Wl,-soname,$@ -o $@ `echo $(SOURCES)|sed s/[.]c/.o/g|sed 's/[^ ]*\///g'` $(LIBS)
install: install-HEADERS install-LIBRARIES
install-HEADERS: $(HEADERS)
test -d $(includedir) || $(mkdir_p) $(includedir)
@list='$(HEADERS)'; for p in $$list; do \
echo " $(INSTALL) $$p $(includedir)/$$f"; \
$(INSTALL) $$p $(includedir)/$$f; \
done
install-LIBRARIES: liblpsolve55.a @SHARED_LIB@
test -d $(libdir) || $(mkdir_p) $(libdir)
@list='liblpsolve55.a @SHARED_LIB@'; for p in $$list; do \
if test -f $$p; then \
echo " $(INSTALL) $$p $(libdir)/$$f"; \
$(INSTALL) $$p $(libdir)/$$f; \
else :; fi; \
done
uninstall-LIBRARIES:
@set -x; list='liblpsolve55.a @SHARED_LIB@'; for p in $$list; do \
echo " rm -f $(libdir)/$$f"; \
rm -f "$(libdir)/$$f"; \
done
uninstall: uninstall-HEADERS uninstall-LIBRARIES
uninstall-HEADERS:
@set -x; @list=$(HEADERS); for p in $$list; do \
echo " rm -f $(includedir)/$$f"; \
rm -f "$(includedir)/$$f"; \
done
dist:
mkdir $(PACKAGE_STRING)
tar -cpf- -T MANIFEST | (cd $(PACKAGE_STRING) && tar -xpf- )
tar -czpf $(PACKAGE_STRING).tar.bz2 ./$(PACKAGE_STRING)
-rm -fr $(PACKAGE_STRING)
CLEANFILES = *.o *.so *.a
clean:
-rm -f $(CLEANFILES)
.PHONY: install install-HEADERS install-LIBRARIES uninstall uninstall-HEADERS uninstall-LIBRARIES all

View File

@ -1,89 +0,0 @@
#
# Makefile for building lp_solve using GNU Make
# Usage:
# gmake -f Makefile.msc [all | bin | lib | clean]
#
# $Revision: 1.1 $
#
AR = ar
ARFLAGS = rv
CC = cl
LEX = flex
YACC = bison
INC = -I. -Ibfp -Ibfp/bfp_LUSOL -Ibfp/bfp_LUSOL/LUSOL -Icolamd -Ishared
# Uncomment any of the following two depending on your profile
#DEBUG = -g -pg
DEBUG = /ML /O1 /Zp8 /Gd /W2 /DWIN32 /D_WINDOWS
DEFINE = -DNoParanoia -DWIN32 -DYY_NEVER_INTERACTIVE -DPARSER_LP -DINVERSE_ACTIVE=INVERSE_LUSOL -DRoleIsExternalInvEngine
# Uncomment any of the following two depending on how easily compiler messages scare you
CFLAGS= $(INC) $(DEBUG) $(DEFINE) -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE
LFLAGS = -L -l
YFLAGS = --no-lines -y
LDFLAGS =
LUSOLSRC = bfp/bfp_LUSOL/lp_LUSOL.c bfp/bfp_LUSOL/LUSOL/lusol.c
LUSOLOBJS = bfp/bfp_LUSOL/lp_LUSOL.obj bfp/bfp_LUSOL/LUSOL/lusol.obj
OBJECTS = $(LUSOLOBJS) lp_MDO.obj shared/commonlib.obj colamd/colamd.obj \
shared/mmio.obj shared/myblas.obj ini.obj fortify.obj lp_rlp.obj lp_crash.obj \
lp_Hash.obj lp_lib.obj lp_wlp.obj lp_matrix.obj lp_mipbb.obj lp_MPS.obj \
lp_params.obj lp_presolve.obj lp_price.obj lp_pricePSE.obj lp_report.obj \
lp_scale.obj lp_simplex.obj lp_SOS.obj lp_utils.obj yacc_read.obj
SRC = $(LUSOLSRC) lp_MDO.c shared/commonlib.c colamd/colamd.c \
shared/mmio.c shared/myblas.c ini.c fortify.c lp_rlp.c lp_crash.c \
lp_Hash.c lp_lib.c lp_wlp.c lp_matrix.c lp_mipbb.c lp_MPS.c \
lp_params.c lp_presolve.c lp_price.c lp_pricePSE.c lp_report.c \
lp_scale.c lp_simplex.c lp_SOS.c lp_utils.c yacc_read.c
#LIBRARIES = liblpsolve55.lib liblpsolve55d.lib lpsolve55.dll
LIBRARIES =
#BINARIES = lp_solve.exe demo.exe
BINARIES = lp_solve.exe
ALL = $(BINARIES) $(DEMOS) $(LIBRARIES)
.PHONY=clean lp_solve
all: $(ALL)
lib: $(LIBRARIES)
bin: $(BINARIES)
objects: $(OBJECTS)
$(OBJECTS): $(SRC)
$(CC) -c $(CFLAGS) $(SRC)
lp_rlp.c: lp_rlp.l lp_rlp.y
$(LEX) $(LFLAGS) lp_rlp.l
sed -e "s/yy/lp_yy/g" lex.yy.c >lp_rlp.h
rm -f lex.yy.c
$(YACC) $(YFLAGS) lp_rlp.y
sed -e "s/yy/lp_yy/g" y.tab.c >lp_rlp.c
rm -f y.tab.c
$(CC) $(CFLAGS) $(DEBUG) $(DEFINE) $(INC) -c $*.c
lp_solve.exe: lp_solve/lp_solve.c $(OBJECTS)
$(CC) $(CFLAGS) $(DEBUG) $(DEFINE) $(INC) $< $(OBJECTS) -Felp_solve/lp_solve $(LDFLAGS)
demo.exe: demo/demo.c $(OBJECTS)
$(CC) $(CFLAGS) $(DEBUG) $(DEFINE) $(INC) $< $(OBJECTS) -Fedemo/demo $(LDFLAGS)
lpsolve.res: lpsolve.rc
$(RC) lpsolve.rc
liblpsolve55.lib: $(OBJECTS)
$(LIB) *.obj /OUT:lpsolve55/$@
lpsolve55.dll: $(OBJECTS)
$(CC) -fpic -shared -Wl,-Bsymbolic -Wl,-soname,$@ -o lpsolve55/$@ `echo $(SRC)|sed 's/[.]c/.obj/g'` $(LDFLAGS)
clean:
rm -f $(OBJECTS) *.lib *.dll lp_solve/lp_solve.exe demo/demo.exe lpsolve55/*.dll lpsolve55/*.lib

View File

@ -1,344 +0,0 @@
Introduction
------------
What is lp_solve and what is it not?
The simple answer is, lp_solve is a Mixed Integer Linear Programming (MILP) solver.
It is a free (see LGPL for the GNU lesser general public license) linear (integer) programming solver
based on the revised simplex method and the Branch-and-bound method for the integers.
It contains full source, examples and manuals.
lp_solve solves pure linear, (mixed) integer/binary, semi-continuous and
special ordered sets (SOS) models.
See the reference guide for more information.
lp_solve 5.5
------------
Why a jump from version numbers 5.1 to 5.5 ?
This is done to indicate that this is more than just another update.
The solver engine was revised and optimised in such a way that performance has improved considerably.
Numerical stability is also better resulting in more models that can be solved.
The LUSOL bfp is now also the default. In the past, the etaPFI bfp package was the default,
but for larger models this leads faster to numerical instabilities and performance problems.
Overall, the v5.5 code is faster and more robust than v5.1.
This robustness is for example proven by the fact that many more models can now be solved even without scaling.
The API hasn't changed very much.
There are a couple of new routines and one routine has an extra argument.
Some constants got new values.
* Fundamental internal change to the solver engine resulting in better performance and numerical stability.
Both the LP solver and the B&B solvers are enhanced.
* Optimised MILP branch truncation, with reduced cost fixing.
* LUSOL bfp is now the default.
* Presolve is improved in functionality and performance.
* Better handling of degeneracy, with more options.
* Store and read options from a file make it easier to set options.
* Partial pricing for the primal simplex now works.
* Full support for xli_ZIMPL v2.0.3.
* The objective function is no longer stored as part of the constraint matrix.
* Dual-long step code is in place, but not fully activated yet.
* General code cleanup.
* Added OBJSENSE and OBJNAME headers in the free MPS format (See MPS file format).
* The MathProg xli driver has now the ability to generate a model.
* New API routines
Start by taking a look at 'Changes compared to version 4', 'Changes from version 5.1 to version 5.5'
and 'lp_solve usage'
This gives a good starting point.
BFP's
-----
BFP stands for Basis Factorization Package, which is a unique lp_solve feature. Considerable
effort has been put in this new feature and we have big expectations for this. BFP is a generic
interface model and users can develop their own implementations based on the provided templates.
We are very interested in providing as many different BFPs as possible to the community.
lp_solve 5.5 has the LUSOL BFP built in as default engine. In addition two other
BFPs are included for both Windows and Linux: bfp_etaPFI.dll, bfp_GLPK.dll for Windows and
libbfp_etaPFI.so, libbfp_GLPK.so for Linux. The bfp_etaPFI includes
advanced column ordering using the COLAMD library, as well as better pivot management for
stability. For complex models, however, the LU factorization approach is much better, and
lp_solve now includes LUSOL as one of the most stable engines available anywhere. LUSOL was
originally developed by Prof. Saunders at Stanford, and it has now been ported to C
and enhanced by Kjell.
If you compile BFPs yourself, make sure that under Windows, you use __stdcall convention and
use 8 byte alignments. This is needed for the BFPs to work correctly with the general
distribution of lp_solve and also to make sharing BFPs as uncomplicated as possible.
See the reference guide for more information.
XLI's
-----
XLI stands for eXternal Language Interface, also a unique lp_solve feature. XLI's are stand-alone
libraries used as add-on to lp_solve to make it possible to read and write lp models in a format
not natively supported by lp_solve. Examples are CPLEX lp format, LINDO lp format, MathProg format,
XML format...
See the reference guide for more information.
lpsolve API
-----------
Don't forget that the API has changed compared to previous versions of lpsolve and that you just
can't use the version 5 lpsolve library with your version 4 or older code. That is also the
reason why the library is now called lpsolve55.dll/lpsolve55.a. lpsolve55.dll or lpsolve55.a are
only needed when you call the lpsolve library via the API interface from your program.
The lp_solve program is still a stand-alone executable program.
There are examples interfaces for different language like C, VB, C#, VB.NET, Java,
Delphi, and there is now also even a COM object to access the lpsolve library. This means that
the door is wide-open for using lp_solve in many different situations. Thus everything that is
available in version 4 is now also available in version 5 and already much more!
See the reference guide for more information.
Conversion between lp modeling formats
--------------------------------------
Note that lp2mps and mps2lp don't exist anymore. However this functionality is now implemented
in lp_solve:
lp2mps can be simulated as following:
lp_solve -parse_only -lp infile -wmps outfile
mps2lp can be simulated as following:
lp_solve -parse_only -mps infile -wlp outfile
via the -rxli option, a model can be read via an XLI library and via the -wxli option, a model
can be written via an XLI library.
How to build the executables yourself.
---------------------------------------
At this time, there are no Makefiles yet. However for the time being, there are batch files/scripts
to build. For the Microsoft compiler under Windows, use cvc6.bat, for the gnu compiler under Windows,
use cgcc.bat and for Unix/Linux, use the ccc shell script (sh ccc).
See the reference guide for more information.
IDE
---
Under Windows, there is now also a very user friendly lpsolve IDE. Check out LPSolveIDE
See the reference guide for more information.
Documentation (reference guide)
-------------------------------
See lp_solve55.chm for a Windows HTML help documentation file.
The html files are also in lp_solve_5.5_doc.tar.gz. Start with index.htm
Also see http://lpsolve.sourceforge.net/ for a on-line documentation
Change history:
---------------
17/05/05 version 5.5.0.0
- Beta release of version 5.5
??/??/05 version 5.5.0.1
- ?
26/06/05 version 5.5.0.2
- ?
29/06/05 version 5.5.0.3
- ?
16/08/05 version 5.5.0.4
- There are no API changes
- The LUSOL message routine could generate a crash under some cicumstances. Fixed
- A crash could occur when building the model in add_row_mode. Fixed.
- write_params didn't write the PRESOLVE and PRESOLVELOOPS correctly. Fixed.
- write_params didn't write constants with value 0. Fixed.
- The library did not compile under msdev 2002 (VC 7.0 _MSC_VER 1300). Fixed.
- There were some problems with printing long long variables which could generate a crash. Fixed.
- An overflow error could occur because memory was sometimes overwritten. Fixed.
- Presolve routines are revised. They are again improved and made faster.
Also some problems with it are fixed (possible crashes).
- Solver revised. Again made faster and more stable.
- get_row/get_column returned FALSE if the row/column is empty. Fixed.
- get_rowex/get_columnex now returns -1 if and error is detected. This instead of 0.
This to know the distinction between an empty row/column and an error.
- set_bounds had a possible problem when min and max are equal. Fixed.
- A crash/damage error could occur when rows/columns are added after a solve. Fixed.
- The my_chsign macro in lp_types.h gave warnings with some compilers. Fixed.
- The lp_solve program now returns 255 if an unexpected error occurs. Before this was 1
But this interferes with the lpsolve library return codes.
- With the lp_solve program, debug and print modes were not written correctly in a
specified parameter file. Fixed.
- With the lp_solve program, presolveloops was not set correctly. Fixed.
17/09/05 version 5.5.0.5
- In some cases, SOS restrictions were not optimized till optimality. Fixed.
- Presolve sometimes generated 'Column -xxx out of range during presolve' with a possible crash.
- Presolve sometimes removed integer and/or semi-cont variables that should not be deleted. Fixed.
- B&B sometimes didn't find the most optimal solution. Fixed.
- Internal constant COMP_EQUAL renamed to COMP_PREFERNONE because this could interfere with a define
in the standard header files.
- The lp parser had problems with variables starting with INF and there is a + or - sign just before it.
Fixed.
- Added options -presolvem, -presolvefd, -presolvebnd, -presolved, -presolveslk
- Updated documentation. put_bb_branchfunc, put_bb_nodefunc, set_epslevel, dualize_lp, set_basisvar
16/11/05 version 5.5.0.6
- set_add_rowmode should not be called after a solve. There is now a test in this routine when this is
done and it then returns FALSE.
- When an empty string ("") as filename is provided to set_outputfile, then output is completely
ignored.
- In some cases, SOS models did not solve to their most optimal solution.
- There was as problem with get_sensitivity_objex. Calling it (sometimes only after multiple times)
resulted in protection errors/core dumps.
- When a model has no constraints, it did not solve most of the times.
- column_in_lp didn't work anymore.
- Large upper bounds could make the model unstable. A change was made to fix this.
- set_improve could let crash the model.
- lp_params.c used the non-ANSI function unlink(). Changed to ANSI function remove().
- Presolve is again revised considerably.
- SOS handling is improved when there are a lot of SOS constraints.
- Limited constraint-to-SOS1 presolve to constraints with at least 4 variables.
- Limited bound tightening presolve loops.
12/02/06 version 5.5.0.7
- When SOS restrictions are added after a previous solve, a crash could occur.
- Optimized renaming a variable when the new name is equal to the old name.
- A possible crash could occur when presolve was enabled
- The constant ANTIDEGEN_DEFAULT is changed. ANTIDEGEN_INFEASIBLE is removed from it.
This constant should not be used unless you have some very tight and hard to solve
models where the optimal solution numerically straddles infeasibility.
- There was a possible problem with set_row(ex). It sometimes wrongfully changed the row.
- When integer variables were scaled, it could happen that because of rounding errors,
a loop was created.
- Sometimes integer models kept on looping in the B&B algorithm.
- A memory overrun could occur when an initial basis is set. This when variable names
are in Rnnn format and constraint names in Cnnn format.
- Some fixes are made in presolve.
- On 64-bit systems, compiler warnings were given and some code worked wrong resulting in
wrong results.
- lp_solve.c didn't compile with some compilers because if a very deep nested if statement.
- The distributed files now have the version number include in the filename.
For example lp_solve_5.5.0.7_exe.zip
This for a possible move to SourceForge in the (near?) future.
- When illegal bounds are specified in the MPS format (lower bound larger than upper bound)
then a warning was given but the illegal bound was just ignored and the model was solved.
This resulted in a solution that did not comply to the original model. Now the message is
seen as an error and solving is aborted.
06/09/06 version 5.5.0.8
- When presolve is active and columns are removed and there are SOS constraints, then presolve
had an error which could result in hanging while solve or maybe wrong solutions.
- set_row(ex) set wrong values when used after a previous solve and scaling is active.
- disabled PRESOLVE_REDUCEMIP since it is very rare that this is effective, and also that it adds
code complications and delayed presolve effects that are not captured properly.
- made routine guess_basis available for all languages (now exported by the dll).
The routine is now also documented.
- some bug corrections in guess_basis.
- Corrected a problem with add_column(ex) when add_rowmode is enabled.
- write_lp now wraps long lines over multiple lines to make it more readable.
- A compilation warning/error sometimes occured on is_fixedvar in lp_lusol.c with some compilers.
- Added options -wxlisol and -wxlisolopt to lp_solve program to write a solution file for those
XLIs that support it.
- Updated CPLEX XLI to support constants in objective.
- Added documentation on infeasible models, guess_basis, DIMACS models, CPLEX format, Zimpl, GNU Mathprog.
Corrected/updated documentation on get_col_name, get_row_name, get_nameindex, write_xli,
External Language Interfaces.
- The mps reader was improved for the rarely cases where the same elements are provided multiple
times. These are now added.
- Revised the java unittest example because it gave some errors that it shouldn't give.
07/10/06 version 5.5.0.9
- set_row(ex) could sometimes set wrong values in the model.
- Sometimes models with semi-cont variables which are also integer and scaling is active, a solution
was returned that is not most optimal or it returns infeasible.
- write_mps didn't write semi-cont variables with an infinite upper bound.
- When presolve can solve the model on its own and objective direction is maximize then a wrong sign
was shown in the reported price on screen.
- write_lp writes constraint and bounds in the same way if a constraint is not named. If a constraint
only has one variable then it looks like a bound. This can give problems because when a constraint
is interpreted as bound and it is negative then the problem definition changes.
Therefore a constraint which is not named and having only one variable in it is getting a name to
make sure it is interpreted as a constraint.
- The lp_solve program didn't interprete the PRESOLVED solve return code very well. Fixed.
- bfp_GLPK and xli_MathProg are now compiled against GLPK 4.11
- When an integer model is aborted before the most optimal solution is found (timeout or
break at first, ...) solve returned OPTIMAL (0) instead of SUBOPTIMAL (1). This is now corrected.
14/01/07 version 5.5.0.10
- If a model has integer variables, but the model is already integer optimal in the simplex fase,
then it was reported as suboptimal feasible.
- get_objective, get_variables, get_ptr_variables, get_constraints, get_ptr_constraints, get_primal_solution
reported 'not a valid basis' when presolve is active and the model is entirely solved by presolve.
- presolve on a model with SOS variables sometimes went wrong.
- presolve on a model with SOS variables where infeasibility is detected crashed.
- read_bas could fail when not all constraints had names or had names like default variable names.
- A crash could occur with set_row(ex) in rowmode.
- The lp format has been extended with a free section to define free variables.
- bfp_GLPK and xli_MathProg are now compiled against GLPK 4.13
- fixed bug in the pseudocost logic that can blow up subsequent pseudocost values in that
branch and make them almost random.
- In some rare cases a memory overrun could occur when constraints are added after a previous solve.
- Made the copy_lp routine work. Note that information about the optimisation of the original model
is not copied (at this time). Only the model is.
- Fixed a bug in the hashing routines that had only influence in some rare cases in the
MATLAB, O-Matrix, Scilab, Octave, Python drivers.
- coldual sometimes worked on a uninitialised variable value with unpredictable results.
27/12/07 version 5.5.0.11
- Fixed a problem in presolve. Sometimes an array-index-out-of-bounds error occured.
- Added a makefile for Linux.
- When adding constraints, in some rare cases a memory overrun could occur resulting in a crash.
- add_constraintex with count=0 and row=colno=NULL gave a protection error.
several XLIs didn't work anymore because of this.
- set_constr_type sometimes set wrong signs for the coefficient matrix when add_rowmode is on.
- presolve did an unnecessary extra loop. Also a test is added to stop presolve when very few
changes are done.
- for very large models, a request of much more memory than is reasonable could occur. Fixed.
- Modified LINDO XLI to read keywords also not at column 1 and to accept an empty objective function.
Previously this wat not possible.
- In some rare cases, numbers very close to their integer values (for example 11276.999999999998)
were truncated to their ceiling value (for example 11276) instead of rounded
(for example 11277).
- Solved a problem with presolve with an all-int constraint.
- Solved a problem with presolve coldominate
- Added stronger checking of the MPS format.
Fields that must be blank are now also tested accordingly so that if data is there that it is
not ignored as before.
- FREE MPS format was not read ok if row/column name were all numbers
or a FR, MI, PL, BV bound was defined. Fixed.
- The lp-format now also supports a bin(ary) section to define binary variables.
- When an integer model is aborted before the most optimal solution is found
via break at first or break at value, solve returned OPTIMAL (0) instead of SUBOPTIMAL (1).
This is now corrected. Problem occured in version 5.5.0.10
- Fixed a problem with del_constraint. Constraints names were not shifted and reported variable result was incorrect.
- read_XLI failed with MathProg if datamodel was provided with "" when there is no datamodel.
NULL was expected in the past. "" is now also accepted.
- Added an XLI to read Xpress lp files.
- Added routines MPS_writefileex, write_lpex.
- Added options -o0, -o1 to lp_solve command driven program to specify if objective is in basis or not.
- Added new information in the reference guide:
- Linear programming basics
- Presolve
- Xpress lp files
We are thrilled to hear from you and your experiences with this new version. The good and the bad.
Also we would be pleased to hear about your experiences with the different BFPs on your models.
Please send reactions to:
Peter Notebaert: lpsolve@peno.be
Kjell Eikland: kjell.eikland@broadpark.no

View File

@ -1,6 +0,0 @@
1 1 -0.12264700E+04
1 2 0.82867600E+01
2 3 0.62150700E+01
2 1 0.19468000E+03
3 2 -0.23990100E+04
3 3 -0.32849100E+04

View File

@ -1,89 +0,0 @@
Notes for Contribution of LUSOL to COIN-OR
May 2004
Introduction
============
LUSOL maintains sparse LU factors of a square or rectangular sparse matrix. It includes a Basis Factorization Package (BFP) suitable for implementing simplex and reduced-gradient methods for optimization. It is a set of routines written in ANSI C (adapted from the original Fortran 77 version).
LUSOL includes the following features:
- A Markowitz-based sparse LU factorization for square,
rectangular and possibly singular matrices.
- Three options for balancing sparsity and stability:
Threshold Partial/Rook/Complete Pivoting (TPP, TRP, TCP).
- Rank-revealing properties. TRP and TCP are intended for detecting singularities.
- Dynamic storage allocation (C version only).
- Stable column replacement as in the method of Bartels and Golub.
- Other stable updates: add, replace, or delete row or column
(currently F77 version only).
- Implementation into an easy-to-use BFP API (C version only).
Implementation
==============
The Factor routine is similar to the classical Markowitz routines MA28 and LA05 in the Harwell Subroutine Library. The source matrix nonzeros are stored column-wise with the largest entry at the top of each column. Internally, the structure is also accessible row-wise. All entries in a particular column or row are held in contiguous storage. Fill is accommodated by moving a column or row to the beginning of free storage. Occasional compressions recover storage. This scheme is effective for column-oriented TPP. When the remaining matrix reaches a specified density, the factors are completed using dense processing.
TRP uses an additional vector of storage to maintain the largest element in each remaining row.
TCP uses a heap structure to hold the largest element in each column. The largest element in the remaining matrix is then available at the top of the heap.
The final L is stored column-wise (and never changed). The final U is stored row-wise as a triangular or trapezoidal sparse matrix.
Column replacements are implemented using a forward sweep of 2-by-2 stabilized elimination matrices. L is updated in product form. U is updated explicitly.
The other updates use either forward or backward sweeps. They tend to generate more nonzeros than column replacement.
Both the F77 and C versions contain extensive comments, method and implementational information as part of the code.
The C version contains a record-based wrapper for the data. Function calls have been simplified by including references to this structure. New maintenance routines enable dynamic instance creation and destruction, and simplifies access to the most frequently used functions. The LUSOL C library is multi-instance and fully re-entrant. All control and output parameters have been given long descriptive names for usability.
Benefits
========
Rank-revealing properties and rectangular factors (and updates) have not previously been available in sparse LU software. With sensible parameter settings and reasonably scaled data, all routines are numerically stable. The updates may be called hundreds of times, and the decision to refactorize can be based on sparsity considerations alone.
In the Factor routine, rook pivoting (TRP) gives reliable rank determination without catastrophic degradation in sparsity or speed. Complete pivoting (TCP) is included for moderate-sized matrices and for checking pathological cases (but the factors tend to be substantially more dense).
To conserve storage, one may request only the row and column pivot orders. The factors are discarded as they are computed. This is useful for basis repair, or for selecting a basis from a rectangular matrix.
Known Inefficiencies
====================
LUSOL is usually efficient on sparse matrices with dimensions up to about 100,000 (but not millions).
In the Factor routine, row and column lists must be updated each time a row and column is eliminated. Deleting the pivot row and column is inefficient if the original matrix contains unusually dense rows or columns. For TPP, dense columns could be kept aside and incorporated at the end via updates (but dense rows remain a difficulty). For TRP and TCP, all rows and columns must be present to achieve the required numerical properties.
For TRP, the current bottleneck is updating the vector containing the largest element in each row. One solution would be to include the matrix nonzeros in the row structure (but this carries its own cost).
For TCP, the heap structure is already efficient, but the dense factors (and the extended searching for acceptable pivots) are unavoidable expenses.
The triangular Solve routines do not take full of advantage of sparse right-hand sides. Gilbert and Peierls have shown how to solve Lx = (sparse b) efficiently if L is stored column-wise. Their approach could therefore be implemented in LUSOL for solves with L and U(transpose). Solves with L(transpose) and U would need a second copy of L and U.
Original Reference
==================
P. E. Gill, W. Murray, M. A. Saunders and M. H. Wright, Maintaining LU factors of a general sparse matrix, Linear Algebra and its Applications 88/89, 239-270 (1987).
Maintainers
===========
F77 version: Michael Saunders (saunders@stanford.edu).
C version: Kjell Eikland (kjell.eikland@broadpark.no).
Contributors
============
Philip Gill, Walter Murray, Margaret Wright, Michael O'Sullivan.

View File

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

View File

@ -1,89 +0,0 @@
Notes for Contribution of LUSOL to COIN-OR
May 2004
Introduction
============
LUSOL maintains sparse LU factors of a square or rectangular sparse matrix. It includes a Basis Factorization Package (BFP) suitable for implementing simplex and reduced-gradient methods for optimization. It is a set of routines written in ANSI C (adapted from the original Fortran 77 version).
LUSOL includes the following features:
- A Markowitz-based sparse LU factorization for square,
rectangular and possibly singular matrices.
- Three options for balancing sparsity and stability:
Threshold Partial/Rook/Complete Pivoting (TPP, TRP, TCP).
- Rank-revealing properties. TRP and TCP are intended for detecting singularities.
- Dynamic storage allocation (C version only).
- Stable column replacement as in the method of Bartels and Golub.
- Other stable updates: add, replace, or delete row or column
(currently F77 version only).
- Implementation into an easy-to-use BFP API (C version only).
Implementation
==============
The Factor routine is similar to the classical Markowitz routines MA28 and LA05 in the Harwell Subroutine Library. The source matrix nonzeros are stored column-wise with the largest entry at the top of each column. Internally, the structure is also accessible row-wise. All entries in a particular column or row are held in contiguous storage. Fill is accommodated by moving a column or row to the beginning of free storage. Occasional compressions recover storage. This scheme is effective for column-oriented TPP. When the remaining matrix reaches a specified density, the factors are completed using dense processing.
TRP uses an additional vector of storage to maintain the largest element in each remaining row.
TCP uses a heap structure to hold the largest element in each column. The largest element in the remaining matrix is then available at the top of the heap.
The final L is stored column-wise (and never changed). The final U is stored row-wise as a triangular or trapezoidal sparse matrix.
Column replacements are implemented using a forward sweep of 2-by-2 stabilized elimination matrices. L is updated in product form. U is updated explicitly.
The other updates use either forward or backward sweeps. They tend to generate more nonzeros than column replacement.
Both the F77 and C versions contain extensive comments, method and implementational information as part of the code.
The C version contains a record-based wrapper for the data. Function calls have been simplified by including references to this structure. New maintenance routines enable dynamic instance creation and destruction, and simplifies access to the most frequently used functions. The LUSOL C library is multi-instance and fully re-entrant. All control and output parameters have been given long descriptive names for usability.
Benefits
========
Rank-revealing properties and rectangular factors (and updates) have not previously been available in sparse LU software. With sensible parameter settings and reasonably scaled data, all routines are numerically stable. The updates may be called hundreds of times, and the decision to refactorize can be based on sparsity considerations alone.
In the Factor routine, rook pivoting (TRP) gives reliable rank determination without catastrophic degradation in sparsity or speed. Complete pivoting (TCP) is included for moderate-sized matrices and for checking pathological cases (but the factors tend to be substantially more dense).
To conserve storage, one may request only the row and column pivot orders. The factors are discarded as they are computed. This is useful for basis repair, or for selecting a basis from a rectangular matrix.
Known Inefficiencies
====================
LUSOL is usually efficient on sparse matrices with dimensions up to about 100,000 (but not millions).
In the Factor routine, row and column lists must be updated each time a row and column is eliminated. Deleting the pivot row and column is inefficient if the original matrix contains unusually dense rows or columns. For TPP, dense columns could be kept aside and incorporated at the end via updates (but dense rows remain a difficulty). For TRP and TCP, all rows and columns must be present to achieve the required numerical properties.
For TRP, the current bottleneck is updating the vector containing the largest element in each row. One solution would be to include the matrix nonzeros in the row structure (but this carries its own cost).
For TCP, the heap structure is already efficient, but the dense factors (and the extended searching for acceptable pivots) are unavoidable expenses.
The triangular Solve routines do not take full of advantage of sparse right-hand sides. Gilbert and Peierls have shown how to solve Lx = (sparse b) efficiently if L is stored column-wise. Their approach could therefore be implemented in LUSOL for solves with L and U(transpose). Solves with L(transpose) and U would need a second copy of L and U.
Original Reference
==================
P. E. Gill, W. Murray, M. A. Saunders and M. H. Wright, Maintaining LU factors of a general sparse matrix, Linear Algebra and its Applications 88/89, 239-270 (1987).
Maintainers
===========
F77 version: Michael Saunders (saunders@stanford.edu).
C version: Kjell Eikland (kjell.eikland@broadpark.no).
Contributors
============
Philip Gill, Walter Murray, Margaret Wright, Michael O'Sullivan.

View File

@ -1,35 +0,0 @@
README.TXT for LUSOL - Advanced LU solver with enhanced numerical stability options
-----------------------------------------------------------------------------------
LUSOL - pronounced "L-U-SOL" - was developed by Prof. Michael Saunders at the
Stanford (University) Optimization Laboratory over a period of 2 decades of
progressive improvements. It is a particularly capable matrix factorization system
and includes sparsity-preserving column updates and equation solving. It is
therefore particularly well suited to be part of a system to solve tough mathematical
programming problems. Further details can be found in the file "LUSOL-overview.txt."
A big step has been made in converting the original Fortran code into a much more
easily accessible and modularized system based on ANSI C as part of the release of
lp_solve v5. LUSOL is fully implemented as a "Basis Factorization Package", BFP in
lp_solve and is the BFP of choice for large and complex models, if not all. As part
of the conversion to C, processor optimized BLAS functionality has been enabled, and
future enhancements to LUSOL may make increasing use of this, ensuring top performance.
For the lp_solve release of LUSOL, a stand-alone equation solving system has also been
developed. A pre-compiled Windows command-line executable version is included in the
standard distribution of LUSOL. In addition, the program options illustrate several
advanced uses of LUSOL. The equation solving utility features reading of standard
matrix files in the Harwell-Boeing, MatrixMarket and text formats. Sample matrix
models are provided for Harwell-Boeing (.RUA) and MatrixMarket (.mtx).
The LUSOL code is released under the GNU Lesser General Public Licence. Confer the
file "Licence_LGPL.txt" for the full terms of this licence. These terms make lp_solve
and LUSOL available and distributable on equal licencing terms. It is expected that
LUSOL will have an official repository in the near future, but the LUSOL archive at
the Yahoo lp_solve group will be an official copy and the formal repository until
further notice.
Kjell Eikland
14 July 2004
Oslo, Norway

View File

@ -1,36 +0,0 @@
Traditional column-based L0
---------------------------
V[ 3] = V[ 3] + L[1,3]*V[ 1]
0.9375 = -1.26316 + -0.789474*-2.7875
V[ 2] = V[ 2] + L[1,2]*V[ 1]
-0.846875 = -0.15 + 0.25*-2.7875
V[ 2] = V[ 2] + L[3,2]*V[ 3]
-0.925 = -0.846875 + -0.0833333*0.9375
V[ 4] = V[ 4] + L[3,4]*V[ 3]
-0.3125 = 0 + -0.333333*0.9375
Solution vector
-2.7875 -0.925 0.9375 -0.3125
New row-based L0
----------------
V[ 4] = V[ 4] + L[3,4]*V[ 3]
0.421053 = 0 + -0.333333*-1.26316
V[ 2] = V[ 2] + L[3,2]*V[ 3]
-0.0447368 = -0.15 + -0.0833333*-1.26316
V[ 2] = V[ 2] + L[1,2]*V[ 1]
-0.741612 = -0.0447368 + 0.25*-2.7875
V[ 3] = V[ 3] + L[1,3]*V[ 1]
0.9375 = -1.26316 + -0.789474*-2.7875
Solution vector
-2.7875 -0.741612 0.9375 0.421053
L0 generated
----------------
0 0 0 0
0 0 0 0
0 0.25 -0.789474 0
0-0.0833333 0 -0.333333

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +0,0 @@
-0.187248E+05
0.112479E+05
0.132356E+05

View File

@ -1,847 +0,0 @@
#include <sys/types.h>
#if defined INTEGERTIME || defined CLOCKTIME || defined PosixTime
# include <time.h>
#elif defined EnhTime
# include <windows.h>
#else
# include <sys/timeb.h>
#endif
#include <stdlib.h>
#include <stdio.h>
#ifdef WIN32
# include <io.h> /* Used in file search functions */
#endif
#include <ctype.h>
#include <string.h>
#include <math.h>
#include "commonlib.h"
#ifdef FORTIFY
# include "lp_fortify.h"
#endif
/* Math operator equivalence function */
int intpow(int base, int exponent)
{
int result = 1;
while(exponent > 0) {
result *= base;
exponent--;
}
while(exponent < 0) {
result /= base;
exponent++;
}
return( result );
}
int mod(int n, int d)
{
return(n % d);
}
/* Some string functions */
void strtoup(char *s)
{
if(s != NULL)
while (*s) {
*s = toupper(*s);
s++;
}
}
void strtolo(char *s)
{
if(s != NULL)
while (*s) {
*s = tolower(*s);
s++;
}
}
void strcpyup(char *t, char *s)
{
if((s != NULL) && (t != NULL)) {
while (*s) {
*t = toupper(*s);
t++;
s++;
}
*t = '\0';
}
}
void strcpylo(char *t, char *s)
{
if((s != NULL) && (t != NULL)) {
while (*s) {
*t = tolower(*s);
t++;
s++;
}
*t = '\0';
}
}
/* Unix library naming utility function */
MYBOOL so_stdname(char *stdname, char *descname, int buflen)
{
char *ptr;
if((descname == NULL) || (stdname == NULL) || (((int) strlen(descname)) >= buflen - 6))
return( FALSE );
strcpy(stdname, descname);
if((ptr = strrchr(descname, '/')) == NULL)
ptr = descname;
else
ptr++;
stdname[(int) (ptr - descname)] = 0;
if(strncmp(ptr, "lib", 3))
strcat(stdname, "lib");
strcat(stdname, ptr);
if(strcmp(stdname + strlen(stdname) - 3, ".so"))
strcat(stdname, ".so");
return( TRUE );
}
/* Return the greatest common divisor of a and b, or -1 if it is
not defined. Return through the pointer arguments the integers
such that gcd(a,b) = c*a + b*d. */
int gcd(LLONG a, LLONG b, int *c, int *d)
{
LLONG q,r,t;
int cret,dret,C,D,rval, sgn_a = 1,sgn_b = 1, swap = 0;
if((a == 0) || (b == 0))
return( -1 );
/* Use local multiplier instances, if necessary */
if(c == NULL)
c = &cret;
if(d == NULL)
d = &dret;
/* Normalize so that 0 < a <= b */
if(a < 0){
a = -a;
sgn_a = -1;
}
if(b < 0){
b = -b;
sgn_b = -1;
}
if(b < a){
t = b;
b = a;
a = t;
swap = 1;
}
/* Now a <= b and both >= 1. */
q = b/a;
r = b - a*q;
if(r == 0) {
if(swap){
*d = 1;
*c = 0;
}
else {
*c = 1;
*d = 0;
}
*c = sgn_a*(*c);
*d = sgn_b*(*d);
return( (int) a );
}
rval = gcd(a,r,&C,&D);
if(swap){
*d = (int) (C-D*q);
*c = D;
}
else {
*d = D;
*c = (int) (C-D*q);
}
*c = sgn_a*(*c);
*d = sgn_b*(*d);
return( rval );
}
/* Array search functions */
int findIndex(int target, int *attributes, int count, int offset)
{
int focusPos, beginPos, endPos;
int focusAttrib, beginAttrib, endAttrib;
/* Set starting and ending index offsets */
beginPos = offset;
endPos = beginPos + count - 1;
if(endPos < beginPos)
return(-1);
/* Do binary search logic based on a sorted (decending) attribute vector */
focusPos = (beginPos + endPos) / 2;
beginAttrib = attributes[beginPos];
focusAttrib = attributes[focusPos];
endAttrib = attributes[endPos];
while(endPos - beginPos > LINEARSEARCH) {
if(beginAttrib == target) {
focusAttrib = beginAttrib;
endPos = beginPos;
}
else if(endAttrib == target) {
focusAttrib = endAttrib;
beginPos = endPos;
}
else if(focusAttrib < target) {
beginPos = focusPos + 1;
beginAttrib = attributes[beginPos];
focusPos = (beginPos + endPos) / 2;
focusAttrib = attributes[focusPos];
}
else if(focusAttrib > target) {
endPos = focusPos - 1;
endAttrib = attributes[endPos];
focusPos = (beginPos + endPos) / 2;
focusAttrib = attributes[focusPos];
}
else {
beginPos = focusPos;
endPos = focusPos;
}
}
/* Do linear (unsorted) search logic */
if(endPos - beginPos <= LINEARSEARCH) {
/* CPU intensive loop; provide alternative evaluation models */
#if defined DOFASTMATH
/* Do fast pointer arithmetic */
int *attptr = attributes + beginPos;
while((beginPos < endPos) && ((*attptr) < target)) {
beginPos++;
attptr++;
}
focusAttrib = (*attptr);
#else
/* Do traditional indexed access */
focusAttrib = attributes[beginPos];
while((beginPos < endPos) && (focusAttrib < target)) {
beginPos++;
focusAttrib = attributes[beginPos];
}
#endif
}
/* Return the index if a match was found, or signal failure with a -1 */
if(focusAttrib == target) /* Found; return retrieval index */
return(beginPos);
else if(focusAttrib > target) /* Not found; last item */
return(-beginPos);
else if(beginPos > offset+count-1)
return(-(endPos+1)); /* Not found; end of list */
else
return(-(beginPos+1)); /* Not found; intermediate point */
}
int findIndexEx(void *target, void *attributes, int count, int offset, int recsize, findCompare_func findCompare, MYBOOL ascending)
{
int focusPos, beginPos, endPos, compare, order;
void *focusAttrib, *beginAttrib, *endAttrib;
/* Set starting and ending index offsets */
beginPos = offset;
endPos = beginPos + count - 1;
if(endPos < beginPos)
return(-1);
order = (ascending ? -1 : 1);
/* Do binary search logic based on a sorted attribute vector */
focusPos = (beginPos + endPos) / 2;
beginAttrib = CMP_ATTRIBUTES(beginPos);
focusAttrib = CMP_ATTRIBUTES(focusPos);
endAttrib = CMP_ATTRIBUTES(endPos);
compare = 0;
while(endPos - beginPos > LINEARSEARCH) {
if(findCompare(target, beginAttrib) == 0) {
focusAttrib = beginAttrib;
endPos = beginPos;
}
else if(findCompare(target, endAttrib) == 0) {
focusAttrib = endAttrib;
beginPos = endPos;
}
else {
compare = findCompare(target, focusAttrib)*order;
if(compare < 0) {
beginPos = focusPos + 1;
beginAttrib = CMP_ATTRIBUTES(beginPos);
focusPos = (beginPos + endPos) / 2;
focusAttrib = CMP_ATTRIBUTES(focusPos);
}
else if(compare > 0) {
endPos = focusPos - 1;
endAttrib = CMP_ATTRIBUTES(endPos);
focusPos = (beginPos + endPos) / 2;
focusAttrib = CMP_ATTRIBUTES(focusPos);
}
else {
beginPos = focusPos;
endPos = focusPos;
}
}
}
/* Do linear (unsorted) search logic */
if(endPos - beginPos <= LINEARSEARCH) {
/* Do traditional indexed access */
focusAttrib = CMP_ATTRIBUTES(beginPos);
if(beginPos == endPos)
compare = findCompare(target, focusAttrib)*order;
else
while((beginPos < endPos) &&
((compare = findCompare(target, focusAttrib)*order) < 0)) {
beginPos++;
focusAttrib = CMP_ATTRIBUTES(beginPos);
}
}
/* Return the index if a match was found, or signal failure with a -1 */
if(compare == 0) /* Found; return retrieval index */
return(beginPos);
else if(compare > 0) /* Not found; last item */
return(-beginPos);
else if(beginPos > offset+count-1)
return(-(endPos+1)); /* Not found; end of list */
else
return(-(beginPos+1)); /* Not found; intermediate point */
}
/* Simple sorting and searching comparison "operators" */
int CMP_CALLMODEL compareCHAR(const void *current, const void *candidate)
{
return( CMP_COMPARE( *(char *) current, *(char *) candidate ) );
}
int CMP_CALLMODEL compareINT(const void *current, const void *candidate)
{
return( CMP_COMPARE( *(int *) current, *(int *) candidate ) );
}
int CMP_CALLMODEL compareREAL(const void *current, const void *candidate)
{
return( CMP_COMPARE( *(REAL *) current, *(REAL *) candidate ) );
}
/* Heap sort function (procedurally based on the Numerical Recipes version,
but expanded and generalized to hande any object with the use of
qsort-style comparison operator). An expanded version is also implemented,
where interchanges are reflected in a caller-initialized integer "tags" list. */
void hpsort(void *attributes, int count, int offset, int recsize, MYBOOL descending, findCompare_func findCompare)
{
register int i, j, k, ir, order;
register char *hold, *base;
char *save;
if(count < 2)
return;
offset -= 1;
attributes = CMP_ATTRIBUTES(offset);
base = CMP_ATTRIBUTES(1);
save = (char *) malloc(recsize);
if(descending)
order = -1;
else
order = 1;
k = (count >> 1) + 1;
ir = count;
for(;;) {
if(k > 1) {
MEMCOPY(save, CMP_ATTRIBUTES(--k), recsize);
}
else {
hold = CMP_ATTRIBUTES(ir);
MEMCOPY(save, hold, recsize);
MEMCOPY(hold, base, recsize);
if(--ir == 1) {
MEMCOPY(base, save, recsize);
break;
}
}
i = k;
j = k << 1;
while(j <= ir) {
hold = CMP_ATTRIBUTES(j);
if( (j < ir) && (findCompare(hold, CMP_ATTRIBUTES(j+1))*order < 0) ) {
hold += recsize;
j++;
}
if(findCompare(save, hold)*order < 0) {
MEMCOPY(CMP_ATTRIBUTES(i), hold, recsize);
i = j;
j <<= 1;
}
else
break;
}
MEMCOPY(CMP_ATTRIBUTES(i), save, recsize);
}
FREE(save);
}
void hpsortex(void *attributes, int count, int offset, int recsize, MYBOOL descending, findCompare_func findCompare, int *tags)
{
if(count < 2)
return;
if(tags == NULL) {
hpsort(attributes, count, offset, recsize, descending, findCompare);
return;
}
else {
register int i, j, k, ir, order;
register char *hold, *base;
char *save;
int savetag;
offset -= 1;
attributes = CMP_ATTRIBUTES(offset);
tags += offset;
base = CMP_ATTRIBUTES(1);
save = (char *) malloc(recsize);
if(descending)
order = -1;
else
order = 1;
k = (count >> 1) + 1;
ir = count;
for(;;) {
if(k > 1) {
MEMCOPY(save, CMP_ATTRIBUTES(--k), recsize);
savetag = tags[k];
}
else {
hold = CMP_ATTRIBUTES(ir);
MEMCOPY(save, hold, recsize);
MEMCOPY(hold, base, recsize);
savetag = tags[ir];
tags[ir] = tags[1];
if(--ir == 1) {
MEMCOPY(base, save, recsize);
tags[1] = savetag;
break;
}
}
i = k;
j = k << 1;
while(j <= ir) {
hold = CMP_ATTRIBUTES(j);
if( (j < ir) && (findCompare(hold, CMP_ATTRIBUTES(j+1))*order < 0) ) {
hold += recsize;
j++;
}
if(findCompare(save, hold)*order < 0) {
MEMCOPY(CMP_ATTRIBUTES(i), hold, recsize);
tags[i] = tags[j];
i = j;
j <<= 1;
}
else
break;
}
MEMCOPY(CMP_ATTRIBUTES(i), save, recsize);
tags[i] = savetag;
}
FREE(save);
}
}
/* This is a "specialized generic" version of C.A.R Hoare's Quick Sort algorithm.
It will handle arrays that are already sorted, and arrays with duplicate keys.
The implementation here requires the user to pass a comparison operator and
assumes that the array passed has the QSORTrec format, which i.a. includes
the ability for to do linked list sorting. If the passed comparison operator
is NULL, the comparison is assumed to be for integers. */
#define QS_IS_switch 4 /* Threshold for switching to insertion sort */
void QS_swap(UNIONTYPE QSORTrec a[], int i, int j)
{
UNIONTYPE QSORTrec T = a[i];
a[i] = a[j];
a[j] = T;
}
int QS_addfirst(UNIONTYPE QSORTrec a[], void *mydata)
{
a[0].pvoid2.ptr = mydata;
return( 0 );
}
int QS_append(UNIONTYPE QSORTrec a[], int ipos, void *mydata)
{
if(ipos <= 0)
ipos = QS_addfirst(a, mydata);
else
a[ipos].pvoid2.ptr = mydata;
return( ipos );
}
void QS_replace(UNIONTYPE QSORTrec a[], int ipos, void *mydata)
{
a[ipos].pvoid2.ptr = mydata;
}
void QS_insert(UNIONTYPE QSORTrec a[], int ipos, void *mydata, int epos)
{
for(; epos > ipos; epos--)
a[epos] = a[epos-1];
a[ipos].pvoid2.ptr = mydata;
}
void QS_delete(UNIONTYPE QSORTrec a[], int ipos, int epos)
{
for(; epos > ipos; epos--)
a[epos] = a[epos-1];
}
int QS_sort(UNIONTYPE QSORTrec a[], int l, int r, findCompare_func findCompare)
{
register int i, j, nmove = 0;
UNIONTYPE QSORTrec v;
/* Perform the a fast QuickSort */
if((r-l) > QS_IS_switch) {
i = (r+l)/2;
/* Tri-Median Method */
if(findCompare((char *) &a[l], (char *) &a[i]) > 0)
{ nmove++; QS_swap(a,l,i); }
if(findCompare((char *) &a[l], (char *) &a[r]) > 0)
{ nmove++; QS_swap(a,l,r); }
if(findCompare((char *) &a[i], (char *) &a[r]) > 0)
{ nmove++; QS_swap(a,i,r); }
j = r-1;
QS_swap(a,i,j);
i = l;
v = a[j];
for(;;) {
while(findCompare((char *) &a[++i], (char *) &v) < 0);
while(findCompare((char *) &a[--j], (char *) &v) > 0);
if(j < i) break;
nmove++; QS_swap (a,i,j);
}
nmove++; QS_swap(a,i,r-1);
nmove += QS_sort(a,l,j,findCompare);
nmove += QS_sort(a,i+1,r,findCompare);
}
return( nmove );
}
int QS_finish(UNIONTYPE QSORTrec a[], int lo0, int hi0, findCompare_func findCompare)
{
int i, j, nmove = 0;
UNIONTYPE QSORTrec v;
/* This is actually InsertionSort, which is faster for local sorts */
for(i = lo0+1; i <= hi0; i++) {
/* Save bottom-most item */
v = a[i];
/* Shift down! */
j = i;
while ((j > lo0) && (findCompare((char *) &a[j-1], (char *) &v) > 0)) {
a[j] = a[j-1];
j--;
nmove++;
}
/* Store bottom-most item at the top */
a[j] = v;
}
return( nmove );
}
MYBOOL QS_execute(UNIONTYPE QSORTrec a[], int count, findCompare_func findCompare, int *nswaps)
{
int iswaps = 0;
/* Check and initialize */
if(count <= 1)
goto Finish;
count--;
/* Perform sort */
iswaps = QS_sort(a, 0, count, findCompare);
#if QS_IS_switch > 0
iswaps += QS_finish(a, 0, count, findCompare);
#endif
Finish:
if(nswaps != NULL)
*nswaps = iswaps;
return( TRUE );
}
/* Simple specialized bubble/insertion sort functions */
int sortByREAL(int *item, REAL *weight, int size, int offset, MYBOOL unique)
{
int i, ii, saveI;
REAL saveW;
for(i = 1; i < size; i++) {
ii = i+offset-1;
while ((ii >= offset) && (weight[ii] >= weight[ii+1])) {
if(weight[ii] == weight[ii+1]) {
if(unique)
return(item[ii]);
}
else {
saveI = item[ii];
saveW = weight[ii];
item[ii] = item[ii+1];
weight[ii] = weight[ii+1];
item[ii+1] = saveI;
weight[ii+1] = saveW;
}
ii--;
}
}
return(0);
}
int sortByINT(int *item, int *weight, int size, int offset, MYBOOL unique)
{
int i, ii, saveI;
int saveW;
for(i = 1; i < size; i++) {
ii = i+offset-1;
while ((ii >= offset) && (weight[ii] >= weight[ii+1])) {
if(weight[ii] == weight[ii+1]) {
if(unique)
return(item[ii]);
}
else {
saveI = item[ii];
saveW = weight[ii];
item[ii] = item[ii+1];
weight[ii] = weight[ii+1];
item[ii+1] = saveI;
weight[ii+1] = saveW;
}
ii--;
}
}
return(0);
}
REAL sortREALByINT(REAL *item, int *weight, int size, int offset, MYBOOL unique)
{
int i, ii, saveW;
REAL saveI;
for(i = 1; i < size; i++) {
ii = i+offset-1;
while ((ii >= offset) && (weight[ii] >= weight[ii+1])) {
if(weight[ii] == weight[ii+1]) {
if(unique)
return(item[ii]);
}
else {
saveI = item[ii];
saveW = weight[ii];
item[ii] = item[ii+1];
weight[ii] = weight[ii+1];
item[ii+1] = saveI;
weight[ii+1] = saveW;
}
ii--;
}
}
return(0);
}
/* Time and message functions */
double timeNow(void)
{
#ifdef INTEGERTIME
return((double)time(NULL));
#elif defined CLOCKTIME
return((double)clock()/CLOCKS_PER_SEC /* CLK_TCK */);
#elif defined PosixTime
struct timespec t;
# if 0
clock_gettime(CLOCK_REALTIME, &t);
return( (double) t.tv_sec + (double) t.tv_nsec/1.0e9 );
# else
static double timeBase;
clock_gettime(CLOCK_MONOTONIC, &t);
if(timeBase == 0)
timeBase = clockNow() - ((double) t.tv_sec + (double) t.tv_nsec/1.0e9);
return( timeBase + (double) t.tv_sec + (double) t.tv_nsec/1.0e9 );
# endif
#elif defined EnhTime
static LARGE_INTEGER freq;
static double timeBase;
LARGE_INTEGER now;
QueryPerformanceCounter(&now);
if(timeBase == 0) {
QueryPerformanceFrequency(&freq);
timeBase = clockNow() - (double) now.QuadPart/(double) freq.QuadPart;
}
return( timeBase + (double) now.QuadPart/(double) freq.QuadPart );
#else
struct timeb buf;
ftime(&buf);
return((double)buf.time+((double) buf.millitm)/1000.0);
#endif
}
/* Miscellaneous reporting functions */
/* List a vector of INT values for the given index range */
void blockWriteINT(FILE *output, char *label, int *myvector, int first, int last)
{
int i, k = 0;
fprintf(output, label);
fprintf(output, "\n");
for(i = first; i <= last; i++) {
fprintf(output, " %5d", myvector[i]);
k++;
if(k % 12 == 0) {
fprintf(output, "\n");
k = 0;
}
}
if(k % 12 != 0)
fprintf(output, "\n");
}
/* List a vector of MYBOOL values for the given index range */
void blockWriteBOOL(FILE *output, char *label, MYBOOL *myvector, int first, int last, MYBOOL asRaw)
{
int i, k = 0;
fprintf(output, label);
fprintf(output, "\n");
for(i = first; i <= last; i++) {
if(asRaw)
fprintf(output, " %1d", myvector[i]);
else
fprintf(output, " %5s", my_boolstr(myvector[i]));
k++;
if(k % 36 == 0) {
fprintf(output, "\n");
k = 0;
}
}
if(k % 36 != 0)
fprintf(output, "\n");
}
/* List a vector of REAL values for the given index range */
void blockWriteREAL(FILE *output, char *label, REAL *myvector, int first, int last)
{
int i, k = 0;
fprintf(output, label);
fprintf(output, "\n");
for(i = first; i <= last; i++) {
fprintf(output, " %18g", myvector[i]);
k++;
if(k % 4 == 0) {
fprintf(output, "\n");
k = 0;
}
}
if(k % 4 != 0)
fprintf(output, "\n");
}
/* CONSOLE vector and matrix printing routines */
void printvec( int n, REAL *x, int modulo )
{
int i;
if (modulo <= 0) modulo = 5;
for (i = 1; i<=n; i++) {
if(mod(i, modulo) == 1)
printf("\n%2d:%12g", i, x[i]);
else
printf(" %2d:%12g", i, x[i]);
}
if(i % modulo != 0) printf("\n");
}
void printmatUT( int size, int n, REAL *U, int modulo)
{
int i, ll;
ll = 0;
for(i = 1; i<=n; i++) {
printvec(n-i+1, &U[ll], modulo);
ll += size-i+1;
}
}
void printmatSQ( int size, int n, REAL *X, int modulo)
{
int i, ll;
ll = 0;
for(i = 1; i<=n; i++) {
printvec(n, &X[ll], modulo);
ll += size;
}
}
/* Miscellaneous file functions */
#if defined _MSC_VER
/* Check MS versions before 7 */
#if _MSC_VER < 1300
# define intptr_t long
#endif
int fileCount( char *filemask )
{
struct _finddata_t c_file;
intptr_t hFile;
int count = 0;
/* Find first .c file in current directory */
if( (hFile = _findfirst( filemask, &c_file )) == -1L )
;
/* Iterate over all matching names */
else {
while( _findnext( hFile, &c_file ) == 0 )
count++;
_findclose( hFile );
}
return( count );
}
MYBOOL fileSearchPath( char *envvar, char *searchfile, char *foundpath )
{
char pathbuffer[_MAX_PATH];
_searchenv( searchfile, envvar, pathbuffer );
if(pathbuffer[0] == '\0')
return( FALSE );
else {
if(foundpath != NULL)
strcpy(foundpath, pathbuffer);
return( TRUE );
}
}
#endif

View File

@ -1,324 +0,0 @@
#ifndef HEADER_commonlib
#define HEADER_commonlib
#include <stdlib.h>
#include <stdio.h>
static char SpaceChars[3] = {" " "\7"};
static char NumChars[14] = {"0123456789-+."};
#define BIGNUMBER 1.0e+30
#define TINYNUMBER 1.0e-04
#define MACHINEPREC 2.22e-16
#define MATHPREC 1.0e-16
#define ERRLIMIT 1.0e-06
#ifndef LINEARSEARCH
#define LINEARSEARCH 5
#endif
#if 0
#define INTEGERTIME
#endif
/* ************************************************************************ */
/* Define loadable library function headers */
/* ************************************************************************ */
#if (defined WIN32) || (defined WIN64)
#define my_LoadLibrary(name) LoadLibrary(name)
#define my_GetProcAddress(handle, name) GetProcAddress(handle, name)
#define my_FreeLibrary(handle) FreeLibrary(handle); \
handle = NULL
#else
#define my_LoadLibrary(name) dlopen(name, RTLD_LAZY)
#define my_GetProcAddress(handle, name) dlsym(handle, name)
#define my_FreeLibrary(handle) dlclose(handle); \
handle = NULL
#endif
/* ************************************************************************ */
/* Define sizes of standard number types */
/* ************************************************************************ */
#ifndef LLONG
#if defined __BORLANDC__
#define LLONG __int64
#elif !defined _MSC_VER || _MSC_VER >= 1310
#define LLONG long long
#else
#define LLONG __int64
#endif
#endif
#ifndef MYBOOL
#if 0
#define MYBOOL unsigned int
#else
#define MYBOOL unsigned char
#endif
#endif
#ifndef REAL
#define REAL double
#endif
#ifndef BLAS_prec
#define BLAS_prec "d" /* The BLAS precision prefix must correspond to the REAL type */
#endif
#ifndef REALXP
#if 1
#define REALXP long double /* Set local accumulation variable as long double */
#else
#define REALXP REAL /* Set local accumulation as default precision */
#endif
#endif
#ifndef my_boolstr
#define my_boolstr(x) (!(x) ? "FALSE" : "TRUE")
#endif
#ifndef NULL
#define NULL 0
#endif
#ifndef FALSE
#define FALSE 0
#define TRUE 1
#endif
#ifndef DEF_STRBUFSIZE
#define DEF_STRBUFSIZE 512
#endif
#ifndef MAXINT32
#define MAXINT32 2147483647
#endif
#ifndef MAXUINT32
#define MAXUINT32 4294967295
#endif
#ifndef MAXINT64
#if defined _LONGLONG || defined __LONG_LONG_MAX__ || defined LLONG_MAX
#define MAXINT64 9223372036854775807ll
#else
#define MAXINT64 9223372036854775807l
#endif
#endif
#ifndef MAXUINT64
#if defined _LONGLONG || defined __LONG_LONG_MAX__ || defined LLONG_MAX
#define MAXUINT64 18446744073709551616ll
#else
#define MAXUINT64 18446744073709551616l
#endif
#endif
#ifndef DOFASTMATH
#define DOFASTMATH
#endif
#ifndef CALLOC
#define CALLOC(ptr, nr)\
if(!((void *) ptr = calloc((size_t)(nr), sizeof(*ptr))) && nr) {\
printf("calloc of %d bytes failed on line %d of file %s\n",\
(size_t) nr * sizeof(*ptr), __LINE__, __FILE__);\
}
#endif
#ifndef MALLOC
#define MALLOC(ptr, nr)\
if(!((void *) ptr = malloc((size_t)((size_t) (nr) * sizeof(*ptr)))) && nr) {\
printf("malloc of %d bytes failed on line %d of file %s\n",\
(size_t) nr * sizeof(*ptr), __LINE__, __FILE__);\
}
#endif
#ifndef REALLOC
#define REALLOC(ptr, nr)\
if(!((void *) ptr = realloc(ptr, (size_t)((size_t) (nr) * sizeof(*ptr)))) && nr) {\
printf("realloc of %d bytes failed on line %d of file %s\n",\
(size_t) nr * sizeof(*ptr), __LINE__, __FILE__);\
}
#endif
#ifndef FREE
#define FREE(ptr)\
if((void *) ptr != NULL) {\
free(ptr);\
ptr = NULL; \
}
#endif
#ifndef MEMCOPY
#define MEMCOPY(nptr, optr, nr)\
memcpy((nptr), (optr), (size_t)((size_t)(nr) * sizeof(*(optr))))
#endif
#ifndef MEMMOVE
#define MEMMOVE(nptr, optr, nr)\
memmove((nptr), (optr), (size_t)((size_t)(nr) * sizeof(*(optr))))
#endif
#ifndef MEMALLOCCOPY
#define MEMALLOCCOPY(nptr, optr, nr)\
{MALLOC(nptr, (size_t)(nr));\
MEMCOPY(nptr, optr, (size_t)(nr));}
#endif
#ifndef STRALLOCCOPY
#define STRALLOCCOPY(nstr, ostr)\
{nstr = (char *) malloc((size_t) (strlen(ostr) + 1));\
strcpy(nstr, ostr);}
#endif
#ifndef MEMCLEAR
/*#define useMMX*/
#ifdef useMMX
#define MEMCLEAR(ptr, nr)\
mem_set((ptr), '\0', (size_t)((size_t)(nr) * sizeof(*(ptr))))
#else
#define MEMCLEAR(ptr, nr)\
memset((ptr), '\0', (size_t)((size_t)(nr) * sizeof(*(ptr))))
#endif
#endif
#define MIN(x, y) ((x) < (y) ? (x) : (y))
#define MAX(x, y) ((x) > (y) ? (x) : (y))
#define SETMIN(x, y) if((x) > (y)) x = y
#define SETMAX(x, y) if((x) < (y)) x = y
#define LIMIT(lo, x, hi) ((x < (lo) ? lo : ((x) > hi ? hi : x)))
#define BETWEEN(x, a, b) (MYBOOL) (((x)-(a)) * ((x)-(b)) <= 0)
#define IF(t, x, y) ((t) ? (x) : (y))
#define SIGN(x) ((x) < 0 ? -1 : 1)
#define DELTA_SIZE(newSize, oldSize) ((int) ((newSize) * MIN(1.33, pow(1.5, fabs((double)newSize)/((oldSize+newSize)+1)))))
#ifndef CMP_CALLMODEL
#if (defined WIN32) || (defined WIN64)
#define CMP_CALLMODEL _cdecl
#else
#define CMP_CALLMODEL
#endif
#endif
typedef int (CMP_CALLMODEL findCompare_func)(const void *current, const void *candidate);
#define CMP_COMPARE(current, candidate) ( current < candidate ? -1 : (current > candidate ? 1 : 0) )
#define CMP_ATTRIBUTES(item) (((char *) attributes)+(item)*recsize)
#ifndef UNIONTYPE
#ifdef __cplusplus
#define UNIONTYPE
#else
#define UNIONTYPE union
#endif
#endif
/* This defines a 16 byte sort record (in both 32 and 64 bit OS-es) */
typedef struct _QSORTrec1
{
void *ptr;
void *ptr2;
} QSORTrec1;
typedef struct _QSORTrec2
{
void *ptr;
double realval;
} QSORTrec2;
typedef struct _QSORTrec3
{
void *ptr;
int intval;
int intpar1;
} QSORTrec3;
typedef struct _QSORTrec4
{
REAL realval;
int intval;
int intpar1;
} QSORTrec4;
typedef struct _QSORTrec5
{
double realval;
long int longval;
} QSORTrec5;
typedef struct _QSORTrec6
{
double realval;
double realpar1;
} QSORTrec6;
typedef struct _QSORTrec7
{
int intval;
int intpar1;
int intpar2;
int intpar3;
} QSORTrec7;
union QSORTrec
{
QSORTrec1 pvoid2;
QSORTrec2 pvoidreal;
QSORTrec3 pvoidint2;
QSORTrec4 realint2;
QSORTrec5 reallong;
QSORTrec6 real2;
QSORTrec7 int4;
};
#ifdef __cplusplus
extern "C" {
#endif
int intpow(int base, int exponent);
int mod(int n, int d);
void strtoup(char *s);
void strtolo(char *s);
void strcpyup(char *t, char *s);
void strcpylo(char *t, char *s);
MYBOOL so_stdname(char *stdname, char *descname, int buflen);
int gcd(LLONG a, LLONG b, int *c, int *d);
int findIndex(int target, int *attributes, int count, int offset);
int findIndexEx(void *target, void *attributes, int count, int offset, int recsize, findCompare_func findCompare, MYBOOL ascending);
int CMP_CALLMODEL compareCHAR(const void *current, const void *candidate);
int CMP_CALLMODEL compareINT(const void *current, const void *candidate);
int CMP_CALLMODEL compareREAL(const void *current, const void *candidate);
void hpsort(void *attributes, int count, int offset, int recsize, MYBOOL descending, findCompare_func findCompare);
void hpsortex(void *attributes, int count, int offset, int recsize, MYBOOL descending, findCompare_func findCompare, int *tags);
void QS_swap(UNIONTYPE QSORTrec a[], int i, int j);
int QS_addfirst(UNIONTYPE QSORTrec a[], void *mydata);
int QS_append(UNIONTYPE QSORTrec a[], int ipos, void *mydata);
void QS_replace(UNIONTYPE QSORTrec a[], int ipos, void *mydata);
void QS_insert(UNIONTYPE QSORTrec a[], int ipos, void *mydata, int epos);
void QS_delete(UNIONTYPE QSORTrec a[], int ipos, int epos);
MYBOOL QS_execute(UNIONTYPE QSORTrec a[], int count, findCompare_func findCompare, int *nswaps);
int sortByREAL(int *item, REAL *weight, int size, int offset, MYBOOL unique);
int sortByINT(int *item, int *weight, int size, int offset, MYBOOL unique);
REAL sortREALByINT(REAL *item, int *weight, int size, int offset, MYBOOL unique);
double timeNow(void);
void blockWriteBOOL(FILE *output, char *label, MYBOOL *myvector, int first, int last, MYBOOL asRaw);
void blockWriteINT(FILE *output, char *label, int *myvector, int first, int last);
void blockWriteREAL(FILE *output, char *label, REAL *myvector, int first, int last);
void printvec( int n, REAL *x, int modulo );
void printmatSQ( int size, int n, REAL *X, int modulo );
void printmatUT( int size, int n, REAL *U, int modulo );
#if defined _MSC_VER
int fileCount( char *filemask );
MYBOOL fileSearchPath( char *envvar, char *searchfile, char *foundpath );
#endif
#ifdef __cplusplus
}
#endif
#endif /* HEADER_commonlib */

File diff suppressed because it is too large Load Diff

View File

@ -1,67 +0,0 @@
#ifndef IOHB_H
#define IOHB_H
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#ifdef __cplusplus
extern "C" {
#endif
int readHB_info(const char* filename, int* M, int* N, int* nz, char** Type,
int* Nrhs);
int readHB_header(FILE* in_file, char* Title, char* Key, char* Type,
int* Nrow, int* Ncol, int* Nnzero, int* Nrhs, int* Nrhsix,
char* Ptrfmt, char* Indfmt, char* Valfmt, char* Rhsfmt,
int* Ptrcrd, int* Indcrd, int* Valcrd, int* Rhscrd,
char *Rhstype);
int readHB_mat_double(const char* filename, int colptr[], int rowind[],
double val[]);
int readHB_newmat_double(const char* filename, int* M, int* N, int* nonzeros,
int** colptr, int** rowind, double** val);
int readHB_aux_double(const char* filename, const char AuxType, double b[]);
int readHB_newaux_double(const char* filename, const char AuxType, double** b);
int writeHB_mat_double(const char* filename, int M, int N,
int nz, const int colptr[], const int rowind[],
const double val[], int Nrhs, const double rhs[],
const double guess[], const double exact[],
const char* Title, const char* Key, const char* Type,
char* Ptrfmt, char* Indfmt, char* Valfmt, char* Rhsfmt,
const char* Rhstype);
int readHB_mat_char(const char* filename, int colptr[], int rowind[],
char val[], char* Valfmt);
int readHB_newmat_char(const char* filename, int* M, int* N, int* nonzeros, int** colptr,
int** rowind, char** val, char** Valfmt);
int readHB_aux_char(const char* filename, const char AuxType, char b[]);
int readHB_newaux_char(const char* filename, const char AuxType, char** b, char** Rhsfmt);
int writeHB_mat_char(const char* filename, int M, int N,
int nz, const int colptr[], const int rowind[],
const char val[], int Nrhs, const char rhs[],
const char guess[], const char exact[],
const char* Title, const char* Key, const char* Type,
char* Ptrfmt, char* Indfmt, char* Valfmt, char* Rhsfmt,
const char* Rhstype);
int ParseIfmt(char* fmt, int* perline, int* width);
int ParseRfmt(char* fmt, int* perline, int* width, int* prec, int* flag);
void IOHBTerminate(char* message);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,796 +0,0 @@
/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
LUSOL routines from the Stanford Optimization Laboratory
The parts included are:
lusol1 Factor a given matrix A from scratch (lu1fac).
lusol2 Heap-management routines for lu1fac.
lusol6 Solve with the current LU factors.
lusol7 Utilities for all update routines.
lusol8 Replace a column (Bartels-Golub update).
------------------------------------------------------------------
26 Apr 2002: TCP implemented using heap data structure.
01 May 2002: lu1DCP implemented.
07 May 2002: lu1mxc must put 0.0 at top of empty columns.
09 May 2002: lu1mCP implements Markowitz with cols searched
in heap order.
Often faster (searching 20 or 40 cols) but more dense.
11 Jun 2002: TRP implemented.
lu1mRP implements Markowitz with Threshold Rook
Pivoting.
lu1mxc maintains max col elements (was lu1max.)
lu1mxr maintains max row elements.
12 Jun 2002: lu1mCP seems too slow on big problems (e.g. memplus).
Disabled it for the moment. (Use lu1mar + TCP.)
14 Dec 2002: TSP implemented.
lu1mSP implements Markowitz with TSP.
07 Mar 2003: character*1, character*2 changed to f90 form.
Comments changed from * in column to ! in column 1.
Comments kept within column 72 to avoid compiler
warning.
06 Mar 2004: Translation to C by Kjell Eikland with the addition
of data wrappers, parametric constants, various
helper routines, and dynamic memory reallocation.
26 May 2004: Added LUSOL_IP_UPDATELIMIT parameter and provided
for dynamic memory expansion based on possible
forward requirements.
08 Jul 2004: Revised logic in lu6chk based on new code from
Michael Saunders.
01 Dec 2005: Add support for CMEX interface (disable by undef MATLAB)
Also include various bug fixes (disable by undef YZHANG)
Yin Zhang <yzhang@cs.utexas.edu>
01 Jan 2006: Added storage of singular indeces, not only the last.
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <float.h>
#include <math.h>
#include "lusol.h"
#include "myblas.h"
#ifdef MATLAB
#include "mex.h"
#endif
/* LUSOL Object creation and destruction */
void *clean_realloc(void *oldptr, int width, int newsize, int oldsize)
{
newsize *= width;
oldsize *= width;
oldptr = LUSOL_REALLOC(oldptr, newsize);
if(newsize > oldsize)
/* MEMCLEAR(oldptr+oldsize, newsize-oldsize); */
memset((char *)oldptr+oldsize, '\0', newsize-oldsize);
return(oldptr);
}
MYBOOL LUSOL_realloc_a(LUSOLrec *LUSOL, int newsize)
{
int oldsize;
if(newsize < 0)
newsize = LUSOL->lena + MAX(abs(newsize), LUSOL_MINDELTA_a);
oldsize = LUSOL->lena;
LUSOL->lena = newsize;
if(newsize > 0)
newsize++;
if(oldsize > 0)
oldsize++;
LUSOL->a = (REAL *) clean_realloc(LUSOL->a, sizeof(*(LUSOL->a)),
newsize, oldsize);
LUSOL->indc = (int *) clean_realloc(LUSOL->indc, sizeof(*(LUSOL->indc)),
newsize, oldsize);
LUSOL->indr = (int *) clean_realloc(LUSOL->indr, sizeof(*(LUSOL->indr)),
newsize, oldsize);
if((newsize == 0) ||
((LUSOL->a != NULL) && (LUSOL->indc != NULL) && (LUSOL->indr != NULL)))
return( TRUE );
else
return( FALSE );
}
MYBOOL LUSOL_expand_a(LUSOLrec *LUSOL, int *delta_lena, int *right_shift)
{
#ifdef StaticMemAlloc
return( FALSE );
#else
int LENA, NFREE, LFREE;
/* Add expansion factor to avoid having to resize too often/too much;
(exponential formula suggested by Michael A. Saunders) */
LENA = LUSOL->lena;
*delta_lena = DELTA_SIZE(*delta_lena, LENA);
/* Expand it! */
if((*delta_lena <= 0) || !LUSOL_realloc_a(LUSOL, LENA+(*delta_lena)))
return( FALSE );
/* Make sure we return the actual memory increase of a */
*delta_lena = LUSOL->lena-LENA;
/* Shift the used memory area to the right */
LFREE = *right_shift;
NFREE = LFREE+*delta_lena;
LENA -= LFREE-1;
MEMMOVE(LUSOL->a+NFREE, LUSOL->a+LFREE, LENA);
MEMMOVE(LUSOL->indr+NFREE, LUSOL->indr+LFREE, LENA);
MEMMOVE(LUSOL->indc+NFREE, LUSOL->indc+LFREE, LENA);
/* Also return the new starting position for the used memory area of a */
*right_shift = NFREE;
LUSOL->expanded_a++;
return( TRUE );
#endif
}
MYBOOL LUSOL_realloc_r(LUSOLrec *LUSOL, int newsize)
{
int oldsize;
if(newsize < 0)
newsize = LUSOL->maxm + MAX(abs(newsize), LUSOL_MINDELTA_rc);
oldsize = LUSOL->maxm;
LUSOL->maxm = newsize;
if(newsize > 0)
newsize++;
if(oldsize > 0)
oldsize++;
LUSOL->lenr = (int *) clean_realloc(LUSOL->lenr, sizeof(*(LUSOL->lenr)),
newsize, oldsize);
LUSOL->ip = (int *) clean_realloc(LUSOL->ip, sizeof(*(LUSOL->ip)),
newsize, oldsize);
LUSOL->iqloc = (int *) clean_realloc(LUSOL->iqloc, sizeof(*(LUSOL->iqloc)),
newsize, oldsize);
LUSOL->ipinv = (int *) clean_realloc(LUSOL->ipinv, sizeof(*(LUSOL->ipinv)),
newsize, oldsize);
LUSOL->locr = (int *) clean_realloc(LUSOL->locr, sizeof(*(LUSOL->locr)),
newsize, oldsize);
if((newsize == 0) ||
((LUSOL->lenr != NULL) &&
(LUSOL->ip != NULL) && (LUSOL->iqloc != NULL) &&
(LUSOL->ipinv != NULL) && (LUSOL->locr != NULL))) {
#ifndef ClassicHamaxR
#ifdef AlwaysSeparateHamaxR
if(LUSOL->luparm[LUSOL_IP_PIVOTTYPE] == LUSOL_PIVMOD_TRP)
#endif
{
LUSOL->amaxr = (REAL *) clean_realloc(LUSOL->amaxr, sizeof(*(LUSOL->amaxr)),
newsize, oldsize);
if((newsize > 0) && (LUSOL->amaxr == NULL))
return( FALSE );
}
#endif
return( TRUE );
}
else
return( FALSE );
}
MYBOOL LUSOL_realloc_c(LUSOLrec *LUSOL, int newsize)
{
int oldsize;
if(newsize < 0)
newsize = LUSOL->maxn + MAX(abs(newsize), LUSOL_MINDELTA_rc);
oldsize = LUSOL->maxn;
LUSOL->maxn = newsize;
if(newsize > 0)
newsize++;
if(oldsize > 0)
oldsize++;
LUSOL->lenc = (int *) clean_realloc(LUSOL->lenc, sizeof(*(LUSOL->lenc)),
newsize, oldsize);
LUSOL->iq = (int *) clean_realloc(LUSOL->iq, sizeof(*(LUSOL->iq)),
newsize, oldsize);
LUSOL->iploc = (int *) clean_realloc(LUSOL->iploc, sizeof(*(LUSOL->iploc)),
newsize, oldsize);
LUSOL->iqinv = (int *) clean_realloc(LUSOL->iqinv, sizeof(*(LUSOL->iqinv)),
newsize, oldsize);
LUSOL->locc = (int *) clean_realloc(LUSOL->locc, sizeof(*(LUSOL->locc)),
newsize, oldsize);
LUSOL->w = (REAL *) clean_realloc(LUSOL->w, sizeof(*(LUSOL->w)),
newsize, oldsize);
#ifdef LUSOLSafeFastUpdate
LUSOL->vLU6L = (REAL *) clean_realloc(LUSOL->vLU6L, sizeof(*(LUSOL->vLU6L)),
newsize, oldsize);
#else
LUSOL->vLU6L = LUSOL->w;
#endif
if((newsize == 0) ||
((LUSOL->w != NULL) && (LUSOL->lenc != NULL) &&
(LUSOL->iq != NULL) && (LUSOL->iploc != NULL) &&
(LUSOL->iqinv != NULL) && (LUSOL->locc != NULL))) {
#ifndef ClassicHamaxR
if(LUSOL->luparm[LUSOL_IP_PIVOTTYPE] == LUSOL_PIVMOD_TCP) {
LUSOL->Ha = (REAL *) clean_realloc(LUSOL->Ha, sizeof(*(LUSOL->Ha)),
newsize, oldsize);
LUSOL->Hj = (int *) clean_realloc(LUSOL->Hj, sizeof(*(LUSOL->Hj)),
newsize, oldsize);
LUSOL->Hk = (int *) clean_realloc(LUSOL->Hk, sizeof(*(LUSOL->Hk)),
newsize, oldsize);
if((newsize > 0) &&
((LUSOL->Ha == NULL) || (LUSOL->Hj == NULL) || (LUSOL->Hk == NULL)))
return( FALSE );
}
#endif
#ifndef ClassicdiagU
if(LUSOL->luparm[LUSOL_IP_KEEPLU] == FALSE) {
LUSOL->diagU = (REAL *) clean_realloc(LUSOL->diagU, sizeof(*(LUSOL->diagU)),
newsize, oldsize);
if((newsize > 0) && (LUSOL->diagU == NULL))
return( FALSE );
}
#endif
return( TRUE );
}
else
return( FALSE );
}
LUSOLrec *LUSOL_create(FILE *outstream, int msgfil, int pivotmodel, int updatelimit)
{
LUSOLrec *newLU;
newLU = (LUSOLrec *) LUSOL_CALLOC(1, sizeof(*newLU));
if(newLU == NULL)
return( newLU );
newLU->luparm[LUSOL_IP_SCALAR_NZA] = LUSOL_MULT_nz_a;
newLU->outstream = outstream;
newLU->luparm[LUSOL_IP_PRINTUNIT] = msgfil;
newLU->luparm[LUSOL_IP_PRINTLEVEL] = LUSOL_MSG_SINGULARITY;
LUSOL_setpivotmodel(newLU, pivotmodel, LUSOL_PIVTOL_DEFAULT);
newLU->parmlu[LUSOL_RP_GAMMA] = LUSOL_DEFAULT_GAMMA;
newLU->parmlu[LUSOL_RP_ZEROTOLERANCE] = 3.0e-13;
newLU->parmlu[LUSOL_RP_SMALLDIAG_U] = /*3.7e-11;*/
newLU->parmlu[LUSOL_RP_EPSDIAG_U] = 3.7e-11;
newLU->parmlu[LUSOL_RP_COMPSPACE_U] = 3.0e+0;
newLU->luparm[LUSOL_IP_MARKOWITZ_MAXCOL] = 5;
newLU->parmlu[LUSOL_RP_MARKOWITZ_CONLY] = 0.3e+0;
newLU->parmlu[LUSOL_RP_MARKOWITZ_DENSE] = 0.5e+0;
newLU->parmlu[LUSOL_RP_SMARTRATIO] = LUSOL_DEFAULT_SMARTRATIO;
#ifdef ForceRowBasedL0
newLU->luparm[LUSOL_IP_ACCELERATION] = LUSOL_BASEORDER;
#endif
newLU->luparm[LUSOL_IP_KEEPLU] = TRUE;
newLU->luparm[LUSOL_IP_UPDATELIMIT] = updatelimit;
init_BLAS();
return( newLU );
}
MYBOOL LUSOL_sizeto(LUSOLrec *LUSOL, int init_r, int init_c, int init_a)
{
if(init_c == 0)
LUSOL_FREE(LUSOL->isingular);
if(LUSOL_realloc_a(LUSOL, init_a) &&
LUSOL_realloc_r(LUSOL, init_r) &&
LUSOL_realloc_c(LUSOL, init_c))
return( TRUE );
else
return( FALSE );
}
char *LUSOL_pivotLabel(LUSOLrec *LUSOL)
{
static /*const*/ char *pivotText[LUSOL_PIVMOD_MAX+1] =
{"TPP", "TRP", "TCP", "TSP"};
return(pivotText[LUSOL->luparm[LUSOL_IP_PIVOTTYPE]]);
}
void LUSOL_setpivotmodel(LUSOLrec *LUSOL, int pivotmodel, int initlevel)
{
REAL newFM, newUM;
/* Set pivotmodel if specified */
if(pivotmodel > LUSOL_PIVMOD_NOCHANGE) {
if((pivotmodel <= LUSOL_PIVMOD_DEFAULT) || (pivotmodel > LUSOL_PIVMOD_MAX))
pivotmodel = LUSOL_PIVMOD_TPP;
LUSOL->luparm[LUSOL_IP_PIVOTTYPE] = pivotmodel;
}
/* Check if we need bother about changing tolerances */
if((initlevel <= LUSOL_PIVTOL_NOCHANGE) || (initlevel > LUSOL_PIVTOL_MAX))
return;
/* Set default pivot tolerances
(note that UPDATEMAX should always be <= FACTORMAX) */
if(initlevel == LUSOL_PIVTOL_BAGGY) { /* Extra-loose pivot thresholds */
newFM = 500.0;
newUM = newFM / 20;
}
else if(initlevel == LUSOL_PIVTOL_LOOSE) { /* Moderately tight pivot tolerances */
newFM = 100.0;
newUM = newFM / 10;
}
else if(initlevel == LUSOL_PIVTOL_NORMAL) { /* Standard pivot tolerances */
newFM = 28.0;
newUM = newFM / 4;
}
else if(initlevel == LUSOL_PIVTOL_SLIM) { /* Better accuracy pivot tolerances */
newFM = 10.0;
newUM = newFM / 2;
}
else if(initlevel == LUSOL_PIVTOL_TIGHT) { /* Enhanced accuracy pivot tolerances */
newFM = 5.0;
newUM = newFM / 2;
}
else if(initlevel == LUSOL_PIVTOL_SUPER) { /* Very tight pivot tolerances for extra accuracy */
newFM = 2.5;
newUM = 1.99;
}
else { /* Extremely tight pivot tolerances for extra accuracy */
newFM = 1.99;
newUM = newFM / 1.49;
}
/* Set the tolerances */
LUSOL->parmlu[LUSOL_RP_FACTORMAX_Lij] = newFM;
LUSOL->parmlu[LUSOL_RP_UPDATEMAX_Lij] = newUM;
}
MYBOOL LUSOL_tightenpivot(LUSOLrec *LUSOL)
{
REAL newvalue;
/* Give up tightening if we are already less than limit and we cannot change strategy */
if(MIN(LUSOL->parmlu[LUSOL_RP_FACTORMAX_Lij],
LUSOL->parmlu[LUSOL_RP_UPDATEMAX_Lij]) < 1.1) {
if(LUSOL->luparm[LUSOL_IP_PIVOTTYPE] >= LUSOL_PIVMOD_TRP)
return( FALSE );
LUSOL_setpivotmodel(LUSOL, LUSOL->luparm[LUSOL_IP_PIVOTTYPE]+1, LUSOL_PIVTOL_DEFAULT+1);
return( 2 );
}
/* Otherwise tighten according to defined schedule */
#if 0 /* This is Michael Saunder's proposed tightening procedure */
newvalue = sqrt(LUSOL->parmlu[LUSOL_RP_FACTORMAX_Lij]);
LUSOL->parmlu[LUSOL_RP_FACTORMAX_Lij] = newvalue;
SETMIN(LUSOL->parmlu[LUSOL_RP_UPDATEMAX_Lij], newvalue);
#elif 0 /* This is Kjell Eikland's schedule #1 */
newvalue = sqrt(LUSOL->parmlu[LUSOL_RP_FACTORMAX_Lij]);
LUSOL->parmlu[LUSOL_RP_FACTORMAX_Lij] = newvalue;
LUSOL->parmlu[LUSOL_RP_UPDATEMAX_Lij] = 1.0 + (newvalue - 1.0) / 2;
#else /* This was Kjell Eikland's schedule #2 */
LUSOL->parmlu[LUSOL_RP_FACTORMAX_Lij] = 1.0 + LUSOL->parmlu[LUSOL_RP_FACTORMAX_Lij]/3.0;
LUSOL->parmlu[LUSOL_RP_UPDATEMAX_Lij] = 1.0 + LUSOL->parmlu[LUSOL_RP_UPDATEMAX_Lij]/3.0;
#endif
return( TRUE );
}
MYBOOL LUSOL_addSingularity(LUSOLrec *LUSOL, int singcol, int *inform)
{
int NSING = LUSOL->luparm[LUSOL_IP_SINGULARITIES],
ASING = LUSOL->luparm[LUSOL_IP_SINGULARLISTSIZE];
/* Check if we need to allocated list memory to store multiple singularities */
if((NSING > 0) && (NSING >= ASING)) {
/* Increase list in "reasonable" steps */
ASING += (int) (10.0 * (log10((REAL) LUSOL->m)+1.0));
LUSOL->isingular = (int *) LUSOL_REALLOC(LUSOL->isingular, sizeof(*LUSOL->isingular)*(ASING+1));
if(LUSOL->isingular == NULL) {
LUSOL->luparm[LUSOL_IP_SINGULARLISTSIZE] = 0;
*inform = LUSOL_INFORM_NOMEMLEFT;
return( FALSE );
}
LUSOL->luparm[LUSOL_IP_SINGULARLISTSIZE] = ASING;
/* Transfer the first singularity if the list was just created */
if(NSING == 1)
LUSOL->isingular[NSING] = LUSOL->luparm[LUSOL_IP_SINGULARINDEX];
}
/* Update singularity count and store its index */
NSING++;
if(NSING > 1) {
LUSOL->isingular[0] = NSING;
LUSOL->isingular[NSING] = singcol;
}
LUSOL->luparm[LUSOL_IP_SINGULARITIES] = NSING;
/* Mimic old logic by keeping the last singularity stored */
LUSOL->luparm[LUSOL_IP_SINGULARINDEX] = singcol;
return( TRUE );
}
int LUSOL_getSingularity(LUSOLrec *LUSOL, int singitem)
{
if((singitem > LUSOL->luparm[LUSOL_IP_SINGULARITIES]) || (singitem < 0))
singitem = -1;
else if(singitem == 0)
singitem = LUSOL->luparm[LUSOL_IP_SINGULARITIES];
else if(singitem > 1)
singitem = LUSOL->isingular[singitem];
else
singitem = LUSOL->luparm[LUSOL_IP_SINGULARINDEX];
return( singitem );
}
int LUSOL_findSingularityPosition(LUSOLrec *LUSOL, int singcol)
/* The purpose of this routine is to find the slack row/column in
user-index that was singular in the last unsuccessful column
update; zero is returned if the search was unsuccessful.
By adding a slack at this position this particular singularity
should disappear.
(Source: Michael A. Saunders; private communication to KE) */
{
#if 0 /* Michael Saunders version */
int j;
for(j = LUSOL->m; j > 0; j--)
if(LUSOL->iq[j] == singcol)
break;
singcol = j;
#else /* Kjell Eikland version (note that iqinv could be invalid in early versions of LUSOL) */
singcol = LUSOL->iqinv[singcol];
#endif
return( LUSOL->ip[singcol] );
}
char *LUSOL_informstr(LUSOLrec *LUSOL, int inform)
{
static char *informText[LUSOL_INFORM_MAX-LUSOL_INFORM_MIN+1] =
{"LUSOL_RANKLOSS: Lost rank",
"LUSOL_LUSUCCESS: Success",
"LUSOL_LUSINGULAR: Singular A",
"LUSOL_LUUNSTABLE: Unstable factorization",
"LUSOL_ADIMERR: Row or column count exceeded",
"LUSOL_ADUPLICATE: Duplicate A matrix entry found",
"(Undefined message)",
"(Undefined message)",
"LUSOL_ANEEDMEM: Insufficient memory for factorization",
"LUSOL_FATALERR: Fatal internal error",
"LUSOL_NOPIVOT: Found no suitable pivot",
"LUSOL_NOMEMLEFT: Could not obtain more memory"};
if((inform < LUSOL_INFORM_MIN) || (inform > LUSOL_INFORM_MAX))
inform = LUSOL->luparm[LUSOL_IP_INFORM];
return(informText[inform-LUSOL_INFORM_MIN]);
}
void LUSOL_clear(LUSOLrec *LUSOL, MYBOOL nzonly)
{
int len;
LUSOL->nelem = 0;
if(!nzonly) {
/* lena arrays */
len = LUSOL->lena + LUSOL_ARRAYOFFSET;
MEMCLEAR(LUSOL->a, len);
MEMCLEAR(LUSOL->indc, len);
MEMCLEAR(LUSOL->indr, len);
/* maxm arrays */
len = LUSOL->maxm + LUSOL_ARRAYOFFSET;
MEMCLEAR(LUSOL->lenr, len);
MEMCLEAR(LUSOL->ip, len);
MEMCLEAR(LUSOL->iqloc, len);
MEMCLEAR(LUSOL->ipinv, len);
MEMCLEAR(LUSOL->locr, len);
#ifndef ClassicHamaxR
if((LUSOL->amaxr != NULL)
#ifdef AlwaysSeparateHamaxR
&& (LUSOL->luparm[LUSOL_IP_PIVOTTYPE] == LUSOL_PIVMOD_TRP)
#endif
)
MEMCLEAR(LUSOL->amaxr, len);
#endif
/* maxn arrays */
len = LUSOL->maxn + LUSOL_ARRAYOFFSET;
MEMCLEAR(LUSOL->lenc, len);
MEMCLEAR(LUSOL->iq, len);
MEMCLEAR(LUSOL->iploc, len);
MEMCLEAR(LUSOL->iqinv, len);
MEMCLEAR(LUSOL->locc, len);
MEMCLEAR(LUSOL->w, len);
if(LUSOL->luparm[LUSOL_IP_PIVOTTYPE] == LUSOL_PIVMOD_TCP) {
MEMCLEAR(LUSOL->Ha, len);
MEMCLEAR(LUSOL->Hj, len);
MEMCLEAR(LUSOL->Hk, len);
}
#ifndef ClassicdiagU
if(LUSOL->luparm[LUSOL_IP_KEEPLU] == FALSE) {
MEMCLEAR(LUSOL->diagU, len);
}
#endif
}
}
MYBOOL LUSOL_assign(LUSOLrec *LUSOL, int iA[], int jA[], REAL Aij[], int nzcount, MYBOOL istriplet)
{
int k, m, n, ij, kol;
/* Adjust the size of the a structure */
if(nzcount > (LUSOL->lena/LUSOL->luparm[LUSOL_IP_SCALAR_NZA]) &&
!LUSOL_realloc_a(LUSOL, nzcount*LUSOL->luparm[LUSOL_IP_SCALAR_NZA]))
return( FALSE );
m = 0;
n = 0;
kol = 1;
for(k = 1; k <= nzcount; k++) {
/* First the row indicator */
ij = iA[k];
if(ij > m) {
m = ij;
if(m > LUSOL->maxm &&
!LUSOL_realloc_r(LUSOL, -(m / LUSOL_MINDELTA_FACTOR + 1)))
return( FALSE );
}
LUSOL->indc[k] = ij;
/* Then the column indicator;
Handle both triplet and column count formats */
if(istriplet)
ij = jA[k];
else {
if(k >= jA[kol])
kol++;
ij = kol;
}
if(ij > n) {
n = ij;
if(n > LUSOL->maxn &&
!LUSOL_realloc_c(LUSOL, -(n / LUSOL_MINDELTA_FACTOR + 1)))
return( FALSE );
}
LUSOL->indr[k] = ij;
/* Lastly the matrix value itself */
LUSOL->a[k] = Aij[k];
}
LUSOL->m = m;
LUSOL->n = n;
LUSOL->nelem = nzcount;
return( TRUE );
}
int LUSOL_loadColumn(LUSOLrec *LUSOL, int iA[], int jA, REAL Aij[], int nzcount, int offset1)
{
int i, ii, nz, k;
nz = LUSOL->nelem;
i = nz + nzcount;
if(i > (LUSOL->lena/LUSOL->luparm[LUSOL_IP_SCALAR_NZA]) &&
!LUSOL_realloc_a(LUSOL, i*LUSOL->luparm[LUSOL_IP_SCALAR_NZA]))
return( -1 );
k = 0;
for(ii = 1; ii <= nzcount; ii++) {
i = ii + offset1;
if(Aij[i] == 0)
continue;
if(iA[i] <= 0 || iA[i] > LUSOL->m ||
jA <= 0 || jA > LUSOL->n) {
LUSOL_report(LUSOL, 0, "Variable index outside of set bounds (r:%d/%d, c:%d/%d)\n",
iA[i], LUSOL->m, jA, LUSOL->n);
continue;
}
k++;
nz++;
LUSOL->a[nz] = Aij[i];
LUSOL->indc[nz] = iA[i];
LUSOL->indr[nz] = jA;
}
LUSOL->nelem = nz;
return( k );
}
void LUSOL_free(LUSOLrec *LUSOL)
{
LUSOL_realloc_a(LUSOL, 0);
LUSOL_realloc_r(LUSOL, 0);
LUSOL_realloc_c(LUSOL, 0);
if(LUSOL->L0 != NULL)
LUSOL_matfree(&(LUSOL->L0));
if(LUSOL->U != NULL)
LUSOL_matfree(&(LUSOL->U));
if(!is_nativeBLAS())
unload_BLAS();
LUSOL_FREE(LUSOL);
}
void LUSOL_report(LUSOLrec *LUSOL, int msglevel, char *format, ...)
{
va_list ap;
va_start(ap, format);
if(LUSOL == NULL) {
vfprintf(stderr, format, ap);
}
else if(msglevel >= 0 /*LUSOL->luparm[2]*/) {
if(LUSOL->writelog != NULL) {
char buff[255];
vsprintf(buff, format, ap);
LUSOL->writelog(LUSOL, LUSOL->loghandle, buff);
}
if(LUSOL->outstream != NULL) {
vfprintf(LUSOL->outstream, format, ap);
fflush(LUSOL->outstream);
}
}
va_end(ap);
}
void LUSOL_timer(LUSOLrec *LUSOL, int timerid, char *text)
{
LUSOL_report(LUSOL, -1, "TimerID %d at %s - %s\n",
timerid, "", text);
}
int LUSOL_factorize(LUSOLrec *LUSOL)
{
int inform;
LU1FAC( LUSOL, &inform );
return( inform );
}
int LUSOL_ftran(LUSOLrec *LUSOL, REAL b[], int NZidx[], MYBOOL prepareupdate)
{
int inform;
REAL *vector;
if(prepareupdate)
vector = LUSOL->vLU6L;
else
vector = LUSOL->w;
/* Copy RHS vector, but make adjustment for offset since this
can create a memory error when the calling program uses
a 0-base vector offset back to comply with LUSOL. */
MEMCOPY(vector+1, b+1, LUSOL->n);
vector[0] = 0;
LU6SOL(LUSOL, LUSOL_SOLVE_Aw_v, vector, b, NZidx, &inform);
LUSOL->luparm[LUSOL_IP_FTRANCOUNT]++;
return(inform);
}
int LUSOL_btran(LUSOLrec *LUSOL, REAL b[], int NZidx[])
{
int inform;
/* Copy RHS vector, but make adjustment for offset since this
can create a memory error when the calling program uses
a 0-base vector offset back to comply with LUSOL. */
MEMCOPY(LUSOL->w+1, b+1, LUSOL->m);
LUSOL->w[0] = 0;
LU6SOL(LUSOL, LUSOL_SOLVE_Atv_w, b, LUSOL->w, NZidx, &inform);
LUSOL->luparm[LUSOL_IP_BTRANCOUNT]++;
return(inform);
}
int LUSOL_replaceColumn(LUSOLrec *LUSOL, int jcol, REAL v[])
{
int inform;
REAL DIAG, VNORM;
LU8RPC(LUSOL, LUSOL_UPDATE_OLDNONEMPTY, LUSOL_UPDATE_NEWNONEMPTY,
jcol, v, NULL,
&inform, &DIAG, &VNORM);
LUSOL->replaced_c++;
return( inform );
}
REAL LUSOL_vecdensity(LUSOLrec *LUSOL, REAL V[])
{
int I, N = 0;
for(I = 1; I <= LUSOL->m; I++)
if(fabs(V[I]) > 0)
N++;
return( (REAL) N / (REAL) LUSOL->m );
}
char relationChar(REAL left, REAL right)
{
if(left > right)
return('>');
else if(left == right)
return('=');
else
return('<');
}
/* Retrieve the core modules ordered by order of dependency */
#include "lusol2.c" /* Heap management */
#include "lusol6a.c" /* Singularity checking and equation solving */
#include "lusol1.c" /* Factorization and core components */
#include "lusol7a.c" /* Utility routines for updates */
#include "lusol8a.c" /* Column update */
void LUSOL_dump(FILE *output, LUSOLrec *LUSOL)
{
MYBOOL userfile = (MYBOOL) (output != NULL);
if(!userfile)
output = fopen("LUSOL.dbg", "w");
blockWriteREAL(output, "a", LUSOL->a, 1, LUSOL->lena);
blockWriteINT(output, "indc", LUSOL->indc, 1, LUSOL->lena);
blockWriteINT(output, "indr", LUSOL->indr, 1, LUSOL->lena);
blockWriteINT(output, "ip", LUSOL->ip, 1, LUSOL->m);
blockWriteINT(output, "iq", LUSOL->iq, 1, LUSOL->n);
blockWriteINT(output, "lenc", LUSOL->lenc, 1, LUSOL->n);
blockWriteINT(output, "lenr", LUSOL->lenr, 1, LUSOL->m);
blockWriteINT(output, "locc", LUSOL->locc, 1, LUSOL->n);
blockWriteINT(output, "locr", LUSOL->locr, 1, LUSOL->m);
blockWriteINT(output, "iploc", LUSOL->iploc, 1, LUSOL->n);
blockWriteINT(output, "iqloc", LUSOL->iqloc, 1, LUSOL->m);
blockWriteINT(output, "ipinv", LUSOL->ipinv, 1, LUSOL->m);
blockWriteINT(output, "iqinv", LUSOL->iqinv, 1, LUSOL->n);
if(!userfile)
fclose(output);
}
LUSOLmat *LUSOL_matcreate(int dim, int nz)
{
LUSOLmat *newm;
newm = (LUSOLmat *) LUSOL_CALLOC(1, sizeof(*newm));
if(newm != NULL) {
newm->a = (REAL *) LUSOL_MALLOC((nz+1)*sizeof(REAL));
newm->lenx = (int *) LUSOL_MALLOC((dim+1)*sizeof(int));
newm->indx = (int *) LUSOL_MALLOC((dim+1)*sizeof(int));
newm->indr = (int *) LUSOL_MALLOC((nz+1)*sizeof(int));
newm->indc = (int *) LUSOL_MALLOC((nz+1)*sizeof(int));
if((newm->a == NULL) ||
(newm->lenx == NULL) || (newm->indx == NULL) ||
(newm->indr == NULL) || (newm->indc == NULL))
LUSOL_matfree(&newm);
}
return(newm);
}
void LUSOL_matfree(LUSOLmat **mat)
{
if((mat == NULL) || (*mat == NULL))
return;
LUSOL_FREE((*mat)->a);
LUSOL_FREE((*mat)->indc);
LUSOL_FREE((*mat)->indr);
LUSOL_FREE((*mat)->lenx);
LUSOL_FREE((*mat)->indx);
LUSOL_FREE(*mat);
}

View File

@ -1,357 +0,0 @@
#ifndef HEADER_LUSOL
#define HEADER_LUSOL
/* Include necessary libraries */
/* ------------------------------------------------------------------------- */
#include <stdio.h>
#include "commonlib.h"
/* Version information */
/* ------------------------------------------------------------------------- */
#define LUSOL_VERMAJOR 2
#define LUSOL_VERMINOR 2
#define LUSOL_RELEASE 2
#define LUSOL_BUILD 0
/* Dynamic memory management macros */
/* ------------------------------------------------------------------------- */
#ifdef MATLAB
#define LUSOL_MALLOC(bytesize) mxMalloc(bytesize)
#define LUSOL_CALLOC(count, recsize) mxCalloc(count, recsize)
#define LUSOL_REALLOC(ptr, bytesize) mxRealloc((void *) ptr, bytesize)
#define LUSOL_FREE(ptr) {mxFree(ptr); ptr=NULL;}
#else
#define LUSOL_MALLOC(bytesize) malloc(bytesize)
#define LUSOL_CALLOC(count, recsize) calloc(count, recsize)
#define LUSOL_REALLOC(ptr, bytesize) realloc((void *) ptr, bytesize)
#define LUSOL_FREE(ptr) {free(ptr); ptr=NULL;}
#endif
/* Performance compiler options */
/* ------------------------------------------------------------------------- */
#if 1
#define ForceInitialization /* Satisfy compilers, check during debugging! */
#define LUSOLFastDenseIndex /* Increment the linearized dense address */
#define LUSOLFastClear /* Use intrinsic functions for memory zeroing */
#define LUSOLFastMove /* Use intrinsic functions for memory moves */
#define LUSOLFastCopy /* Use intrinsic functions for memory copy */
#define LUSOLFastSolve /* Use pointer operations in equation solving */
#define LUSOLSafeFastUpdate /* Use separate array for LU6L result storage */
/*#define UseOld_LU6CHK_20040510 */
/*#define AlwaysSeparateHamaxR */ /* Enabled when the pivot model is fixed */
#if 0
#define ForceRowBasedL0 /* Create a row-sorted version of L0 */
#endif
/* #define SetSmallToZero*/
/* #define DoTraceL0 */
#endif
/*#define UseTimer */
/* Legacy compatibility and testing options (Fortran-LUSOL) */
/* ------------------------------------------------------------------------- */
#if 0
#define LegacyTesting
#define StaticMemAlloc /* Preallocated vs. dynamic memory allocation */
#define ClassicdiagU /* Store diagU at end of a */
#define ClassicHamaxR /* Store H+AmaxR at end of a/indc/indr */
#endif
/* General constants and data type definitions */
/* ------------------------------------------------------------------------- */
#define LUSOL_ARRAYOFFSET 1
#ifndef ZERO
#define ZERO 0
#endif
#ifndef ONE
#define ONE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
#ifndef NULL
#define NULL 0
#endif
#ifndef REAL
#define REAL double
#endif
#ifndef REALXP
#define REALXP long double
#endif
#ifndef MYBOOL
#define MYBOOL unsigned char
#endif
/* User-settable default parameter values */
/* ------------------------------------------------------------------------- */
#define LUSOL_DEFAULT_GAMMA 2.0
#define LUSOL_SMALLNUM 1.0e-20 /* IAEE doubles have precision 2.22e-16 */
#define LUSOL_BIGNUM 1.0e+20
#define LUSOL_MINDELTA_FACTOR 4
#define LUSOL_MINDELTA_a 10000
#if 1
#define LUSOL_MULT_nz_a 2 /* Suggested by Yin Zhang */
#else
#define LUSOL_MULT_nz_a 5 /* Could consider 6 or 7 */
#endif
#define LUSOL_MINDELTA_rc 1000
#define LUSOL_DEFAULT_SMARTRATIO 0.667
/* Fixed system parameters (changeable only by developers) */
/* ------------------------------------------------------------------------- */
/* parmlu INPUT parameters: */
#define LUSOL_RP_SMARTRATIO 0
#define LUSOL_RP_FACTORMAX_Lij 1
#define LUSOL_RP_UPDATEMAX_Lij 2
#define LUSOL_RP_ZEROTOLERANCE 3
#define LUSOL_RP_SMALLDIAG_U 4
#define LUSOL_RP_EPSDIAG_U 5
#define LUSOL_RP_COMPSPACE_U 6
#define LUSOL_RP_MARKOWITZ_CONLY 7
#define LUSOL_RP_MARKOWITZ_DENSE 8
#define LUSOL_RP_GAMMA 9
/* parmlu OUPUT parameters: */
#define LUSOL_RP_MAXELEM_A 10
#define LUSOL_RP_MAXMULT_L 11
#define LUSOL_RP_MAXELEM_U 12
#define LUSOL_RP_MAXELEM_DIAGU 13
#define LUSOL_RP_MINELEM_DIAGU 14
#define LUSOL_RP_MAXELEM_TCP 15
#define LUSOL_RP_GROWTHRATE 16
#define LUSOL_RP_USERDATA_1 17
#define LUSOL_RP_USERDATA_2 18
#define LUSOL_RP_USERDATA_3 19
#define LUSOL_RP_RESIDUAL_U 20
#define LUSOL_RP_LASTITEM LUSOL_RP_RESIDUAL_U
/* luparm INPUT parameters: */
#define LUSOL_IP_USERDATA_0 0
#define LUSOL_IP_PRINTUNIT 1
#define LUSOL_IP_PRINTLEVEL 2
#define LUSOL_IP_MARKOWITZ_MAXCOL 3
#define LUSOL_IP_SCALAR_NZA 4
#define LUSOL_IP_UPDATELIMIT 5
#define LUSOL_IP_PIVOTTYPE 6
#define LUSOL_IP_ACCELERATION 7
#define LUSOL_IP_KEEPLU 8
#define LUSOL_IP_SINGULARLISTSIZE 9
/* luparm OUTPUT parameters: */
#define LUSOL_IP_INFORM 10
#define LUSOL_IP_SINGULARITIES 11
#define LUSOL_IP_SINGULARINDEX 12
#define LUSOL_IP_MINIMUMLENA 13
#define LUSOL_IP_MAXLEN 14
#define LUSOL_IP_UPDATECOUNT 15
#define LUSOL_IP_RANK_U 16
#define LUSOL_IP_COLCOUNT_DENSE1 17
#define LUSOL_IP_COLCOUNT_DENSE2 18
#define LUSOL_IP_COLINDEX_DUMIN 19
#define LUSOL_IP_COLCOUNT_L0 20
#define LUSOL_IP_NONZEROS_L0 21
#define LUSOL_IP_NONZEROS_U0 22
#define LUSOL_IP_NONZEROS_L 23
#define LUSOL_IP_NONZEROS_U 24
#define LUSOL_IP_NONZEROS_ROW 25
#define LUSOL_IP_COMPRESSIONS_LU 26
#define LUSOL_IP_MARKOWITZ_MERIT 27
#define LUSOL_IP_TRIANGROWS_U 28
#define LUSOL_IP_TRIANGROWS_L 29
#define LUSOL_IP_FTRANCOUNT 30
#define LUSOL_IP_BTRANCOUNT 31
#define LUSOL_IP_ROWCOUNT_L0 32
#define LUSOL_IP_LASTITEM LUSOL_IP_ROWCOUNT_L0
/* Macros for matrix-based access for dense part of A and timer mapping */
/* ------------------------------------------------------------------------- */
#define DAPOS(row, col) (row + (col-1)*LDA)
#define timer(text, id) LUSOL_timer(LUSOL, id, text)
/* Parameter/option defines */
/* ------------------------------------------------------------------------- */
#define LUSOL_MSG_NONE -1
#define LUSOL_MSG_SINGULARITY 0
#define LUSOL_MSG_STATISTICS 10
#define LUSOL_MSG_PIVOT 50
#define LUSOL_BASEORDER 0
#define LUSOL_OTHERORDER 1
#define LUSOL_AUTOORDER 2
#define LUSOL_ACCELERATE_L0 4
#define LUSOL_ACCELERATE_U 8
#define LUSOL_PIVMOD_NOCHANGE -2 /* Don't change active pivoting model */
#define LUSOL_PIVMOD_DEFAULT -1 /* Set pivoting model to default */
#define LUSOL_PIVMOD_TPP 0 /* Threshold Partial pivoting (normal) */
#define LUSOL_PIVMOD_TRP 1 /* Threshold Rook pivoting */
#define LUSOL_PIVMOD_TCP 2 /* Threshold Complete pivoting */
#define LUSOL_PIVMOD_TSP 3 /* Threshold Symmetric pivoting */
#define LUSOL_PIVMOD_MAX LUSOL_PIVMOD_TSP
#define LUSOL_PIVTOL_NOCHANGE 0
#define LUSOL_PIVTOL_BAGGY 1
#define LUSOL_PIVTOL_LOOSE 2
#define LUSOL_PIVTOL_NORMAL 3
#define LUSOL_PIVTOL_SLIM 4
#define LUSOL_PIVTOL_TIGHT 5
#define LUSOL_PIVTOL_SUPER 6
#define LUSOL_PIVTOL_CORSET 7
#define LUSOL_PIVTOL_DEFAULT LUSOL_PIVTOL_SLIM
#define LUSOL_PIVTOL_MAX LUSOL_PIVTOL_CORSET
#define LUSOL_UPDATE_OLDEMPTY 0 /* No/empty current column. */
#define LUSOL_UPDATE_OLDNONEMPTY 1 /* Current column need not have been empty. */
#define LUSOL_UPDATE_NEWEMPTY 0 /* New column is taken to be zero. */
#define LUSOL_UPDATE_NEWNONEMPTY 1 /* v(*) contains the new column;
on exit, v(*) satisfies L*v = a(new). */
#define LUSOL_UPDATE_USEPREPARED 2 /* v(*) must satisfy L*v = a(new). */
#define LUSOL_SOLVE_Lv_v 1 /* v solves L v = v(input). w is not touched. */
#define LUSOL_SOLVE_Ltv_v 2 /* v solves L'v = v(input). w is not touched. */
#define LUSOL_SOLVE_Uw_v 3 /* w solves U w = v. v is not altered. */
#define LUSOL_SOLVE_Utv_w 4 /* v solves U'v = w. w is destroyed. */
#define LUSOL_SOLVE_Aw_v 5 /* w solves A w = v. v is altered as in 1. */
#define LUSOL_FTRAN LUSOL_SOLVE_Aw_v
#define LUSOL_SOLVE_Atv_w 6 /* v solves A'v = w. w is destroyed. */
#define LUSOL_BTRAN LUSOL_SOLVE_Atv_w
/* If mode = 3,4,5,6, v and w must not be the same arrays.
If lu1fac has just been used to factorize a symmetric matrix A
(which must be definite or quasi-definite), the factors A = L U
may be regarded as A = LDL', where D = diag(U). In such cases,
the following (faster) solve codes may be used: */
#define LUSOL_SOLVE_Av_v 7 /* v solves A v = L D L'v = v(input). w is not touched. */
#define LUSOL_SOLVE_LDLtv_v 8 /* v solves L |D| L'v = v(input). w is not touched. */
#define LUSOL_INFORM_RANKLOSS -1
#define LUSOL_INFORM_LUSUCCESS 0
#define LUSOL_INFORM_LUSINGULAR 1
#define LUSOL_INFORM_LUUNSTABLE 2
#define LUSOL_INFORM_ADIMERR 3
#define LUSOL_INFORM_ADUPLICATE 4
#define LUSOL_INFORM_ANEEDMEM 7 /* Set lena >= luparm[LUSOL_IP_MINIMUMLENA] */
#define LUSOL_INFORM_FATALERR 8
#define LUSOL_INFORM_NOPIVOT 9 /* No diagonal pivot found with TSP or TDP. */
#define LUSOL_INFORM_NOMEMLEFT 10
#define LUSOL_INFORM_MIN LUSOL_INFORM_RANKLOSS
#define LUSOL_INFORM_MAX LUSOL_INFORM_NOMEMLEFT
#define LUSOL_INFORM_GETLAST 10 /* Code for LUSOL_informstr. */
#define LUSOL_INFORM_SERIOUS LUSOL_INFORM_LUUNSTABLE
/* Prototypes for call-back functions */
/* ------------------------------------------------------------------------- */
typedef void LUSOLlogfunc(void *lp, void *userhandle, char *buf);
/* Sparse matrix data */
typedef struct _LUSOLmat {
REAL *a;
int *lenx, *indr, *indc, *indx;
} LUSOLmat;
/* The main LUSOL data record */
/* ------------------------------------------------------------------------- */
typedef struct _LUSOLrec {
/* General data */
FILE *outstream; /* Output stream, initialized to STDOUT */
LUSOLlogfunc *writelog;
void *loghandle;
LUSOLlogfunc *debuginfo;
/* Parameter storage arrays */
int luparm[LUSOL_IP_LASTITEM + 1];
REAL parmlu[LUSOL_RP_LASTITEM + 1];
/* Arrays of length lena+1 */
int lena, nelem;
int *indc, *indr;
REAL *a;
/* Arrays of length maxm+1 (row storage) */
int maxm, m;
int *lenr, *ip, *iqloc, *ipinv, *locr;
/* Arrays of length maxn+1 (column storage) */
int maxn, n;
int *lenc, *iq, *iploc, *iqinv, *locc;
REAL *w, *vLU6L;
/* List of singular columns, with dynamic size allocation */
int *isingular;
/* Extra arrays of length n for TCP and keepLU == FALSE */
REAL *Ha, *diagU;
int *Hj, *Hk;
/* Extra arrays of length m for TRP*/
REAL *amaxr;
/* Extra array for L0 and U stored by row/column for faster btran/ftran */
LUSOLmat *L0;
LUSOLmat *U;
/* Miscellaneous data */
int expanded_a;
int replaced_c;
int replaced_r;
} LUSOLrec;
LUSOLrec *LUSOL_create(FILE *outstream, int msgfil, int pivotmodel, int updatelimit);
MYBOOL LUSOL_sizeto(LUSOLrec *LUSOL, int init_r, int init_c, int init_a);
MYBOOL LUSOL_assign(LUSOLrec *LUSOL, int iA[], int jA[], REAL Aij[],
int nzcount, MYBOOL istriplet);
void LUSOL_clear(LUSOLrec *LUSOL, MYBOOL nzonly);
void LUSOL_free(LUSOLrec *LUSOL);
LUSOLmat *LUSOL_matcreate(int dim, int nz);
void LUSOL_matfree(LUSOLmat **mat);
int LUSOL_loadColumn(LUSOLrec *LUSOL, int iA[], int jA, REAL Aij[], int nzcount, int offset1);
void LUSOL_setpivotmodel(LUSOLrec *LUSOL, int pivotmodel, int initlevel);
int LUSOL_factorize(LUSOLrec *LUSOL);
int LUSOL_replaceColumn(LUSOLrec *LUSOL, int jcol, REAL v[]);
MYBOOL LUSOL_tightenpivot(LUSOLrec *LUSOL);
MYBOOL LUSOL_addSingularity(LUSOLrec *LUSOL, int singcol, int *inform);
int LUSOL_getSingularity(LUSOLrec *LUSOL, int singitem);
int LUSOL_findSingularityPosition(LUSOLrec *LUSOL, int singcol);
char *LUSOL_pivotLabel(LUSOLrec *LUSOL);
char *LUSOL_informstr(LUSOLrec *LUSOL, int inform);
REAL LUSOL_vecdensity(LUSOLrec *LUSOL, REAL V[]);
void LUSOL_report(LUSOLrec *LUSOL, int msglevel, char *format, ...);
void LUSOL_timer(LUSOLrec *LUSOL, int timerid, char *text);
int LUSOL_ftran(LUSOLrec *LUSOL, REAL b[], int NZidx[], MYBOOL prepareupdate);
int LUSOL_btran(LUSOLrec *LUSOL, REAL b[], int NZidx[]);
void LU1FAC(LUSOLrec *LUSOL, int *INFORM);
MYBOOL LU1L0(LUSOLrec *LUSOL, LUSOLmat **mat, int *inform);
void LU6SOL(LUSOLrec *LUSOL, int MODE, REAL V[], REAL W[], int NZidx[], int *INFORM);
void LU8RPC(LUSOLrec *LUSOL, int MODE1, int MODE2,
int JREP, REAL V[], REAL W[],
int *INFORM, REAL *DIAG, REAL *VNORM);
void LUSOL_dump(FILE *output, LUSOLrec *LUSOL);
void print_L0(LUSOLrec *LUSOL);
#endif /* HEADER_LUSOL */

File diff suppressed because it is too large Load Diff

View File

@ -1,204 +0,0 @@
/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
File lusol2 LUSOL heap management routines
Hbuild Hchange Hdelete Hdown Hinsert Hup
Heap-management routines for LUSOL's lu1fac.
May be useful for other applications.
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
For LUSOL, the heap structure involves three arrays of length N.
N is the current number of entries in the heap.
Ha(1:N) contains the values that the heap is partially sorting.
For LUSOL they are double precision values -- the largest
element in each remaining column of the updated matrix.
The biggest entry is in Ha(1), the top of the heap.
Hj(1:N) contains column numbers j.
Ha(k) is the biggest entry in column j = Hj(k).
Hk(1:N) contains indices within the heap. It is the
inverse of Hj(1:N), so k = Hk(j) <=> j = Hj(k).
Column j is entry k in the heap.
hops is the number of heap operations,
i.e., the number of times an entry is moved
(the number of "hops" up or down the heap).
Together, Hj and Hk let us find values inside the heap
whenever we want to change one of the values in Ha.
For other applications, Ha may need to be some other data type,
like the keys that sort routines operate on.
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
11 Feb 2002: MATLAB version derived from "Algorithms" by
R. Sedgewick
03 Mar 2002: F77 version derived from MATLAB version.
07 May 2002: Safeguard input parameters k, N, Nk.
We don't want them to be output!
07 May 2002: Current version of lusol2.f.
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
/* ==================================================================
Hdown updates heap by moving down tree from node k.
------------------------------------------------------------------
01 May 2002: Need Nk for length of Hk.
05 May 2002: Change input paramter k to kk to stop k being output.
05 May 2002: Current version of Hdown.
================================================================== */
void HDOWN(REAL HA[], int HJ[], int HK[], int N, int K, int *HOPS)
{
int J, JJ, JV, N2;
REAL V;
*HOPS = 0;
V = HA[K];
JV = HJ[K];
N2 = N/2;
/* while 1
break */
x100:
if(K>N2)
goto x200;
(*HOPS)++;
J = K+K;
if(J<N) {
if(HA[J]<HA[J+1])
J++;
}
/* break */
if(V>=HA[J])
goto x200;
HA[K] = HA[J];
JJ = HJ[J];
HJ[K] = JJ;
HK[JJ] = K;
K = J;
goto x100;
/* end while */
x200:
HA[K] = V;
HJ[K] = JV;
HK[JV] = K;
}
/* ==================================================================
Hup updates heap by moving up tree from node k.
------------------------------------------------------------------
01 May 2002: Need Nk for length of Hk.
05 May 2002: Change input paramter k to kk to stop k being output.
05 May 2002: Current version of Hup.
================================================================== */
void HUP(REAL HA[], int HJ[], int HK[], int K, int *HOPS)
{
int J, JV, K2;
REAL V;
*HOPS = 0;
V = HA[K];
JV = HJ[K];
/* while 1
break */
x100:
if(K<2)
goto x200;
K2 = K/2;
/* break */
if(V<HA[K2])
goto x200;
(*HOPS)++;
HA[K] = HA[K2];
J = HJ[K2];
HJ[K] = J;
HK[J] = K;
K = K2;
goto x100;
/* end while */
x200:
HA[K] = V;
HJ[K] = JV;
HK[JV] = K;
}
/* ==================================================================
Hinsert inserts (v,jv) into heap of length N-1
to make heap of length N.
------------------------------------------------------------------
03 Apr 2002: First version of Hinsert.
01 May 2002: Require N to be final length, not old length.
Need Nk for length of Hk.
07 May 2002: Protect input parameters N, Nk.
07 May 2002: Current version of Hinsert.
================================================================== */
void HINSERT(REAL HA[], int HJ[], int HK[], int N,
REAL V, int JV, int *HOPS)
{
HA[N] = V;
HJ[N] = JV;
HK[JV] = N;
HUP(HA,HJ,HK,N,HOPS);
}
/* ==================================================================
Hchange changes Ha(k) to v in heap of length N.
------------------------------------------------------------------
01 May 2002: Need Nk for length of Hk.
07 May 2002: Protect input parameters N, Nk, k.
07 May 2002: Current version of Hchange.
================================================================== */
void HCHANGE(REAL HA[], int HJ[], int HK[], int N, int K,
REAL V, int JV, int *HOPS)
{
REAL V1;
V1 = HA[K];
HA[K] = V;
HJ[K] = JV;
HK[JV] = K;
if(V1<V)
HUP (HA,HJ,HK, K,HOPS);
else
HDOWN(HA,HJ,HK,N,K,HOPS);
}
/* ==================================================================
Hdelete deletes Ha(k) from heap of length N.
------------------------------------------------------------------
03 Apr 2002: Current version of Hdelete.
01 May 2002: Need Nk for length of Hk.
07 May 2002: Protect input parameters N, Nk, k.
07 May 2002: Current version of Hdelete.
================================================================== */
void HDELETE(REAL HA[], int HJ[], int HK[], int *N, int K, int *HOPS)
{
int JV, NX;
REAL V;
NX = *N;
V = HA[NX];
JV = HJ[NX];
(*N)--;
*HOPS = 0;
if(K<NX)
HCHANGE(HA,HJ,HK,NX,K,V,JV,HOPS);
}
/* ==================================================================
Hbuild initializes the heap by inserting each element of Ha.
Input: Ha, Hj.
Output: Ha, Hj, Hk, hops.
------------------------------------------------------------------
01 May 2002: Use k for new length of heap, not k-1 for old length.
05 May 2002: Use kk in call to stop loop variable k being altered.
(Actually Hinsert no longer alters that parameter.)
07 May 2002: ftnchek wants us to protect Nk, Ha(k), Hj(k) too.
07 May 2002: Current version of Hbuild.
================================================================== */
void HBUILD(REAL HA[], int HJ[], int HK[], int N, int *HOPS)
{
int H, JV, K, KK;
REAL V;
*HOPS = 0;
for(K = 1; K <= N; K++) {
KK = K;
V = HA[K];
JV = HJ[K];
HINSERT(HA,HJ,HK,KK,V,JV,&H);
(*HOPS) += H;
}
}

View File

@ -1,867 +0,0 @@
/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
File lusol6a
lu6sol lu6L lu6Lt lu6U Lu6Ut lu6LD lu6chk
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
26 Apr 2002: lu6 routines put into a separate file.
15 Dec 2002: lu6sol modularized via lu6L, lu6Lt, lu6U, lu6Ut.
lu6LD implemented to allow solves with LDL' or L|D|L'.
15 Dec 2002: Current version of lusol6a.f.
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
/* ==================================================================
lu6chk looks at the LU factorization A = L*U.
If mode = 1, lu6chk is being called by lu1fac.
(Other modes not yet implemented.)
------------------------------------------------------------------
The important input parameters are
lprint = luparm(2)
keepLU = luparm(8)
Utol1 = parmlu(4)
Utol2 = parmlu(5)
and the significant output parameters are
inform = luparm(10)
nsing = luparm(11)
jsing = luparm(12)
jumin = luparm(19)
Lmax = parmlu(11)
Umax = parmlu(12)
DUmax = parmlu(13)
DUmin = parmlu(14)
and w(*).
Lmax and Umax return the largest elements in L and U.
DUmax and DUmin return the largest and smallest diagonals of U
(excluding diagonals that are exactly zero).
In general, w(j) is set to the maximum absolute element in
the j-th column of U. However, if the corresponding diagonal
of U is small in absolute terms or relative to w(j)
(as judged by the parameters Utol1, Utol2 respectively),
then w(j) is changed to - w(j).
Thus, if w(j) is not positive, the j-th column of A
appears to be dependent on the other columns of A.
The number of such columns, and the position of the last one,
are returned as nsing and jsing.
Note that nrank is assumed to be set already, and is not altered.
Typically, nsing will satisfy nrank + nsing = n, but if
Utol1 and Utol2 are rather large, nsing > n - nrank may occur.
If keepLU = 0,
Lmax and Umax are already set by lu1fac.
The diagonals of U are in the top of A.
Only Utol1 is used in the singularity test to set w(*).
inform = 0 if A appears to have full column rank (nsing = 0).
inform = 1 otherwise (nsing .gt. 0).
------------------------------------------------------------------
00 Jul 1987: Early version.
09 May 1988: f77 version.
11 Mar 2001: Allow for keepLU = 0.
17 Nov 2001: Briefer output for singular factors.
05 May 2002: Comma needed in format 1100 (via Kenneth Holmstrom).
06 May 2002: With keepLU = 0, diags of U are in natural order.
They were not being extracted correctly.
23 Apr 2004: TRP can judge singularity better by comparing
all diagonals to DUmax.
27 Jun 2004: (PEG) Allow write only if nout .gt. 0.
================================================================== */
#ifdef UseOld_LU6CHK_20040510
void LU6CHK(LUSOLrec *LUSOL, int MODE, int LENA2, int *INFORM)
{
MYBOOL KEEPLU;
int I, J, JUMIN, K, L, L1, L2, LENL, LPRINT, NDEFIC, NRANK;
REAL AIJ, DIAG, DUMAX, DUMIN, LMAX, UMAX, UTOL1, UTOL2;
LPRINT = LUSOL->luparm[LUSOL_IP_PRINTLEVEL];
KEEPLU = (MYBOOL) (LUSOL->luparm[LUSOL_IP_KEEPLU]!=0);
NRANK = LUSOL->luparm[LUSOL_IP_RANK_U];
LENL = LUSOL->luparm[LUSOL_IP_NONZEROS_L];
UTOL1 = LUSOL->parmlu[LUSOL_RP_SMALLDIAG_U];
UTOL2 = LUSOL->parmlu[LUSOL_RP_EPSDIAG_U];
*INFORM = LUSOL_INFORM_LUSUCCESS;
LMAX = ZERO;
UMAX = ZERO;
LUSOL->luparm[LUSOL_IP_SINGULARITIES] = 0;
LUSOL->luparm[LUSOL_IP_SINGULARINDEX] = 0;
JUMIN = 0;
DUMAX = ZERO;
DUMIN = LUSOL_BIGNUM;
#ifdef LUSOLFastClear
MEMCLEAR(LUSOL->w+1, LUSOL->n);
#else
for(I = 1; I <= LUSOL->n; I++)
LUSOL->w[I] = ZERO;
#endif
if(KEEPLU) {
/* --------------------------------------------------------------
Find Lmax.
-------------------------------------------------------------- */
for(L = (LENA2+1)-LENL; L <= LENA2; L++) {
SETMAX(LMAX,fabs(LUSOL->a[L]));
}
/* --------------------------------------------------------------
Find Umax and set w(j) = maximum element in j-th column of U.
-------------------------------------------------------------- */
for(K = 1; K <= NRANK; K++) {
I = LUSOL->ip[K];
L1 = LUSOL->locr[I];
L2 = (L1+LUSOL->lenr[I])-1;
for(L = L1; L <= L2; L++) {
J = LUSOL->indr[L];
AIJ = fabs(LUSOL->a[L]);
SETMAX(LUSOL->w[J],AIJ);
SETMAX(UMAX,AIJ);
}
}
/* --------------------------------------------------------------
Negate w(j) if the corresponding diagonal of U is
too small in absolute terms or relative to the other elements
in the same column of U.
Also find DUmax and DUmin, the extreme diagonals of U.
-------------------------------------------------------------- */
for(K = 1; K <= LUSOL->n; K++) {
J = LUSOL->iq[K];
if(K>NRANK)
DIAG = ZERO;
else {
I = LUSOL->ip[K];
L1 = LUSOL->locr[I];
DIAG = fabs(LUSOL->a[L1]);
SETMAX(DUMAX,DIAG);
if(DUMIN>DIAG) {
DUMIN = DIAG;
JUMIN = J;
}
}
if((DIAG<=UTOL1) || (DIAG<=UTOL2*LUSOL->w[J])) {
LUSOL_addSingularity(LUSOL, J, INFORM);
LUSOL->w[J] = -LUSOL->w[J];
}
}
LUSOL->parmlu[LUSOL_RP_MAXMULT_L] = LMAX;
LUSOL->parmlu[LUSOL_RP_MAXELEM_U] = UMAX;
}
else {
/* --------------------------------------------------------------
keepLU = 0.
Only diag(U) is stored. Set w(*) accordingly.
-------------------------------------------------------------- */
for(K = 1; K <= LUSOL->n; K++) {
J = LUSOL->iq[K];
if(K>NRANK)
DIAG = ZERO;
else {
/* ! diag = abs( diagU(k) ) ! 06 May 2002: Diags are in natural order */
DIAG = fabs(LUSOL->diagU[J]);
LUSOL->w[J] = DIAG;
SETMAX(DUMAX,DIAG);
if(DUMIN>DIAG) {
DUMIN = DIAG;
JUMIN = J;
}
}
if(DIAG<=UTOL1) {
LUSOL_addSingularity(LUSOL, J, INFORM);
LUSOL->w[J] = -LUSOL->w[J];
}
}
}
/* -----------------------------------------------------------------
Set output parameters.
----------------------------------------------------------------- */
if(JUMIN==0)
DUMIN = ZERO;
LUSOL->luparm[LUSOL_IP_COLINDEX_DUMIN] = JUMIN;
LUSOL->parmlu[LUSOL_RP_MAXELEM_DIAGU] = DUMAX;
LUSOL->parmlu[LUSOL_RP_MINELEM_DIAGU] = DUMIN;
/* The matrix has been judged singular. */
if(LUSOL->luparm[LUSOL_IP_SINGULARITIES]>0) {
*INFORM = LUSOL_INFORM_LUSINGULAR;
NDEFIC = LUSOL->n-NRANK;
if(LPRINT>=LUSOL_MSG_SINGULARITY) {
LUSOL_report(LUSOL, 0, "Singular(m%cn) rank:%9d n-rank:%8d nsing:%9d\n",
relationChar(LUSOL->m, LUSOL->n),NRANK,NDEFIC,
LUSOL->luparm[LUSOL_IP_SINGULARITIES]);
}
}
/* Exit. */
LUSOL->luparm[LUSOL_IP_INFORM] = *INFORM;
}
#else
void LU6CHK(LUSOLrec *LUSOL, int MODE, int LENA2, int *INFORM)
{
MYBOOL KEEPLU, TRP;
int I, J, JUMIN, K, L, L1, L2, LENL, LDIAGU, LPRINT, NDEFIC, NRANK;
REAL AIJ, DIAG, DUMAX, DUMIN, LMAX, UMAX, UTOL1, UTOL2;
LPRINT = LUSOL->luparm[LUSOL_IP_PRINTLEVEL];
KEEPLU = (MYBOOL) (LUSOL->luparm[LUSOL_IP_KEEPLU] != 0);
TRP = (MYBOOL) (LUSOL->luparm[LUSOL_IP_PIVOTTYPE] == LUSOL_PIVMOD_TRP);
NRANK = LUSOL->luparm[LUSOL_IP_RANK_U];
LENL = LUSOL->luparm[LUSOL_IP_NONZEROS_L];
UTOL1 = LUSOL->parmlu[LUSOL_RP_SMALLDIAG_U];
UTOL2 = LUSOL->parmlu[LUSOL_RP_EPSDIAG_U];
*INFORM = LUSOL_INFORM_LUSUCCESS;
LMAX = ZERO;
UMAX = ZERO;
LUSOL->luparm[LUSOL_IP_SINGULARITIES] = 0;
LUSOL->luparm[LUSOL_IP_SINGULARINDEX] = 0;
JUMIN = 0;
DUMAX = ZERO;
DUMIN = LUSOL_BIGNUM;
#ifdef LUSOLFastClear
MEMCLEAR(LUSOL->w+1, LUSOL->n);
#else
for(I = 1; I <= LUSOL->n; I++)
LUSOL->w[I] = ZERO;
#endif
if(KEEPLU) {
/* --------------------------------------------------------------
Find Lmax.
-------------------------------------------------------------- */
for(L = (LENA2+1)-LENL; L <= LENA2; L++) {
SETMAX(LMAX,fabs(LUSOL->a[L]));
}
/* --------------------------------------------------------------
Find Umax and set w(j) = maximum element in j-th column of U.
-------------------------------------------------------------- */
for(K = 1; K <= NRANK; K++) {
I = LUSOL->ip[K];
L1 = LUSOL->locr[I];
L2 = (L1+LUSOL->lenr[I])-1;
for(L = L1; L <= L2; L++) {
J = LUSOL->indr[L];
AIJ = fabs(LUSOL->a[L]);
SETMAX(LUSOL->w[J],AIJ);
SETMAX(UMAX,AIJ);
}
}
LUSOL->parmlu[LUSOL_RP_MAXMULT_L] = LMAX;
LUSOL->parmlu[LUSOL_RP_MAXELEM_U] = UMAX;
/* --------------------------------------------------------------
Find DUmax and DUmin, the extreme diagonals of U.
-------------------------------------------------------------- */
for(K = 1; K <= NRANK; K++) {
J = LUSOL->iq[K];
I = LUSOL->ip[K];
L1 = LUSOL->locr[I];
DIAG = fabs(LUSOL->a[L1]);
SETMAX( DUMAX, DIAG );
if(DUMIN > DIAG) {
DUMIN = DIAG;
JUMIN = J;
}
}
}
else {
/* --------------------------------------------------------------
keepLU = 0.
Only diag(U) is stored. Set w(*) accordingly.
Find DUmax and DUmin, the extreme diagonals of U.
-------------------------------------------------------------- */
LDIAGU = LENA2 - LUSOL->n;
for(K = 1; K <= NRANK; K++) {
J = LUSOL->iq[K];
DIAG = fabs( LUSOL->a[LDIAGU + J] ); /* are in natural order */
LUSOL->w[J] = DIAG;
SETMAX( DUMAX, DIAG );
if(DUMIN > DIAG) {
DUMIN = DIAG;
JUMIN = J;
}
}
}
/* --------------------------------------------------------------
Negate w(j) if the corresponding diagonal of U is
too small in absolute terms or relative to the other elements
in the same column of U.
23 Apr 2004: TRP ensures that diags are NOT small relative to
other elements in their own column.
Much better, we can compare all diags to DUmax.
-------------------------------------------------------------- */
if((MODE == 1) && TRP) {
SETMAX( UTOL1, UTOL2*DUMAX );
}
if(KEEPLU) {
for(K = 1; K <= LUSOL->n; K++) {
J = LUSOL->iq[K];
if(K>NRANK)
DIAG = ZERO;
else {
I = LUSOL->ip[K];
L1 = LUSOL->locr[I];
DIAG = fabs(LUSOL->a[L1]);
}
if((DIAG<=UTOL1) || (DIAG<=UTOL2*LUSOL->w[J])) {
LUSOL_addSingularity(LUSOL, J, INFORM);
LUSOL->w[J] = -LUSOL->w[J];
}
}
}
else { /* keepLU = FALSE */
for(K = 1; K <= LUSOL->n; K++) {
J = LUSOL->iq[K];
DIAG = LUSOL->w[J];
if(DIAG<=UTOL1) {
LUSOL_addSingularity(LUSOL, J, INFORM);
LUSOL->w[J] = -LUSOL->w[J];
}
}
}
/* -----------------------------------------------------------------
Set output parameters.
----------------------------------------------------------------- */
if(JUMIN==0)
DUMIN = ZERO;
LUSOL->luparm[LUSOL_IP_COLINDEX_DUMIN] = JUMIN;
LUSOL->parmlu[LUSOL_RP_MAXELEM_DIAGU] = DUMAX;
LUSOL->parmlu[LUSOL_RP_MINELEM_DIAGU] = DUMIN;
/* The matrix has been judged singular. */
if(LUSOL->luparm[LUSOL_IP_SINGULARITIES]>0) {
*INFORM = LUSOL_INFORM_LUSINGULAR;
NDEFIC = LUSOL->n-NRANK;
if((LUSOL->outstream!=NULL) && (LPRINT>=LUSOL_MSG_SINGULARITY)) {
LUSOL_report(LUSOL, 0, "Singular(m%cn) rank:%9d n-rank:%8d nsing:%9d\n",
relationChar(LUSOL->m, LUSOL->n),NRANK,NDEFIC,
LUSOL->luparm[LUSOL_IP_SINGULARITIES]);
}
}
/* Exit. */
LUSOL->luparm[LUSOL_IP_INFORM] = *INFORM;
}
#endif
/* ------------------------------------------------------------------
Include routines for row-based L0.
20 Apr 2005 Current version - KE.
------------------------------------------------------------------ */
#include "lusol6l0.c"
/* ------------------------------------------------------------------
lu6L solves L v = v(input).
------------------------------------------------------------------
15 Dec 2002: First version derived from lu6sol.
15 Dec 2002: Current version.
------------------------------------------------------------------ */
void LU6L(LUSOLrec *LUSOL, int *INFORM, REAL V[], int NZidx[])
{
int JPIV, K, L, L1, LEN, LENL, LENL0, NUML, NUML0;
REAL SMALL;
register REAL VPIV;
#ifdef LUSOLFastSolve
REAL *aptr;
int *iptr, *jptr;
#else
int I, J;
#endif
NUML0 = LUSOL->luparm[LUSOL_IP_COLCOUNT_L0];
LENL0 = LUSOL->luparm[LUSOL_IP_NONZEROS_L0];
LENL = LUSOL->luparm[LUSOL_IP_NONZEROS_L];
SMALL = LUSOL->parmlu[LUSOL_RP_ZEROTOLERANCE];
*INFORM = LUSOL_INFORM_LUSUCCESS;
L1 = LUSOL->lena+1;
for(K = 1; K <= NUML0; K++) {
LEN = LUSOL->lenc[K];
L = L1;
L1 -= LEN;
JPIV = LUSOL->indr[L1];
VPIV = V[JPIV];
if(fabs(VPIV)>SMALL) {
/* ***** This loop could be coded specially. */
#ifdef LUSOLFastSolve
L--;
for(aptr = LUSOL->a+L, iptr = LUSOL->indc+L;
LEN > 0; LEN--, aptr--, iptr--)
V[*iptr] += (*aptr) * VPIV;
#else
for(; LEN > 0; LEN--) {
L--;
I = LUSOL->indc[L];
V[I] += LUSOL->a[L]*VPIV;
}
#endif
}
#ifdef SetSmallToZero
else
V[JPIV] = 0;
#endif
}
L = (LUSOL->lena-LENL0)+1;
NUML = LENL-LENL0;
/* ***** This loop could be coded specially. */
#ifdef LUSOLFastSolve
L--;
for(aptr = LUSOL->a+L, jptr = LUSOL->indr+L, iptr = LUSOL->indc+L;
NUML > 0; NUML--, aptr--, jptr--, iptr--) {
if(fabs(V[*jptr])>SMALL)
V[*iptr] += (*aptr) * V[*jptr];
#ifdef SetSmallToZero
else
V[*jptr] = 0;
#endif
}
#else
for(; NUML > 0; NUML--) {
L--;
J = LUSOL->indr[L];
if(fabs(V[J])>SMALL) {
I = LUSOL->indc[L];
V[I] += LUSOL->a[L]*V[J];
}
#ifdef SetSmallToZero
else
V[J] = 0;
#endif
}
#endif
/* Exit. */
LUSOL->luparm[LUSOL_IP_INFORM] = *INFORM;
}
/* ==================================================================
lu6LD assumes lu1fac has computed factors A = LU of a
symmetric definite or quasi-definite matrix A,
using Threshold Symmetric Pivoting (TSP), luparm(6) = 3,
or Threshold Diagonal Pivoting (TDP), luparm(6) = 4.
It also assumes that no updates have been performed.
In such cases, U = D L', where D = diag(U).
lu6LDL returns v as follows:
mode
1 v solves L D v = v(input).
2 v solves L|D|v = v(input).
------------------------------------------------------------------
15 Dec 2002: First version of lu6LD.
15 Dec 2002: Current version.
================================================================== */
void LU6LD(LUSOLrec *LUSOL, int *INFORM, int MODE, REAL V[], int NZidx[])
{
int IPIV, K, L, L1, LEN, NUML0;
REAL DIAG, SMALL;
register REAL VPIV;
#ifdef LUSOLFastSolve
REAL *aptr;
int *jptr;
#else
int J;
#endif
/* Solve L D v(new) = v or L|D|v(new) = v, depending on mode.
The code for L is the same as in lu6L,
but when a nonzero entry of v arises, we divide by
the corresponding entry of D or |D|. */
NUML0 = LUSOL->luparm[LUSOL_IP_COLCOUNT_L0];
SMALL = LUSOL->parmlu[LUSOL_RP_ZEROTOLERANCE];
*INFORM = LUSOL_INFORM_LUSUCCESS;
L1 = LUSOL->lena+1;
for(K = 1; K <= NUML0; K++) {
LEN = LUSOL->lenc[K];
L = L1;
L1 -= LEN;
IPIV = LUSOL->indr[L1];
VPIV = V[IPIV];
if(fabs(VPIV)>SMALL) {
/* ***** This loop could be coded specially. */
#ifdef LUSOLFastSolve
L--;
for(aptr = LUSOL->a+L, jptr = LUSOL->indc+L;
LEN > 0; LEN--, aptr--, jptr--)
V[*jptr] += (*aptr)*VPIV;
#else
for(; LEN > 0; LEN--) {
L--;
J = LUSOL->indc[L];
V[J] += LUSOL->a[L]*VPIV;
}
#endif
/* Find diag = U(ipiv,ipiv) and divide by diag or |diag|. */
L = LUSOL->locr[IPIV];
DIAG = LUSOL->a[L];
if(MODE==2)
DIAG = fabs(DIAG);
V[IPIV] = VPIV/DIAG;
}
#ifdef SetSmallToZero
else
V[IPIV] = 0;
#endif
}
}
/* ==================================================================
lu6Lt solves L'v = v(input).
------------------------------------------------------------------
15 Dec 2002: First version derived from lu6sol.
15 Dec 2002: Current version.
================================================================== */
void LU6LT(LUSOLrec *LUSOL, int *INFORM, REAL V[], int NZidx[])
{
#ifdef DoTraceL0
REAL TEMP;
#endif
int K, L, L1, L2, LEN, LENL, LENL0, NUML0;
REAL SMALL;
register REALXP SUM;
register REAL HOLD;
#if (defined LUSOLFastSolve) && !(defined DoTraceL0)
REAL *aptr;
int *iptr, *jptr;
#else
int I, J;
#endif
NUML0 = LUSOL->luparm[LUSOL_IP_COLCOUNT_L0];
LENL0 = LUSOL->luparm[LUSOL_IP_NONZEROS_L0];
LENL = LUSOL->luparm[LUSOL_IP_NONZEROS_L];
SMALL = LUSOL->parmlu[LUSOL_RP_ZEROTOLERANCE];
*INFORM = LUSOL_INFORM_LUSUCCESS;
L1 = (LUSOL->lena-LENL)+1;
L2 = LUSOL->lena-LENL0;
/* ***** This loop could be coded specially. */
#if (defined LUSOLFastSolve) && !(defined DoTraceL0)
for(L = L1, aptr = LUSOL->a+L1, iptr = LUSOL->indr+L1, jptr = LUSOL->indc+L1;
L <= L2; L++, aptr++, iptr++, jptr++) {
HOLD = V[*jptr];
if(fabs(HOLD)>SMALL)
V[*iptr] += (*aptr)*HOLD;
#ifdef SetSmallToZero
else
V[*jptr] = 0;
#endif
}
#else
for(L = L1; L <= L2; L++) {
J = LUSOL->indc[L];
HOLD = V[J];
if(fabs(HOLD)>SMALL) {
I = LUSOL->indr[L];
V[I] += LUSOL->a[L]*HOLD;
}
#ifdef SetSmallToZero
else
V[J] = 0;
#endif
}
#endif
/* Do row-based L0 version, if available */
if((LUSOL->L0 != NULL) ||
((LUSOL->luparm[LUSOL_IP_BTRANCOUNT] == 0) && LU1L0(LUSOL, &(LUSOL->L0), INFORM))) {
LU6L0T_v(LUSOL, LUSOL->L0, V, NZidx, INFORM);
}
/* Alternatively, do the standard column-based L0 version */
else {
/* Perform loop over columns */
for(K = NUML0; K >= 1; K--) {
SUM = ZERO;
LEN = LUSOL->lenc[K];
L1 = L2+1;
L2 += LEN;
/* ***** This loop could be coded specially. */
#if (defined LUSOLFastSolve) && !(defined DoTraceL0)
for(L = L1, aptr = LUSOL->a+L1, jptr = LUSOL->indc+L1;
L <= L2; L++, aptr++, jptr++)
SUM += (*aptr) * V[*jptr];
#else
for(L = L1; L <= L2; L++) {
J = LUSOL->indc[L];
#ifndef DoTraceL0
SUM += LUSOL->a[L]*V[J];
#else
TEMP = V[LUSOL->indr[L1]] + SUM;
SUM += LUSOL->a[L]*V[J];
printf("V[%3d] = V[%3d] + L[%d,%d]*V[%3d]\n", LUSOL->indr[L1], LUSOL->indr[L1], J,LUSOL->indr[L1], J);
printf("%6g = %6g + %6g*%6g\n", V[LUSOL->indr[L1]] + SUM, TEMP, LUSOL->a[L], V[J]);
#endif
}
#endif
V[LUSOL->indr[L1]] += (REAL) SUM;
}
}
/* Exit. */
LUSOL->luparm[LUSOL_IP_INFORM] = *INFORM;
}
void print_L0(LUSOLrec *LUSOL)
{
int I, J, K, L, L1, L2, LEN, LENL0, NUML0;
REAL *denseL0 = (REAL*) calloc(LUSOL->m+1, (LUSOL->n+1)*sizeof(*denseL0));
NUML0 = LUSOL->luparm[LUSOL_IP_COLCOUNT_L0];
LENL0 = LUSOL->luparm[LUSOL_IP_NONZEROS_L0];
L2 = LUSOL->lena-LENL0;
for(K = NUML0; K >= 1; K--) {
LEN = LUSOL->lenc[K];
L1 = L2+1;
L2 += LEN;
for(L = L1; L <= L2; L++) {
I = LUSOL->indc[L];
I = LUSOL->ipinv[I]; /* Undo row mapping */
J = LUSOL->indr[L];
denseL0[(LUSOL->n+1)*(J-1) + I] = LUSOL->a[L];
}
}
for(I = 1; I <= LUSOL->n; I++) {
for(J = 1; J <= LUSOL->m; J++)
fprintf(stdout, "%10g", denseL0[(LUSOL->n+1)*(J-1) + I]);
fprintf(stdout, "\n");
}
LUSOL_FREE(denseL0);
}
/* ------------------------------------------------------------------
Include routines for column-based U.
5 Feb 2006 Current version - KE.
------------------------------------------------------------------ */
#include "lusol6u.c"
/* ==================================================================
lu6U solves U w = v. v is not altered.
------------------------------------------------------------------
15 Dec 2002: First version derived from lu6sol.
15 Dec 2002: Current version.
================================================================== */
void LU6U(LUSOLrec *LUSOL, int *INFORM, REAL V[], REAL W[], int NZidx[])
{
/* Do column-based U version, if available */
if((LUSOL->U != NULL) ||
((LUSOL->luparm[LUSOL_IP_FTRANCOUNT] == 0) && LU1U0(LUSOL, &(LUSOL->U), INFORM))) {
LU6U0_v(LUSOL, LUSOL->U, V, W, NZidx, INFORM);
}
/* Alternatively, do the standard column-based L0 version */
else {
int I, J, K, KLAST, L, L1, L2, L3, NRANK, NRANK1;
REAL SMALL;
register REALXP T;
#ifdef LUSOLFastSolve
REAL *aptr;
int *jptr;
#endif
NRANK = LUSOL->luparm[LUSOL_IP_RANK_U];
SMALL = LUSOL->parmlu[LUSOL_RP_ZEROTOLERANCE];
*INFORM = LUSOL_INFORM_LUSUCCESS;
NRANK1 = NRANK+1;
/* Find the first nonzero in v(1:nrank), counting backwards. */
for(KLAST = NRANK; KLAST >= 1; KLAST--) {
I = LUSOL->ip[KLAST];
if(fabs(V[I])>SMALL)
break;
}
L = LUSOL->n;
#ifdef LUSOLFastSolve
for(K = KLAST+1, jptr = LUSOL->iq+K; K <= L; K++, jptr++)
W[*jptr] = ZERO;
#else
for(K = KLAST+1; K <= L; K++) {
J = LUSOL->iq[K];
W[J] = ZERO;
}
#endif
/* Do the back-substitution, using rows 1:klast of U. */
for(K = KLAST; K >= 1; K--) {
I = LUSOL->ip[K];
T = V[I];
L1 = LUSOL->locr[I];
L2 = L1+1;
L3 = (L1+LUSOL->lenr[I])-1;
/* ***** This loop could be coded specially. */
#ifdef LUSOLFastSolve
for(L = L2, aptr = LUSOL->a+L2, jptr = LUSOL->indr+L2;
L <= L3; L++, aptr++, jptr++)
T -= (*aptr) * W[*jptr];
#else
for(L = L2; L <= L3; L++) {
J = LUSOL->indr[L];
T -= LUSOL->a[L]*W[J];
}
#endif
J = LUSOL->iq[K];
if(fabs((REAL) T)<=SMALL)
T = ZERO;
else
T /= LUSOL->a[L1];
W[J] = (REAL) T;
}
/* Compute residual for overdetermined systems. */
T = ZERO;
for(K = NRANK1; K <= LUSOL->m; K++) {
I = LUSOL->ip[K];
T += fabs(V[I]);
}
/* Exit. */
if(T>ZERO)
*INFORM = LUSOL_INFORM_LUSINGULAR;
LUSOL->luparm[LUSOL_IP_INFORM] = *INFORM;
LUSOL->parmlu[LUSOL_RP_RESIDUAL_U] = (REAL) T;
}
}
/* ==================================================================
lu6Ut solves U'v = w. w is destroyed.
------------------------------------------------------------------
15 Dec 2002: First version derived from lu6sol.
15 Dec 2002: Current version.
================================================================== */
void LU6UT(LUSOLrec *LUSOL, int *INFORM, REAL V[], REAL W[], int NZidx[])
{
int I, J, K, L, L1, L2, NRANK, NRANK1,
*ip = LUSOL->ip + 1, *iq = LUSOL->iq + 1;
REAL SMALL;
register REAL T;
#ifdef LUSOLFastSolve
REAL *aptr;
int *jptr;
#endif
NRANK = LUSOL->luparm[LUSOL_IP_RANK_U];
SMALL = LUSOL->parmlu[LUSOL_RP_ZEROTOLERANCE];
*INFORM = LUSOL_INFORM_LUSUCCESS;
NRANK1 = NRANK+1;
L = LUSOL->m;
#ifdef LUSOLFastSolve
for(K = NRANK1, jptr = LUSOL->ip+K; K <= L; K++, jptr++)
V[*jptr] = ZERO;
#else
for(K = NRANK1; K <= L; K++) {
I = LUSOL->ip[K];
V[I] = ZERO;
}
#endif
/* Do the forward-substitution, skipping columns of U(transpose)
when the associated element of w(*) is negligible. */
#if 0
for(K = 1; K <= NRANK; K++) {
I = LUSOL->ip[K];
J = LUSOL->iq[K];
#else
for(K = 1; K <= NRANK; K++, ip++, iq++) {
I = *ip;
J = *iq;
#endif
T = W[J];
if(fabs(T)<=SMALL) {
V[I] = ZERO;
continue;
}
L1 = LUSOL->locr[I];
T /= LUSOL->a[L1];
V[I] = T;
L2 = (L1+LUSOL->lenr[I])-1;
L1++;
/* ***** This loop could be coded specially. */
#ifdef LUSOLFastSolve
for(L = L1, aptr = LUSOL->a+L1, jptr = LUSOL->indr+L1;
L <= L2; L++, aptr++, jptr++)
W[*jptr] -= T * (*aptr);
#else
for(L = L1; L <= L2; L++) {
J = LUSOL->indr[L];
W[J] -= T*LUSOL->a[L];
}
#endif
}
/* Compute residual for overdetermined systems. */
T = ZERO;
for(K = NRANK1; K <= LUSOL->n; K++) {
J = LUSOL->iq[K];
T += fabs(W[J]);
}
/* Exit. */
if(T>ZERO)
*INFORM = LUSOL_INFORM_LUSINGULAR;
LUSOL->luparm[LUSOL_IP_INFORM] = *INFORM;
LUSOL->parmlu[LUSOL_RP_RESIDUAL_U] = T;
}
/* ==================================================================
lu6sol uses the factorization A = L U as follows:
------------------------------------------------------------------
mode
1 v solves L v = v(input). w is not touched.
2 v solves L'v = v(input). w is not touched.
3 w solves U w = v. v is not altered.
4 v solves U'v = w. w is destroyed.
5 w solves A w = v. v is altered as in 1.
6 v solves A'v = w. w is destroyed.
If mode = 3,4,5,6, v and w must not be the same arrays.
If lu1fac has just been used to factorize a symmetric matrix A
(which must be definite or quasi-definite), the factors A = L U
may be regarded as A = LDL', where D = diag(U). In such cases,
mode
7 v solves A v = L D L'v = v(input). w is not touched.
8 v solves L |D| L'v = v(input). w is not touched.
ip(*), iq(*) hold row and column numbers in pivotal order.
lenc(k) is the length of the k-th column of initial L.
lenr(i) is the length of the i-th row of U.
locc(*) is not used.
locr(i) is the start of the i-th row of U.
U is assumed to be in upper-trapezoidal form (nrank by n).
The first entry for each row is the diagonal element
(according to the permutations ip, iq). It is stored at
location locr(i) in a(*), indr(*).
On exit, inform = 0 except as follows.
if(mode = 3,4,5,6 and if U (and hence A) is singular,)
inform = 1 if there is a nonzero residual in solving the system
involving U. parmlu(20) returns the norm of the residual.
------------------------------------------------------------------
July 1987: Early version.
09 May 1988: f77 version.
27 Apr 2000: Abolished the dreaded "computed go to".
But hard to change other "go to"s to "if then else".
15 Dec 2002: lu6L, lu6Lt, lu6U, lu6Ut added to modularize lu6sol.
================================================================== */
void LU6SOL(LUSOLrec *LUSOL, int MODE, REAL V[], REAL W[], int NZidx[], int *INFORM)
{
if(MODE==LUSOL_SOLVE_Lv_v) { /* Solve L v(new) = v. */
LU6L(LUSOL, INFORM,V, NZidx);
}
else if(MODE==LUSOL_SOLVE_Ltv_v) { /* Solve L'v(new) = v. */
LU6LT(LUSOL, INFORM,V, NZidx);
}
else if(MODE==LUSOL_SOLVE_Uw_v) { /* Solve U w = v. */
LU6U(LUSOL, INFORM,V,W, NZidx);
}
else if(MODE==LUSOL_SOLVE_Utv_w) { /* Solve U'v = w. */
LU6UT(LUSOL, INFORM,V,W, NZidx);
}
else if(MODE==LUSOL_SOLVE_Aw_v) { /* Solve A w = v (i.e. FTRAN) */
LU6L(LUSOL, INFORM,V, NZidx); /* via L v(new) = v */
LU6U(LUSOL, INFORM,V,W, NULL); /* ... and U w = v(new). */
}
else if(MODE==LUSOL_SOLVE_Atv_w) { /* Solve A'v = w (i.e. BTRAN) */
LU6UT(LUSOL, INFORM,V,W, NZidx); /* via U'v = w */
LU6LT(LUSOL, INFORM,V, NULL); /* ... and L'v(new) = v. */
}
else if(MODE==LUSOL_SOLVE_Av_v) { /* Solve LDv(bar) = v */
LU6LD(LUSOL, INFORM,1,V, NZidx); /* and L'v(new) = v(bar). */
LU6LT(LUSOL, INFORM,V, NULL);
}
else if(MODE==LUSOL_SOLVE_LDLtv_v) { /* Solve L|D|v(bar) = v */
LU6LD(LUSOL, INFORM,2,V, NZidx); /* and L'v(new) = v(bar). */
LU6LT(LUSOL, INFORM,V, NULL);
}
}

View File

@ -1,163 +0,0 @@
/* Create a row-based version of L0.
This makes it possible to solve L0'x=h (btran) faster for sparse h,
since we only run down the columns of L0' (rows of LO) for which
the corresponding entry in h is non-zero. */
MYBOOL LU1L0(LUSOLrec *LUSOL, LUSOLmat **mat, int *inform)
{
MYBOOL status = FALSE;
int K, L, LL, L1, L2, LENL0, NUML0, I;
int *lsumr;
/* Assume success */
*inform = LUSOL_INFORM_LUSUCCESS;
/* Check if there is anything worth doing */
if(mat == NULL)
return( status );
if(*mat != NULL)
LUSOL_matfree(mat);
NUML0 = LUSOL->luparm[LUSOL_IP_COLCOUNT_L0];
LENL0 = LUSOL->luparm[LUSOL_IP_NONZEROS_L0];
if((NUML0 == 0) || (LENL0 == 0) ||
(LUSOL->luparm[LUSOL_IP_ACCELERATION] == LUSOL_BASEORDER) ||
((LUSOL->luparm[LUSOL_IP_ACCELERATION] & LUSOL_ACCELERATE_L0) == 0))
return( status );
/* Allocate temporary array */
lsumr = (int *) LUSOL_CALLOC((LUSOL->m+1), sizeof(*lsumr));
if(lsumr == NULL) {
*inform = LUSOL_INFORM_NOMEMLEFT;
return( status );
}
/* Compute non-zero counts by permuted row index (order is unimportant) */
K = 0;
L2 = LUSOL->lena;
L1 = L2-LENL0+1;
for(L = L1; L <= L2; L++) {
I = LUSOL->indc[L];
lsumr[I]++;
if(lsumr[I] == 1)
K++;
}
LUSOL->luparm[LUSOL_IP_ROWCOUNT_L0] = K;
/* Check if we should apply "smarts" before proceeding to the row matrix creation */
if((LUSOL->luparm[LUSOL_IP_ACCELERATION] & LUSOL_AUTOORDER) &&
((REAL) LUSOL->luparm[LUSOL_IP_ROWCOUNT_L0] /
#if 0
LUSOL->luparm[LUSOL_IP_COLCOUNT_L0]
#else
LUSOL->m
#endif
> LUSOL->parmlu[LUSOL_RP_SMARTRATIO]))
goto Finish;
/* We are Ok to create the new matrix object */
*mat = LUSOL_matcreate(LUSOL->m, LENL0);
if(*mat == NULL) {
*inform = LUSOL_INFORM_NOMEMLEFT;
goto Finish;
}
/* Cumulate row counts to get vector offsets; first row is leftmost
(stick with Fortran array offset for consistency) */
(*mat)->lenx[0] = 1;
for(K = 1; K <= LUSOL->m; K++) {
(*mat)->lenx[K] = (*mat)->lenx[K-1] + lsumr[K];
lsumr[K] = (*mat)->lenx[K-1];
}
/* Map the matrix into row order by permuted index;
Note: The first permuted row is located leftmost in the array.
The column order is irrelevant, since the indeces will
refer to constant / resolved values of V[] during solve. */
L2 = LUSOL->lena;
L1 = L2-LENL0+1;
for(L = L1; L <= L2; L++) {
I = LUSOL->indc[L];
LL = lsumr[I]++;
(*mat)->a[LL] = LUSOL->a[L];
(*mat)->indr[LL] = LUSOL->indr[L];
(*mat)->indc[LL] = I;
}
/* Pack row starting positions, and set mapper from original index to packed */
I = 0;
for(L = 1; L <= LUSOL->m; L++) {
K = LUSOL->ip[L];
if((*mat)->lenx[K] > (*mat)->lenx[K-1]) {
I++;
(*mat)->indx[I] = K;
}
}
/* Confirm that everything went well */
status = TRUE;
/* Clean up */
Finish:
FREE(lsumr);
return( status );
}
/* Solve L0' v = v based on row-based version of L0, constructed by LU1L0 */
void LU6L0T_v(LUSOLrec *LUSOL, LUSOLmat *mat, REAL V[], int NZidx[], int *INFORM)
{
#ifdef DoTraceL0
REAL TEMP;
#endif
int LEN, K, KK, L, L1, NUML0;
REAL SMALL;
register REAL VPIV;
#if (defined LUSOLFastSolve) && !(defined DoTraceL0)
REAL *aptr;
int *jptr;
#else
int J;
#endif
NUML0 = LUSOL->luparm[LUSOL_IP_ROWCOUNT_L0];
SMALL = LUSOL->parmlu[LUSOL_RP_ZEROTOLERANCE];
/* Loop over the nz columns of L0' - from the end, going forward. */
for(K = NUML0; K > 0; K--) {
KK = mat->indx[K];
L = mat->lenx[KK];
L1 = mat->lenx[KK-1];
LEN = L - L1;
if(LEN == 0)
continue;
/* Get value of the corresponding active entry of V[] */
VPIV = V[KK];
/* Only process the column of L0' if the value of V[] is non-zero */
if(fabs(VPIV)>SMALL) {
/* ***** This loop could be coded specially. */
#if (defined LUSOLFastSolve) && !(defined DoTraceL0)
L--;
for(aptr = mat->a+L, jptr = mat->indr+L;
LEN > 0; LEN--, aptr--, jptr--)
V[*jptr] += VPIV * (*aptr);
#else
for(; LEN > 0; LEN--) {
L--;
J = mat->indr[L];
#ifndef DoTraceL0
V[J] += VPIV * mat->a[L];
#else
TEMP = V[J];
V[J] += VPIV * mat->a[L];
printf("V[%3d] = V[%3d] + L[%d,%d]*V[%3d]\n", J, J, KK,J, KK);
printf("%6g = %6g + %6g*%6g\n", V[J], TEMP, mat->a[L], VPIV);
#endif
}
#endif
}
#ifdef SetSmallToZero
else
V[KK] = 0;
#endif
}
}

View File

@ -1,176 +0,0 @@
/* Create a column-based version of U.
This makes it possible to solve Ux=h (ftran) faster for sparse h,
since we only run down the rows of U (columns of U') for which
the corresponding entry in h is non-zero. */
MYBOOL LU1U0(LUSOLrec *LUSOL, LUSOLmat **mat, int *inform)
{
MYBOOL status = FALSE;
int K, L, LL, LENU, NUMU, J;
int *lsumc;
/* Assume success */
*inform = LUSOL_INFORM_LUSUCCESS;
/* Check if there is anything worth doing */
if(mat == NULL)
return( status );
if(*mat != NULL)
LUSOL_matfree(mat);
NUMU = LUSOL->luparm[LUSOL_IP_RANK_U];
LENU = LUSOL->luparm[LUSOL_IP_NONZEROS_U];
if((NUMU == 0) || (LENU == 0) ||
(LUSOL->luparm[LUSOL_IP_ACCELERATION] == LUSOL_BASEORDER) ||
((LUSOL->luparm[LUSOL_IP_ACCELERATION] & LUSOL_ACCELERATE_U) == 0))
return( status );
/* Allocate temporary array */
lsumc = (int *) LUSOL_CALLOC((LUSOL->n+1), sizeof(*lsumc));
if(lsumc == NULL) {
*inform = LUSOL_INFORM_NOMEMLEFT;
return( status );
}
/* Compute non-zero counts by permuted column index (order is unimportant) */
for(L = 1; L <= LENU; L++) {
J = LUSOL->indr[L];
lsumc[J]++;
}
/* Check if we should apply "smarts" before proceeding to the column matrix creation */
if((LUSOL->luparm[LUSOL_IP_ACCELERATION] & LUSOL_AUTOORDER) &&
((REAL) sqrt((REAL) NUMU/LENU) > LUSOL->parmlu[LUSOL_RP_SMARTRATIO]))
goto Finish;
/* We are Ok to create the new matrix object */
*mat = LUSOL_matcreate(LUSOL->n, LENU);
if(*mat == NULL) {
*inform = LUSOL_INFORM_NOMEMLEFT;
goto Finish;
}
/* Cumulate row counts to get vector offsets; first column is leftmost
(stick with Fortran array offset for consistency) */
(*mat)->lenx[0] = 1;
for(K = 1; K <= LUSOL->n; K++) {
(*mat)->lenx[K] = (*mat)->lenx[K-1] + lsumc[K];
lsumc[K] = (*mat)->lenx[K-1];
}
/* Map the matrix into column order by permuted index;
Note: The first permuted column is located leftmost in the array.
The row order is irrelevant, since the indeces will
refer to constant / resolved values of V[] during solve. */
for(L = 1; L <= LENU; L++) {
J = LUSOL->indr[L];
LL = lsumc[J]++;
(*mat)->a[LL] = LUSOL->a[L];
(*mat)->indr[LL] = J;
(*mat)->indc[LL] = LUSOL->indc[L];
}
/* Pack column starting positions, and set mapper from original index to packed */
J = 0;
for(L = 1; L <= LUSOL->n; L++) {
K = LUSOL->iq[L];
#if 1 /* Deactivate to produce a full-rank version (implicit unit diagonals) */
if((*mat)->lenx[K] > (*mat)->lenx[K-1])
#endif
{
J++;
(*mat)->indx[J] = K;
}
}
/* Confirm that everything went well */
status = TRUE;
/* Clean up */
Finish:
FREE(lsumc);
return( status );
}
/* Solve U w = v based on column-based version of U, constructed by LU1U0 */
void LU6U0_v(LUSOLrec *LUSOL, LUSOLmat *mat, REAL V[], REAL W[], int NZidx[], int *INFORM)
{
#ifdef DoTraceU0
REAL TEMP;
#endif
int LEN, I, K, L, L1, NRANK, NRANK1, KLAST;
REAL SMALL;
register REAL T;
#if (defined xxLUSOLFastSolve) && !(defined DoTraceU0)
REAL *aptr;
int *jptr;
#else
int J;
#endif
NRANK = LUSOL->luparm[LUSOL_IP_RANK_U];
SMALL = LUSOL->parmlu[LUSOL_RP_ZEROTOLERANCE];
*INFORM = LUSOL_INFORM_LUSUCCESS;
NRANK1 = NRANK+1;
/* Find the first nonzero in v(1:nrank), counting backwards. */
for(KLAST = NRANK; KLAST >= 1; KLAST--) {
I = LUSOL->ip[KLAST];
if(fabs(V[I])>SMALL)
break;
}
L = LUSOL->n;
#ifdef xxLUSOLFastSolve
for(K = KLAST+1, jptr = LUSOL->iq+K; K <= L; K++, jptr++)
W[*jptr] = ZERO;
#else
for(K = KLAST+1; K <= L; K++) {
J = LUSOL->iq[K];
W[J] = ZERO;
}
#endif
/* Loop over the nz columns of U - from the right, going left. */
for(K = NRANK; K > 0; K--) {
I = mat->indx[K];
L = mat->lenx[I];
L1 = mat->lenx[I-1];
LEN = L - L1;
T = V[I];
if(fabs(T)<=SMALL) {
W[K] = ZERO;
continue;
}
T /= mat->a[L1]; /* Should it be L or L1 ? */
W[K] = T;
LEN--;
/* ***** This loop could be coded specially. */
#ifdef xxLUSOLFastSolve
L--;
for(aptr = mat->a+L, jptr = mat->indc+L;
LEN > 0; LEN--, aptr--, jptr--)
V[*jptr] -= T * (*aptr);
#else
for(; LEN > 0; LEN--) {
L--;
J = mat->indc[L];
#ifndef DoTraceL0
V[J] -= T * mat->a[L];
#else
TEMP = V[J];
V[J] += T * mat->a[L];
printf("V[%3d] = V[%3d] + L[%d,%d]*V[%3d]\n", J, J, I,J, I);
printf("%6g = %6g + %6g*%6g\n", V[J], TEMP, mat->a[L], T);
#endif
}
#endif
}
/* Compute residual for overdetermined systems. */
T = ZERO;
for(K = NRANK1; K <= LUSOL->m; K++) {
I = LUSOL->ip[K];
T += fabs(V[I]);
}
/* Exit. */
if(T>ZERO)
*INFORM = LUSOL_INFORM_LUSINGULAR;
LUSOL->luparm[LUSOL_IP_INFORM] = *INFORM;
LUSOL->parmlu[LUSOL_RP_RESIDUAL_U] = (REAL) T;
}

View File

@ -1,704 +0,0 @@
/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
File lusol7a
lu7add lu7cyc lu7elm lu7for lu7rnk lu7zap
Utilities for LUSOL's update routines.
lu7for is the most important -- the forward sweep.
01 May 2002: Derived from LUSOL's original lu7a.f file.
01 May 2002: Current version of lusol7a.f.
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
/* ==================================================================
lu7add inserts the first nrank elements of the vector v(*)
as column jadd of U. We assume that U does not yet have any
entries in this column.
Elements no larger than parmlu(3) are treated as zero.
klast will be set so that the last row to be affected
(in pivotal order) is row ip(klast).
------------------------------------------------------------------
09 May 1988: First f77 version.
================================================================== */
void LU7ADD(LUSOLrec *LUSOL, int JADD, REAL V[], int LENL, int *LENU,
int *LROW, int NRANK, int *INFORM, int *KLAST, REAL *VNORM)
{
REAL SMALL;
int K, I, LENI, MINFRE, NFREE, LR1, LR2, L;
#ifndef LUSOLFastMove
int J;
#endif
SMALL = LUSOL->parmlu[LUSOL_RP_ZEROTOLERANCE];
*VNORM = ZERO;
*KLAST = 0;
for(K = 1; K <= NRANK; K++) {
I = LUSOL->ip[K];
if(fabs(V[I])<=SMALL)
continue;
*KLAST = K;
(*VNORM) += fabs(V[I]);
LENI = LUSOL->lenr[I];
/* Compress row file if necessary. */
MINFRE = LENI+1;
NFREE = LUSOL->lena - LENL - *LROW;
if(NFREE<MINFRE) {
LU1REC(LUSOL, LUSOL->m, TRUE,LROW,LUSOL->indr,LUSOL->lenr,LUSOL->locr);
NFREE = LUSOL->lena - LENL - *LROW;
if(NFREE<MINFRE)
goto x970;
}
/* Move row i to the end of the row file,
unless it is already there.
No need to move if there is a gap already. */
if(LENI==0)
LUSOL->locr[I] = (*LROW) + 1;
LR1 = LUSOL->locr[I];
LR2 = (LR1+LENI)-1;
if(LR2==*LROW)
goto x150;
if(LUSOL->indr[LR2+1]==0)
goto x180;
LUSOL->locr[I] = (*LROW) + 1;
#ifdef LUSOLFastMove
L = LR2-LR1+1;
if(L > 0) {
LR2 = (*LROW)+1;
MEMMOVE(LUSOL->a+LR2, LUSOL->a+LR1, L);
MEMMOVE(LUSOL->indr+LR2, LUSOL->indr+LR1, L);
MEMCLEAR(LUSOL->indr+LR1, L);
*LROW += L;
}
#else
for(L = LR1; L <= LR2; L++) {
(*LROW)++;
LUSOL->a[*LROW] = LUSOL->a[L];
J = LUSOL->indr[L];
LUSOL->indr[L] = 0;
LUSOL->indr[*LROW] = J;
}
#endif
x150:
LR2 = *LROW;
(*LROW)++;
/* Add the element of v. */
x180:
LR2++;
LUSOL->a[LR2] = V[I];
LUSOL->indr[LR2] = JADD;
LUSOL->lenr[I] = LENI+1;
(*LENU)++;
}
/* Normal exit. */
*INFORM = LUSOL_INFORM_LUSUCCESS;
goto x990;
/* Not enough storage. */
x970:
*INFORM = LUSOL_INFORM_ANEEDMEM;
x990:
;
}
/* ==================================================================
lu7cyc performs a cyclic permutation on the row or column ordering
stored in ip, moving entry kfirst down to klast.
If kfirst .ge. klast, lu7cyc should not be called.
Sometimes klast = 0 and nothing should happen.
------------------------------------------------------------------
09 May 1988: First f77 version.
================================================================== */
void LU7CYC(LUSOLrec *LUSOL, int KFIRST, int KLAST, int IX[])
{
if(KFIRST<KLAST) {
int IFIRST, K;
#ifdef LUSOLFastMove
#if 1
IFIRST = IX[KFIRST];
K = KLAST-KFIRST;
MEMMOVE(IX+KFIRST, IX+KFIRST+1, K);
IX[KLAST] = IFIRST;
#else
int *IXK, *IXK1;
IXK = IX+KFIRST;
IFIRST = *IXK;
for(K = KFIRST, IXK1 = IXK+1; K <= KLAST-1; K++, IXK++, IXK1++) {
*IXK = *IXK1;
}
*IXK = IFIRST;
#endif
#else
IFIRST = IX[KFIRST];
for(K = KFIRST; K <= KLAST-1; K++) {
IX[K] = IX[K+1];
}
IX[KLAST] = IFIRST;
#endif
}
}
/* ==================================================================
lu7elm eliminates the subdiagonal elements of a vector v(*),
where L*v = y for some vector y.
If jelm > 0, y has just become column jelm of the matrix A.
lu7elm should not be called unless m is greater than nrank.
inform = 0 if y contained no subdiagonal nonzeros to eliminate.
inform = 1 if y contained at least one nontrivial subdiagonal.
inform = 7 if there is insufficient storage.
------------------------------------------------------------------
09 May 1988: First f77 version.
No longer calls lu7for at end. lu8rpc, lu8mod do so.
================================================================== */
void LU7ELM(LUSOLrec *LUSOL, int JELM, REAL V[], int *LENL,
int *LROW, int NRANK, int *INFORM, REAL *DIAG)
{
REAL VI, VMAX, SMALL;
int NRANK1, MINFRE, NFREE, KMAX, L, K, I, LMAX, IMAX, L1, L2;
#ifdef ForceInitialization
LMAX = 0;
#endif
SMALL = LUSOL->parmlu[LUSOL_RP_ZEROTOLERANCE];
NRANK1 = NRANK+1;
*DIAG = ZERO;
/* Compress row file if necessary. */
MINFRE = LUSOL->m-NRANK;
NFREE = LUSOL->lena-(*LENL)-(*LROW);
if(NFREE>=MINFRE)
goto x100;
LU1REC(LUSOL, LUSOL->m,TRUE,LROW,LUSOL->indr,LUSOL->lenr,LUSOL->locr);
NFREE = LUSOL->lena-(*LENL)-(*LROW);
if(NFREE<MINFRE)
goto x970;
/* Pack the subdiagonals of v into L, and find the largest. */
x100:
VMAX = ZERO;
KMAX = 0;
L = (LUSOL->lena-(*LENL))+1;
for(K = NRANK1; K <= LUSOL->m; K++) {
I = LUSOL->ip[K];
VI = fabs(V[I]);
if(VI<=SMALL)
continue;
L--;
LUSOL->a[L] = V[I];
LUSOL->indc[L] = I;
if(VMAX>=VI)
continue;
VMAX = VI;
KMAX = K;
LMAX = L;
}
if(KMAX==0)
goto x900;
/* ------------------------------------------------------------------
Remove vmax by overwriting it with the last packed v(i).
Then set the multipliers in L for the other elements.
------------------------------------------------------------------ */
IMAX = LUSOL->ip[KMAX];
VMAX = LUSOL->a[LMAX];
LUSOL->a[LMAX] = LUSOL->a[L];
LUSOL->indc[LMAX] = LUSOL->indc[L];
L1 = L+1;
L2 = LUSOL->lena-(*LENL);
*LENL = ((*LENL)+L2)-L;
for(L = L1; L <= L2; L++) {
LUSOL->a[L] /= -VMAX;
LUSOL->indr[L] = IMAX;
}
/* Move the row containing vmax to pivotal position nrank + 1. */
LUSOL->ip[KMAX] = LUSOL->ip[NRANK1];
LUSOL->ip[NRANK1] = IMAX;
*DIAG = VMAX;
/* ------------------------------------------------------------------
If jelm is positive, insert vmax into a new row of U.
This is now the only subdiagonal element.
------------------------------------------------------------------ */
if(JELM>0) {
(*LROW)++;
LUSOL->locr[IMAX] = *LROW;
LUSOL->lenr[IMAX] = 1;
LUSOL->a[*LROW] = VMAX;
LUSOL->indr[*LROW] = JELM;
}
*INFORM = LUSOL_INFORM_LUSINGULAR;
goto x990;
/* No elements to eliminate. */
x900:
*INFORM = LUSOL_INFORM_LUSUCCESS;
goto x990;
/* Not enough storage. */
x970:
*INFORM = LUSOL_INFORM_ANEEDMEM;
x990:
;
}
/* ==================================================================
lu7for (forward sweep) updates the LU factorization A = L*U
when row iw = ip(klast) of U is eliminated by a forward
sweep of stabilized row operations, leaving ip * U * iq upper
triangular.
The row permutation ip is updated to preserve stability and/or
sparsity. The column permutation iq is not altered.
kfirst is such that row ip(kfirst) is the first row involved
in eliminating row iw. (Hence, kfirst marks the first nonzero
in row iw in pivotal order.) If kfirst is unknown it may be
input as 1.
klast is such that row ip(klast) is the row being eliminated.
klast is not altered.
lu7for should be called only if kfirst .le. klast.
If kfirst = klast, there are no nonzeros to eliminate, but the
diagonal element of row ip(klast) may need to be moved to the
front of the row.
------------------------------------------------------------------
On entry, locc(*) must be zero.
On exit:
inform = 0 if row iw has a nonzero diagonal (could be small).
inform = 1 if row iw has no diagonal.
inform = 7 if there is not enough storage to finish the update.
On a successful exit (inform le 1), locc(*) will again be zero.
------------------------------------------------------------------
Jan 1985: Final f66 version.
09 May 1988: First f77 version.
================================================================== */
void LU7FOR(LUSOLrec *LUSOL, int KFIRST, int KLAST, int *LENL, int *LENU,
int *LROW, int *INFORM, REAL *DIAG)
{
MYBOOL SWAPPD;
int KBEGIN, IW, LENW, LW1, LW2, JFIRST, MINFRE, NFREE, L, J, KSTART, KSTOP, K,
LFIRST, IV, LENV, LV1, JLAST, LV2, LV3, LV, JV, LW, LDIAG, LIMIT;
REAL AMULT, LTOL, USPACE, SMALL, VJ, WJ;
LTOL = LUSOL->parmlu[LUSOL_RP_UPDATEMAX_Lij];
SMALL = LUSOL->parmlu[LUSOL_RP_ZEROTOLERANCE];
USPACE = LUSOL->parmlu[LUSOL_RP_COMPSPACE_U];
KBEGIN = KFIRST;
SWAPPD = FALSE;
/* We come back here from below if a row interchange is performed. */
x100:
IW = LUSOL->ip[KLAST];
LENW = LUSOL->lenr[IW];
if(LENW==0)
goto x910;
LW1 = LUSOL->locr[IW];
LW2 = (LW1+LENW)-1;
JFIRST = LUSOL->iq[KBEGIN];
if(KBEGIN>=KLAST)
goto x700;
/* Make sure there is room at the end of the row file
in case row iw is moved there and fills in completely. */
MINFRE = LUSOL->n+1;
NFREE = LUSOL->lena-(*LENL)-(*LROW);
if(NFREE<MINFRE) {
LU1REC(LUSOL, LUSOL->m,TRUE,LROW,LUSOL->indr,LUSOL->lenr,LUSOL->locr);
LW1 = LUSOL->locr[IW];
LW2 = (LW1+LENW)-1;
NFREE = LUSOL->lena-(*LENL)-(*LROW);
if(NFREE<MINFRE)
goto x970;
}
/* Set markers on row iw. */
for(L = LW1; L <= LW2; L++) {
J = LUSOL->indr[L];
LUSOL->locc[J] = L;
}
/* ==================================================================
Main elimination loop.
================================================================== */
KSTART = KBEGIN;
KSTOP = MIN(KLAST,LUSOL->n);
for(K = KSTART; K <= KSTOP; K++) {
JFIRST = LUSOL->iq[K];
LFIRST = LUSOL->locc[JFIRST];
if(LFIRST==0)
goto x490;
/* Row iw has its first element in column jfirst. */
WJ = LUSOL->a[LFIRST];
if(K==KLAST)
goto x490;
/* ---------------------------------------------------------------
We are about to use the first element of row iv
to eliminate the first element of row iw.
However, we may wish to interchange the rows instead,
to preserve stability and/or sparsity.
--------------------------------------------------------------- */
IV = LUSOL->ip[K];
LENV = LUSOL->lenr[IV];
LV1 = LUSOL->locr[IV];
VJ = ZERO;
if(LENV==0)
goto x150;
if(LUSOL->indr[LV1]!=JFIRST)
goto x150;
VJ = LUSOL->a[LV1];
if(SWAPPD)
goto x200;
if(LTOL*fabs(WJ)<fabs(VJ))
goto x200;
if(LTOL*fabs(VJ)<fabs(WJ))
goto x150;
if(LENV<=LENW)
goto x200;
/* ---------------------------------------------------------------
Interchange rows iv and iw.
--------------------------------------------------------------- */
x150:
LUSOL->ip[KLAST] = IV;
LUSOL->ip[K] = IW;
KBEGIN = K;
SWAPPD = TRUE;
goto x600;
/* ---------------------------------------------------------------
Delete the eliminated element from row iw
by overwriting it with the last element.
--------------------------------------------------------------- */
x200:
LUSOL->a[LFIRST] = LUSOL->a[LW2];
JLAST = LUSOL->indr[LW2];
LUSOL->indr[LFIRST] = JLAST;
LUSOL->indr[LW2] = 0;
LUSOL->locc[JLAST] = LFIRST;
LUSOL->locc[JFIRST] = 0;
LENW--;
(*LENU)--;
if(*LROW==LW2)
(*LROW)--;
LW2 = LW2-1;
/* ---------------------------------------------------------------
Form the multiplier and store it in the L file.
--------------------------------------------------------------- */
if(fabs(WJ)<=SMALL)
goto x490;
AMULT = -WJ/VJ;
L = LUSOL->lena-(*LENL);
LUSOL->a[L] = AMULT;
LUSOL->indr[L] = IV;
LUSOL->indc[L] = IW;
(*LENL)++;
/* ---------------------------------------------------------------
Add the appropriate multiple of row iv to row iw.
We use two different inner loops. The first one is for the
case where row iw is not at the end of storage.
--------------------------------------------------------------- */
if(LENV==1)
goto x490;
LV2 = LV1+1;
LV3 = (LV1+LENV)-1;
if(LW2==*LROW)
goto x400;
/* ...............................................................
This inner loop will be interrupted only if
fill-in occurs enough to bump into the next row.
............................................................... */
for(LV = LV2; LV <= LV3; LV++) {
JV = LUSOL->indr[LV];
LW = LUSOL->locc[JV];
if(LW>0) {
/* No fill-in. */
LUSOL->a[LW] += AMULT*LUSOL->a[LV];
if(fabs(LUSOL->a[LW])<=SMALL) {
/* Delete small computed element. */
LUSOL->a[LW] = LUSOL->a[LW2];
J = LUSOL->indr[LW2];
LUSOL->indr[LW] = J;
LUSOL->indr[LW2] = 0;
LUSOL->locc[J] = LW;
LUSOL->locc[JV] = 0;
(*LENU)--;
LENW--;
LW2--;
}
}
else {
/* Row iw doesn't have an element in column jv yet
so there is a fill-in. */
if(LUSOL->indr[LW2+1]!=0)
goto x360;
(*LENU)++;
LENW++;
LW2++;
LUSOL->a[LW2] = AMULT*LUSOL->a[LV];
LUSOL->indr[LW2] = JV;
LUSOL->locc[JV] = LW2;
}
}
goto x490;
/* Fill-in interrupted the previous loop.
Move row iw to the end of the row file. */
x360:
LV2 = LV;
LUSOL->locr[IW] = (*LROW)+1;
#ifdef LUSOLFastMove
L = LW2-LW1+1;
if(L > 0) {
int loci, *locp;
for(loci = LW1, locp = LUSOL->indr+LW1;
loci <= LW2; loci++, locp++) {
(*LROW)++;
LUSOL->locc[*locp] = *LROW;
}
LW2 = (*LROW)-L+1;
MEMMOVE(LUSOL->a+LW2, LUSOL->a+LW1, L);
MEMMOVE(LUSOL->indr+LW2, LUSOL->indr+LW1, L);
MEMCLEAR(LUSOL->indr+LW1, L);
}
#else
for(L = LW1; L <= LW2; L++) {
(*LROW)++;
LUSOL->a[*LROW] = LUSOL->a[L];
J = LUSOL->indr[L];
LUSOL->indr[L] = 0;
LUSOL->indr[*LROW] = J;
LUSOL->locc[J] = *LROW;
}
#endif
LW1 = LUSOL->locr[IW];
LW2 = *LROW;
/* ...............................................................
Inner loop with row iw at the end of storage.
............................................................... */
x400:
for(LV = LV2; LV <= LV3; LV++) {
JV = LUSOL->indr[LV];
LW = LUSOL->locc[JV];
if(LW>0) {
/* No fill-in. */
LUSOL->a[LW] += AMULT*LUSOL->a[LV];
if(fabs(LUSOL->a[LW])<=SMALL) {
/* Delete small computed element. */
LUSOL->a[LW] = LUSOL->a[LW2];
J = LUSOL->indr[LW2];
LUSOL->indr[LW] = J;
LUSOL->indr[LW2] = 0;
LUSOL->locc[J] = LW;
LUSOL->locc[JV] = 0;
(*LENU)--;
LENW--;
LW2--;
}
}
else {
/* Row iw doesn't have an element in column jv yet
so there is a fill-in. */
(*LENU)++;
LENW++;
LW2++;
LUSOL->a[LW2] = AMULT*LUSOL->a[LV];
LUSOL->indr[LW2] = JV;
LUSOL->locc[JV] = LW2;
}
}
*LROW = LW2;
/* The k-th element of row iw has been processed.
Reset swappd before looking at the next element. */
x490:
SWAPPD = FALSE;
}
/* ==================================================================
End of main elimination loop.
==================================================================
Cancel markers on row iw. */
x600:
LUSOL->lenr[IW] = LENW;
if(LENW==0)
goto x910;
for(L = LW1; L <= LW2; L++) {
J = LUSOL->indr[L];
LUSOL->locc[J] = 0;
}
/* Move the diagonal element to the front of row iw.
At this stage, lenw gt 0 and klast le n. */
x700:
for(L = LW1; L <= LW2; L++) {
LDIAG = L;
if(LUSOL->indr[L]==JFIRST)
goto x730;
}
goto x910;
x730:
*DIAG = LUSOL->a[LDIAG];
LUSOL->a[LDIAG] = LUSOL->a[LW1];
LUSOL->a[LW1] = *DIAG;
LUSOL->indr[LDIAG] = LUSOL->indr[LW1];
LUSOL->indr[LW1] = JFIRST;
/* If an interchange is needed, repeat from the beginning with the
new row iw, knowing that the opposite interchange cannot occur. */
if(SWAPPD)
goto x100;
*INFORM = LUSOL_INFORM_LUSUCCESS;
goto x950;
/* Singular. */
x910:
*DIAG = ZERO;
*INFORM = LUSOL_INFORM_LUSINGULAR;
/* Force a compression if the file for U is much longer than the
no. of nonzeros in U (i.e. if lrow is much bigger than lenU).
This should prevent memory fragmentation when there is far more
memory than necessary (i.e. when lena is huge). */
x950:
LIMIT = (int) (USPACE*(*LENU))+LUSOL->m+LUSOL->n+1000;
if(*LROW>LIMIT)
LU1REC(LUSOL, LUSOL->m,TRUE,LROW,LUSOL->indr,LUSOL->lenr,LUSOL->locr);
goto x990;
/* Not enough storage. */
x970:
*INFORM = LUSOL_INFORM_ANEEDMEM;
/* Exit. */
x990:
;
}
/* ==================================================================
lu7rnk (check rank) assumes U is currently nrank by n
and determines if row nrank contains an acceptable pivot.
If not, the row is deleted and nrank is decreased by 1.
jsing is an input parameter (not altered). If jsing is positive,
column jsing has already been judged dependent. A substitute
(if any) must be some other column.
------------------------------------------------------------------
-- Jul 1987: First version.
09 May 1988: First f77 version.
================================================================== */
void LU7RNK(LUSOLrec *LUSOL, int JSING, int *LENU,
int *LROW, int *NRANK, int *INFORM, REAL *DIAG)
{
REAL UTOL1, UMAX;
int IW, LENW, L1, L2, LMAX, L, JMAX, KMAX;
#ifdef ForceInitialization
L1 = 0;
L2 = 0;
#endif
UTOL1 = LUSOL->parmlu[LUSOL_RP_SMALLDIAG_U];
*DIAG = ZERO;
/* Find Umax, the largest element in row nrank. */
IW = LUSOL->ip[*NRANK];
LENW = LUSOL->lenr[IW];
if(LENW==0)
goto x400;
L1 = LUSOL->locr[IW];
L2 = (L1+LENW)-1;
UMAX = ZERO;
LMAX = L1;
for(L = L1; L <= L2; L++) {
if(UMAX<fabs(LUSOL->a[L])) {
UMAX = fabs(LUSOL->a[L]);
LMAX = L;
}
}
/* Find which column that guy is in (in pivotal order).
Interchange him with column nrank, then move him to be
the new diagonal at the front of row nrank. */
*DIAG = LUSOL->a[LMAX];
JMAX = LUSOL->indr[LMAX];
for(KMAX = *NRANK; KMAX <= LUSOL->n; KMAX++) {
if(LUSOL->iq[KMAX]==JMAX)
break;
}
LUSOL->iq[KMAX] = LUSOL->iq[*NRANK];
LUSOL->iq[*NRANK] = JMAX;
LUSOL->a[LMAX] = LUSOL->a[L1];
LUSOL->a[L1] = *DIAG;
LUSOL->indr[LMAX] = LUSOL->indr[L1];
LUSOL->indr[L1] = JMAX;
/* See if the new diagonal is big enough. */
if(UMAX<=UTOL1)
goto x400;
if(JMAX==JSING)
goto x400;
/* ------------------------------------------------------------------
The rank stays the same.
------------------------------------------------------------------ */
*INFORM = LUSOL_INFORM_LUSUCCESS;
return;
/* ------------------------------------------------------------------
The rank decreases by one.
------------------------------------------------------------------ */
x400:
*INFORM = LUSOL_INFORM_RANKLOSS;
(*NRANK)--;
if(LENW>0) {
/* Delete row nrank from U. */
LENU = LENU-LENW;
LUSOL->lenr[IW] = 0;
for(L = L1; L <= L2; L++) {
LUSOL->indr[L] = 0;
}
if(L2==*LROW) {
/* This row was at the end of the data structure.
We have to reset lrow.
Preceding rows might already have been deleted, so we
have to be prepared to go all the way back to 1. */
for(L = 1; L <= L2; L++) {
if(LUSOL->indr[*LROW]>0)
goto x900;
(*LROW)--;
}
}
}
x900:
;
}
/* ==================================================================
lu7zap eliminates all nonzeros in column jzap of U.
It also sets kzap to the position of jzap in pivotal order.
Thus, on exit we have iq(kzap) = jzap.
------------------------------------------------------------------
-- Jul 1987: nrank added.
10 May 1988: First f77 version.
================================================================== */
void LU7ZAP(LUSOLrec *LUSOL, int JZAP, int *KZAP, int *LENU, int *LROW,
int NRANK)
{
int K, I, LENI, LR1, LR2, L;
for(K = 1; K <= NRANK; K++) {
I = LUSOL->ip[K];
LENI = LUSOL->lenr[I];
if(LENI==0)
goto x90;
LR1 = LUSOL->locr[I];
LR2 = (LR1+LENI)-1;
for(L = LR1; L <= LR2; L++) {
if(LUSOL->indr[L]==JZAP)
goto x60;
}
goto x90;
/* Delete the old element. */
x60:
LUSOL->a[L] = LUSOL->a[LR2];
LUSOL->indr[L] = LUSOL->indr[LR2];
LUSOL->indr[LR2] = 0;
LUSOL->lenr[I] = LENI-1;
(*LENU)--;
/* Stop if we know there are no more rows containing jzap. */
x90:
*KZAP = K;
if(LUSOL->iq[K]==JZAP)
goto x800;
}
/* nrank must be smaller than n because we haven't found kzap yet. */
L = LUSOL->n;
for(K = NRANK+1; K <= L; K++) {
*KZAP = K;
if(LUSOL->iq[K]==JZAP)
break;
}
/* See if we zapped the last element in the file. */
x800:
if(*LROW>0) {
if(LUSOL->indr[*LROW]==0)
(*LROW)--;
}
}

View File

@ -1,279 +0,0 @@
/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
File lusol8a
lu8rpc
Sparse LU update: Replace Column
LUSOL's sparse implementation of the Bartels-Golub update.
01 May 2002: Derived from LUSOL's original lu8a.f file.
01 May 2002: Current version of lusol8a.f.
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
/* ==================================================================
lu8rpc updates the LU factorization A = L*U when column jrep
is replaced by some vector a(new).
lu8rpc is an implementation of the Bartels-Golub update,
designed for the case where A is rectangular and/or singular.
L is a product of stabilized eliminations (m x m, nonsingular).
P U Q is upper trapezoidal (m x n, rank nrank).
If mode1 = 0, the old column is taken to be zero
(so it does not have to be removed from U).
If mode1 = 1, the old column need not have been zero.
If mode2 = 0, the new column is taken to be zero.
v(*) is not used or altered.
If mode2 = 1, v(*) must contain the new column a(new).
On exit, v(*) will satisfy L*v = a(new).
If mode2 = 2, v(*) must satisfy L*v = a(new).
The array w(*) is not used or altered.
On entry, all elements of locc are assumed to be zero.
On a successful exit (inform != 7), this will again be true.
On exit:
inform = -1 if the rank of U decreased by 1.
inform = 0 if the rank of U stayed the same.
inform = 1 if the rank of U increased by 1.
inform = 2 if the update seemed to be unstable
(diag much bigger than vnorm).
inform = 7 if the update was not completed (lack of storage).
inform = 8 if jrep is not between 1 and n.
------------------------------------------------------------------
-- Jan 1985: Original F66 version.
-- Jul 1987: Modified to maintain U in trapezoidal form.
10 May 1988: First f77 version.
16 Oct 2000: Added test for instability (inform = 2).
================================================================== */
void LU8RPC(LUSOLrec *LUSOL, int MODE1, int MODE2,
int JREP, REAL V[], REAL W[],
int *INFORM, REAL *DIAG, REAL *VNORM)
{
MYBOOL SINGLR;
int LPRINT, NRANK, LENL, LENU, LROW, NRANK0, KREP, KLAST, IW, L1, J1, JSING;
REAL UTOL1, UTOL2;
LPRINT = LUSOL->luparm[LUSOL_IP_PRINTLEVEL];
NRANK = LUSOL->luparm[LUSOL_IP_RANK_U];
LENL = LUSOL->luparm[LUSOL_IP_NONZEROS_L];
LENU = LUSOL->luparm[LUSOL_IP_NONZEROS_U];
LROW = LUSOL->luparm[LUSOL_IP_NONZEROS_ROW];
UTOL1 = LUSOL->parmlu[LUSOL_RP_SMALLDIAG_U];
UTOL2 = LUSOL->parmlu[LUSOL_RP_EPSDIAG_U];
NRANK0 = NRANK;
*DIAG = ZERO;
*VNORM = ZERO;
if(JREP<1)
goto x980;
if(JREP>LUSOL->n)
goto x980;
/* ------------------------------------------------------------------
If mode1 = 0, there are no elements to be removed from U
but we still have to set krep (using a backward loop).
Otherwise, use lu7zap to remove column jrep from U
and set krep at the same time.
------------------------------------------------------------------ */
if(MODE1==LUSOL_UPDATE_OLDEMPTY) {
KREP = LUSOL->n+1;
x10:
KREP--;
if(LUSOL->iq[KREP]!=JREP)
goto x10;
}
else
LU7ZAP(LUSOL, JREP,&KREP,&LENU,&LROW,NRANK);
/* ------------------------------------------------------------------
Insert a new column of u and find klast.
------------------------------------------------------------------ */
if(MODE2==LUSOL_UPDATE_NEWEMPTY) {
KLAST = 0;
}
else {
if(MODE2==LUSOL_UPDATE_NEWNONEMPTY) {
/* Transform v = a(new) to satisfy L*v = a(new). */
LU6SOL(LUSOL, LUSOL_SOLVE_Lv_v, V,W, NULL, INFORM);
}
else if(V==NULL)
/* Otherwise, the V vector is taken to satisfy this already, or stored earlier. */
V=LUSOL->vLU6L;
/* Insert into U any nonzeros in the top of v.
row ip(klast) will contain the last nonzero in pivotal order.
Note that klast will be in the range ( 0, nrank ). */
LU7ADD(LUSOL, JREP,V,LENL,&LENU,&LROW,NRANK,INFORM,&KLAST,VNORM);
if(*INFORM==LUSOL_INFORM_ANEEDMEM)
goto x970;
}
/* ------------------------------------------------------------------
In general, the new column causes U to look like this:
krep n krep n
....a......... ..........a...
. a . . a .
. a . . a .
.a . . a .
P U Q = a . or . a .
b. . . a .
b . . . a .
b . . . a .
b ...... ..a... nrank
c c
c c
c c m
klast points to the last nonzero "a" or "b".
klast = 0 means all "a" and "b" entries are zero.
------------------------------------------------------------------ */
if(MODE2==LUSOL_UPDATE_NEWEMPTY) {
if(KREP>NRANK)
goto x900;
}
else if(NRANK<LUSOL->m) {
/* Eliminate any "c"s (in either case).
Row nrank + 1 may end up containing one nonzero. */
LU7ELM(LUSOL, JREP,V,&LENL,&LROW,NRANK,INFORM,DIAG);
if(*INFORM==LUSOL_INFORM_ANEEDMEM)
goto x970;
if(*INFORM==LUSOL_INFORM_LUSINGULAR) {
/* The nonzero is apparently significant.
Increase nrank by 1 and make klast point to the bottom. */
NRANK++;
KLAST = NRANK;
}
}
if(NRANK<LUSOL->n) {
/* The column rank is low.
In the first case, we want the new column to end up in
position nrank, so the trapezoidal columns will have a chance
later on (in lu7rnk) to pivot in that position.
Otherwise the new column is not part of the triangle. We
swap it into position nrank so we can judge it for singularity.
lu7rnk might choose some other trapezoidal column later. */
if(KREP<NRANK)
KLAST = NRANK;
else {
LUSOL->iq[KREP] = LUSOL->iq[NRANK];
LUSOL->iq[NRANK] = JREP;
KREP = NRANK;
}
}
/* ------------------------------------------------------------------
If krep .lt. klast, there are some "b"s to eliminate:
krep
....a.........
. a .
. a .
.a .
P U Q = a . krep
b. .
b . .
b . .
b ...... nrank
If krep .eq. klast, there are no "b"s, but the last "a" still
has to be moved to the front of row krep (by lu7for).
------------------------------------------------------------------ */
if(KREP<=KLAST) {
/* Perform a cyclic permutation on the current pivotal order,
and eliminate the resulting row spike. krep becomes klast.
The final diagonal (if any) will be correctly positioned at
the front of the new krep-th row. nrank stays the same. */
LU7CYC(LUSOL, KREP,KLAST,LUSOL->ip);
LU7CYC(LUSOL, KREP,KLAST,LUSOL->iq);
LU7FOR(LUSOL, KREP,KLAST,&LENL,&LENU,&LROW,INFORM,DIAG);
if(*INFORM==LUSOL_INFORM_ANEEDMEM)
goto x970;
KREP = KLAST;
/* Test for instability (diag much bigger than vnorm). */
SINGLR = (MYBOOL) ((*VNORM)<UTOL2*fabs(*DIAG));
if(SINGLR)
goto x920;
}
/* ------------------------------------------------------------------
Test for singularity in column krep (where krep<=nrank).
------------------------------------------------------------------ */
*DIAG = ZERO;
IW = LUSOL->ip[KREP];
SINGLR = (MYBOOL) (LUSOL->lenr[IW]==0);
if(!SINGLR) {
L1 = LUSOL->locr[IW];
J1 = LUSOL->indr[L1];
SINGLR = (MYBOOL) (J1!=JREP);
if(!SINGLR) {
*DIAG = LUSOL->a[L1];
SINGLR = (MYBOOL) (fabs(*DIAG)<=UTOL1 || fabs(*DIAG)<=UTOL2*(*VNORM));
}
}
if(SINGLR && (KREP<NRANK)) {
/* Perform cyclic permutations to move column jrep to the end.
Move the corresponding row to position nrank
then eliminate the resulting row spike. */
LU7CYC(LUSOL, KREP,NRANK,LUSOL->ip);
LU7CYC(LUSOL, KREP,LUSOL->n,LUSOL->iq);
LU7FOR(LUSOL, KREP,NRANK,&LENL,&LENU,&LROW,INFORM,DIAG);
if(*INFORM==LUSOL_INFORM_ANEEDMEM)
goto x970;
}
/* Find the best column to be in position nrank.
If singlr, it can't be the new column, jrep.
If nothing satisfactory exists, nrank will be decreased. */
if(SINGLR || (NRANK<LUSOL->n)) {
JSING = 0;
if(SINGLR)
JSING = JREP;
LU7RNK(LUSOL, JSING,&LENU,&LROW,&NRANK,INFORM,DIAG);
}
/* ------------------------------------------------------------------
Update indeces of optional row-based version of L0.
------------------------------------------------------------------ */
#if 0
if(LUSOL->L0 != NULL)
LU1L0UPD(LUSOL, INFORM);
#endif
/* ------------------------------------------------------------------
Set inform for exit.
------------------------------------------------------------------ */
x900:
if(NRANK==NRANK0)
*INFORM = LUSOL_INFORM_LUSUCCESS;
else if(NRANK<NRANK0) {
*INFORM = LUSOL_INFORM_RANKLOSS;
if(NRANK0==LUSOL->n) {
if(LPRINT>=LUSOL_MSG_SINGULARITY)
LUSOL_report(LUSOL, 0, "lu8rpc warning...\nSingularity after replacing column. jrep=%8d diag=%g\n",
JREP,DIAG);
}
}
else
*INFORM = LUSOL_INFORM_LUSINGULAR;
goto x990;
/* Instability. */
x920:
*INFORM = LUSOL_INFORM_LUUNSTABLE;
if(LPRINT>=LUSOL_MSG_SINGULARITY)
LUSOL_report(LUSOL, 0, "lu8rpc warning...\nInstability after replacing column. jrep=%8d diag=%g\n",
JREP,DIAG);
goto x990;
/* Not enough storage. */
x970:
*INFORM = LUSOL_INFORM_ANEEDMEM;
if(LPRINT>=LUSOL_MSG_SINGULARITY)
LUSOL_report(LUSOL, 0, "lu8rpc error...\nInsufficient memory. lena=%8d\n",
LUSOL->lena);
goto x990;
/* jrep is out of range. */
x980:
*INFORM = LUSOL_INFORM_FATALERR;
if(LPRINT>=LUSOL_MSG_SINGULARITY)
LUSOL_report(LUSOL, 0, "lu8rpc error...\njrep is out of range. m=%8d n=%8d jrep=%8d\n",
LUSOL->m,LUSOL->n,JREP);
/* Exit. */
x990:
LUSOL->luparm[LUSOL_IP_UPDATECOUNT]++;
LUSOL->luparm[LUSOL_IP_RANK_U] = NRANK;
LUSOL->luparm[LUSOL_IP_NONZEROS_L] = LENL;
LUSOL->luparm[LUSOL_IP_NONZEROS_U] = LENU;
LUSOL->luparm[LUSOL_IP_NONZEROS_ROW] = LROW;
LUSOL->luparm[LUSOL_IP_INFORM] = *INFORM;
}

View File

@ -1,298 +0,0 @@
#include <stdio.h>
#include <string.h>
#include "mmio.h"
#include "hbio.h"
#include "lusolio.h"
/* Utility routines to read matrix files in the Coordinate Text File format*/
MYBOOL ctf_read_A(char *filename, int maxm, int maxn, int maxnz,
int *m, int *n, int *nnzero, int *iA, int *jA, REAL *Aij)
{
FILE *iofile;
int eof;
char buffer[100];
int k, i, j;
REAL Ak;
MYBOOL filldata;
*nnzero = 0;
*m = 0;
*n = 0;
iofile = fopen(filename, "r" );
if(iofile == NULL) {
printf("A file %s does not exist\n", filename);
return( FALSE );
}
filldata = (MYBOOL) !((iA == NULL) && (jA == NULL) && (Aij == NULL));
eof = TRUE;
for (k = 1; k <= maxnz; k++) {
eof = feof(iofile);
if(eof)
break;
eof = fscanf(iofile, "%d %d %s", &i, &j, buffer);
if(eof == 0 || eof == EOF || i <= 0 || j <= 0 || strlen(buffer) == 0)
break;
Ak = atof(buffer);
(*nnzero)++;
if (filldata) {
iA[k] = i;
jA[k] = j;
Aij[k] = Ak;
}
if (i > *m) *m = i;
if (j > *n) *n = j;
}
fclose( iofile );
if(!eof) {
printf("Too much data in A file. Increase maxnz\n");
printf("Current maxnz = %d\n", maxnz);
return( FALSE );
}
printf("A read successfully\n");
printf("m = %d n = %d nnzero = %d\n",
*m, *n, *nnzero);
if (*m > maxm || *n > maxn) {
printf("However, matrix dimensions exceed maxm or maxn\n");
return( FALSE );
}
return( TRUE );
}
MYBOOL ctf_size_A(char *filename, int *m, int *n, int *nnzero)
{
int maxint = 200000000;
return( ctf_read_A(filename, maxint, maxint, maxint,
m, n, nnzero, NULL, NULL, NULL) );
}
MYBOOL ctf_read_b(char *filename, int m, REAL *b)
{
FILE *iofile;
int eof;
char buffer[100];
int i;
iofile = fopen(filename, "r");
if(iofile == NULL) {
printf("b file %s does not exist\n", filename);
return( FALSE );
}
for (i = 1; i <= m; i++) {
if(feof(iofile))
goto x350;
eof = fscanf(iofile, "%s", buffer);
if(eof == 0 || eof == EOF)
goto x350;
b[i] = atof(buffer);
}
fclose( iofile );
printf("b read successfully\n");
return( TRUE );
x350:
fclose( iofile );
printf("Not enough data in b file.\n");
return( FALSE );
}
/* Utility routines to read matrix files in the MatrixMarket format*/
#define mmf_recsize 255
MYBOOL mmf_read_A(char *filename, int maxM, int maxN, int maxnz,
int *M, int *N, int *nz, int *iA, int *jA, REAL *Aij)
{
MM_typecode matcode;
FILE *f;
int i, k, ret_code, ival, jval;
REAL Aval;
MYBOOL status = FALSE, ispat, filldata;
char buf[mmf_recsize];
f = fopen(filename, "r");
if(f == NULL)
return( status );
if(mm_read_banner(f, &matcode) != 0) {
printf("Could not process Matrix Market banner.\n");
goto x900;
}
/* Screen matrix types since LUSOL only supports a
subset of the Matrix Market data types. */
if(mm_is_complex(matcode) || mm_is_pattern(matcode)) {
printf("Sorry, this application does not support ");
printf("Market Market type: [%s]\n", mm_typecode_to_str(matcode));
goto x900;
}
/* Verify that we have sufficient array storage */
filldata = (MYBOOL) !((iA == NULL) && (jA == NULL) && (Aij == NULL));
if(filldata && maxN > 1 && jA == NULL) {
printf("Market Market insufficient array storage specified\n");
goto x900;
}
/* Find out size of sparse matrix .... */
ret_code = mm_read_mtx_crd_size(f, M, N, nz);
if(ret_code != 0 || !filldata || (*M > maxM) || (*N > maxN) || (*nz > maxnz)) {
status = !filldata;
goto x900;
}
/* NOTE: when reading in doubles, ANSI C requires the use of the "l" */
/* specifier as in "%lg", "%lf", "%le", otherwise errors will occur */
/* (ANSI C X3.159-1989, Sec. 4.9.6.2, p. 136 lines 13-15) */
/* Read dense matrix in column order */
ispat = (MYBOOL) mm_is_pattern(matcode);
k = 1;
if(mm_is_dense(matcode)) {
maxN = MIN(maxN, *N);
for (jval = 1; jval <= maxN; jval++) {
for (i = 1; i <= *M; i++) {
if(fgets(buf, mmf_recsize-1, f) == NULL)
break;
if(sscanf(buf, "%lg\n", &Aval) == 0)
break;
if(Aval != 0) {
if(iA != NULL)
iA[k] = i;
if(jA != NULL)
jA[k] = jval;
/* Make sure we handle dense vector reading properly */
if(iA == NULL && jA == NULL)
Aij[i] = Aval;
else
Aij[k] = Aval;
k++;
}
}
}
}
/* Read sparse matrix by coordinate */
else {
for (i = 1; i <= *nz; i++) {
if(fgets(buf, mmf_recsize-1, f) == NULL)
break;
if(buf[0] == '%')
continue;
if(ispat) {
if(sscanf(buf, "%d %d\n", &ival, &jval) == 0)
continue;
Aij[k] = 1.0;
}
else
if(sscanf(buf, "%d %d %lg\n", &ival, &jval, &Aval) == 0)
continue;
/* Check if it is a nonzero and we are within column dimension */
if(Aval != 0 && jval <= maxN) {
Aij[k] = Aval;
if(iA != NULL)
iA[k] = ival;
if(jA != NULL)
jA[k] = jval;
k++;
}
}
}
*nz = k - 1;
/* Handle case where only the lower triangular parts are given */
if(!mm_is_general(matcode)) {
if((M != N) || (maxN != maxM) || (2*(*nz) > maxnz)) {
printf("Market Market cannot fill in symmetry data\n");
goto x900;
}
ispat = mm_is_skew(matcode);
for(i = 1; i <= *nz; i++) {
iA[k] = jA[i];
jA[k] = iA[i];
if(ispat)
Aij[k] = -Aij[i];
else
Aij[k] = Aij[i];
k++;
}
*nz = k - 1;
}
status = TRUE;
/* Finish up */
x900:
fclose( f );
return( status );
}
MYBOOL mmf_size_A(char *filename, int *M, int *N, int *nz)
{
int maxint = 200000000;
return( mmf_read_A(filename, maxint, maxint, maxint,
M, N, nz, NULL, NULL, NULL) );
}
MYBOOL mmf_read_b(char *filename, int m, REAL *b)
{
int im, jn, nnzero;
return( mmf_read_A(filename, m, 1, m,
&im, &jn, &nnzero, NULL, NULL, b));
}
/* Utility routines to read matrix files in Harwell-Boeing format*/
MYBOOL hbf_read_A(char *filename, int maxM, int maxN, int maxnz,
int *M, int *N, int *nz, int *iA, int *jA, REAL *Aij)
{
MYBOOL success;
success = hbf_size_A(filename, M, N, nz);
if(!success)
return( success );
Aij[1] = 0;
success = (MYBOOL) readHB_mat_double(filename, jA, iA-1, Aij-1);
/* Test if we have a pattern matrix and fill it with all zeros */
if(Aij[1] == 0) {
int i;
for(i = 1; i <= *nz; i++)
Aij[i] = 1;
}
/* Expand the column nz counts to triplet format */
if(success) {
int i, j, ii, k;
k = *nz;
for(j = *N; j > 0; j--) {
ii = jA[j];
for(i = jA[j-1]; i < ii; i++, k--)
jA[k] = j;
}
}
return( success );
}
MYBOOL hbf_size_A(char *filename, int *M, int *N, int *nz)
{
int Nrhs;
char *Type;
return( (MYBOOL) readHB_info(filename, M, N, nz, &Type, &Nrhs) );
}
MYBOOL hbf_read_b(char *filename, int m, REAL *b)
{
return( (MYBOOL) readHB_aux_double(filename, 'F', b) ); /* Same format as matrix */
}

View File

@ -1,24 +0,0 @@
#ifndef HEADER_lusolio
#define HEADER_lusolio
/* Include necessary libraries */
/* ------------------------------------------------------------------------- */
#include "lusol.h"
MYBOOL ctf_read_A(char *filename, int maxm, int maxn, int maxnz,
int *m, int *n, int *nnzero, int *iA, int *jA, REAL *Aij);
MYBOOL ctf_size_A(char *filename, int *m, int *n, int *nnzero);
MYBOOL ctf_read_b(char *filename, int m, REAL *b);
MYBOOL mmf_read_A(char *filename, int maxM, int maxN, int maxnz,
int *M, int *N, int *nz, int *iA, int *jA, REAL *Aij);
MYBOOL mmf_size_A(char *filename, int *M, int *N, int *nz);
MYBOOL mmf_read_b(char *filename, int m, REAL *b);
MYBOOL hbf_read_A(char *filename, int maxM, int maxN, int maxnz,
int *M, int *N, int *nz, int *iA, int *jA, REAL *Aij);
MYBOOL hbf_size_A(char *filename, int *M, int *N, int *nz);
MYBOOL hbf_read_b(char *filename, int m, REAL *b);
#endif /* HEADER_lusolio */

View File

@ -1,493 +0,0 @@
/* This program solves a sparse linear system Ax = b using LUSOL. */
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <time.h>
#include "commonlib.h"
#include "myblas.h"
#include "lusol.h"
#include "lusolio.h"
#include "lusolmain.h"
#if (defined WIN32) || (defined WIN64)
void _strupr_(char *s)
{
_strupr(s);
}
#else
/* Yin Zhang noted that _strupr() is not available on many Unix platforms */
void _strupr_(char *s)
{
int i;
char c;
for (i = 0; i < strlen(s); i++) {
c = s[i];
if (c <= 'z' && c >= 'a') {
s[i] = c - 'a' + 'A';
}
}
}
#endif
MYBOOL getFileName(char *filename, char *test)
{
MYBOOL status;
status = (MYBOOL) (('-' != test[0]) && (strlen(test) > 1));
if(status)
strcpy(filename, test);
return(status);
}
MYBOOL isNum(char val)
{
int ord;
ord = (int) val - 48;
return( (MYBOOL) ((ord >= 0) && (ord <= 9)) );
}
void main( int argc, char *argv[], char *envp[] )
{
/* Output device */
FILE *outunit = stdout;
/* Overall dimensions allocated */
int maxm = MAXROWS, maxn = MAXCOLS, maxnz = MAXNZ,
replace = 0, randcol = 0;
MYBOOL ftran = TRUE;
/* Storage for A, b */
REAL *Aij = NULL, *b = NULL, *xexact = NULL;
int *iA = NULL, *jA = NULL;
/* Storage for LUSOL */
LUSOLrec *LUSOL = NULL;
/* Define local storage variables */
int i , inform, j , k , i1 ,
m , useropt, lenb, lenx,
n , nelem , nnzero;
REAL Amax , test ,
bnorm , rnorm , xnorm,
*rhs = NULL, *r = NULL, *x = NULL;
char fileext[50], filename[255], blasname[255];
MYBOOL printsolution = FALSE, success = FALSE;
/* Check if we have input parameters */
useropt = argc;
if(useropt < 2) {
printf("LUSOL v%d.%d.%d.%d - Linear equation solver - Development edition.\n",
LUSOL_VERMAJOR, LUSOL_VERMINOR, LUSOL_RELEASE, LUSOL_BUILD);
printf("Usage: lusol [-p <type>] [-t <tolerance>] [-m <memscalar>]\n");
printf(" [-s] <MatrixFile> [<RhsFile>]\n");
printf("Options: -p <type> <0..3> Selects pivot type.\n");
printf(" -t <tolerance> <1..100> Selects diagonal tolerance.\n");
printf(" -m <memscalar> <%d..100> Memory allocation scalar.\n", LUSOL_MULT_nz_a);
printf(" -b Solves using btran (rather than ftran).\n");
printf(" -r <times> Randomly replace a column and resolve.\n");
printf(" -s Show the computed solution.\n");
printf(" -blas <lib> Activates external optimized BLAS library.\n");
printf("Formats: Conventional RCV .TXT, MatrixMarket .MTX, or Harwell-Boeing .RUA\n");
printf("Author: Michael A. Saunders (original Fortran version)\n");
printf(" Kjell Eikland (modified C version)\n");
return;
}
/* Create the LUSOL object and set user options */
LUSOL = LUSOL_create(outunit, 0, LUSOL_PIVMOD_TPP, 0);
#if 1
LUSOL->luparm[LUSOL_IP_ACCELERATION] = LUSOL_OTHERORDER | LUSOL_ACCELERATE_L0;
#elif 0
LUSOL->luparm[LUSOL_IP_ACCELERATION] = LUSOL_AUTOORDER | LUSOL_ACCELERATE_L0;
#endif
LUSOL->luparm[LUSOL_IP_SCALAR_NZA] = 10;
i = 1;
n = 0;
filename[0] = '\0';
blasname[0] = '\0';
while((n == 0) && (i < argc)) {
if(strcmp("-p", argv[i]) == 0) {
i1 = i+1;
if((i1 < argc) && isNum(argv[i1][0])) {
i = i1;
m = atoi(argv[i]);
if(m < 0 || m > LUSOL_PIVMOD_MAX)
continue;
LUSOL->luparm[LUSOL_IP_PIVOTTYPE] = m;
}
}
else if(strcmp("-t", argv[i]) == 0) {
i1 = i+1;
if((i1 < argc) && isNum(argv[i1][0])) {
i = i1;
Amax = atof(argv[i]);
if(Amax < 1 || Amax > 100)
continue;
LUSOL->parmlu[LUSOL_RP_FACTORMAX_Lij] = Amax;
}
}
else if(strcmp("-m", argv[i]) == 0) {
i1 = i+1;
if((i1 < argc) && isNum(argv[i1][0])) {
i = i1;
m = atoi(argv[i]);
if(m < LUSOL_MULT_nz_a || m > 100)
continue;
LUSOL->luparm[LUSOL_IP_SCALAR_NZA] = atoi(argv[i]);
}
}
else if(strcmp("-s", argv[i]) == 0)
printsolution = TRUE;
else if(strcmp("-b", argv[i]) == 0)
ftran = FALSE;
else if(strcmp("-r", argv[i]) == 0) {
i1 = i+1;
if((i1 < argc) && isNum(argv[i1][0])) {
i = i1;
m = atoi(argv[i]);
if(m < 0 || m > 10)
continue;
}
else
m = 1;
srand((unsigned) time( NULL ));
replace = 2*m;
}
else if(strcmp("-blas", argv[i]) == 0) {
i1 = i+1;
if((i1 < argc) && getFileName(blasname, argv[i1])) {
if(!load_BLAS(blasname))
fprintf(outunit, "Could not load external BLAS library '%s'\n", blasname);
i = i1;
}
else
fprintf(outunit, "Ignoring incomplete parameter %d '%s'\n", i, argv[i]);
}
else {
if(getFileName(filename, argv[i])) {
useropt = i;
break;
}
else
fprintf(outunit, "Ignoring unknown parameter %d '%s'\n", i, argv[i]);
}
i++;
}
/* Obtain file extension and see if we must estimate matrix data size */
strcpy(fileext, strchr(argv[useropt], '.'));
/* Yin Zhang noted that _strupr() is not available on many Unix platforms. */
_strupr_(fileext);
/* _strupr(fileext);*/
/* Read conventional text file format */
if(strcmp(fileext, ".TXT") == 0) {
if(!ctf_size_A(filename, &maxm, &maxn, &maxnz))
goto x900;
}
/* Read MatrixMarket file format */
else if(strcmp(fileext, ".MTX") == 0) {
if(!mmf_size_A(filename, &maxm, &maxn, &maxnz))
goto x900;
}
/* Read Harwell-Boeing file format */
else if(strcmp(fileext, ".RUA") == 0) {
if(!hbf_size_A(filename, &maxm, &maxn, &maxnz))
goto x900;
}
else {
fprintf(outunit, "Unrecognized matrix file extension %s\n", fileext);
goto x900;
}
/* Create the arrays */
Aij = (REAL *) LUSOL_CALLOC(maxnz + BLAS_BASE, sizeof(REAL));
iA = (int *) LUSOL_CALLOC(maxnz + BLAS_BASE, sizeof(int));
jA = (int *) LUSOL_CALLOC(maxnz + BLAS_BASE, sizeof(int));
if(ftran)
lenb = maxm;
else
lenb = maxn;
b = (REAL *) LUSOL_CALLOC(lenb+BLAS_BASE, sizeof(REAL));
rhs = (REAL *) LUSOL_CALLOC(lenb+BLAS_BASE, sizeof(REAL));
if(ftran)
lenx = maxn;
else
lenx = maxm;
xexact = (REAL *) LUSOL_CALLOC(lenx+BLAS_BASE, sizeof(REAL));
r = (REAL *) LUSOL_CALLOC(lenx+BLAS_BASE, sizeof(REAL));
x = (REAL *) LUSOL_CALLOC(lenx+BLAS_BASE, sizeof(REAL));
/* -----------------------------------------------------------------
Read data files.
----------------------------------------------------------------- */
fprintf(stdout, "\n========================================\n");
fprintf(stdout, "LUSOL v%d.%d.%d.%d - Linear equation solver",
LUSOL_VERMAJOR, LUSOL_VERMINOR, LUSOL_RELEASE, LUSOL_BUILD);
fprintf(stdout, "\n========================================\n");
/* -----------------------------------------------------------------
Read data for A
----------------------------------------------------------------- */
/* Read conventional text file format */
if(strcmp(fileext, ".TXT") == 0) {
if(!ctf_read_A(argv[useropt], maxm, maxn, maxnz,
&m, &n, &nnzero, iA, jA, Aij))
goto x900;
}
/* Read MatrixMarket file format */
else if(strcmp(fileext, ".MTX") == 0) {
if(!mmf_read_A(argv[useropt], maxm, maxn, maxnz,
&m, &n, &nnzero, iA, jA, Aij))
goto x900;
}
/* Read Harwell-Boeing file format */
else if(strcmp(fileext, ".RUA") == 0) {
if(!hbf_read_A(argv[useropt], maxm, maxn, maxnz,
&m, &n, &nnzero, iA, jA, Aij))
goto x900;
}
else {
fprintf(outunit, "Error: Unrecognized matrix file extension %s\n", fileext);
goto x900;
}
/* -----------------------------------------------------------------
Read data for b
----------------------------------------------------------------- */
/* Handle Harwell-Boeing case where the file contains a RHS */
i = strcmp(fileext, ".RUA");
if((useropt == argc-1) && (i != 0)) {
srand(timeNow());
i1 = m;
while(i1 > 0) {
test = rand();
i = RAND_MAX;
i = (int) ((test/i)*(m-1));
/* b[i+1] = 1.0; */
b[i+1] = i - 5;
i1--;
}
if(printsolution)
blockWriteREAL(outunit, "\nGenerated RHS vector", b, 1, lenb);
}
else {
if(i != 0)
useropt++;
strcpy(fileext, strchr(argv[useropt], '.'));
_strupr_(fileext);
/* Read conventional text file format */
if(strcmp(fileext, ".TXT") == 0) {
if(!ctf_read_b(argv[useropt], lenb, b))
goto x900;
}
/* Read MatrixMarket file format */
else if(strcmp(fileext, ".MTX") == 0) {
if(!mmf_read_b(argv[useropt], lenb, b))
goto x900;
}
/* Read Harwell-Boeing file format */
else if(strcmp(fileext, ".RUA") == 0) {
if(!hbf_read_b(argv[useropt], lenb, b))
goto x900;
}
else {
fprintf(outunit, "Error: Unrecognized vector file extension %s\n", fileext);
goto x900;
}
}
success = TRUE;
/* -----------------------------------------------------------------
Show data on input
----------------------------------------------------------------- */
fprintf(outunit, "\nData read from:\n%s\n", filename);
test = (double) nnzero / ((double) m * (double) n);
test *= 100.0;
fprintf(outunit, "Rows = %d Columns = %d Non-zeros = %d Density =%8.4f%%\n",
m, n, nnzero, test);
/* -----------------------------------------------------------------
Load A into (a, indc, indr).
----------------------------------------------------------------- */
#if 0 /* BUG !!! */
if(n != m)
LUSOL->luparm[LUSOL_IP_KEEPLU] = FALSE;
#endif
#ifdef LegacyTesting
LUSOL->luparm[LUSOL_IP_SCALAR_NZA] = LUSOL_MULT_nz_a;
LUSOL_sizeto(LUSOL, MAXROWS, MAXCOLS, MAXNZ*LUSOL_MULT_nz_a);
#endif
if(!LUSOL_assign(LUSOL, iA, jA, Aij, nnzero, TRUE)) {
fprintf(outunit, "Error: LUSOL failed due to insufficient memory.\n");
goto x900;
}
/* ------------------------------------------------------------------
Factor A = L U.
------------------------------------------------------------------ */
nelem = nnzero;
inform = LUSOL_factorize( LUSOL);
if(inform > LUSOL_INFORM_SERIOUS) {
fprintf(outunit, "Error:\n%s\n", LUSOL_informstr(LUSOL, inform));
goto x900;
}
if(n != m)
goto x800;
/* Get the largest element in A; we use it below as an estimate
of ||A||_inf, even though it isn't a proper norm. */
Amax = LUSOL->parmlu[LUSOL_RP_MAXELEM_A];
/* ------------------------------------------------------------------
SOLVE A x = b or x'A = b'.
Save b first because lu6sol() overwrites the rhs.
------------------------------------------------------------------ */
MEMCOPY(x, b, lenb+BLAS_BASE);
Resolve:
if(ftran)
inform = LUSOL_ftran(LUSOL, x, NULL, FALSE);
else
inform = LUSOL_btran(LUSOL, x, NULL);
if(inform > LUSOL_INFORM_SERIOUS) {
fprintf(outunit, "Error:\n%s\n", LUSOL_informstr(LUSOL, inform));
goto x900;
}
if(printsolution)
blockWriteREAL(outunit, "\nSolution vector", x, 1, lenb);
/* ------------------------------------------------------------------
Set r = b - Ax.
Find norm of r and x.
------------------------------------------------------------------ */
MEMCOPY(r, b, lenb+BLAS_BASE);
for(k = 1; k <= nnzero; k++) {
i = iA[k]; /* Row number */
j = jA[k]; /* Column number */
if(ftran)
r[i] -= Aij[k]*x[j];
else
r[j] -= Aij[k]*x[i];
}
/* blockWriteREAL(outunit, "\nResidual vector", r, 1, lenb);*/
bnorm = dnormi( lenb, b );
rnorm = dnormi( lenb, r );
xnorm = dnormi( lenx, x );
/* ------------------------------------------------------------------
Report the findings.
------------------------------------------------------------------ */
if(randcol > 0)
fprintf(outunit, "\n\nColumn %d was %s\n",
randcol,
(mod(replace,2) == 1 ? "replaced with random data" : "restored"));
x800:
fprintf(outunit, "\nLU size statistics (%d reallocations):\n",
LUSOL->expanded_a);
test = LUSOL->luparm[LUSOL_IP_NONZEROS_U0]+LUSOL->luparm[LUSOL_IP_NONZEROS_L0];
fprintf(outunit, "L0-size = %d U0-size = %d LU-nonzeros = %d Fill-in = %.1fx\n",
LUSOL->luparm[LUSOL_IP_NONZEROS_L0],
LUSOL->luparm[LUSOL_IP_NONZEROS_U0],
(int) test, test/nnzero);
if(n != m) {
fprintf(outunit, "%s with a factor tol. of %g identified %d singularities.\n",
LUSOL_pivotLabel(LUSOL), LUSOL->parmlu[LUSOL_RP_FACTORMAX_Lij],
LUSOL->luparm[LUSOL_IP_SINGULARITIES]);
goto x900;
}
test = rnorm / (Amax*xnorm);
fprintf(outunit, "\nAccuracy statistics:\n");
fprintf(outunit, "%s with a factor tol. of %g gave a rel.error of %g and %d singularities.\n",
LUSOL_pivotLabel(LUSOL), LUSOL->parmlu[LUSOL_RP_FACTORMAX_Lij], test,
LUSOL->luparm[LUSOL_IP_SINGULARITIES]);
fprintf(outunit, "Amax = %g bnorm = %g rnorm = %g xnorm = %g\n",
Amax, bnorm, rnorm, xnorm);
fprintf(outunit, "\n");
if (test <= 1.0e-8)
fprintf(outunit, "The equations were solved with very high accuracy.\n");
else if (test <= 1.0e-6)
fprintf(outunit, "The equations were solved with reasonably good accuracy.\n");
else {
if (test <= 1.0e-4)
fprintf(outunit, "Questionable accuracy; the LU factors may not be good enough.\n");
else
fprintf(outunit, "Poor accuracy; the LU factorization probably failed.\n");
if(LUSOL->luparm[LUSOL_IP_PIVOTTYPE] == LUSOL_PIVMOD_TRP)
fprintf(outunit, "Try a smaller factor tolerance (current is %g).\n",
LUSOL->parmlu[LUSOL_RP_FACTORMAX_Lij]);
else
fprintf(outunit, "Try a smaller factor tolerance and/or TRP pivoting.\n");
}
/* Check if we should replace a column and resolve */
if(replace > 0) {
replace--;
MEMCLEAR(x, lenb+BLAS_BASE);
if(mod(replace, 2) == 1) {
/* Randomly find a column and replace the column values with random data */
rnorm = rand();
randcol = (int) (n * rnorm / (RAND_MAX+1.0)) + 1;
for(i = 1; i < m; i++)
x[i] = Amax * rand() / RAND_MAX;
}
else {
/* Put the previously replaced column back and resolve */
for (k = 1; k <= nnzero; k++) {
i = iA[k];
j = jA[k];
if(j == randcol)
x[i] = Aij[k];
}
}
inform = LUSOL_replaceColumn(LUSOL, randcol, x);
MEMCOPY(b, x, lenb+BLAS_BASE);
if(inform != LUSOL_INFORM_LUSUCCESS)
fprintf(outunit, "Error:\n%s\n", LUSOL_informstr(LUSOL, inform));
else
goto Resolve;
}
/* Free memory */
x900:
if(!success)
fprintf(outunit, "Insufficient memory or data file not found.\n");
LUSOL_FREE(Aij);
LUSOL_FREE(b);
LUSOL_FREE(xexact);
LUSOL_FREE(iA);
LUSOL_FREE(jA);
LUSOL_FREE(rhs);
LUSOL_FREE(r);
LUSOL_FREE(x);
#if 0
LUSOL_dump(NULL, LUSOL);
-blas "atlas_AXP_512_360.dll" -b -p 1 "STP3D_A.MTX"
"C:\Shared Files\Visual Studio Projects\LU\MatrixMarket\sherman5.mtx" "C:\Shared Files\Visual Studio Projects\LU\MatrixMarket\sherman5_rhs1.mtx"
A6805.txt b6805.txt
A10009.txt b10009.txt
fidap005.mtx fidap005_rhs1.mtx
fidapm05.mtx fidapm05_rhs1.mtx
-b -p 1 "basis.mtx"
-b -p 1 "LU-test3.mtx"
#endif
LUSOL_free(LUSOL);
/* End of main program for Test of LUSOL */
}

View File

@ -1,26 +0,0 @@
#ifdef StaticMemAlloc
#if 0
#define MAXNZ 300000
#define MAXROWS 15000
#elif 0
#define MAXNZ 60000
#define MAXROWS 12500
#elif 1
#define MAXNZ 40000
#define MAXROWS 3500
#else
#define MAXNZ 1000
#define MAXROWS 50
#endif
#else
#define MAXNZ 1000
#define MAXROWS 50
#endif
#define MAXCOLS MAXROWS
#define MAXLU (LUSOL_MULT_nz_a*MAXNZ)

View File

@ -1,495 +0,0 @@
/*
* Matrix Market I/O library for ANSI C
*
* See http://math.nist.gov/MatrixMarket for details.
*
* (Version 1.01, 5/2003)
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "mmio.h"
int mm_read_unsymmetric_sparse(const char *fname, int *M_, int *N_, int *nz_,
double **val_, int **I_, int **J_)
{
FILE *f;
MM_typecode matcode;
int M, N, nz;
int i;
double *val;
int *I, *J;
if ((f = fopen(fname, "r")) == NULL)
return -1;
if (mm_read_banner(f, &matcode) != 0)
{
printf("mm_read_unsymetric: Could not process Matrix Market banner ");
printf(" in file [%s]\n", fname);
return -1;
}
if ( !(mm_is_real(matcode) && mm_is_matrix(matcode) &&
mm_is_sparse(matcode)))
{
fprintf(stderr, "Sorry, this application does not support ");
fprintf(stderr, "Market Market type: [%s]\n",
mm_typecode_to_str(matcode));
return -1;
}
/* find out size of sparse matrix: M, N, nz .... */
if (mm_read_mtx_crd_size(f, &M, &N, &nz) !=0)
{
fprintf(stderr, "read_unsymmetric_sparse(): could not parse matrix size.\n");
return -1;
}
*M_ = M;
*N_ = N;
*nz_ = nz;
/* reseve memory for matrices */
I = (int *) malloc(nz * sizeof(int));
J = (int *) malloc(nz * sizeof(int));
val = (double *) malloc(nz * sizeof(double));
*val_ = val;
*I_ = I;
*J_ = J;
/* NOTE: when reading in doubles, ANSI C requires the use of the "l" */
/* specifier as in "%lg", "%lf", "%le", otherwise errors will occur */
/* (ANSI C X3.159-1989, Sec. 4.9.6.2, p. 136 lines 13-15) */
for (i=0; i<nz; i++)
{
fscanf(f, "%d %d %lg\n", &I[i], &J[i], &val[i]);
I[i]--; /* adjust from 1-based to 0-based */
J[i]--;
}
fclose(f);
return 0;
}
int mm_is_valid(MM_typecode matcode)
{
if (!mm_is_matrix(matcode)) return 0;
if (mm_is_dense(matcode) && mm_is_pattern(matcode)) return 0;
if (mm_is_real(matcode) && mm_is_hermitian(matcode)) return 0;
if (mm_is_pattern(matcode) && (mm_is_hermitian(matcode) ||
mm_is_skew(matcode))) return 0;
return 1;
}
int mm_read_banner(FILE *f, MM_typecode *matcode)
{
char line[MM_MAX_LINE_LENGTH];
char banner[MM_MAX_TOKEN_LENGTH];
char mtx[MM_MAX_TOKEN_LENGTH];
char crd[MM_MAX_TOKEN_LENGTH];
char data_type[MM_MAX_TOKEN_LENGTH];
char storage_scheme[MM_MAX_TOKEN_LENGTH];
char *p;
mm_clear_typecode(matcode);
if (fgets(line, MM_MAX_LINE_LENGTH, f) == NULL)
return MM_PREMATURE_EOF;
if (sscanf(line, "%s %s %s %s %s", banner, mtx, crd, data_type,
storage_scheme) != 5)
return MM_PREMATURE_EOF;
/* convert to lower case */
for (p=mtx; *p!='\0'; *p= (char) tolower(*p),p++);
for (p=crd; *p!='\0'; *p= (char) tolower(*p),p++);
for (p=data_type; *p!='\0'; *p= (char) tolower(*p),p++);
for (p=storage_scheme; *p!='\0'; *p= (char) tolower(*p),p++);
/* check for banner */
if (strncmp(banner, MatrixMarketBanner, strlen(MatrixMarketBanner)) != 0)
return MM_NO_HEADER;
/* first field should be "mtx" */
if (strcmp(mtx, MM_MTX_STR) != 0)
return MM_UNSUPPORTED_TYPE;
mm_set_matrix(matcode);
/* second field describes whether this is a sparse matrix (in coordinate
storgae) or a dense array */
if (strcmp(crd, MM_SPARSE_STR) == 0)
mm_set_sparse(matcode);
else
if (strcmp(crd, MM_DENSE_STR) == 0)
mm_set_dense(matcode);
else
return MM_UNSUPPORTED_TYPE;
/* third field */
if (strcmp(data_type, MM_REAL_STR) == 0)
mm_set_real(matcode);
else
if (strcmp(data_type, MM_COMPLEX_STR) == 0)
mm_set_complex(matcode);
else
if (strcmp(data_type, MM_PATTERN_STR) == 0)
mm_set_pattern(matcode);
else
if (strcmp(data_type, MM_INT_STR) == 0)
mm_set_integer(matcode);
else
return MM_UNSUPPORTED_TYPE;
/* fourth field */
if (strcmp(storage_scheme, MM_GENERAL_STR) == 0)
mm_set_general(matcode);
else
if (strcmp(storage_scheme, MM_SYMM_STR) == 0)
mm_set_symmetric(matcode);
else
if (strcmp(storage_scheme, MM_HERM_STR) == 0)
mm_set_hermitian(matcode);
else
if (strcmp(storage_scheme, MM_SKEW_STR) == 0)
mm_set_skew(matcode);
else
return MM_UNSUPPORTED_TYPE;
return 0;
}
int mm_write_mtx_crd_size(FILE *f, int M, int N, int nz)
{
if (fprintf(f, "%d %d %d\n", M, N, nz) < 0)
return MM_COULD_NOT_WRITE_FILE;
else
return 0;
}
int mm_read_mtx_crd_size(FILE *f, int *M, int *N, int *nz )
{
char line[MM_MAX_LINE_LENGTH];
int num_items_read;
/* set return null parameter values, in case we exit with errors */
*M = *N = *nz = 0;
/* now continue scanning until you reach the end-of-comments */
do {
if (fgets(line,MM_MAX_LINE_LENGTH,f) == NULL)
return MM_PREMATURE_EOF;
} while (line[0] == '%');
/* line[] is either blank, har M,N or M,N,nz */
if (sscanf(line, "%d %d %d", M, N, nz) >= 2)
return 0;
else
do {
num_items_read = fscanf(f, "%d %d %d", M, N, nz);
if (num_items_read == EOF) return MM_PREMATURE_EOF;
} while (num_items_read < 2);
return 0;
}
int mm_read_mtx_array_size(FILE *f, int *M, int *N)
{
char line[MM_MAX_LINE_LENGTH];
int num_items_read;
/* set return null parameter values, in case we exit with errors */
*M = *N = 0;
/* now continue scanning until you reach the end-of-comments */
do
{
if (fgets(line,MM_MAX_LINE_LENGTH,f) == NULL)
return MM_PREMATURE_EOF;
}while (line[0] == '%');
/* line[] is either blank or has M,N, nz */
if (sscanf(line, "%d %d", M, N) == 2)
return 0;
else /* we have a blank line */
do
{
num_items_read = fscanf(f, "%d %d", M, N);
if (num_items_read == EOF) return MM_PREMATURE_EOF;
}
while (num_items_read != 2);
return 0;
}
int mm_write_mtx_array_size(FILE *f, int M, int N)
{
if (fprintf(f, "%d %d\n", M, N) < 0)
return MM_COULD_NOT_WRITE_FILE;
else
return 0;
}
/*-------------------------------------------------------------------------*/
/******************************************************************/
/* use when I[], J[], and val[]J, and val[] are already allocated */
/******************************************************************/
int mm_read_mtx_crd_data(FILE *f, int M, int N, int nz, int I[], int J[],
double val[], MM_typecode matcode)
{
int i;
if (mm_is_complex(matcode))
{
for (i=0; i<nz; i++)
if (fscanf(f, "%d %d %lg %lg", &I[i], &J[i], &val[2*i], &val[2*i+1])
!= 4) return MM_PREMATURE_EOF;
}
else if (mm_is_real(matcode))
{
for (i=0; i<nz; i++)
{
if (fscanf(f, "%d %d %lg\n", &I[i], &J[i], &val[i])
!= 3) return MM_PREMATURE_EOF;
}
}
else if (mm_is_pattern(matcode))
{
for (i=0; i<nz; i++)
if (fscanf(f, "%d %d", &I[i], &J[i])
!= 2) return MM_PREMATURE_EOF;
}
else
return MM_UNSUPPORTED_TYPE;
return 0;
}
int mm_read_mtx_crd_entry(FILE *f, int *I, int *J,
double *real, double *imag, MM_typecode matcode)
{
if (mm_is_complex(matcode))
{
if (fscanf(f, "%d %d %lg %lg", I, J, real, imag)
!= 4) return MM_PREMATURE_EOF;
}
else if (mm_is_real(matcode))
{
if (fscanf(f, "%d %d %lg\n", I, J, real)
!= 3) return MM_PREMATURE_EOF;
}
else if (mm_is_pattern(matcode))
{
if (fscanf(f, "%d %d", I, J) != 2) return MM_PREMATURE_EOF;
}
else
return MM_UNSUPPORTED_TYPE;
return 0;
}
/************************************************************************
mm_read_mtx_crd() fills M, N, nz, array of values, and return
type code, e.g. 'MCRS'
if matrix is complex, values[] is of size 2*nz,
(nz pairs of real/imaginary values)
************************************************************************/
int mm_read_mtx_crd(char *fname, int *M, int *N, int *nz, int **I, int **J,
double **val, MM_typecode *matcode)
{
int ret_code;
FILE *f;
if (strcmp(fname, "stdin") == 0) f=stdin;
else
if ((f = fopen(fname, "r")) == NULL)
return MM_COULD_NOT_READ_FILE;
if ((ret_code = mm_read_banner(f, matcode)) != 0)
return ret_code;
if (!(mm_is_valid(*matcode) && mm_is_sparse(*matcode) &&
mm_is_matrix(*matcode)))
return MM_UNSUPPORTED_TYPE;
if ((ret_code = mm_read_mtx_crd_size(f, M, N, nz)) != 0)
return ret_code;
*I = (int *) malloc(*nz * sizeof(int));
*J = (int *) malloc(*nz * sizeof(int));
*val = NULL;
if (mm_is_complex(*matcode))
{
*val = (double *) malloc(*nz * 2 * sizeof(double));
ret_code = mm_read_mtx_crd_data(f, *M, *N, *nz, *I, *J, *val,
*matcode);
if (ret_code != 0) return ret_code;
}
else if (mm_is_real(*matcode))
{
*val = (double *) malloc(*nz * sizeof(double));
ret_code = mm_read_mtx_crd_data(f, *M, *N, *nz, *I, *J, *val,
*matcode);
if (ret_code != 0) return ret_code;
}
else if (mm_is_pattern(*matcode))
{
ret_code = mm_read_mtx_crd_data(f, *M, *N, *nz, *I, *J, *val,
*matcode);
if (ret_code != 0) return ret_code;
}
if (f != stdin) fclose(f);
return 0;
}
int mm_write_banner(FILE *f, MM_typecode matcode)
{
char *str = mm_typecode_to_str(matcode);
int ret_code;
ret_code = fprintf(f, "%s %s\n", MatrixMarketBanner, str);
/* free(str); This is a bug from the official distribution - KE fixed */
if (ret_code < 0 )
return MM_COULD_NOT_WRITE_FILE;
else
return 0;
}
int mm_write_mtx_crd(char fname[], int M, int N, int nz, int I[], int J[],
double val[], MM_typecode matcode)
{
FILE *f;
int i;
if (strcmp(fname, "stdout") == 0)
f = stdout;
else
if ((f = fopen(fname, "w")) == NULL)
return MM_COULD_NOT_WRITE_FILE;
/* print banner followed by typecode */
fprintf(f, "%s ", MatrixMarketBanner);
fprintf(f, "%s\n", mm_typecode_to_str(matcode));
/* print matrix sizes and nonzeros */
fprintf(f, "%d %d %d\n", M, N, nz);
/* print values */
if (mm_is_pattern(matcode))
for (i=0; i<nz; i++)
fprintf(f, "%d %d\n", I[i], J[i]);
else
if (mm_is_real(matcode))
for (i=0; i<nz; i++)
fprintf(f, "%d %d %20.16g\n", I[i], J[i], val[i]);
else
if (mm_is_complex(matcode))
for (i=0; i<nz; i++)
fprintf(f, "%d %d %20.16g %20.16g\n", I[i], J[i], val[2*i],
val[2*i+1]);
else
{
if (f != stdout) fclose(f);
return MM_UNSUPPORTED_TYPE;
}
if (f !=stdout) fclose(f);
return 0;
}
char *mm_typecode_to_str(MM_typecode matcode)
{
static char buffer[MM_MAX_LINE_LENGTH];
char *types[4];
/* check for MTX type */
if (mm_is_matrix(matcode))
types[0] = MM_MTX_STR;
else
return NULL;
/* check for CRD or ARR matrix */
if (mm_is_sparse(matcode))
types[1] = MM_SPARSE_STR;
else
if (mm_is_dense(matcode))
types[1] = MM_DENSE_STR;
else
return NULL;
/* check for element data type */
if (mm_is_real(matcode))
types[2] = MM_REAL_STR;
else
if (mm_is_complex(matcode))
types[2] = MM_COMPLEX_STR;
else
if (mm_is_pattern(matcode))
types[2] = MM_PATTERN_STR;
else
if (mm_is_integer(matcode))
types[2] = MM_INT_STR;
else
return NULL;
/* check for symmetry type */
if (mm_is_general(matcode))
types[3] = MM_GENERAL_STR;
else
if (mm_is_symmetric(matcode))
types[3] = MM_SYMM_STR;
else
if (mm_is_hermitian(matcode))
types[3] = MM_HERM_STR;
else
if (mm_is_skew(matcode))
types[3] = MM_SKEW_STR;
else
return NULL;
sprintf(buffer,"%s %s %s %s", types[0], types[1], types[2], types[3]);
return & buffer[0];
}

View File

@ -1,133 +0,0 @@
/*
* Matrix Market I/O library for ANSI C
*
* See http://math.nist.gov/MatrixMarket for details.
*
*
*/
#ifndef MM_IO_H
#define MM_IO_H
#define MM_MAX_LINE_LENGTH 1025
#define MatrixMarketBanner "%%MatrixMarket"
#define MM_MAX_TOKEN_LENGTH 64
typedef char MM_typecode[4];
char *mm_typecode_to_str(MM_typecode matcode);
int mm_read_banner(FILE *f, MM_typecode *matcode);
int mm_read_mtx_crd_size(FILE *f, int *M, int *N, int *nz);
int mm_read_mtx_array_size(FILE *f, int *M, int *N);
int mm_write_banner(FILE *f, MM_typecode matcode);
int mm_write_mtx_crd_size(FILE *f, int M, int N, int nz);
int mm_write_mtx_array_size(FILE *f, int M, int N);
/********************* MM_typecode query fucntions ***************************/
#define mm_is_matrix(typecode) ((typecode)[0]=='M')
#define mm_is_sparse(typecode) ((typecode)[1]=='C')
#define mm_is_coordinate(typecode)((typecode)[1]=='C')
#define mm_is_dense(typecode) ((typecode)[1]=='A')
#define mm_is_array(typecode) ((typecode)[1]=='A')
#define mm_is_complex(typecode) ((typecode)[2]=='C')
#define mm_is_real(typecode) ((typecode)[2]=='R')
#define mm_is_pattern(typecode) ((typecode)[2]=='P')
#define mm_is_integer(typecode) ((typecode)[2]=='I')
#define mm_is_symmetric(typecode)((typecode)[3]=='S')
#define mm_is_general(typecode) ((typecode)[3]=='G')
#define mm_is_skew(typecode) ((typecode)[3]=='K')
#define mm_is_hermitian(typecode)((typecode)[3]=='H')
int mm_is_valid(MM_typecode matcode); /* too complex for a macro */
/********************* MM_typecode modify fucntions ***************************/
#define mm_set_matrix(typecode) ((*typecode)[0]='M')
#define mm_set_coordinate(typecode) ((*typecode)[1]='C')
#define mm_set_array(typecode) ((*typecode)[1]='A')
#define mm_set_dense(typecode) mm_set_array(typecode)
#define mm_set_sparse(typecode) mm_set_coordinate(typecode)
#define mm_set_complex(typecode)((*typecode)[2]='C')
#define mm_set_real(typecode) ((*typecode)[2]='R')
#define mm_set_pattern(typecode)((*typecode)[2]='P')
#define mm_set_integer(typecode)((*typecode)[2]='I')
#define mm_set_symmetric(typecode)((*typecode)[3]='S')
#define mm_set_general(typecode)((*typecode)[3]='G')
#define mm_set_skew(typecode) ((*typecode)[3]='K')
#define mm_set_hermitian(typecode)((*typecode)[3]='H')
#define mm_clear_typecode(typecode) ((*typecode)[0]=(*typecode)[1]= \
(*typecode)[2]=' ',(*typecode)[3]='G')
#define mm_initialize_typecode(typecode) mm_clear_typecode(typecode)
/********************* Matrix Market error codes ***************************/
#define MM_COULD_NOT_READ_FILE 11
#define MM_PREMATURE_EOF 12
#define MM_NOT_MTX 13
#define MM_NO_HEADER 14
#define MM_UNSUPPORTED_TYPE 15
#define MM_LINE_TOO_LONG 16
#define MM_COULD_NOT_WRITE_FILE 17
/******************** Matrix Market internal definitions ********************
MM_matrix_typecode: 4-character sequence
ojbect sparse/ data storage
dense type scheme
string position: [0] [1] [2] [3]
Matrix typecode: M(atrix) C(oord) R(eal) G(eneral)
A(array) C(omplex) H(ermitian)
P(attern) S(ymmetric)
I(nteger) K(kew)
***********************************************************************/
#define MM_MTX_STR "matrix"
#define MM_ARRAY_STR "array"
#define MM_DENSE_STR "array"
#define MM_COORDINATE_STR "coordinate"
#define MM_SPARSE_STR "coordinate"
#define MM_COMPLEX_STR "complex"
#define MM_REAL_STR "real"
#define MM_INT_STR "integer"
#define MM_GENERAL_STR "general"
#define MM_SYMM_STR "symmetric"
#define MM_HERM_STR "hermitian"
#define MM_SKEW_STR "skew-symmetric"
#define MM_PATTERN_STR "pattern"
/* high level routines */
int mm_write_mtx_crd(char fname[], int M, int N, int nz, int I[], int J[],
double val[], MM_typecode matcode);
int mm_read_mtx_crd_data(FILE *f, int M, int N, int nz, int I[], int J[],
double val[], MM_typecode matcode);
int mm_read_mtx_crd_entry(FILE *f, int *I, int *J, double *real, double *img,
MM_typecode matcode);
int mm_read_unsymmetric_sparse(const char *fname, int *M_, int *N_, int *nz_,
double **val_, int **I_, int **J_);
#endif

View File

@ -1,849 +0,0 @@
#include <stdlib.h>
#include <stdio.h>
/*#include <memory.h>*/
#include <string.h>
#include <math.h>
#include "myblas.h"
#ifdef FORTIFY
# include "lp_fortify.h"
#endif
/* ************************************************************************ */
/* Initialize BLAS interfacing routines */
/* ************************************************************************ */
MYBOOL mustinitBLAS = TRUE;
#if (defined WIN32) || (defined WIN64)
HINSTANCE hBLAS = NULL;
#else
void *hBLAS = NULL;
#endif
/* ************************************************************************ */
/* Function pointers for external BLAS library (C base 0) */
/* ************************************************************************ */
BLAS_dscal_func *BLAS_dscal;
BLAS_dcopy_func *BLAS_dcopy;
BLAS_daxpy_func *BLAS_daxpy;
BLAS_dswap_func *BLAS_dswap;
BLAS_ddot_func *BLAS_ddot;
BLAS_idamax_func *BLAS_idamax;
BLAS_idamin_func *BLAS_idamin;
BLAS_dload_func *BLAS_dload;
BLAS_dnormi_func *BLAS_dnormi;
/* ************************************************************************ */
/* Define the BLAS interfacing routines */
/* ************************************************************************ */
void init_BLAS(void)
{
if(mustinitBLAS) {
load_BLAS(NULL);
mustinitBLAS = FALSE;
}
}
MYBOOL is_nativeBLAS(void)
{
#ifdef LoadableBlasLib
return( (MYBOOL) (hBLAS == NULL) );
#else
return( TRUE );
#endif
}
MYBOOL load_BLAS(char *libname)
{
MYBOOL result = TRUE;
#ifdef LoadableBlasLib
if(hBLAS != NULL) {
my_FreeLibrary(hBLAS);
}
#endif
if(libname == NULL) {
if(!mustinitBLAS && is_nativeBLAS())
return( FALSE );
BLAS_dscal = my_dscal;
BLAS_dcopy = my_dcopy;
BLAS_daxpy = my_daxpy;
BLAS_dswap = my_dswap;
BLAS_ddot = my_ddot;
BLAS_idamax = my_idamax;
BLAS_idamin = my_idamin;
BLAS_dload = my_dload;
BLAS_dnormi = my_dnormi;
if(mustinitBLAS)
mustinitBLAS = FALSE;
}
else {
#ifdef LoadableBlasLib
#if (defined WIN32) || (defined WIN64)
char *blasname = libname;
#else
/* First standardize UNIX .SO library name format. */
char blasname[260];
if(!so_stdname(blasname, libname, 260))
return( FALSE );
#endif
/* Get a handle to the Windows DLL module. */
hBLAS = my_LoadLibrary(blasname);
/* If the handle is valid, try to get the function addresses. */
result = (MYBOOL) (hBLAS != NULL);
if(result) {
BLAS_dscal = (BLAS_dscal_func *) my_GetProcAddress(hBLAS, BLAS_prec "scal");
BLAS_dcopy = (BLAS_dcopy_func *) my_GetProcAddress(hBLAS, BLAS_prec "copy");
BLAS_daxpy = (BLAS_daxpy_func *) my_GetProcAddress(hBLAS, BLAS_prec "axpy");
BLAS_dswap = (BLAS_dswap_func *) my_GetProcAddress(hBLAS, BLAS_prec "swap");
BLAS_ddot = (BLAS_ddot_func *) my_GetProcAddress(hBLAS, BLAS_prec "dot");
BLAS_idamax = (BLAS_idamax_func *) my_GetProcAddress(hBLAS, "i" BLAS_prec "amax");
BLAS_idamin = (BLAS_idamin_func *) my_GetProcAddress(hBLAS, "i" BLAS_prec "amin");
#if 0
BLAS_dload = (BLAS_dload_func *) my_GetProcAddress(hBLAS, BLAS_prec "load");
BLAS_dnormi = (BLAS_dnormi_func *) my_GetProcAddress(hBLAS, BLAS_prec "normi");
#endif
}
#endif
/* Do validation */
if(!result ||
((BLAS_dscal == NULL) ||
(BLAS_dcopy == NULL) ||
(BLAS_daxpy == NULL) ||
(BLAS_dswap == NULL) ||
(BLAS_ddot == NULL) ||
(BLAS_idamax == NULL) ||
(BLAS_idamin == NULL) ||
(BLAS_dload == NULL) ||
(BLAS_dnormi == NULL))
) {
load_BLAS(NULL);
result = FALSE;
}
}
return( result );
}
MYBOOL unload_BLAS(void)
{
return( load_BLAS(NULL) );
}
/* ************************************************************************ */
/* Now define the unoptimized local BLAS functions */
/* ************************************************************************ */
void daxpy( int n, REAL da, REAL *dx, int incx, REAL *dy, int incy)
{
dx++;
dy++;
BLAS_daxpy( &n, &da, dx, &incx, dy, &incy);
}
void BLAS_CALLMODEL my_daxpy( int *_n, REAL *_da, REAL *dx, int *_incx, REAL *dy, int *_incy)
{
/* constant times a vector plus a vector.
uses unrolled loops for increments equal to one.
jack dongarra, linpack, 3/11/78.
modified 12/3/93, array[1] declarations changed to array[*] */
int i, ix, iy;
#ifndef DOFASTMATH
int m, mp1;
#endif
register REAL rda;
REAL da = *_da;
int n = *_n, incx = *_incx, incy = *_incy;
if (n <= 0) return;
if (da == 0.0) return;
dx--;
dy--;
ix = 1;
iy = 1;
if (incx < 0)
ix = (-n+1)*incx + 1;
if (incy < 0)
iy = (-n+1)*incy + 1;
rda = da;
/* CPU intensive loop; option to do pointer arithmetic */
#if defined DOFASTMATH
{
REAL *xptr, *yptr;
for (i = 1, xptr = dx + ix, yptr = dy + iy;
i <= n; i++, xptr += incx, yptr += incy)
(*yptr) += rda*(*xptr);
}
#else
if (incx==1 && incy==1) goto x20;
/* code for unequal increments or equal increments not equal to 1 */
for (i = 1; i<=n; i++) {
dy[iy]+= rda*dx[ix];
ix+= incx;
iy+= incy;
}
return;
/* code for both increments equal to 1 */
/* clean-up loop */
x20:
m = n % 4;
if (m == 0) goto x40;
for (i = 1; i<=m; i++)
dy[i]+= rda*dx[i];
if(n < 4) return;
x40:
mp1 = m + 1;
for (i = mp1; i<=n; i=i+4) {
dy[i]+= rda*dx[i];
dy[i + 1]+= rda*dx[i + 1];
dy[i + 2]+= rda*dx[i + 2];
dy[i + 3]+= rda*dx[i + 3];
}
#endif
}
/* ************************************************************************ */
void dcopy( int n, REAL *dx, int incx, REAL *dy, int incy)
{
dx++;
dy++;
BLAS_dcopy( &n, dx, &incx, dy, &incy);
}
void BLAS_CALLMODEL my_dcopy (int *_n, REAL *dx, int *_incx, REAL *dy, int *_incy)
{
/* copies a vector, x, to a vector, y.
uses unrolled loops for increments equal to one.
jack dongarra, linpack, 3/11/78.
modified 12/3/93, array[1] declarations changed to array[*] */
int i, ix, iy;
#ifndef DOFASTMATH
int m, mp1;
#endif
int n = *_n, incx = *_incx, incy = *_incy;
if(n<=0)
return;
dx--;
dy--;
ix = 1;
iy = 1;
if(incx<0)
ix = (-n+1)*incx + 1;
if(incy<0)
iy = (-n+1)*incy + 1;
/* CPU intensive loop; option to do pointer arithmetic */
#if defined DOFASTMATH
{
REAL *xptr, *yptr;
for (i = 1, xptr = dx + ix, yptr = dy + iy;
i <= n; i++, xptr += incx, yptr += incy)
(*yptr) = (*xptr);
}
#else
if(incx==1 && incy==1)
goto x20;
/* code for unequal increments or equal increments not equal to 1 */
for(i = 1; i<=n; i++) {
dy[iy] = dx[ix];
ix+= incx;
iy+= incy;
}
return;
/* code for both increments equal to 1 */
/* version with fast machine copy logic (requires memory.h or string.h) */
x20:
m = n % 7;
if (m == 0) goto x40;
for (i = 1; i<=m; i++)
dy[i] = dx[i];
if (n < 7) return;
x40:
mp1 = m + 1;
for (i = mp1; i<=n; i=i+7) {
dy[i] = dx[i];
dy[i + 1] = dx[i + 1];
dy[i + 2] = dx[i + 2];
dy[i + 3] = dx[i + 3];
dy[i + 4] = dx[i + 4];
dy[i + 5] = dx[i + 5];
dy[i + 6] = dx[i + 6];
}
#endif
}
/* ************************************************************************ */
void dscal (int n, REAL da, REAL *dx, int incx)
{
dx++;
BLAS_dscal (&n, &da, dx, &incx);
}
void BLAS_CALLMODEL my_dscal (int *_n, REAL *_da, REAL *dx, int *_incx)
{
/* Multiply a vector by a constant.
--Input--
N number of elements in input vector(s)
DA double precision scale factor
DX double precision vector with N elements
INCX storage spacing between elements of DX
--Output--
DX double precision result (unchanged if N.LE.0)
Replace double precision DX by double precision DA*DX.
For I = 0 to N-1, replace DX(IX+I*INCX) with DA * DX(IX+I*INCX),
where IX = 1 if INCX .GE. 0, else IX = 1+(1-N)*INCX. */
int i;
#ifndef DOFASTMATH
int m, mp1, ix;
#endif
register REAL rda;
REAL da = *_da;
int n = *_n, incx = *_incx;
if (n <= 0)
return;
rda = da;
dx--;
/* Optionally do fast pointer arithmetic */
#if defined DOFASTMATH
{
REAL *xptr;
for (i = 1, xptr = dx + 1; i <= n; i++, xptr += incx)
(*xptr) *= rda;
}
#else
if (incx == 1)
goto x20;
/* Code for increment not equal to 1 */
ix = 1;
if (incx < 0)
ix = (-n+1)*incx + 1;
for(i = 1; i <= n; i++, ix += incx)
dx[ix] *= rda;
return;
/* Code for increment equal to 1. */
/* Clean-up loop so remaining vector length is a multiple of 5. */
x20:
m = n % 5;
if (m == 0) goto x40;
for( i = 1; i <= m; i++)
dx[i] *= rda;
if (n < 5)
return;
x40:
mp1 = m + 1;
for(i = mp1; i <= n; i += 5) {
dx[i] *= rda;
dx[i+1] *= rda;
dx[i+2] *= rda;
dx[i+3] *= rda;
dx[i+4] *= rda;
}
#endif
}
/* ************************************************************************ */
REAL ddot(int n, REAL *dx, int incx, REAL *dy, int incy)
{
dx++;
dy++;
return( BLAS_ddot (&n, dx, &incx, dy, &incy) );
}
REAL BLAS_CALLMODEL my_ddot(int *_n, REAL *dx, int *_incx, REAL *dy, int *_incy)
{
/* forms the dot product of two vectors.
uses unrolled loops for increments equal to one.
jack dongarra, linpack, 3/11/78.
modified 12/3/93, array[1] declarations changed to array[*] */
register REAL dtemp;
int i, ix, iy;
#ifndef DOFASTMATH
int m, mp1;
#endif
int n = *_n, incx = *_incx, incy = *_incy;
dtemp = 0.0;
if (n<=0)
return( (REAL) dtemp);
dx--;
dy--;
ix = 1;
iy = 1;
if (incx<0)
ix = (-n+1)*incx + 1;
if (incy<0)
iy = (-n+1)*incy + 1;
/* CPU intensive loop; option to do pointer arithmetic */
#if defined DOFASTMATH
{
REAL *xptr, *yptr;
for (i = 1, xptr = dx + ix, yptr = dy + iy;
i <= n; i++, xptr += incx, yptr += incy)
dtemp+= (*yptr)*(*xptr);
}
#else
if (incx==1 && incy==1) goto x20;
/* code for unequal increments or equal increments not equal to 1 */
for (i = 1; i<=n; i++) {
dtemp+= dx[ix]*dy[iy];
ix+= incx;
iy+= incy;
}
return(dtemp);
/* code for both increments equal to 1 */
/* clean-up loop */
x20:
m = n % 5;
if (m == 0) goto x40;
for (i = 1; i<=m; i++)
dtemp+= dx[i]*dy[i];
if (n < 5) goto x60;
x40:
mp1 = m + 1;
for (i = mp1; i<=n; i=i+5)
dtemp+= dx[i]*dy[i] + dx[i + 1]*dy[i + 1] +
dx[i + 2]*dy[i + 2] + dx[i + 3]*dy[i + 3] + dx[i + 4]*dy[i + 4];
x60:
#endif
return(dtemp);
}
/* ************************************************************************ */
void dswap( int n, REAL *dx, int incx, REAL *dy, int incy )
{
dx++;
dy++;
BLAS_dswap( &n, dx, &incx, dy, &incy );
}
void BLAS_CALLMODEL my_dswap( int *_n, REAL *dx, int *_incx, REAL *dy, int *_incy )
{
int i, ix, iy;
#ifndef DOFASTMATH
int m, mp1, ns;
REAL dtemp2, dtemp3;
#endif
register REAL dtemp1;
int n = *_n, incx = *_incx, incy = *_incy;
if (n <= 0) return;
dx--;
dy--;
ix = 1;
iy = 1;
if (incx < 0)
ix = (-n+1)*incx + 1;
if (incy < 0)
iy = (-n+1)*incy + 1;
/* CPU intensive loop; option to do pointer arithmetic */
#if defined DOFASTMATH
{
REAL *xptr, *yptr;
for (i = 1, xptr = dx + ix, yptr = dy + iy;
i <= n; i++, xptr += incx, yptr += incy) {
dtemp1 = (*xptr);
(*xptr) = (*yptr);
(*yptr) = dtemp1;
}
}
#else
if (incx == incy) {
if (incx <= 0) goto x5;
if (incx == 1) goto x20;
goto x60;
}
/* code for unequal or nonpositive increments. */
x5:
for (i = 1; i<=n; i++) {
dtemp1 = dx[ix];
dx[ix] = dy[iy];
dy[iy] = dtemp1;
ix+= incx;
iy+= incy;
}
return;
/* code for both increments equal to 1.
clean-up loop so remaining vector length is a multiple of 3. */
x20:
m = n % 3;
if (m == 0) goto x40;
for (i = 1; i<=m; i++) {
dtemp1 = dx[i];
dx[i] = dy[i];
dy[i] = dtemp1;
}
if (n < 3) return;
x40:
mp1 = m + 1;
for (i = mp1; i<=n; i=i+3) {
dtemp1 = dx[i];
dtemp2 = dx[i+1];
dtemp3 = dx[i+2];
dx[i] = dy[i];
dx[i+1] = dy[i+1];
dx[i+2] = dy[i+2];
dy[i] = dtemp1;
dy[i+1] = dtemp2;
dy[i+2] = dtemp3;
}
return;
/* code for equal, positive, non-unit increments. */
x60:
ns = n*incx;
for (i = 1; i<=ns; i=i+incx) {
dtemp1 = dx[i];
dx[i] = dy[i];
dy[i] = dtemp1;
}
#endif
}
/* ************************************************************************ */
void dload(int n, REAL da, REAL *dx, int incx)
{
dx++;
BLAS_dload (&n, &da, dx, &incx);
}
void BLAS_CALLMODEL my_dload (int *_n, REAL *_da, REAL *dx, int *_incx)
{
/* copies a scalar, a, to a vector, x.
uses unrolled loops when incx equals one.
To change the precision of this program, run the change
program on dload.f
Alternatively, to make a single precision version append a
comment character to the start of all lines between sequential
precision > double
and
end precision > double
comments and delete the comment character at the start of all
lines between sequential
precision > single
and
end precision > single
comments. To make a double precision version interchange
the append and delete operations in these instructions. */
int i, ix, m, mp1;
REAL da = *_da;
int n = *_n, incx = *_incx;
if (n<=0) return;
dx--;
if (incx==1) goto x20;
/* code for incx not equal to 1 */
ix = 1;
if (incx<0)
ix = (-n+1)*incx + 1;
for (i = 1; i<=n; i++) {
dx[ix] = da;
ix+= incx;
}
return;
/* code for incx equal to 1 and clean-up loop */
x20:
m = n % 7;
if (m == 0) goto x40;
for (i = 1; i<=m; i++)
dx[i] = da;
if (n < 7) return;
x40:
mp1 = m + 1;
for (i = mp1; i<=n; i=i+7) {
dx[i] = da;
dx[i + 1] = da;
dx[i + 2] = da;
dx[i + 3] = da;
dx[i + 4] = da;
dx[i + 5] = da;
dx[i + 6] = da;
}
}
/* ************************************************************************ */
int idamax( int n, REAL *x, int is )
{
x++;
return ( BLAS_idamax( &n, x, &is ) );
}
int idamin( int n, REAL *x, int is )
{
x++;
return ( BLAS_idamin( &n, x, &is ) );
}
int BLAS_CALLMODEL my_idamax( int *_n, REAL *x, int *_is )
{
register REAL xmax, xtest;
int i, imax = 0;
#if !defined DOFASTMATH
int ii;
#endif
int n = *_n, is = *_is;
if((n < 1) || (is <= 0))
return(imax);
imax = 1;
if(n == 1)
return(imax);
#if defined DOFASTMATH
xmax = fabs(*x);
for (i = 2, x += is; i <= n; i++, x += is) {
xtest = fabs(*x);
if(xtest > xmax) {
xmax = xtest;
imax = i;
}
}
#else
x--;
ii = 1;
xmax = fabs(x[ii]);
for(i = 2, ii+ = is; i <= n; i++, ii+ = is) {
xtest = fabs(x[ii]);
if(xtest > xmax) {
xmax = xtest;
imax = i;
}
}
#endif
return(imax);
}
int BLAS_CALLMODEL my_idamin( int *_n, REAL *x, int *_is )
{
register REAL xmin, xtest;
int i, imin = 0;
#if !defined DOFASTMATH
int ii;
#endif
int n = *_n, is = *_is;
if((n < 1) || (is <= 0))
return(imin);
imin = 1;
if(n == 1)
return(imin);
#if defined DOFASTMATH
xmin = fabs(*x);
for (i = 2, x += is; i <= n; i++, x += is) {
xtest = fabs(*x);
if(xtest < xmin) {
xmin = xtest;
imin = i;
}
}
#else
x--;
ii = 1;
xmin = fabs(x[ii]);
for(i = 2, ii+ = is; i <= n; i++, ii+ = is) {
xtest = fabs(x[ii]);
if(xtest < xmin) {
xmin = xtest;
imin = i;
}
}
#endif
return(imin);
}
/* ************************************************************************ */
REAL dnormi( int n, REAL *x )
{
x++;
return( BLAS_dnormi( &n, x ) );
}
REAL BLAS_CALLMODEL my_dnormi( int *_n, REAL *x )
{
/* ===============================================================
dnormi returns the infinity-norm of the vector x.
=============================================================== */
int j;
register REAL hold, absval;
int n = *_n;
x--;
hold = 0.0;
/* for(j = 1; j <= n; j++) */
for(j = n; j > 0; j--) {
absval = fabs(x[j]);
hold = MAX( hold, absval );
}
return( hold );
}
/* ************************************************************************ */
/* Subvector and submatrix access routines (Fortran compatibility) */
/* ************************************************************************ */
#ifndef UseMacroVector
int subvec( int item)
{
return( item-1 );
}
#endif
int submat( int nrowb, int row, int col)
{
return( nrowb*(col-1) + subvec(row) );
}
int posmat( int nrowb, int row, int col)
{
return( submat(nrowb, row, col)+BLAS_BASE );
}
/* ************************************************************************ */
/* Randomization functions */
/* ************************************************************************ */
void randomseed(int seeds[])
/* Simply create some default seed values */
{
seeds[1] = 123456;
seeds[2] = 234567;
seeds[3] = 345678;
}
void randomdens( int n, REAL *x, REAL r1, REAL r2, REAL densty, int *seeds )
{
/* ------------------------------------------------------------------
random generates a vector x[*] of random numbers
in the range (r1, r2) with (approximate) specified density.
seeds[*] must be initialized before the first call.
------------------------------------------------------------------ */
int i;
REAL *y;
y = (REAL *) malloc(sizeof(*y) * (n+1));
ddrand( n, x, 1, seeds );
ddrand( n, y, 1, seeds );
for (i = 1; i<=n; i++) {
if (y[i] < densty)
x[i] = r1 + (r2 - r1) * x[i];
else
x[i] = 0.0;
}
free(y);
}
/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
void ddrand( int n, REAL *x, int incx, int *seeds )
{
/* ------------------------------------------------------------------
ddrand fills a vector x with uniformly distributed random numbers
in the interval (0, 1) using a method due to Wichman and Hill.
seeds[1..3] should be set to integer values
between 1 and 30000 before the first entry.
Integer arithmetic up to 30323 is required.
Blatantly copied from Wichman and Hill 19-January-1987.
14-Feb-94. Original version.
30 Jun 1999. seeds stored in an array.
30 Jun 1999. This version of ddrand.
------------------------------------------------------------------ */
int ix, xix;
if (n < 1) return;
for (ix = 1; ix<=1+(n-1)*incx; ix=ix+incx) {
seeds[1] = 171*(seeds[1] % 177) - 2*(seeds[1]/177);
seeds[2] = 172*(seeds[2] % 176) - 35*(seeds[2]/176);
seeds[3] = 170*(seeds[3] % 178) - 63*(seeds[3]/178);
if (seeds[1] < 0) seeds[1] = seeds[1] + 30269;
if (seeds[2] < 0) seeds[2] = seeds[2] + 30307;
if (seeds[3] < 0) seeds[3] = seeds[3] + 30323;
x[ix] = ((REAL) seeds[1])/30269.0 +
((REAL) seeds[2])/30307.0 +
((REAL) seeds[3])/30323.0;
xix = (int) x[ix];
x[ix] = fabs(x[ix] - xix);
}
}

View File

@ -1,130 +0,0 @@
#ifndef HEADER_myblas
#define HEADER_myblas
/* ************************************************************************ */
/* BLAS function interface with local and external loadable versions */
/* Author: Kjell Eikland */
/* Version: Initial version spring 2004 */
/* Licence: LGPL */
/* ************************************************************************ */
/* Changes: 19 September 2004 Moved function pointer variable */
/* declarations from myblas.h to myblas.c */
/* to avoid linker problems with the Mac. */
/* 20 April 2005 Modified all double types to REAL to self- */
/* adjust to global settings. Note that BLAS */
/* as of now does not have double double. */
/* 15 December 2005 Added idamin() */
/* ************************************************************************ */
#define BLAS_BASE 1
#define UseMacroVector
#define LoadableBlasLib
/* ************************************************************************ */
/* Include necessary libraries */
/* ************************************************************************ */
#include "commonlib.h"
#ifdef LoadableBlasLib
#if (defined WIN32) || (defined WIN64)
#include <windows.h>
#else
#include <dlfcn.h>
#endif
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* ************************************************************************ */
/* BLAS functions */
/* ************************************************************************ */
#ifndef BLAS_CALLMODEL
#if (defined WIN32) || (defined WIN64)
#define BLAS_CALLMODEL _cdecl
#else
#define BLAS_CALLMODEL
#endif
#endif
typedef void (BLAS_CALLMODEL BLAS_dscal_func) (int *n, REAL *da, REAL *dx, int *incx);
typedef void (BLAS_CALLMODEL BLAS_dcopy_func) (int *n, REAL *dx, int *incx, REAL *dy, int *incy);
typedef void (BLAS_CALLMODEL BLAS_daxpy_func) (int *n, REAL *da, REAL *dx, int *incx, REAL *dy, int *incy);
typedef void (BLAS_CALLMODEL BLAS_dswap_func) (int *n, REAL *dx, int *incx, REAL *dy, int *incy);
typedef double (BLAS_CALLMODEL BLAS_ddot_func) (int *n, REAL *dx, int *incx, REAL *dy, int *incy);
typedef int (BLAS_CALLMODEL BLAS_idamax_func)(int *n, REAL *x, int *is);
typedef int (BLAS_CALLMODEL BLAS_idamin_func)(int *n, REAL *x, int *is);
typedef void (BLAS_CALLMODEL BLAS_dload_func) (int *n, REAL *da, REAL *dx, int *incx);
typedef double (BLAS_CALLMODEL BLAS_dnormi_func)(int *n, REAL *x);
#ifndef __WINAPI
#if (defined WIN32) || (defined WIN64)
#define __WINAPI WINAPI
#else
#define __WINAPI
#endif
#endif
void init_BLAS(void);
MYBOOL is_nativeBLAS(void);
MYBOOL load_BLAS(char *libname);
MYBOOL unload_BLAS(void);
/* ************************************************************************ */
/* User-callable BLAS definitions (C base 1) */
/* ************************************************************************ */
void dscal ( int n, REAL da, REAL *dx, int incx );
void dcopy ( int n, REAL *dx, int incx, REAL *dy, int incy );
void daxpy ( int n, REAL da, REAL *dx, int incx, REAL *dy, int incy );
void dswap ( int n, REAL *dx, int incx, REAL *dy, int incy );
REAL ddot ( int n, REAL *dx, int incx, REAL *dy, int incy );
int idamax( int n, REAL *x, int is );
int idamin( int n, REAL *x, int is );
void dload ( int n, REAL da, REAL *dx, int incx );
REAL dnormi( int n, REAL *x );
/* ************************************************************************ */
/* Locally implemented BLAS functions (C base 0) */
/* ************************************************************************ */
void BLAS_CALLMODEL my_dscal ( int *n, REAL *da, REAL *dx, int *incx );
void BLAS_CALLMODEL my_dcopy ( int *n, REAL *dx, int *incx, REAL *dy, int *incy );
void BLAS_CALLMODEL my_daxpy ( int *n, REAL *da, REAL *dx, int *incx, REAL *dy, int *incy );
void BLAS_CALLMODEL my_dswap ( int *n, REAL *dx, int *incx, REAL *dy, int *incy );
REAL BLAS_CALLMODEL my_ddot ( int *n, REAL *dx, int *incx, REAL *dy, int *incy );
int BLAS_CALLMODEL my_idamax( int *n, REAL *x, int *is );
int BLAS_CALLMODEL my_idamin( int *n, REAL *x, int *is );
void BLAS_CALLMODEL my_dload ( int *n, REAL *da, REAL *dx, int *incx );
REAL BLAS_CALLMODEL my_dnormi( int *n, REAL *x );
/* ************************************************************************ */
/* Subvector and submatrix access routines (Fortran compatibility) */
/* ************************************************************************ */
#ifdef UseMacroVector
#define subvec(item) (item - 1)
#else
int subvec( int item );
#endif
int submat( int nrowb, int row, int col );
int posmat( int nrowb, int row, int col );
/* ************************************************************************ */
/* Randomization functions */
/* ************************************************************************ */
void randomseed(int *seeds);
void randomdens( int n, REAL *x, REAL r1, REAL r2, REAL densty, int *seeds);
void ddrand( int n, REAL *x, int incx, int *seeds );
#ifdef __cplusplus
}
#endif
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,952 +0,0 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include "commonlib.h"
#include "myblas.h"
#include "sparselib.h"
sparseMatrix *createMatrix(int dimLimit, int lenLimit, int initVectors)
{
int initsize;
sparseMatrix *matrix;
if(initVectors < 0)
initVectors = 0;
if(initVectors == 0)
initsize = MIN(INITIALSIZE, dimLimit);
else
initsize = MAX(INITIALSIZE, initVectors);
CALLOC(matrix, 1);
matrix->limit = dimLimit;
matrix->limitVector = lenLimit;
resizeMatrix(matrix, initsize);
while(initVectors > 0) {
initVectors--;
appendMatrix(matrix, createVector(lenLimit, 2));
}
return(matrix);
}
void resizeMatrix(sparseMatrix *matrix, int newSize)
{
int oldSize;
if(matrix == NULL)
oldSize = 0;
else
oldSize = matrix->size;
while(oldSize>newSize) {
oldSize--;
freeVector(matrix->list[oldSize]);
return;
}
REALLOC(matrix->list, newSize);
while(oldSize<newSize) {
matrix->list[oldSize] = NULL;
oldSize++;
}
if(newSize>0)
matrix->size = newSize;
}
int appendMatrix(sparseMatrix *matrix, sparseVector *newVector)
{
if(matrix->count == matrix->size)
resizeMatrix(matrix, matrix->size + 10);
matrix->list[matrix->count] = newVector;
matrix->count++;
putDiagonalIndex(newVector, matrix->count);
return(matrix->count);
}
int NZcountMatrix(sparseMatrix *matrix)
{
int i, nz;
nz = 0;
for(i = 0; i < matrix->count; i++)
nz += matrix->list[i]->count;
return( nz );
}
void freeMatrix(sparseMatrix *matrix)
{
resizeMatrix(matrix, 0);
FREE(matrix);
}
void printMatrix(int n, sparseMatrix *matrix, int modulo, MYBOOL showEmpty)
{
int i;
for(i = 1; i<=matrix->count; i++)
if(matrix->list[i-1] != NULL) {
if(showEmpty || matrix->list[i-1]->count>0)
printVector(n, matrix->list[i-1], modulo);
}
}
sparseVector *createVector(int dimLimit, int initSize)
{
sparseVector *newitem;
CALLOC(newitem, 1);
newitem->limit = dimLimit;
initSize = resizeVector(newitem, initSize);
return(newitem);
}
sparseVector *cloneVector(sparseVector *sparse)
{
sparseVector *hold;
hold = createVector(sparse->limit, sparse->count);
hold->count = sparse->count;
MEMCOPY(&hold->value[0], &sparse->value[0], (sparse->count+1));
MEMCOPY(&hold->index[0], &sparse->index[0], (sparse->count+1));
return(hold);
}
int redimensionVector(sparseVector *sparse, int newDim)
{
int olddim, i;
olddim = sparse->limit;
sparse->limit = newDim;
if(lastIndex(sparse)>newDim) {
i = sparse->count;
while(i>0 && sparse->index[i]>newDim) i--;
sparse->count = i;
resizeVector(sparse, sparse->count);
}
return(olddim);
}
int resizeVector(sparseVector *sparse, int newSize)
{
int oldsize;
oldsize = sparse->size;
REALLOC(sparse->value, (newSize+1));
REALLOC(sparse->index, (newSize+1));
sparse->size = newSize;
return(oldsize);
}
void moveVector(sparseVector *sparse, int destPos, int sourcePos, int itemCount)
{
int i;
if(itemCount <= 0 || sourcePos == destPos)
return;
#if defined DOFASTMATH
if(TRUE) {
MEMMOVE(&sparse->value[destPos], &sparse->value[sourcePos], itemCount);
MEMMOVE(&sparse->index[destPos], &sparse->index[sourcePos], itemCount);
}
else {
int *idxPtr1, *idxPtr2;
double *valPtr1, *valPtr2;
for(i = 1, idxPtr1 = sparse->index+destPos, idxPtr2 = sparse->index+sourcePos,
valPtr1 = sparse->value+destPos, valPtr2 = sparse->value+sourcePos;
i<=itemCount; i++, idxPtr1++, idxPtr2++, valPtr1++, valPtr2++) {
*idxPtr1 = *idxPtr2;
*valPtr1 = *valPtr2;
}
}
#else
for(i = 1; i<=itemCount; i++) {
sparse->value[destPos] = sparse->value[sourcePos];
sparse->index[destPos] = sparse->index[sourcePos];
destPos++;
sourcePos++;
}
#endif
}
void rotateVector(sparseVector *sparse, int startPos, int chainSize, int stepDelta)
{
/* int idxHold; */
/* double valHold; */
}
void swapVector(sparseVector *sparse1, sparseVector *sparse2)
{
int n, m, *idx;
REAL *val;
n = sparse1->count;
sparse1->count = sparse2->count;
sparse2->count = n;
n = sparse1->size;
sparse1->size = sparse2->size;
sparse2->size = n;
n = sparse1->limit;
sparse1->limit = sparse2->limit;
sparse2->limit = n;
idx = sparse1->index;
sparse1->index = sparse2->index;
sparse2->index = idx;
val = sparse1->value;
sparse1->value = sparse2->value;
sparse2->value = val;
n = getDiagonalIndex(sparse1);
m = getDiagonalIndex(sparse2);
putDiagonalIndex(sparse1, m);
putDiagonalIndex(sparse2, n);
}
void freeVector(sparseVector *sparse)
{
if(sparse != NULL) {
FREE(sparse->value);
FREE(sparse->index);
FREE(sparse);
}
}
MYBOOL verifyVector(sparseVector *sparse)
{
int i, n, k1, k2, kd;
int err = 0;
double vd;
n = sparse->count;
kd = sparse->index[0];
vd = sparse->value[0];
if(n <= 1)
return(TRUE);
k1 = 0;
k2 = sparse->index[1];
if(k2 == kd && sparse->value[1] != vd)
err = 2;
for(i = 2; i <= n && err == 0; i++) {
k1 = k2;
k2 = sparse->index[i];
if(k1 >= k2) err = 1;
if(k2 == kd && sparse->value[i] != vd) err = 2;
}
if(err == 0)
return(TRUE);
else if(err == 1)
printf("Invalid sparse vector index order");
else if(err == 2)
printf("Invalid sparse vector diagonal value");
return(FALSE);
}
int firstIndex(sparseVector *sparse)
{
return(sparse->index[1]);
}
int lastIndex(sparseVector *sparse)
{
return(sparse->index[sparse->count]);
}
int getDiagonalIndex(sparseVector *sparse)
{
return(sparse->index[0]);
}
int putDiagonalIndex(sparseVector *sparse, int index)
{
int oldindex;
oldindex = sparse->index[0];
if(index > 0) {
sparse->index[0] = 0; /* Must temporarily set to zero to force vector search in getItem */
sparse->value[0] = getItem(sparse, index);
}
else
sparse->value[0] = 0;
sparse->index[0] = index;
return(oldindex);
}
MYBOOL putDiagonal(sparseVector *sparse, REAL value)
{
if(sparse->index[0]>0) {
putItem(sparse, sparse->index[0], value);
return(TRUE);
}
else
return(FALSE);
}
REAL getDiagonal(sparseVector *sparse)
{
return(sparse->value[0]);
}
REAL getItem(sparseVector *sparse, int targetIndex)
{
/* First check if we want the diagonal element */
if(targetIndex == sparse->index[0])
return(sparse->value[0]);
/* If not, search for the variable's position in the index list */
targetIndex = findIndex(targetIndex, sparse->index, sparse->count, BLAS_BASE);
if(targetIndex < 0)
return(0);
else
return(sparse->value[targetIndex]);
}
REAL addtoItem(sparseVector *sparse, int targetIndex, REAL value)
{
int idx;
if(targetIndex > 0)
idx = findIndex(targetIndex, sparse->index, sparse->count, BLAS_BASE);
else {
idx = -targetIndex;
if(idx > sparse->count)
/* Index error; ignore item */
return(0.0);
}
if(idx <=0 )
value = putItem(sparse, targetIndex, value);
else {
value += sparse->value[idx];
putItem(sparse, -idx, value);
}
return(value);
}
REAL putItem(sparseVector *sparse, int targetIndex, REAL value)
{
REAL last = 0.0;
int posIndex;
if(targetIndex < 0) {
posIndex = -targetIndex;
if(posIndex > sparse->count)
return(last);
targetIndex = sparse->index[posIndex];
}
else
posIndex = findIndex(targetIndex, sparse->index, sparse->count, BLAS_BASE);
if(fabs(value) < MACHINEPREC)
value = 0;
if(targetIndex == sparse->index[0])
sparse->value[0] = value;
if(posIndex < 0) {
if(value != 0) {
if(sparse->count == sparse->size)
resizeVector(sparse, sparse->size + RESIZEDELTA);
posIndex = -posIndex;
sparse->count++;
if(posIndex < sparse->count)
moveVector(sparse, posIndex+1, posIndex, sparse->count-posIndex);
sparse->value[posIndex] = value;
sparse->index[posIndex] = targetIndex;
}
}
else {
if(value == 0) {
last = sparse->value[posIndex];
if(sparse->count > posIndex)
moveVector(sparse, posIndex, posIndex+1, sparse->count-posIndex);
sparse->count--;
}
else {
sparse->value[posIndex] = value;
sparse->index[posIndex] = targetIndex;
}
}
#ifdef DEBUG_SPARSELIB
verifyVector(sparse);
#endif
return(last);
}
void swapItems(sparseVector *sparse, int firstIndex, int secondIndex)
{
int i,j,ki,kj;
REAL hold;
if(firstIndex == secondIndex)
return;
if(firstIndex > secondIndex) {
i = firstIndex;
firstIndex = secondIndex;
secondIndex = i;
}
if(FALSE) {
i = 1;
ki = 0;
while(i <= sparse->count && (ki = sparse->index[i])<firstIndex) i++;
j = i;
kj = 0;
while(j <= sparse->count && (kj = sparse->index[j])<secondIndex) j++;
}
else {
i = findIndex(firstIndex, sparse->index, sparse->count, BLAS_BASE);
if(i < 0)
i = -i;
j = findIndex(secondIndex, sparse->index, sparse->count, BLAS_BASE);
if(j < 0)
j = -j;
}
if(i > sparse->count)
ki = 0;
else
ki = sparse->index[i];
if(j > sparse->count)
kj = 0;
else
kj = sparse->index[j];
if(ki == firstIndex && kj == secondIndex) { /* Found both -> swap in place */
hold = sparse->value[i];
sparse->value[i] = sparse->value[j];
sparse->value[j] = hold;
if(sparse->index[0] == firstIndex)
sparse->value[0] = sparse->value[i];
else if(sparse->index[0] == secondIndex)
sparse->value[0] = sparse->value[j];
}
else if(ki == firstIndex) { /* Found first, but not the second -> shift left */
j--;
if(i < j) {
hold = sparse->value[i];
moveVector(sparse, i, i+1, j-i);
sparse->value[j] = hold;
}
sparse->index[j] = secondIndex;
if(sparse->index[0] == firstIndex)
sparse->value[0] = 0;
else if(sparse->index[0] == secondIndex)
sparse->value[0] = sparse->value[j];
}
else if(kj == secondIndex) { /* Found second, but not the first -> shift right */
if(i < j) {
hold = sparse->value[j];
moveVector(sparse, i+1, i, j-i);
sparse->value[i] = hold;
}
sparse->index[i] = firstIndex;
if(sparse->index[0] == firstIndex)
sparse->value[0] = sparse->value[i];
else if(sparse->index[0] == secondIndex)
sparse->value[0] = 0;
}
#ifdef DEBUG_SPARSELIB
verifyVector(sparse);
#endif
}
void clearVector(sparseVector *sparse, int indexStart, int indexEnd)
{
int i;
i = sparse->count;
if(i==0) return;
if(indexStart<=0)
indexStart=sparse->index[1];
if(indexEnd<=0)
indexEnd=sparse->index[i];
if(indexStart>indexEnd) return;
if(sparse->index[0]>=indexStart && sparse->index[0]<=indexEnd) {
sparse->value[0] = 0;
}
if(indexStart<=sparse->index[1] && indexEnd>=sparse->index[i])
sparse->count = 0;
else {
while(i>0 && sparse->index[i]>indexEnd) i--;
indexEnd = i;
while(i>0 && sparse->index[i]>=indexStart) i--;
indexStart = i+1;
if(indexEnd>=indexStart) {
i = sparse->count-indexEnd;
moveVector(sparse, indexStart, indexEnd+1, i);
sparse->count -= indexEnd-indexStart+1;
}
}
#ifdef DEBUG_SPARSELIB
verifyVector(sparse);
#endif
}
int getVector(sparseVector *sparse, REAL *dense, int indexStart, int indexEnd, MYBOOL doClear)
{
int i,k;
i = 1;
while(i<=sparse->count && sparse->index[i]<indexStart) i++;
while(i<=sparse->count && (k=sparse->index[i])<=indexEnd) {
while(indexStart<k) {
dense[indexStart] = 0;
indexStart++;
}
dense[indexStart] = sparse->value[i];
indexStart++;
i++;
}
while(indexStart<=indexEnd) {
dense[indexStart] = 0;
indexStart++;
}
k = sparse->count;
if(doClear) {
sparse->count = 0;
sparse->value[0] = 0;
}
return(k);
}
void putVector(sparseVector *sparse, REAL *dense, int indexStart, int indexEnd)
{
int i,n;
n = sparse->count;
if(indexStart<=0)
indexStart=sparse->index[1];
if(indexEnd<=0)
indexEnd=sparse->index[n];
if(n==0 || sparse->index[n]<indexStart) {
i = sparse->index[0];
if(i>=indexStart && i<=indexEnd)
sparse->value[0] = 0;
for(i = indexStart; i<=indexEnd; i++) {
if(dense[i] == 0) continue;
if(sparse->size == sparse->count)
resizeVector(sparse, sparse->size + RESIZEDELTA);
sparse->count++;
sparse->value[sparse->count] = dense[i];
sparse->index[sparse->count] = i;
if(i == sparse->index[0])
sparse->value[0] = dense[i];
}
}
else {
while(indexStart <= indexEnd) {
putItem(sparse, indexStart, dense[indexStart]);
indexStart++;
}
}
#ifdef DEBUG_SPARSELIB
verifyVector(sparse);
#endif
}
void fillVector(sparseVector *sparse, int count, REAL value)
{
int i;
if(sparse->count > 0)
clearVector(sparse, 0, 0);
for(i = 1; i<=count; i++)
putItem(sparse, i, value);
}
REAL dotVector(sparseVector *sparse, REAL *dense, int indexStart, int indexEnd)
{
int i, n;
long REAL sum;
n = sparse->count;
sum = 0;
if(n > 0) {
if(indexStart<=0)
indexStart=sparse->index[1];
if(indexEnd<=0)
indexEnd=sparse->index[n];
if(indexStart > 1) {
i = findIndex(indexStart, sparse->index, sparse->count, BLAS_BASE);
if(i < 0) {
i = -i;
if(i > n)
return(sum);
}
}
else
i = 1;
/* CPU intensive loop; provide alternative evaluation models */
#if defined DOFASTMATH
{
/* Do fast pointer arithmetic */
int *indexptr;
REAL *valueptr;
/* for(i = 1, indexptr = sparse->index + 1;
i <= n && (*indexptr) < indexStart; i++, indexptr++); */
indexptr = sparse->index + i;
for(valueptr = sparse->value + i;
i <= n && (*indexptr) <= indexEnd; i++, indexptr++, valueptr++)
sum += (*valueptr) * dense[(*indexptr)];
}
#else
{
/* Do traditional indexed access */
int k;
/* i = 1; */
/* while(i<=n && sparse->index[i]<indexStart) i++; */
while(i<=n && (k = sparse->index[i])<=indexEnd) {
sum += sparse->value[i] * dense[k];
i++;
}
}
#endif
}
return(sum);
}
void daxpyVector1(sparseVector *sparse, REAL scalar, REAL *dense, int indexStart, int indexEnd)
{
int i, n;
if(scalar == 0) return;
n = sparse->count;
if(indexStart<=0)
indexStart=sparse->index[1];
if(indexEnd<=0)
indexEnd=sparse->index[n];
/* CPU intensive loop; provide alternative evaluation models */
#if defined DOFASTMATH
{
/* Do fast pointer arithmetic */
int *indexptr;
REAL *valueptr;
for(i = 1, indexptr = sparse->index + 1;
i <= n && (*indexptr) < indexStart; i++, indexptr++);
for(valueptr = sparse->value + i;
i <= n && (*indexptr) <= indexEnd; i++, indexptr++, valueptr++)
dense[(*indexptr)] += (*valueptr) * scalar;
}
#else
{
/* Do traditional indexed access */
int k;
for(i = 1; i<= n; i++) {
k = sparse->index[i];
if(k<indexStart) continue;
if(k>indexEnd) break;
dense[k] += sparse->value[i] * scalar;
}
}
#endif
}
void daxpyVector2(REAL *dense, REAL scalar, sparseVector *sparse, int indexStart, int indexEnd)
{
sparseVector *hold;
hold = createVector(sparse->limit, sparse->count);
putDiagonalIndex(hold, getDiagonalIndex(sparse));
putVector(hold, dense, indexStart, indexEnd);
daxpyVector3(hold, scalar, sparse, indexStart, indexEnd);
freeVector(hold);
}
void daxpyVector3(sparseVector *sparse1, REAL scalar, sparseVector *sparse2, int indexStart, int indexEnd)
{
int i1, i2, k, p1, p2, c1, c2;
sparseVector *hold;
if(sparse1->count == 0) return;
/* Spool to start positions */
i1 = 1;
c1 = sparse1->count;
while(i1 <= c1 && sparse1->index[i1] < indexStart) i1++;
if(i1 <= c1)
p1 = sparse1->index[i1];
else
p1 = indexEnd+1;
i2 = 1;
c2 = sparse2->count;
while(i2 <= c2 && sparse2->index[i2] < indexStart) i2++;
if(i2 <= c2)
p2 = sparse2->index[i2];
else
p2 = indexEnd+1;
/* Create a temporary vector */
k = c1+c2;
if(k > 0) {
hold = createVector(MAX(sparse1->limit, sparse2->limit), k);
putDiagonalIndex(hold, getDiagonalIndex(sparse2));
}
else
hold = sparse2;
/* Loop over all items in both vectors */
while((i1 <= c1 && p1 <= indexEnd) ||
(i2 <= c2 && p2 <= indexEnd)) {
k = 0;
/* Add/spool exclusive right-vector items */
while(i2 <= c2 && p2 < p1) {
if(hold != sparse2)
putItem(hold, p2, sparse2->value[i2]);
i2++;
if(i2 <= c2)
p2 = sparse2->index[i2];
else
p2 = indexEnd+1;
k++;
}
/* Add equal-indexed items */
while(i1 <= c1 && i2 <= c2 && p1 == p2) {
/* if(hold != sparse2) */
putItem(hold, p1, scalar*sparse1->value[i1]+sparse2->value[i2]);
/* else
addtoItem(sparse2, -i2, scalar*sparse1->value[i1]); */
i1++;
if(i1 <= c1)
p1 = sparse1->index[i1];
else
p1 = indexEnd+1;
i2++;
if(i2 <= c2)
p2 = sparse2->index[i2];
else
p2 = indexEnd+1;
k++;
}
/* Add exclusive left-vector items */
while(i1 <= c1 && p1 < p2) {
putItem(hold, p1, scalar*sparse1->value[i1]);
/* if(hold == sparse2) c2++; */
i1++;
if(i1 <= c1)
p1 = sparse1->index[i1];
else
p1 = indexEnd+1;
k++;
}
if(k == 0) break;
}
/* if(hold != sparse2) */
{
swapVector(hold, sparse2);
freeVector(hold);
}
#ifdef DEBUG_SPARSELIB
verifyVector(sparse2);
#endif
}
void dswapVector1(sparseVector *sparse, REAL *dense, int indexStart, int indexEnd)
{
int i, d, n;
REAL *x;
if(indexStart <= 0)
indexStart = 1;
n = lastIndex(sparse);
if(indexEnd <= 0)
indexEnd = n;
CALLOC(x, (MAX(indexEnd,n)+1));
getVector(sparse, x, indexStart, n, FALSE);
d = getDiagonalIndex(sparse);
clearVector(sparse, indexStart, n);
for(i = indexStart; i<=indexEnd; i++) {
if(dense[i] != 0)
putItem(sparse, i, dense[i]);
}
for(i = indexEnd+1; i<=n; i++) {
if(x[i] != 0)
putItem(sparse, i, x[i]);
}
MEMCOPY(&dense[indexStart], &x[indexStart], (indexEnd-indexStart+1));
#ifdef DEBUG_SPARSELIB
verifyVector(sparse);
#endif
FREE(x);
}
void dswapVector2(REAL *dense, sparseVector *sparse, int indexStart, int indexEnd)
{
dswapVector1(sparse, dense, indexStart, indexEnd);
}
void dswapVector3(sparseVector *sparse1, sparseVector *sparse2, int indexStart, int indexEnd)
{
REAL *dense1, *dense2;
if(indexStart<=0)
indexStart = 1;
if(indexEnd<=0)
indexEnd = MAX(lastIndex(sparse1), lastIndex(sparse2));
if(indexStart <= firstIndex(sparse1) && indexStart <= firstIndex(sparse2) &&
indexEnd >= lastIndex(sparse1) && indexEnd >= lastIndex(sparse2)) {
swapVector(sparse1, sparse2);
}
else {
CALLOC(dense1, (indexEnd+1));
CALLOC(dense2, (indexEnd+1));
getVector(sparse1, dense1, indexStart, indexEnd, TRUE);
getVector(sparse2, dense2, indexStart, indexEnd, TRUE);
clearVector(sparse1, indexStart, indexEnd);
clearVector(sparse2, indexStart, indexEnd);
putVector(sparse1, dense2, indexStart, indexEnd);
putVector(sparse2, dense1, indexStart, indexEnd);
FREE(dense1);
FREE(dense2);
}
}
int idamaxVector(sparseVector *sparse, int is, REAL *maxValue)
{
int i, n, imax;
REAL xmax;
n = sparse->count;
imax = 1;
if(n == 0)
xmax = 0;
else {
xmax = fabs(sparse->value[imax]);
/* CPU intensive loop; provide alternative evaluation models */
#if defined DOFASTMATH
{
/* Do fast pointer arithmetic */
int *indexptr;
REAL *valueptr;
for(i = 1, indexptr = sparse->index + 1;
i <= n && (*indexptr) <= is; i++, indexptr++);
for(valueptr = sparse->value + i;
i <= n; i++, indexptr++, valueptr++) {
if((*valueptr)>xmax) {
xmax = (*valueptr);
imax = (*indexptr);
}
}
}
#else
{
REAL xtest;
/* Do traditional indexed access */
i = 1;
while(i <= n && sparse->index[i] <= is) i++;
for(; i<=n; i++) {
xtest = fabs(sparse->value[i]);
if(xtest>xmax) {
xmax = xtest;
imax = sparse->index[i];
}
}
}
#endif
}
if(maxValue != NULL)
(*maxValue) = sparse->index[imax];
return(imax);
}
void printVector(int n, sparseVector *sparse, int modulo )
{
int i,j,k;
if(sparse == NULL) return;
if (modulo <= 0) modulo = 5;
for (i = 1, j = 1; j<=n; i++, j++) {
if(i<=sparse->count)
k = sparse->index[i];
else
k = n+1;
while (j < k) {
if(mod(j, modulo) == 1)
printf("\n%2d:%12g", j, 0.0);
else
printf(" %2d:%12g", j, 0.0);
j++;
}
if(k<=n) {
if(mod(j, modulo) == 1)
printf("\n%2d:%12g", k, sparse->value[i]);
else
printf(" %2d:%12g", k, sparse->value[i]);
}
}
if(mod(j, modulo) != 0) printf("\n");
}

View File

@ -1,84 +0,0 @@
#include "commonlib.h"
/*#define DEBUG_SPARSELIB*/
#define INITIALSIZE 10
#define RESIZEDELTA 4
#ifndef SPARSELIB
#define SPARSELIB
typedef struct _sparseVector {
int limit;
int size;
int count;
int *index;
REAL *value;
} sparseVector;
typedef struct _sparseMatrix {
int limit;
int size;
int count;
int limitVector;
sparseVector **list;
} sparseMatrix;
#endif
#ifdef __cplusplus
extern "C" {
#endif
sparseMatrix *createMatrix(int dimLimit, int lenLimit, int initVectors);
void resizeMatrix(sparseMatrix *matrix, int newSize);
int appendMatrix(sparseMatrix *matrix, sparseVector *newVector);
int NZcountMatrix(sparseMatrix *matrix);
void freeMatrix(sparseMatrix *matrix);
void printMatrix(int n, sparseMatrix *matrix, int modulo, MYBOOL showEmpty);
sparseVector *createVector(int dimLimit, int initSize);
sparseVector *cloneVector(sparseVector *sparse);
int redimensionVector(sparseVector *sparse, int newDim);
int resizeVector(sparseVector *sparse, int newSize);
void moveVector(sparseVector *sparse, int destPos, int sourcePos, int itemCount);
void rotateVector(sparseVector *sparse, int startPos, int chainSize, int stepDelta);
void swapVector(sparseVector *sparse1, sparseVector *sparse2);
void freeVector(sparseVector *sparse);
void printVector(int n, sparseVector *sparse, int modulo);
MYBOOL verifyVector(sparseVector *sparse);
int firstIndex(sparseVector *sparse);
int lastIndex(sparseVector *sparse);
int getDiagonalIndex(sparseVector *sparse);
int putDiagonalIndex(sparseVector *sparse, int index);
MYBOOL putDiagonal(sparseVector *sparse, REAL value);
REAL getDiagonal(sparseVector *sparse);
REAL getItem(sparseVector *sparse, int targetIndex);
REAL putItem(sparseVector *sparse, int targetIndex, REAL value);
REAL addtoItem(sparseVector *sparse, int targetIndex, REAL value);
void swapItems(sparseVector *sparse, int firstIndex, int secondIndex);
void clearVector(sparseVector *sparse, int indexStart, int indexEnd);
int getVector(sparseVector *sparse, REAL *dense, int indexStart, int indexEnd, MYBOOL doClear);
void putVector(sparseVector *sparse, REAL *dense, int indexStart, int indexEnd);
void fillVector(sparseVector *sparse, int count, REAL value);
REAL dotVector(sparseVector *sparse, REAL *dense, int indexStart, int indexEnd);
void daxpyVector1(sparseVector *sparse, REAL scalar, REAL *dense, int indexStart, int indexEnd);
void daxpyVector2(REAL *dense, REAL scalar, sparseVector *sparse, int indexStart, int indexEnd);
void daxpyVector3(sparseVector *sparse1, REAL scalar, sparseVector *sparse2, int indexStart, int indexEnd);
void dswapVector1(sparseVector *sparse, REAL *dense, int indexStart, int indexEnd);
void dswapVector2(REAL *dense, sparseVector *sparse, int indexStart, int indexEnd);
void dswapVector3(sparseVector *sparse1, sparseVector *sparse2, int indexStart, int indexEnd);
int idamaxVector(sparseVector *sparse, int is, REAL *maxValue);
#ifdef __cplusplus
}
#endif

View File

@ -1,27 +0,0 @@
#include "bfp_LUSOL.h"
#include "lp_lib.h"
#include "lp_LUSOL.h"
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
#if defined FORTIFY
int EndOfPgr(int i)
{
exit(i);
}
#endif

View File

@ -1,15 +0,0 @@
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
//#pragma once
//RoleIsExternalInvEngine;INVERSE_ACTIVE=INVERSE_LUSOL
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
// Windows Header Files:
#include <windows.h>
// TODO: reference additional headers your program requires here

View File

@ -1,735 +0,0 @@
/* Modularized simplex basis factorization module - w/interface for lp_solve v5.0+
----------------------------------------------------------------------------------
Author: Kjell Eikland
Contact: kjell.eikland@broadpark.no
License terms: LGPL.
Requires: lusol.h, lp_lib.h, myblas.h
Release notes:
v2.0.0 1 March 2004 First implementation of the LUSOL v2.0 C translation.
v2.0.1 1 April 2004 Added singularity recovery and fast/reuse update logic.
v2.0.2 23 May 2004 Moved mustrefact() function into the BFP structure.
v2.0.3 5 September 2004 Reworked pivot threshold tightening logic and default
values.
v2.1.0 18 June 2005 Made changes to allow for "pure" factorization;
i.e. without the objective function included.
---------------------------------------------------------------------------------- */
/* Generic include libraries */
#include <stdlib.h>
#include <string.h>
#include "lp_lib.h"
/* Include libraries for this factorization system */
#include "myblas.h"
#include "commonlib.h"
#include "lp_LUSOL.h"
#include "lusol.h"
#ifdef FORTIFY
# include "lp_fortify.h"
#endif
/* Include routines common to factorization engine implementations */
#include "lp_BFP1.c"
#include "lp_BFP2.c"
/* MUST MODIFY */
char * BFP_CALLMODEL bfp_name(void)
{
return( "LUSOL v2.2.1.0" );
}
/* MUST MODIFY */
MYBOOL BFP_CALLMODEL bfp_resize(lprec *lp, int newsize)
{
INVrec *lu;
lu = lp->invB;
/* Increment dimensionality since we put the objective row at the top */
newsize = newsize + bfp_rowoffset(lp);
lu->dimalloc = newsize;
/* Allocate index tracker arrays, LU matrices and various work vectors */
if(!allocREAL(lp, &(lu->value), newsize+MATINDEXBASE, AUTOMATIC))
return( FALSE );
/* Data specific to the factorization engine */
if(lu->LUSOL != NULL) {
if(newsize > 0)
LUSOL_sizeto(lu->LUSOL, newsize, newsize, 0);
else {
LUSOL_free(lu->LUSOL);
lu->LUSOL = NULL;
}
}
else if(newsize > 0) {
int asize;
REAL bsize;
lu->LUSOL = LUSOL_create(NULL, 0, LUSOL_PIVMOD_TPP, bfp_pivotmax(lp)*0);
#if 1
lu->LUSOL->luparm[LUSOL_IP_ACCELERATION] = LUSOL_AUTOORDER;
lu->LUSOL->parmlu[LUSOL_RP_SMARTRATIO] = 0.50;
#endif
#if 0
lu->timed_refact = DEF_TIMEDREFACT;
#else
lu->timed_refact = FALSE;
#endif
/* The following adjustments seem necessary to make the really tough NETLIB
models perform reliably and still performant (e.g. cycle.mps) */
#if 0
lu->LUSOL->parmlu[LUSOL_RP_SMALLDIAG_U] =
lu->LUSOL->parmlu[LUSOL_RP_EPSDIAG_U] = lp->epsprimal;
#endif
#if 0
lu->LUSOL->parmlu[LUSOL_RP_ZEROTOLERANCE] = lp->epsvalue;
#endif
#if 1
LUSOL_setpivotmodel(lu->LUSOL, LUSOL_PIVMOD_NOCHANGE, LUSOL_PIVTOL_SLIM);
#else
LUSOL_setpivotmodel(lu->LUSOL, LUSOL_PIVMOD_NOCHANGE, LUSOL_PIVTOL_TIGHT);
#endif
#ifdef LUSOL_UseBLAS
/* if(fileSearchPath("PATH", "myBLAS.DLL", NULL) && load_BLAS("myBLAS")) */
if(is_nativeBLAS() && load_BLAS(libnameBLAS))
lp->report(lp, NORMAL, "Optimized BLAS was successfully loaded for bfp_LUSOL.\n");
#endif
/* Try to minimize memory allocation if we have a large number of unit columns */
bsize = (REAL) lp->get_nonzeros(lp);
if(newsize > lp->columns)
bsize += newsize;
else
bsize = bsize/lp->columns*newsize;
/* Add a "reasonable" delta to allow for B and associated factorizations
that are denser than average; this makes reallocations less frequent.
Values between 1.2 and 1.5 appear to be reasonable. */
asize = (int) (bsize*MAX_DELTAFILLIN*1.3333);
if(!LUSOL_sizeto(lu->LUSOL, newsize, newsize, asize))
return( FALSE );
}
lu->dimcount = newsize;
return( TRUE );
}
/* MUST MODIFY */
void BFP_CALLMODEL bfp_free(lprec *lp)
{
INVrec *lu;
lu = lp->invB;
if(lu == NULL)
return;
/* General arrays */
FREE(lu->opts);
FREE(lu->value);
/* Data specific to the factorization engine */
LUSOL_free(lu->LUSOL);
FREE(lu);
lp->invB = NULL;
}
/* MUST MODIFY */
int BFP_CALLMODEL bfp_nonzeros(lprec *lp, MYBOOL maximum)
{
INVrec *lu;
lu = lp->invB;
if(maximum == TRUE)
return(lu->max_LUsize);
else if(maximum == AUTOMATIC)
return(lu->max_Bsize);
else
return(lu->LUSOL->luparm[LUSOL_IP_NONZEROS_L0]+lu->LUSOL->luparm[LUSOL_IP_NONZEROS_U0]);
/* return(lu->LUSOL->luparm[LUSOL_IP_NONZEROS_ROW]); */
}
/* MUST MODIFY (or ignore) */
int BFP_CALLMODEL bfp_memallocated(lprec *lp)
{
int mem;
LUSOLrec *LUSOL = lp->invB->LUSOL;
mem = sizeof(REAL) * (LUSOL->lena+LUSOL->maxm+LUSOL_RP_LASTITEM);
mem += sizeof(int) * (2*LUSOL->lena+5*LUSOL->maxm+5*LUSOL->maxn+LUSOL_IP_LASTITEM);
if(LUSOL->luparm[LUSOL_IP_PIVOTTYPE] == LUSOL_PIVMOD_TCP)
mem += sizeof(REAL) * LUSOL->maxn + 2*sizeof(REAL)*LUSOL->maxn;
else if(LUSOL->luparm[LUSOL_IP_PIVOTTYPE] == LUSOL_PIVMOD_TRP)
mem += sizeof(REAL) * LUSOL->maxn;
if(!LUSOL->luparm[LUSOL_IP_KEEPLU])
mem += sizeof(REAL) * LUSOL->maxn;
return( mem );
}
/* MUST MODIFY */
int BFP_CALLMODEL bfp_preparefactorization(lprec *lp)
{
INVrec *lu = lp->invB;
/* Finish any outstanding business */
if(lu->is_dirty == AUTOMATIC)
lp->bfp_finishfactorization(lp);
/* Clear or resize the existing LU matrices - specific for the factorization engine */
LUSOL_clear(lu->LUSOL, TRUE);
if(lu->dimcount != lp->rows + bfp_rowoffset(lp))
lp->bfp_resize(lp, lp->rows);
/* Reset additional indicators */
lp->bfp_updaterefactstats(lp);
lu->col_pos = 0;
return(0);
}
/* LOCAL HELPER ROUTINE - Replace a basis column with corresponding slack */
int bfp_LUSOLsetcolumn(lprec *lp, int posnr, int colnr)
{
int nz, inform;
nz = lp->get_lpcolumn(lp, colnr, lp->invB->LUSOL->w + bfp_rowoffset(lp), NULL, NULL);
inform = LUSOL_replaceColumn(lp->invB->LUSOL, posnr, lp->invB->LUSOL->w);
return( inform );
}
/* LOCAL HELPER ROUTINE - force the basis to be the identity matrix */
int bfp_LUSOLidentity(lprec *lp, int *rownum)
{
int i, nz;
INVrec *invB = lp->invB;
/* Reset the factorization engine */
LUSOL_clear(invB->LUSOL, TRUE);
/* Add the basis columns */
lp->invB->set_Bidentity = TRUE;
for(i = 1; i <= invB->dimcount; i++) {
nz = lp->get_basiscolumn(lp, i, rownum, invB->value);
LUSOL_loadColumn(invB->LUSOL, rownum, i, invB->value, nz, 0);
}
lp->invB->set_Bidentity = FALSE;
/* Factorize */
i = LUSOL_factorize(invB->LUSOL);
return( i );
}
/* LOCAL HELPER ROUTINE */
int bfp_LUSOLfactorize(lprec *lp, MYBOOL *usedpos, int *rownum, int *singular)
{
int i, j, nz, deltarows = bfp_rowoffset(lp);
INVrec *invB = lp->invB;
/* Handle normal, presumed nonsingular case */
if(singular == NULL) {
/* Optionally do a symbolic minimum degree ordering;
not that slack variables should not be processed */
/*#define UsePreprocessMDO*/
#ifdef UsePreprocessMDO
int *mdo;
mdo = lp->bfp_createMDO(lp, usedpos, lp->rows, TRUE);
if(mdo != NULL) {
for(i = 1; i <= lp->rows; i++)
lp->set_basisvar(lp, i, mdo[i]);
FREE(mdo);
}
#endif
/* Reset the factorization engine */
LUSOL_clear(invB->LUSOL, TRUE);
/* Add the basis columns in the original order */
for(i = 1; i <= invB->dimcount; i++) {
nz = lp->get_basiscolumn(lp, i, rownum, invB->value);
LUSOL_loadColumn(invB->LUSOL, rownum, i, invB->value, nz, 0);
if((i > deltarows) && (lp->var_basic[i-deltarows] > lp->rows))
lp->invB->user_colcount++;
}
/* Factorize */
i = LUSOL_factorize(invB->LUSOL);
}
/* Handle case where a column may be singular */
else {
LLrec *map;
/* Reset the factorization engine */
i = bfp_LUSOLidentity(lp, rownum);
/* Build map of available columns */
nz = createLink(lp->rows, &map, NULL);
for(i = 1; i <= lp->rows; i++) {
if(lp->var_basic[i] <= lp->rows)
removeLink(map, i);
}
/* Rebuild the basis, column by column, while skipping slack columns */
j = firstActiveLink(map);
for(i = 1; i <= lp->rows; i++) {
if(lp->var_basic[i] <= lp->rows)
continue;
nz = bfp_LUSOLsetcolumn(lp, j+deltarows, lp->var_basic[i]);
if(nz == LUSOL_INFORM_LUSUCCESS)
lp->invB->user_colcount++;
else {
nz = bfp_LUSOLsetcolumn(lp, j+deltarows, i);
lp->set_basisvar(lp, i, i);
}
j = nextActiveLink(map, j);
}
/* Sort the basis list */
MEMCOPY(rownum, lp->var_basic, lp->rows+1);
sortByINT(lp->var_basic, rownum, lp->rows, 1, TRUE);
}
return( i );
}
/* LOCAL HELPER ROUTINE */
void bfp_LUSOLtighten(lprec *lp)
{
int infolevel = DETAILED;
switch(LUSOL_tightenpivot(lp->invB->LUSOL)) {
case FALSE: lp->report(lp, infolevel, "bfp_factorize: Very hard numerics, but cannot tighten LUSOL thresholds further.\n");
break;
case TRUE: lp->report(lp, infolevel, "bfp_factorize: Frequent refact pivot count %d at iter %.0f; tightened thresholds.\n",
lp->invB->num_pivots, (REAL) lp->get_total_iter(lp));
break;
default: lp->report(lp, infolevel, "bfp_factorize: LUSOL switched to %s pivoting model to enhance stability.\n",
LUSOL_pivotLabel(lp->invB->LUSOL));
}
}
#define is_fixedvar is_fixedvar_ /* resolves a compiler warning/error conflict with lp_lib.h */
static MYBOOL is_fixedvar(lprec *lp, int variable)
{
if((lp->bb_bounds != NULL && lp->bb_bounds->UBzerobased) || (variable <= lp->rows))
return( (MYBOOL) (lp->upbo[variable] < lp->epsprimal) );
else
return( (MYBOOL) (lp->upbo[variable]-lp->lowbo[variable] < lp->epsprimal) );
} /* is_fixedvar */
/* MUST MODIFY */
int BFP_CALLMODEL bfp_factorize(lprec *lp, int uservars, int Bsize, MYBOOL *usedpos, MYBOOL final)
{
int kcol, inform,
*rownum = NULL,
singularities = 0,
dimsize = lp->invB->dimcount;
LUSOLrec *LUSOL = lp->invB->LUSOL;
/* Set dimensions and create work array */
SETMAX(lp->invB->max_Bsize, Bsize+(1+lp->rows-uservars));
kcol = lp->invB->dimcount;
LUSOL->m = kcol;
LUSOL->n = kcol;
allocINT(lp, &rownum, kcol+1, FALSE);
/* Check if the refactorization frequency is low;
tighten pivot thresholds if appropriate */
inform = lp->bfp_pivotcount(lp);
if(!final && /* No solution update-based refactorization */
!lp->invB->force_refact && /* No sparsity-based refactorization */
!lp->is_action(lp->spx_action,
ACTION_TIMEDREINVERT) && /* No optimal time-based refactorization */
(inform > 5) && (inform < 0.25*lp->bfp_pivotmax(lp)))
bfp_LUSOLtighten(lp);
/* Reload B and factorize */
inform = bfp_LUSOLfactorize(lp, usedpos, rownum, NULL);
/* Do some checks */
#ifdef Paranoia
if(uservars != lp->invB->user_colcount) {
lp->report(lp, SEVERE, "bfp_factorize: User variable count reconciliation failed\n");
return( singularities );
}
#endif
/* Check result and do further remedial action if necessary */
if(inform != LUSOL_INFORM_LUSUCCESS) {
int singularcols,
replacedcols = 0;
REAL hold;
/* Make sure we do not tighten factorization pivot criteria too often, and simply
accept the substitution of slack columns into the basis */
if((lp->invB->num_singular+1) % TIGHTENAFTER == 0)
bfp_LUSOLtighten(lp);
/* Try to restore a non-singular basis by substituting singular columns with slacks */
while((inform == LUSOL_INFORM_LUSINGULAR) && (replacedcols < dimsize)) {
int iLeave, jLeave, iEnter;
MYBOOL isfixed;
singularities++;
singularcols = LUSOL->luparm[LUSOL_IP_SINGULARITIES];
hold = (REAL) lp->get_total_iter(lp);
lp->report(lp, NORMAL, "bfp_factorize: Resolving %d singularit%s at refact %d, iter %.0f\n",
singularcols, my_plural_y(singularcols), lp->invB->num_refact, hold);
/* Find the failing / singular column(s) and make slack substitutions */
for(kcol = 1; kcol <= singularcols; kcol++) {
/* Determine leaving and entering columns. */
iLeave = LUSOL_getSingularity(LUSOL, kcol); /* This is the singular column as natural index */
iEnter = iLeave; /* This is the target replacement slack */
#if 1
iEnter = LUSOL->iqinv[iEnter];
iEnter = LUSOL->ip[iEnter];
#endif
iLeave-= bfp_rowextra(lp); /* This is the original B column/basis index */
jLeave = lp->var_basic[iLeave]; /* This is the IA column index in lp_solve */
/* Express the slack index in original lp_solve [1..rows] reference and check validity */
/* if(B4 != NULL) iEnter = B4->B4_row[iEnter]; v6 FUNCTIONALITY */
iEnter -= bfp_rowextra(lp);
if(lp->is_basic[iEnter]) {
lp->report(lp, DETAILED, "bfp_factorize: Replacement slack %d is already basic!\n", iEnter);
/* See if we can find a good alternative slack variable to enter */
iEnter = 0;
for(inform = 1; inform <= lp->rows; inform++)
if(!lp->is_basic[inform]) {
if((iEnter == 0) || (lp->upbo[inform] > lp->upbo[iEnter])) {
iEnter = inform;
if(my_infinite(lp, lp->upbo[iEnter]))
break;
}
}
if(iEnter == 0) {
lp->report(lp, SEVERE, "bfp_factorize: Could not find replacement slack variable!\n");
break;
}
}
/* We should update bound states for both the entering and leaving variables.
Note that this may cause (primal or dual) infeasibility, but I assume that
lp_solve traps this and takes necessary corrective action. */
isfixed = is_fixedvar(lp, iEnter);
if(isfixed)
lp->fixedvars++;
hold = lp->upbo[jLeave];
lp->is_lower[jLeave] = isfixed || (fabs(hold)>=lp->infinite) || (lp->rhs[iLeave] < hold);
lp->is_lower[iEnter] = TRUE;
/* Do the basis replacement */
lp->set_basisvar(lp, iLeave, iEnter);
}
/* Refactorize with slack substitutions */
inform = bfp_LUSOLfactorize(lp, NULL, rownum, NULL);
replacedcols += singularcols;
}
/* Check if we had a fundamental problem */
if(singularities >= dimsize) {
lp->report(lp, IMPORTANT, "bfp_factorize: LUSOL was unable to recover from a singular basis\n");
lp->spx_status = NUMFAILURE;
}
}
/* Clean up before returning */
FREE(rownum);
/* Update statistics */
/* SETMAX(lp->invB->max_Bsize, (*Bsize)); */
lp->invB->num_singular += singularities; /* The total number of singular updates */
return( singularities );
}
/* MUST MODIFY */
MYBOOL BFP_CALLMODEL bfp_finishupdate(lprec *lp, MYBOOL changesign)
/* Was addetacol() in versions of lp_solve before 4.0.1.8 - KE */
{
int i, k, kcol, deltarows = bfp_rowoffset(lp);
REAL DIAG, VNORM;
INVrec *lu = lp->invB;
LUSOLrec *LUSOL = lu->LUSOL;
if(!lu->is_dirty)
return( FALSE );
if(lu->is_dirty != AUTOMATIC)
lu->is_dirty = FALSE;
/* Perform the update */
k = lu->col_pos+deltarows;
lu->num_pivots++;
if(lu->col_leave > lu->dimcount-deltarows)
lu->user_colcount--;
if(lu->col_enter > lu->dimcount-deltarows)
lu->user_colcount++;
kcol = lu->col_pos;
lu->col_pos = 0;
/* Do standard update */
#ifdef LUSOLSafeFastUpdate /* NB! Defined in lusol.h */
if(TRUE || !changesign) {
if(changesign) {
REAL *temp = LUSOL->vLU6L;
for(i = 1, temp++; i <= lp->rows+deltarows; i++, temp++)
if(*temp != 0)
*temp = -(*temp);
}
/* Execute the update using data prepared earlier */
LU8RPC(LUSOL, LUSOL_UPDATE_OLDNONEMPTY, LUSOL_UPDATE_USEPREPARED,
k, NULL, NULL, &i, &DIAG, &VNORM);
}
else
#endif
{
/* Retrieve the data for the entering column (base 0) */
i = lp->get_lpcolumn(lp, lu->col_enter, lu->value+deltarows, NULL, NULL);
lu->value[0] = 0;
/* Execute the update */
LU8RPC(LUSOL, LUSOL_UPDATE_OLDNONEMPTY, LUSOL_UPDATE_NEWNONEMPTY,
k, lu->value, NULL, &i, &DIAG, &VNORM);
}
if(i == LUSOL_INFORM_LUSUCCESS) {
/* Check if we should refactorize based on accumulation of fill-in */
DIAG = LUSOL->luparm[LUSOL_IP_NONZEROS_L]+LUSOL->luparm[LUSOL_IP_NONZEROS_U];
VNORM = LUSOL->luparm[LUSOL_IP_NONZEROS_L0]+LUSOL->luparm[LUSOL_IP_NONZEROS_U0];
#if 0
/* This is Michael Saunder's fixed parameter */
VNORM *= MAX_DELTAFILLIN;
#else
/* This is Kjell Eikland's dynamic error accumulation measure */
VNORM *= pow(MAX_DELTAFILLIN, pow((0.5*LUSOL->nelem/VNORM), 0.25));
#endif
lu->force_refact = (MYBOOL) ((DIAG > VNORM) && (lu->num_pivots > 20));
#if 0
/* Additional KE logic to reduce maximum pivot count based on the density of B */
if(!lu->force_refact) {
VNORM = lp->rows+1;
VNORM = 1.0 - pow((REAL) LUSOL->nelem/VNORM/VNORM, 0.2);
lu->force_refact = (MYBOOL) (lu->num_pivots > VNORM*lp->bfp_pivotmax(lp));
}
#endif
}
/* Handle errors */
else {
/* int infolevel = NORMAL; */
int infolevel = DETAILED;
lp->report(lp, infolevel, "bfp_finishupdate: Failed at iter %.0f, pivot %d;\n%s\n",
(REAL) (lp->total_iter+lp->current_iter), lu->num_pivots, LUSOL_informstr(LUSOL, i));
if(i == LUSOL_INFORM_ANEEDMEM) { /* To compress used memory and realloc, if necessary */
lp->invert(lp, INITSOL_USEZERO, FALSE);
if(i != LUSOL_INFORM_LUSUCCESS)
lp->report(lp, NORMAL, "bfp_finishupdate: Insufficient memory at iter %.0f;\n%s\n",
(REAL) (lp->total_iter+lp->current_iter), LUSOL_informstr(LUSOL, i));
}
else if(i == LUSOL_INFORM_RANKLOSS) { /* To fix rank loss and clear cumulative errors */
#if 0
/* This is test code to do pivot in slack BEFORE refactorization (pessimistic approach);
assumes that LUSOL returns correct information about the source of the singularity */
kcol = LUSOL->luparm[LUSOL_IP_SINGULARINDEX];
#ifdef MAPSINGULARCOLUMN
kcol = LUSOL_findColumnPosition(LUSOL, kcol);
#endif
lp->set_basisvar(lp, kcol-deltarows, kcol-deltarows);
#endif
lp->invert(lp, INITSOL_USEZERO, FALSE);
i = LUSOL->luparm[LUSOL_IP_INFORM];
if(i != LUSOL_INFORM_LUSUCCESS)
lp->report(lp, NORMAL, "bfp_finishupdate: Recovery attempt unsuccessful at iter %.0f;\n%s\n",
(REAL) (lp->total_iter+lp->current_iter), LUSOL_informstr(LUSOL, i));
else
lp->report(lp, infolevel, "bfp_finishupdate: Correction or recovery was successful.\n");
}
}
return( (MYBOOL) (i == LUSOL_INFORM_LUSUCCESS) );
} /* bfp_finishupdate */
/* MUST MODIFY */
void BFP_CALLMODEL bfp_ftran_normal(lprec *lp, REAL *pcol, int *nzidx)
{
int i;
INVrec *lu;
lu = lp->invB;
/* Do the LUSOL ftran */
i = LUSOL_ftran(lu->LUSOL, pcol-bfp_rowoffset(lp), nzidx, FALSE);
if(i != LUSOL_INFORM_LUSUCCESS) {
lu->status = BFP_STATUS_ERROR;
lp->report(lp, NORMAL, "bfp_ftran_normal: Failed at iter %.0f, pivot %d;\n%s\n",
(REAL) (lp->total_iter+lp->current_iter), lu->num_pivots, LUSOL_informstr(lu->LUSOL, i));
}
}
/* MAY MODIFY */
void BFP_CALLMODEL bfp_ftran_prepare(lprec *lp, REAL *pcol, int *nzidx)
{
int i;
INVrec *lu;
lu = lp->invB;
/* Do the LUSOL ftran */
i = LUSOL_ftran(lu->LUSOL, pcol-bfp_rowoffset(lp), nzidx, TRUE);
if(i != LUSOL_INFORM_LUSUCCESS) {
lu->status = BFP_STATUS_ERROR;
lp->report(lp, NORMAL, "bfp_ftran_prepare: Failed at iter %.0f, pivot %d;\n%s\n",
(REAL) (lp->total_iter+lp->current_iter), lu->num_pivots, LUSOL_informstr(lu->LUSOL, i));
}
}
/* MUST MODIFY */
void BFP_CALLMODEL bfp_btran_normal(lprec *lp, REAL *prow, int *nzidx)
{
int i;
INVrec *lu;
lu = lp->invB;
/* Do the LUSOL btran */
i = LUSOL_btran(lu->LUSOL, prow-bfp_rowoffset(lp), nzidx);
if(i != LUSOL_INFORM_LUSUCCESS) {
lu->status = BFP_STATUS_ERROR;
lp->report(lp, NORMAL, "bfp_btran_normal: Failed at iter %.0f, pivot %d;\n%s\n",
(REAL) (lp->total_iter+lp->current_iter), lu->num_pivots, LUSOL_informstr(lu->LUSOL, i));
}
/* Check performance data */
#if 0
if(lu->num_pivots == 1) {
if(lu->LUSOL->luparm[LUSOL_IP_ACCELERATION] > 0)
lp->report(lp, NORMAL, "RowL0 R:%10.7f C:%10.7f NZ:%10.7f\n",
(REAL) lu->LUSOL->luparm[LUSOL_IP_ROWCOUNT_L0] / lu->LUSOL->m,
(REAL) lu->LUSOL->luparm[LUSOL_IP_COLCOUNT_L0] / lu->LUSOL->m,
(REAL) lu->LUSOL->luparm[LUSOL_IP_NONZEROS_L0] / pow((REAL) lu->LUSOL->m, 2));
else
lp->report(lp, NORMAL, "ColL0 C:%10.7f NZ:%10.7f\n",
(REAL) lu->LUSOL->luparm[LUSOL_IP_COLCOUNT_L0] / lu->LUSOL->m,
(REAL) lu->LUSOL->luparm[LUSOL_IP_NONZEROS_L0] / pow((REAL) lu->LUSOL->m, 2));
}
#endif
}
/* MUST MODIFY - Routine to find maximum rank of equality constraints */
int BFP_CALLMODEL bfp_findredundant(lprec *lp, int items, getcolumnex_func cb, int *maprow, int *mapcol)
{
int i, j, nz = 0, m = 0, n = 0, *nzrows = NULL;
REAL *nzvalues = NULL, *arraymax = NULL;
LUSOLrec *LUSOL;
/* Are we capable of finding redundancy with this BFP? */
if((maprow == NULL) && (mapcol == NULL))
return( n );
/* If so, initialize memory structures */
if(!allocINT(lp, &nzrows, items, FALSE) ||
!allocREAL(lp, &nzvalues, items, FALSE))
return( n );
/* Compute the number of non-empty columns */
m = 0;
for(j = 1; j <= mapcol[0]; j++) {
n = cb(lp, mapcol[j], NULL, NULL, maprow);
if(n > 0) {
m++;
mapcol[m] = mapcol[j];
nz += n;
}
}
mapcol[0] = m;
/* Instantiate a LUSOL object */
LUSOL = LUSOL_create(NULL, 0, LUSOL_PIVMOD_TRP, 0);
if((LUSOL == NULL) || !LUSOL_sizeto(LUSOL, items, m, nz*LUSOL_MULT_nz_a))
goto Finish;
/* Modify relevant LUSOL parameters */
LUSOL->m = items;
LUSOL->n = m;
#if 0
LUSOL->luparm[LUSOL_IP_KEEPLU] = FALSE;
LUSOL->luparm[LUSOL_IP_PIVOTTYPE] = LUSOL_PIVMOD_TRP;
LUSOL->parmlu[LUSOL_RP_FACTORMAX_Lij] = 2.0;
#endif
/* Load the columns into LUSOL */
for(j = 1; j <= m; j++) {
n = cb(lp, mapcol[j], nzvalues, nzrows, maprow);
i = LUSOL_loadColumn(LUSOL, nzrows, j, nzvalues, n, -1);
if(n != i) {
lp->report(lp, IMPORTANT, "bfp_findredundant: Error %d while loading column %d with %d nz\n",
i, j, n);
n = 0;
goto Finish;
}
}
/* Scale rows to prevent numerical problems */
if((lp->scalemode != SCALE_NONE) && allocREAL(lp, &arraymax, items+1, TRUE)) {
for(i = 1; i <= nz; i++) {
SETMAX(arraymax[LUSOL->indc[i]], fabs(LUSOL->a[i]));
}
for(i = 1; i <= nz; i++)
LUSOL->a[i] /= arraymax[LUSOL->indc[i]];
FREE(arraymax);
}
/* Factorize for maximum rank */
n = 0;
i = LUSOL_factorize(LUSOL);
/* lp->report(lp, NORMAL, "bfp_findredundant: r=%d c=%d - %s\n", items, m, LUSOL_informstr(LUSOL, i));*/
if((i == LUSOL_INFORM_LUSUCCESS) || (i != LUSOL_INFORM_LUSINGULAR))
goto Finish;
/* We have a singular matrix, obtain the indeces of the singular rows */
for(i = LUSOL->luparm[LUSOL_IP_RANK_U] + 1; i <= items; i++) {
n++;
maprow[n] = LUSOL->ip[i];
}
maprow[0] = n;
/* Clean up */
Finish:
LUSOL_free(LUSOL);
FREE(nzrows);
FREE(nzvalues);
return( n );
}

View File

@ -1,63 +0,0 @@
#ifndef HEADER_lp_LUSOL
#define HEADER_lp_LUSOL
/* Include libraries for this inverse system */
#include "lp_types.h"
#include "lusol.h"
/* LUSOL defines */
#ifdef WIN32
# define LUSOL_UseBLAS
#endif
/*#define MAPSINGULARCOLUMN*/
#define MATINDEXBASE LUSOL_ARRAYOFFSET /* Inversion engine index start for arrays */
#define LU_START_SIZE 10000 /* Start size of LU; realloc'ed if needed */
#define DEF_MAXPIVOT 250 /* Maximum number of pivots before refactorization */
#define MAX_DELTAFILLIN 2.0 /* Do refactorizations based on sparsity considerations */
#define TIGHTENAFTER 10 /* Tighten LU pivot criteria only after this number of singularities */
/* typedef */ struct _INVrec
{
int status; /* Last operation status code */
int dimcount; /* The actual number of LU rows/columns */
int dimalloc; /* The allocated LU rows/columns size */
int user_colcount; /* The number of user LU columns */
LUSOLrec *LUSOL;
int col_enter; /* The full index of the entering column */
int col_leave; /* The full index of the leaving column */
int col_pos; /* The B column to be changed at the next update using data in value[.]*/
REAL *value;
REAL *pcol; /* Reference to the elimination vector */
REAL theta_enter; /* Value of the entering column theta */
int max_Bsize; /* The largest B matrix of user variables */
int max_colcount; /* The maximum number of user columns in LU */
int max_LUsize; /* The largest NZ-count of LU-files generated */
int num_refact; /* Number of times the basis was refactored */
int num_timed_refact;
int num_dense_refact;
double time_refactstart; /* Time since start of last refactorization-pivots cyle */
double time_refactnext; /* Time estimated to next refactorization */
int num_pivots; /* Number of pivots since last refactorization */
int num_singular; /* The total number of singular updates */
char *opts;
MYBOOL is_dirty; /* Specifies if a column is incompletely processed */
MYBOOL force_refact; /* Force refactorization at the next opportunity */
MYBOOL timed_refact; /* Set if timer-driven refactorization should be active */
MYBOOL set_Bidentity; /* Force B to be the identity matrix at the next refactorization */
} /* INVrec */;
#ifdef __cplusplus
/* namespace LUSOL */
extern "C" {
#endif
/* Put function headers here */
#include "lp_BFP.h"
#ifdef __cplusplus
}
#endif
#endif /* HEADER_lp_LUSOL */

View File

@ -1,82 +0,0 @@
/* ---------------------------------------------------------------------------------- */
/* lp_solve v5+ headers for basis inversion / factorization libraries */
/* ---------------------------------------------------------------------------------- */
#define BFP_STATUS_RANKLOSS -1
#define BFP_STATUS_SUCCESS 0
#define BFP_STATUS_SINGULAR 1
#define BFP_STATUS_UNSTABLE 2
#define BFP_STATUS_NOPIVOT 3
#define BFP_STATUS_DIMERROR 4
#define BFP_STATUS_DUPLICATE 5
#define BFP_STATUS_NOMEMORY 6
#define BFP_STATUS_ERROR 7 /* Unspecified, command-related error */
#define BFP_STATUS_FATAL 8
#define BFP_STAT_ERROR -1
#define BFP_STAT_REFACT_TOTAL 0
#define BFP_STAT_REFACT_TIMED 1
#define BFP_STAT_REFACT_DENSE 2
#ifndef BFP_CALLMODEL
#ifdef WIN32
#define BFP_CALLMODEL __stdcall /* "Standard" call model */
#else
#define BFP_CALLMODEL
#endif
#endif
#ifdef RoleIsExternalInvEngine
#define __BFP_EXPORT_TYPE __EXPORT_TYPE
#else
#define __BFP_EXPORT_TYPE
#endif
/* Routines with UNIQUE implementations for each inversion engine */
/* ---------------------------------------------------------------------------------- */
char __BFP_EXPORT_TYPE *(BFP_CALLMODEL bfp_name)(void);
void __BFP_EXPORT_TYPE (BFP_CALLMODEL bfp_free)(lprec *lp);
MYBOOL __BFP_EXPORT_TYPE (BFP_CALLMODEL bfp_resize)(lprec *lp, int newsize);
int __BFP_EXPORT_TYPE (BFP_CALLMODEL bfp_nonzeros)(lprec *lp, MYBOOL maximum);
int __BFP_EXPORT_TYPE (BFP_CALLMODEL bfp_memallocated)(lprec *lp);
int __BFP_EXPORT_TYPE (BFP_CALLMODEL bfp_preparefactorization)(lprec *lp);
int __BFP_EXPORT_TYPE (BFP_CALLMODEL bfp_factorize)(lprec *lp, int uservars, int Bsize, MYBOOL *usedpos, MYBOOL final);
MYBOOL __BFP_EXPORT_TYPE (BFP_CALLMODEL bfp_finishupdate)(lprec *lp, MYBOOL changesign);
void __BFP_EXPORT_TYPE (BFP_CALLMODEL bfp_ftran_normal)(lprec *lp, REAL *pcol, int *nzidx);
void __BFP_EXPORT_TYPE (BFP_CALLMODEL bfp_ftran_prepare)(lprec *lp, REAL *pcol, int *nzidx);
void __BFP_EXPORT_TYPE (BFP_CALLMODEL bfp_btran_normal)(lprec *lp, REAL *prow, int *nzidx);
int __BFP_EXPORT_TYPE (BFP_CALLMODEL bfp_status)(lprec *lp);
int __BFP_EXPORT_TYPE (BFP_CALLMODEL bfp_findredundant)(lprec *lp, int items, getcolumnex_func cb, int *maprow, int*mapcol);
/* Routines SHARED for all inverse implementations; located in lp_BFP1.c */
/* ---------------------------------------------------------------------------------- */
MYBOOL __BFP_EXPORT_TYPE (BFP_CALLMODEL bfp_compatible)(lprec *lp, int bfpversion, int lpversion, int sizeofvar);
int __BFP_EXPORT_TYPE (BFP_CALLMODEL bfp_indexbase)(lprec *lp);
int __BFP_EXPORT_TYPE (BFP_CALLMODEL bfp_rowoffset)(lprec *lp);
int __BFP_EXPORT_TYPE (BFP_CALLMODEL bfp_pivotmax)(lprec *lp);
REAL __BFP_EXPORT_TYPE (BFP_CALLMODEL bfp_efficiency)(lprec *lp);
REAL __BFP_EXPORT_TYPE *(BFP_CALLMODEL bfp_pivotvector)(lprec *lp);
int __BFP_EXPORT_TYPE (BFP_CALLMODEL bfp_pivotcount)(lprec *lp);
MYBOOL __BFP_EXPORT_TYPE (BFP_CALLMODEL bfp_mustrefactorize)(lprec *lp);
int __BFP_EXPORT_TYPE (BFP_CALLMODEL bfp_refactcount)(lprec *lp, int kind);
MYBOOL __BFP_EXPORT_TYPE (BFP_CALLMODEL bfp_isSetI)(lprec *lp);
int *bfp_createMDO(lprec *lp, MYBOOL *usedpos, int count, MYBOOL doMDO);
void BFP_CALLMODEL bfp_updaterefactstats(lprec *lp);
int BFP_CALLMODEL bfp_rowextra(lprec *lp);
/* Routines with OPTIONAL SHARED code; template routines suitable for canned */
/* inverse engines are located in lp_BFP2.c */
/* ---------------------------------------------------------------------------------- */
MYBOOL __BFP_EXPORT_TYPE (BFP_CALLMODEL bfp_init)(lprec *lp, int size, int deltasize, char *options);
MYBOOL __BFP_EXPORT_TYPE (BFP_CALLMODEL bfp_restart)(lprec *lp);
MYBOOL __BFP_EXPORT_TYPE (BFP_CALLMODEL bfp_implicitslack)(lprec *lp);
MYBOOL __BFP_EXPORT_TYPE (BFP_CALLMODEL bfp_pivotalloc)(lprec *lp, int newsize);
int __BFP_EXPORT_TYPE (BFP_CALLMODEL bfp_colcount)(lprec *lp);
MYBOOL __BFP_EXPORT_TYPE (BFP_CALLMODEL bfp_canresetbasis)(lprec *lp);
void __BFP_EXPORT_TYPE (BFP_CALLMODEL bfp_finishfactorization)(lprec *lp);
LREAL __BFP_EXPORT_TYPE (BFP_CALLMODEL bfp_prepareupdate)(lprec *lp, int row_nr, int col_nr, REAL *pcol);
REAL __BFP_EXPORT_TYPE (BFP_CALLMODEL bfp_pivotRHS)(lprec *lp, LREAL theta, REAL *pcol);
void __BFP_EXPORT_TYPE (BFP_CALLMODEL bfp_btran_double)(lprec *lp, REAL *prow, int *pnzidx, REAL *drow, int *dnzidx);

View File

@ -1,206 +0,0 @@
/* Routines located in lp_BFP1.cpp; common for all factorization engines */
/* Cfr. lp_BFP.h for definitions */
/* ---------------------------------------------------------------------------------- */
/* Changes: */
/* 29 May 2004 Corrected calculation of bfp_efficiency(), which required */
/* modifying the max_Bsize to include slack variables. KE. */
/* 16 June 2004 Make the symbolic minimum degree ordering routine available */
/* to BFPs as a routine internal to the library. KE */
/* 1 July 2004 Change due to change in MDO naming. */
/* ---------------------------------------------------------------------------------- */
/* MUST MODIFY */
MYBOOL BFP_CALLMODEL bfp_compatible(lprec *lp, int bfpversion, int lpversion, int sizeofvar)
{
MYBOOL status = FALSE;
if((lp != NULL) && (bfpversion == BFPVERSION) && (sizeof(REAL) == sizeofvar)) {
#if 0
if(lpversion == MAJORVERSION) /* Forces BFP renewal at lp_solve major version changes */
#endif
status = TRUE;
}
return( status );
}
/* DON'T MODIFY */
int BFP_CALLMODEL bfp_status(lprec *lp)
{
return(lp->invB->status);
}
/* DON'T MODIFY */
int BFP_CALLMODEL bfp_indexbase(lprec *lp)
{
return( MATINDEXBASE );
}
/* DON'T MODIFY */
int BFP_CALLMODEL bfp_rowoffset(lprec *lp)
{
if(lp->obj_in_basis)
return( 1 );
else
return( 0 );
}
/* DON'T MODIFY */
int BFP_CALLMODEL bfp_pivotmax(lprec *lp)
{
if(lp->max_pivots > 0)
return( lp->max_pivots );
else
return( DEF_MAXPIVOT );
}
/* DON'T MODIFY */
REAL * BFP_CALLMODEL bfp_pivotvector(lprec *lp)
{
return( lp->invB->pcol );
}
/* DON'T MODIFY */
REAL BFP_CALLMODEL bfp_efficiency(lprec *lp)
{
REAL hold;
hold = lp->bfp_nonzeros(lp, AUTOMATIC);
if(hold == 0)
hold = 1 + lp->rows;
hold = lp->bfp_nonzeros(lp, TRUE)/hold;
return(hold);
}
/* DON'T MODIFY */
int BFP_CALLMODEL bfp_pivotcount(lprec *lp)
{
return(lp->invB->num_pivots);
}
/* DON'T MODIFY */
int BFP_CALLMODEL bfp_refactcount(lprec *lp, int kind)
{
if(kind == BFP_STAT_REFACT_TOTAL)
return(lp->invB->num_refact);
else if(kind == BFP_STAT_REFACT_TIMED)
return(lp->invB->num_timed_refact);
else if(kind == BFP_STAT_REFACT_DENSE)
return(lp->invB->num_dense_refact);
else
return( BFP_STAT_ERROR );
}
/* DON'T MODIFY */
MYBOOL BFP_CALLMODEL bfp_mustrefactorize(lprec *lp)
{
MYBOOL test = lp->is_action(lp->spx_action, ACTION_REINVERT | ACTION_TIMEDREINVERT);
if(!test) {
REAL f;
INVrec *lu = lp->invB;
if(lu->num_pivots > 0)
f = (timeNow()-lu->time_refactstart) / (REAL) lu->num_pivots;
else
f = 0;
/* Always refactorize if we are above the set pivot limit */
if(lu->force_refact ||
(lu->num_pivots >= lp->bfp_pivotmax(lp)))
lp->set_action(&lp->spx_action, ACTION_REINVERT);
/* Check if we should do an optimal time-based refactorization */
else if(lu->timed_refact && (lu->num_pivots > 1) &&
(f > MIN_TIMEPIVOT) && (f > lu->time_refactnext)) {
/* If we have excessive time usage in automatic mode then
treat as untimed case and update optimal time metric, ... */
if((lu->timed_refact == AUTOMATIC) &&
(lu->num_pivots < 0.4*lp->bfp_pivotmax(lp)))
lu->time_refactnext = f;
/* ... otherwise set flag for the optimal time-based refactorization */
else
lp->set_action(&lp->spx_action, ACTION_TIMEDREINVERT);
}
/* Otherwise simply update the optimal time metric */
else
lu->time_refactnext = f;
#if 0
if(lu->num_pivots % 10 == 0)
lp->report(lp, NORMAL, "bfp pivot %d - start %f - timestat %f",
lu->num_pivots, lu->time_refactstart, f);
#endif
}
test = lp->is_action(lp->spx_action, ACTION_REINVERT | ACTION_TIMEDREINVERT);
return(test);
}
/* DON'T MODIFY */
MYBOOL BFP_CALLMODEL bfp_isSetI(lprec *lp)
{
return( (MYBOOL) lp->invB->set_Bidentity );
}
/* DON'T MODIFY */
int *bfp_createMDO(lprec *lp, MYBOOL *usedpos, int count, MYBOOL doMDO)
{
int *mdo, i, j, kk;
mdo = (int *) malloc((count + 1)*sizeof(*mdo));
/* allocINT(lp, &mdo, count + 1, FALSE); */
/* Fill the mdo[] array with remaining full-pivot basic user variables */
kk = 0;
for(j = 1; j <= lp->columns; j++) {
i = lp->rows + j;
if(usedpos[i] == TRUE) {
kk++;
mdo[kk] = i;
}
}
mdo[0] = kk;
if(kk == 0)
goto Process;
/* Calculate the approximate minimum degree column ordering */
if(doMDO) {
i = lp->getMDO(lp, usedpos, mdo, NULL, FALSE);
if(i != 0) {
lp->report(lp, CRITICAL, "bfp_createMDO: Internal error %d in minimum degree ordering routine", i);
FREE(mdo);
}
}
Process:
return( mdo );
}
void BFP_CALLMODEL bfp_updaterefactstats(lprec *lp)
{
INVrec *lu = lp->invB;
/* Signal that we are refactorizing */
lu->is_dirty = AUTOMATIC;
/* Set time of start of current refactorization cycle */
lu->time_refactstart = timeNow();
lu->time_refactnext = 0;
lu->user_colcount = 0;
/* Do the numbers */
if(lu->force_refact)
lu->num_dense_refact++;
else if(lu->timed_refact && lp->is_action(lp->spx_action, ACTION_TIMEDREINVERT))
lu->num_timed_refact++;
lu->num_refact++;
}
int BFP_CALLMODEL bfp_rowextra(lprec *lp)
{
if(lp->is_obj_in_basis(lp))
return( 1 );
else
return( 0 );
}

View File

@ -1,177 +0,0 @@
/* Routines located in lp_BFP2.cpp; optional shared for canned implementations */
/* Cfr. lp_BFP.h for definitions */
/* ---------------------------------------------------------------------------------- */
/* DON'T MODIFY */
MYBOOL BFP_CALLMODEL bfp_init(lprec *lp, int size, int delta, char *options)
{
INVrec *lu;
lp->invB = (INVrec *) calloc(1, sizeof(*(lp->invB)));
lu = lp->invB;
if((lu == NULL) ||
!lp->bfp_resize(lp, size) ||
!lp->bfp_restart(lp))
return( FALSE );
/* Store any passed options */
if(options != NULL) {
size_t len = strlen(options);
lu->opts = (char *) malloc(len + 1);
strcpy(lu->opts, options);
}
/* Prepare for factorization and undo values reset by bfp_preparefactorization */
lp->bfp_preparefactorization(lp);
lu->num_refact = 0;
return( TRUE );
}
/* DON'T MODIFY */
MYBOOL BFP_CALLMODEL bfp_restart(lprec *lp)
{
INVrec *lu;
lu = lp->invB;
if(lu == NULL)
return( FALSE );
lu->status = BFP_STATUS_SUCCESS;
lu->max_Bsize = 0; /* The largest NZ-count of the B matrix */
lu->max_colcount = 0; /* The maximum number of user columns in B */
lu->max_LUsize = 0; /* The largest NZ-count of LU-files generated */
lu->num_refact = 0; /* The number of times the basis has been factored */
lu->num_timed_refact = 0;
lu->num_dense_refact = 0;
lu->num_pivots = 0; /* The number of pivots since last factorization */
lu->pcol = NULL;
lu->set_Bidentity = FALSE;
return( TRUE );
}
/* DON'T MODIFY */
MYBOOL BFP_CALLMODEL bfp_implicitslack(lprec *lp)
{
return( FALSE );
}
/* DON'T MODIFY */
int BFP_CALLMODEL bfp_colcount(lprec *lp)
{
return(lp->invB->user_colcount);
}
/* DON'T MODIFY */
MYBOOL BFP_CALLMODEL bfp_canresetbasis(lprec *lp)
{
return( FALSE );
}
/* DON'T MODIFY */
MYBOOL BFP_CALLMODEL bfp_pivotalloc(lprec *lp, int newsize)
{
/* Does nothing in the default implementation */
return( TRUE );
}
/* DON'T MODIFY */
void BFP_CALLMODEL bfp_finishfactorization(lprec *lp)
{
INVrec *lu;
lu = lp->invB;
SETMAX(lu->max_colcount, lp->bfp_colcount(lp));
SETMAX(lu->max_LUsize, lp->bfp_nonzeros(lp, FALSE));
/* Signal that we done factorizing/reinverting */
lu->is_dirty = FALSE;
lp->clear_action(&lp->spx_action, ACTION_REINVERT | ACTION_TIMEDREINVERT);
lu->force_refact = FALSE;
/* Store information about the current inverse */
lu->num_pivots = 0;
}
/* DON'T MODIFY */
LREAL BFP_CALLMODEL bfp_prepareupdate(lprec *lp, int row_nr, int col_nr, REAL *pcol)
/* Was condensecol() in versions of lp_solve before 4.0.1.8 - KE */
{
LREAL pivValue;
INVrec *lu;
lu = lp->invB;
/* Store the incoming pivot value for RHS update purposes */
lu->col_enter = col_nr; /* The index of the new data column */
lu->col_pos = row_nr; /* The basis column to be replaced */
lu->col_leave = lp->var_basic[row_nr];
if(pcol == NULL)
pivValue = 0;
else
pivValue = pcol[row_nr];
lu->theta_enter = pivValue;
/* Save reference to the elimination vector */
lu->pcol = pcol;
/* Set completion status; but hold if we are reinverting */
if(lu->is_dirty != AUTOMATIC)
lu->is_dirty = TRUE;
return( pivValue );
}
/* DON'T MODIFY */
REAL BFP_CALLMODEL bfp_pivotRHS(lprec *lp, LREAL theta, REAL *pcol)
/* This function is used to adjust the RHS in bound swap operations as
well as handling the updating of the RHS for normal basis changes.
Was rhsmincol(), ie. "rhs minus column" in versions of lp_solve before 4.0.1.8 - KE */
{
INVrec *lu;
lu = lp->invB;
if(pcol == NULL)
pcol = lu->pcol;
if(theta != 0) {
register int i, n = lp->rows;
register LREAL roundzero = lp->epsvalue;
register LREAL *rhs = lp->rhs, rhsmax = 0;
for(i = 0; i <= n; i++, rhs++, pcol++) {
(*rhs) -= theta * (*pcol);
my_roundzero(*rhs, roundzero);
SETMAX(rhsmax, fabs(*rhs));
}
lp->rhsmax = rhsmax;
}
if(pcol == lu->pcol)
return( lu->theta_enter );
else
return( 0.0 );
}
/* DON'T MODIFY */
void BFP_CALLMODEL bfp_btran_double(lprec *lp, REAL *prow, int *pnzidx, REAL *drow, int *dnzidx)
{
if(prow != NULL)
lp->bfp_btran_normal(lp, prow, pnzidx);
if(drow != NULL)
lp->bfp_btran_normal(lp, drow, dnzidx);
}

View File

@ -1,27 +0,0 @@
# Look for lpsolve
#
# Set
# lpsolve_FOUND = TRUE
# lpsolve_INCLUDE_DIRS = /usr/local/include
# lpsolve_LIBRARY = /usr/local/lib/liblpsolve.so
# lpsolve_LIBRARY_DIRS = /usr/local/lib
set(lpsolve_BUILD_PATH "${CMAKE_SOURCE_DIR}/gtsam/3rdparty/lp_solve_5.5/lpsolve55")
find_library (lpsolve_LIBRARY liblpsolve55.a PATHS ${lpsolve_BUILD_PATH})
if (lpsolve_LIBRARY)
get_filename_component (lpsolve_LIBRARY_DIRS "${lpsolve_LIBRARY}" PATH)
get_filename_component (_ROOT_DIR "${lpsolve_LIBRARY_DIRS}" PATH)
set (lpsolve_FOUND TRUE)
set (lpsolve_INCLUDE_DIRS "${_ROOT_DIR}")
unset (_ROOT_DIR)
if (NOT EXISTS "${lpsolve_INCLUDE_DIRS}/lp_lib.h")
unset (lpsolve_INCLUDE_DIRS)
unset (lpsolve_LIBRARY)
unset (lpsolve_LIBRARY_DIRS)
endif ()
endif ()
include (FindPackageHandleStandardArgs)
find_package_handle_standard_args (lpsolve DEFAULT_MSG lpsolve_LIBRARY_DIRS lpsolve_LIBRARY lpsolve_INCLUDE_DIRS)
mark_as_advanced (lpsolve_LIBRARY_DIRS lpsolve_LIBRARY lpsolve_INCLUDE_DIRS)

File diff suppressed because it is too large Load Diff

View File

@ -1,286 +0,0 @@
/* ========================================================================== */
/* === colamd/symamd prototypes and definitions ============================= */
/* ========================================================================== */
/*
You must include this file (colamd.h) in any routine that uses colamd,
symamd, or the related macros and definitions.
Authors:
The authors of the code itself are Stefan I. Larimore and Timothy A.
Davis (davis@cise.ufl.edu), University of Florida. The algorithm was
developed in collaboration with John Gilbert, Xerox PARC, and Esmond
Ng, Oak Ridge National Laboratory.
Date:
May 4, 2001. Version 2.1.
Acknowledgements:
This work was supported by the National Science Foundation, under
grants DMS-9504974 and DMS-9803599.
Notice:
Copyright (c) 1998-2001 by the University of Florida.
All Rights Reserved.
THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
EXPRESSED OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
Permission is hereby granted to use or copy this program for any
purpose, provided the above notices are retained on all copies.
User documentation of any code that uses this code must cite the
Authors, the Copyright, and "Used by permission." If this code is
accessible from within Matlab, then typing "help colamd" and "help
symamd" must cite the Authors. Permission to modify the code and to
distribute modified code is granted, provided the above notices are
retained, and a notice that the code was modified is included with the
above copyright notice. You must also retain the Availability
information below, of the original version.
This software is provided free of charge.
Availability:
The colamd/symamd library is available at
http://www.cise.ufl.edu/research/sparse/colamd
This is the http://www.cise.ufl.edu/research/sparse/colamd/colamd.h
file. It is required by the colamd.c, colamdmex.c, and symamdmex.c
files, and by any C code that calls the routines whose prototypes are
listed below, or that uses the colamd/symamd definitions listed below.
*/
#ifndef COLAMD_H
#define COLAMD_H
/* ========================================================================== */
/* === Include files ======================================================== */
/* ========================================================================== */
#include <stdlib.h>
/* ========================================================================== */
/* === Knob and statistics definitions ====================================== */
/* ========================================================================== */
/* size of the knobs [ ] array. Only knobs [0..1] are currently used. */
#define COLAMD_KNOBS 20
/* number of output statistics. Only stats [0..6] are currently used. */
#define COLAMD_STATS 20
/* knobs [0] and stats [0]: dense row knob and output statistic. */
#define COLAMD_DENSE_ROW 0
/* knobs [1] and stats [1]: dense column knob and output statistic. */
#define COLAMD_DENSE_COL 1
/* stats [2]: memory defragmentation count output statistic */
#define COLAMD_DEFRAG_COUNT 2
/* stats [3]: colamd status: zero OK, > 0 warning or notice, < 0 error */
#define COLAMD_STATUS 3
/* stats [4..6]: error info, or info on jumbled columns */
#define COLAMD_INFO1 4
#define COLAMD_INFO2 5
#define COLAMD_INFO3 6
/* error codes returned in stats [3]: */
#define COLAMD_OK (0)
#define COLAMD_OK_BUT_JUMBLED (1)
#define COLAMD_ERROR_A_not_present (-1)
#define COLAMD_ERROR_p_not_present (-2)
#define COLAMD_ERROR_nrow_negative (-3)
#define COLAMD_ERROR_ncol_negative (-4)
#define COLAMD_ERROR_nnz_negative (-5)
#define COLAMD_ERROR_p0_nonzero (-6)
#define COLAMD_ERROR_A_too_small (-7)
#define COLAMD_ERROR_col_length_negative (-8)
#define COLAMD_ERROR_row_index_out_of_bounds (-9)
#define COLAMD_ERROR_out_of_memory (-10)
#define COLAMD_ERROR_internal_error (-999)
/* ========================================================================== */
/* === Row and Column structures ============================================ */
/* ========================================================================== */
/* User code that makes use of the colamd/symamd routines need not directly */
/* reference these structures. They are used only for the COLAMD_RECOMMENDED */
/* macro. */
typedef struct Colamd_Col_struct
{
int start ; /* index for A of first row in this column, or DEAD */
/* if column is dead */
int length ; /* number of rows in this column */
union
{
int thickness ; /* number of original columns represented by this */
/* col, if the column is alive */
int parent ; /* parent in parent tree super-column structure, if */
/* the column is dead */
} shared1 ;
union
{
int score ; /* the score used to maintain heap, if col is alive */
int order ; /* pivot ordering of this column, if col is dead */
} shared2 ;
union
{
int headhash ; /* head of a hash bucket, if col is at the head of */
/* a degree list */
int hash ; /* hash value, if col is not in a degree list */
int prev ; /* previous column in degree list, if col is in a */
/* degree list (but not at the head of a degree list) */
} shared3 ;
union
{
int degree_next ; /* next column, if col is in a degree list */
int hash_next ; /* next column, if col is in a hash list */
} shared4 ;
} Colamd_Col ;
typedef struct Colamd_Row_struct
{
int start ; /* index for A of first col in this row */
int length ; /* number of principal columns in this row */
union
{
int degree ; /* number of principal & non-principal columns in row */
int p ; /* used as a row pointer in init_rows_cols () */
} shared1 ;
union
{
int mark ; /* for computing set differences and marking dead rows*/
int first_column ;/* first column in row (used in garbage collection) */
} shared2 ;
} Colamd_Row ;
/* ========================================================================== */
/* === Colamd recommended memory size ======================================= */
/* ========================================================================== */
/*
The recommended length Alen of the array A passed to colamd is given by
the COLAMD_RECOMMENDED (nnz, n_row, n_col) macro. It returns -1 if any
argument is negative. 2*nnz space is required for the row and column
indices of the matrix. COLAMD_C (n_col) + COLAMD_R (n_row) space is
required for the Col and Row arrays, respectively, which are internal to
colamd. An additional n_col space is the minimal amount of "elbow room",
and nnz/5 more space is recommended for run time efficiency.
This macro is not needed when using symamd.
*/
#define COLAMD_C(n_col) (((n_col) + 1) * sizeof (Colamd_Col) / sizeof (int))
#define COLAMD_R(n_row) (((n_row) + 1) * sizeof (Colamd_Row) / sizeof (int))
#define COLAMD_RECOMMENDED(nnz, n_row, n_col) \
( \
((nnz) < 0 || (n_row) < 0 || (n_col) < 0) \
? \
(-1) \
: \
(2 * (nnz) + COLAMD_C (n_col) + COLAMD_R (n_row) + (n_col) + ((nnz) / 5)) \
)
/* ========================================================================== */
/* === Prototypes of user-callable routines ================================= */
/* ========================================================================== */
/*
#ifdef __cplusplus
#define __EXTERN_C extern "C"
#else
#define __EXTERN_C
#endif
*/
#ifndef __BORLANDC__
#ifdef __cplusplus
#define __EXTERN_C extern "C"
#else
#define __EXTERN_C
#endif
#else /* Otherwise set up for the Borland compiler */
#define __EXTERN_C extern "C"
#endif
#ifdef __cplusplus
__EXTERN_C {
#endif
int colamd_recommended /* returns recommended value of Alen, */
/* or (-1) if input arguments are erroneous */
(
int nnz, /* nonzeros in A */
int n_row, /* number of rows in A */
int n_col /* number of columns in A */
) ;
void colamd_set_defaults /* sets default parameters */
( /* knobs argument is modified on output */
double knobs [COLAMD_KNOBS] /* parameter settings for colamd */
) ;
int colamd /* returns (1) if successful, (0) otherwise*/
( /* A and p arguments are modified on output */
int n_row, /* number of rows in A */
int n_col, /* number of columns in A */
int Alen, /* size of the array A */
int A [], /* row indices of A, of size Alen */
int p [], /* column pointers of A, of size n_col+1 */
double knobs [COLAMD_KNOBS],/* parameter settings for colamd */
int stats [COLAMD_STATS] /* colamd output statistics and error codes */
) ;
int symamd /* return (1) if OK, (0) otherwise */
(
int n, /* number of rows and columns of A */
int A [], /* row indices of A */
int p [], /* column pointers of A */
int perm [], /* output permutation, size n_col+1 */
double knobs [COLAMD_KNOBS], /* parameters (uses defaults if NULL) */
int stats [COLAMD_STATS], /* output statistics and error codes */
void * (*allocate) (size_t, size_t),
/* pointer to calloc (ANSI C) or */
/* mxCalloc (for Matlab mexFunction) */
void (*release) (void *)
/* pointer to free (ANSI C) or */
/* mxFree (for Matlab mexFunction) */
) ;
void colamd_report
(
int stats [COLAMD_STATS]
) ;
void symamd_report
(
int stats [COLAMD_STATS]
) ;
#endif /* COLAMD_H */
#ifdef __cplusplus
}
#endif

View File

@ -1,144 +0,0 @@
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
It was created by lpsolve configure 5.5.0.11, which was
generated by GNU Autoconf 2.59. Invocation command line was
$ ./configure --prefix /Users/thduynguyen/install
## --------- ##
## Platform. ##
## --------- ##
hostname = lawn-143-215-58-168.lawn.gatech.edu
uname -m = x86_64
uname -r = 12.5.0
uname -s = Darwin
uname -v = Darwin Kernel Version 12.5.0: Sun Sep 29 13:33:47 PDT 2013; root:xnu-2050.48.12~1/RELEASE_X86_64
/usr/bin/uname -p = i386
/bin/uname -X = unknown
/bin/arch = unknown
/usr/bin/arch -k = unknown
/usr/convex/getsysinfo = unknown
hostinfo = Mach kernel version:
Darwin Kernel Version 12.5.0: Sun Sep 29 13:33:47 PDT 2013; root:xnu-2050.48.12~1/RELEASE_X86_64
Kernel configured for up to 4 processors.
2 processors are physically available.
4 processors are logically available.
Processor type: i486 (Intel 80486)
Processors active: 0 1 2 3
Primary memory available: 8.00 gigabytes
Default processor set: 167 tasks, 1145 threads, 4 processors
Load average: 1.33, Mach factor: 2.66
/bin/machine = unknown
/usr/bin/oslevel = unknown
/bin/universe = unknown
PATH: /Users/thduynguyen/Library/Enthought/Canopy_64bit/User/bin
PATH: /Library/Frameworks/Python.framework/Versions/2.7/bin
PATH: /opt/local/bin
PATH: /opt/local/sbin
PATH: /usr/bin
PATH: /bin
PATH: /usr/sbin
PATH: /sbin
PATH: /usr/local/bin
PATH: /opt/X11/bin
## ----------- ##
## Core tests. ##
## ----------- ##
configure:1279: error: cannot find install-sh or install.sh in . ./.. ./../..
## ---------------- ##
## Cache variables. ##
## ---------------- ##
ac_cv_env_CC_set=
ac_cv_env_CC_value=
ac_cv_env_CFLAGS_set=
ac_cv_env_CFLAGS_value=
ac_cv_env_CPPFLAGS_set=
ac_cv_env_CPPFLAGS_value=
ac_cv_env_LDFLAGS_set=
ac_cv_env_LDFLAGS_value=
ac_cv_env_build_alias_set=
ac_cv_env_build_alias_value=
ac_cv_env_host_alias_set=
ac_cv_env_host_alias_value=
ac_cv_env_target_alias_set=
ac_cv_env_target_alias_value=
## ----------------- ##
## Output variables. ##
## ----------------- ##
CC=''
CCSHARED=''
CFLAGS=''
CPPFLAGS=''
DEF=''
DEFS=''
ECHO_C='ECHO_N=''
ECHO_T=''
EXEEXT=''
INSTALL_DATA=''
INSTALL_PROGRAM=''
INSTALL_SCRIPT=''
LDFLAGS=''
LIBOBJS=''
LIBS=''
LTLIBOBJS=''
OBJEXT=''
PACKAGE_BUGREPORT=''
PACKAGE_NAME='lpsolve'
PACKAGE_STRING='lpsolve 5.5.0.11'
PACKAGE_TARNAME='lpsolve'
PACKAGE_VERSION='5.5.0.11'
PATH_SEPARATOR=':'
SHARED_LIB=''
SHELL='/bin/sh'
SO=''
ac_ct_CC=''
bindir='${exec_prefix}/bin'
build=''
build_alias=''
build_cpu=''
build_os=''
build_vendor=''
datadir='${prefix}/share'
exec_prefix='NONE'
host=''
host_alias=''
host_cpu=''
host_os=''
host_vendor=''
includedir='${prefix}/include'
infodir='${prefix}/info'
libdir='${exec_prefix}/lib'
libexecdir='${exec_prefix}/libexec'
localstatedir='${prefix}/var'
mandir='${prefix}/man'
oldincludedir='/usr/include'
prefix='/Users/thduynguyen/install'
program_transform_name='s,x,x,'
sbindir='${exec_prefix}/sbin'
sharedstatedir='${prefix}/com'
sysconfdir='${prefix}/etc'
target_alias=''
## ----------- ##
## confdefs.h. ##
## ----------- ##
#define PACKAGE_BUGREPORT ""
#define PACKAGE_NAME "lpsolve"
#define PACKAGE_STRING "lpsolve 5.5.0.11"
#define PACKAGE_TARNAME "lpsolve"
#define PACKAGE_VERSION "5.5.0.11"
configure: exit 1

File diff suppressed because it is too large Load Diff

View File

@ -1,57 +0,0 @@
AC_PREREQ(2.52)
AC_INIT([lpsolve],5.5.0.11,[], [])
AC_CONFIG_SRCDIR(lp_simplex.c)
AC_CANONICAL_HOST
SHARED_LIB=liblpsolve55.so
SO=.so
case $host_os in
hp*|HP*)
DEF=-ldld
case `uname -m` in
ia64) SO=.so;;
*) SO=.sl;;
esac
if test "$GCC" = yes;
then CCSHARED="-fPIC";
else CCSHARED="+z";
fi;;
CYGWIN*)
SO=.dll;;
linux)
CCSHARED="-fPIC";;
apple-darwin)
DEF=-ldl -idirafter /usr/include/sys -DINTEGERTIME -Wno-long-double
;;
OpenUNIX*|UnixWare*)
DEF='-dy -DNOLONGLONG'
if test "$GCC" = "yes"
then CCSHARED="-fPIC"
else CCSHARED="-K PIC"
fi;;
SCO_SV*)
DEF='-dy -DNOLONGLONG'
if test "$GCC" = "yes"
then CCSHARED="-fPIC"
else CCSHARED="-Kpic -belf"
fi;;
*)
esac
AC_SUBST(SO)
AC_SUBST(CCSHARED)
AC_SUBST(DEF)
AC_SUBST(SHARED_LIB)
AC_PROG_CC
if test "x$GCC" != "xyes"
then
echo "*** non GNU CC compiler detected."
echo "*** This package has not been tested very well with non GNU compilers"
fi
AC_PROG_INSTALL
AC_CONFIG_FILES([ \
Makefile \
])
AC_OUTPUT

View File

@ -1,22 +0,0 @@
#ifndef __DECLARE_H__
#define __DECLARE_H__
#if !defined ANSI_PROTOTYPES
# if defined MSDOS || defined __BORLANDC__ || defined __HIGHC__ || defined SCO_UNIX || defined AViiON
# define ANSI_PROTOTYPES 1
# endif
#endif
#if ANSI_PROTOTYPES!=0
# define __OF(args) args
#else
# define __OF(args) ()
#endif
#if defined __HIGHC__
# define VARARG ...
#else
# define VARARG
#endif
#endif

View File

@ -1,10 +0,0 @@
@echo off
REM This batch file compiles the demo program with the Borland C++ 5.5 compiler for Windows
set src=../shared/commonlib.c ../shared/mmio.c ../shared/myblas.c ../ini.c ../lp_rlp.c ../lp_crash.c ../bfp/bfp_LUSOL/lp_LUSOL.c ../bfp/bfp_LUSOL/LUSOL/lusol.c ../lp_Hash.c ../lp_lib.c ../lp_wlp.c ../lp_matrix.c ../lp_mipbb.c ../lp_MPS.c ../lp_params.c ../lp_presolve.c ../lp_price.c ../lp_pricePSE.c ../lp_report.c ../lp_scale.c ../lp_simplex.c ../lp_SOS.c ../lp_utils.c ../yacc_read.c ../lp_MDO.c ../colamd/colamd.c
set c=bcc32 -w-8004 -w-8057
%c% -I.. -I../bfp -I../bfp/bfp_LUSOL -I../bfp/bfp_LUSOL/LUSOL -I../colamd -I../shared /O0 -a8 -DWIN32 -DYY_NEVER_INTERACTIVE=1 -DPARSER_LP -DINVERSE_ACTIVE=INVERSE_LUSOL -DRoleIsExternalInvEngine demo.c -edemo.exe %src%
if exist *.obj del *.obj

View File

@ -1,15 +0,0 @@
src='../lp_MDO.c ../shared/commonlib.c ../colamd/colamd.c ../shared/mmio.c ../shared/myblas.c ../ini.c ../lp_rlp.c ../lp_crash.c ../bfp/bfp_LUSOL/lp_LUSOL.c ../bfp/bfp_LUSOL/LUSOL/lusol.c ../lp_Hash.c ../lp_lib.c ../lp_wlp.c ../lp_matrix.c ../lp_mipbb.c ../lp_MPS.c ../lp_params.c ../lp_presolve.c ../lp_price.c ../lp_pricePSE.c ../lp_report.c ../lp_scale.c ../lp_simplex.c ../lp_SOS.c ../lp_utils.c ../yacc_read.c'
c=cc
math=-lm
def=
if [ "$PLATFORM" = "SCO_UNIX" ]
then def='-dy -K PIC -DNOLONGLONG'
dl=-lc
else dl=-ldl
fi
opts='-O3'
$c -I.. -I../bfp -I../bfp/bfp_LUSOL -I../bfp/bfp_LUSOL/LUSOL -I../colamd -I../shared $opts $def -DYY_NEVER_INTERACTIVE -DPARSER_LP -DINVERSE_ACTIVE=INVERSE_LUSOL -DRoleIsExternalInvEngine demo.c $src -o demo $math $dl

View File

@ -1,14 +0,0 @@
src='../bfp/lp_MDO.c ../commonlib.c ../myblas.c ../colamd/colamd.c ../ini.c ../fortify.c ../lp_rlp.c ../lp_crash.c ../bfp/bfp_etaPFI/lp_etaPFI.c ../lp_Hash.c ../lp_lib.c ../lp_wlp.c ../lp_matrix.c ../lp_mipbb.c ../lp_MPS.c ../lp_params.c ../lp_presolve.c ../lp_price.c ../lp_pricePSE.c ../lp_report.c ../lp_scale.c ../lp_simplex.c demo.c ../lp_SOS.c ../lp_utils.c ../yacc_read.c'
c=cc
math=-lm
def=
if [ "$PLATFORM" = "SCO_UNIX" ]
then def='-DLoadInverseLib=0 -DLoadLanguageLib=0 -D__HYPER=long'
else dl=-ldl
fi
opts='-idirafter /usr/include/sys -O3 -DINTEGERTIME -Wno-long-double'
$c -I.. -I../bfp -I../bfp/bfp_etaPFI -I../colamd $opts $def -DYY_NEVER_INTERACTIVE -DPARSER_LP $src -o demo $math $dl

View File

@ -1,15 +0,0 @@
@echo off
REM This batch file compiles the demo program with the gnu gcc compiler under DOS/Windows
REM There are two ways to do that: use the lpsolve code directly or use that static library.
rem link lpsolve code with application
set src=../lp_MDO.c ../shared/commonlib.c ../colamd/colamd.c ../shared/mmio.c ../shared/myblas.c ../ini.c ../lp_rlp.c ../lp_crash.c ../bfp/bfp_LUSOL/lp_LUSOL.c ../bfp/bfp_LUSOL/LUSOL/lusol.c ../lp_Hash.c ../lp_lib.c ../lp_wlp.c ../lp_matrix.c ../lp_mipbb.c ../lp_MPS.c ../lp_params.c ../lp_presolve.c ../lp_price.c ../lp_pricePSE.c ../lp_report.c ../lp_scale.c ../lp_simplex.c ../lp_SOS.c ../lp_utils.c ../yacc_read.c
rem statically link lpsolve library
rem set src=../lpsolve55/liblpsolve55.a
set c=gcc
%c% -DINLINE=static -I.. -I../bfp -I../bfp/bfp_LUSOL -I../bfp/bfp_LUSOL/LUSOL -I../colamd -I../shared -O3 -DBFP_CALLMODEL=__stdcall -DYY_NEVER_INTERACTIVE -DPARSER_LP -DINVERSE_ACTIVE=INVERSE_LUSOL -DRoleIsExternalInvEngine demo.c %src% -o demo.exe

View File

@ -1,10 +0,0 @@
@echo off
REM This batch file compiles the demo program with the Microsoft Visual C/C++ compiler under Windows
set src=../shared/commonlib.c ../shared/mmio.c ../shared/myblas.c ../ini.c ../lp_rlp.c ../lp_crash.c ../bfp/bfp_LUSOL/lp_LUSOL.c ../bfp/bfp_LUSOL/LUSOL/lusol.c ../lp_Hash.c ../lp_lib.c ../lp_wlp.c ../lp_matrix.c ../lp_mipbb.c ../lp_MPS.c ../lp_params.c ../lp_presolve.c ../lp_price.c ../lp_pricePSE.c ../lp_report.c ../lp_scale.c ../lp_simplex.c ../lp_SOS.c ../lp_utils.c ../yacc_read.c ../lp_MDO.c ../colamd/colamd.c
set c=cl
%c% -I.. -I../bfp -I../bfp/bfp_LUSOL -I../bfp/bfp_LUSOL/LUSOL -I../colamd -I../shared /O1 /Zp8 /Gd -DWIN32 -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE -DYY_NEVER_INTERACTIVE -DPARSER_LP -DINVERSE_ACTIVE=INVERSE_LUSOL -DRoleIsExternalInvEngine demo.c %src% -o demo.exe
if exist *.obj del *.obj

View File

@ -1,10 +0,0 @@
@echo off
REM This batch file compiles the demo program with the Microsoft Visual C/C++ compiler under Windows
set src=../shared/commonlib.c ../shared/mmio.c ../shared/myblas.c ../ini.c ../lp_rlp.c ../lp_crash.c ../bfp/bfp_LUSOL/lp_LUSOL.c ../bfp/bfp_LUSOL/LUSOL/lusol.c ../lp_Hash.c ../lp_lib.c ../lp_wlp.c ../lp_matrix.c ../lp_mipbb.c ../lp_MPS.c ../lp_params.c ../lp_presolve.c ../lp_price.c ../lp_pricePSE.c ../lp_report.c ../lp_scale.c ../lp_simplex.c ../lp_SOS.c ../lp_utils.c ../yacc_read.c ../lp_MDO.c ../colamd/colamd.c
set c=cl
%c% -I.. -I../bfp -I../bfp/bfp_LUSOL -I../bfp/bfp_LUSOL/LUSOL -I../colamd -I../shared /O1 /Zp8 /Gd -DWIN32 -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE -DYY_NEVER_INTERACTIVE -DPARSER_LP -DINVERSE_ACTIVE=INVERSE_LUSOL -DRoleIsExternalInvEngine -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE demo.c %src% /Fedemo.exe
if exist *.obj del *.obj

View File

@ -1,265 +0,0 @@
/*
This program is originally made by by Jeroen J. Dirks (jeroend@tor.numetrix.com)
Adapted by Peter Notebaert (lpsolve@peno.be)
*/
#include <stdio.h>
#include "lp_lib.h"
#if defined FORTIFY
#include "lp_fortify.h"
int EndOfPgr(int i)
{
exit(i);
}
#endif
void press_ret(void)
{
#if !defined NORETURN
printf("[return]");
getchar();
#endif
}
int main(void)
{
# if defined ERROR
# undef ERROR
# endif
# define ERROR() { fprintf(stderr, "Error\n"); exit(1); }
lprec *lp;
int majorversion, minorversion, release, build;
#if defined FORTIFY
Fortify_EnterScope();
#endif
lp_solve_version(&majorversion, &minorversion, &release, &build);
printf("lp_solve %d.%d.%d.%d demo\n\n", majorversion, minorversion, release, build);
printf("This demo will show most of the features of lp_solve %d.%d.%d.%d\n", majorversion, minorversion, release, build);
press_ret();
printf("\nWe start by creating a new problem with 4 variables and 0 constraints\n");
printf("We use: lp=make_lp(0,4);\n");
if ((lp=make_lp(0,4)) == NULL)
ERROR();
press_ret();
printf("We can show the current problem with print_lp(lp)\n");
print_lp(lp);
press_ret();
printf("Now we add some constraints\n");
printf("str_add_constraint(lp, \"3 2 2 1\" ,LE,4)\n");
printf("This is the string version of add_constraint. For the normal version\n");
printf("of add_constraint see the help file\n");
if (!str_add_constraint(lp, "3 2 2 1", LE, 4))
ERROR();
print_lp(lp);
press_ret();
printf("str_add_constraint(lp, \"0 4 3 1\" ,GE,3)\n");
if (!str_add_constraint(lp, "0 4 3 1", GE, 3))
ERROR();
print_lp(lp);
press_ret();
printf("Set the objective function\n");
printf("str_set_obj_fn(lp, \"2 3 -2 3\")\n");
if (!str_set_obj_fn(lp, "2 3 -2 3"))
ERROR();
print_lp(lp);
press_ret();
printf("Now solve the problem with printf(solve(lp));\n");
printf("%d",solve(lp));
press_ret();
printf("The value is 0, this means we found an optimal solution\n");
printf("We can display this solution with print_objective(lp) and print_solution(lp)\n");
print_objective(lp);
print_solution(lp, 1);
print_constraints(lp, 1);
press_ret();
printf("The dual variables of the solution are printed with\n");
printf("print_duals(lp);\n");
print_duals(lp);
press_ret();
printf("We can change a single element in the matrix with\n");
printf("set_mat(lp,2,1,0.5)\n");
if (!set_mat(lp,2,1,0.5))
ERROR();
print_lp(lp);
press_ret();
printf("If we want to maximize the objective function use set_maxim(lp);\n");
set_maxim(lp);
print_lp(lp);
press_ret();
printf("after solving this gives us:\n");
solve(lp);
print_objective(lp);
print_solution(lp, 1);
print_constraints(lp, 1);
print_duals(lp);
press_ret();
printf("Change the value of a rhs element with set_rh(lp,1,7.45)\n");
set_rh(lp,1,7.45);
print_lp(lp);
solve(lp);
print_objective(lp);
print_solution(lp, 1);
print_constraints(lp, 1);
press_ret();
printf("We change %s to the integer type with\n", get_col_name(lp, 4));
printf("set_int(lp, 4, TRUE)\n");
set_int(lp, 4, TRUE);
print_lp(lp);
printf("We set branch & bound debugging on with set_debug(lp, TRUE)\n");
set_debug(lp, TRUE);
printf("and solve...\n");
press_ret();
solve(lp);
print_objective(lp);
print_solution(lp, 1);
print_constraints(lp, 1);
press_ret();
printf("We can set bounds on the variables with\n");
printf("set_lowbo(lp,2,2); & set_upbo(lp,4,5.3)\n");
set_lowbo(lp,2,2);
set_upbo(lp,4,5.3);
print_lp(lp);
press_ret();
solve(lp);
print_objective(lp);
print_solution(lp, 1);
print_constraints(lp, 1);
press_ret();
printf("Now remove a constraint with del_constraint(lp, 1)\n");
del_constraint(lp,1);
print_lp(lp);
printf("Add an equality constraint\n");
if (!str_add_constraint(lp, "1 2 1 4", EQ, 8))
ERROR();
print_lp(lp);
press_ret();
printf("A column can be added with:\n");
printf("str_add_column(lp,\"3 2 2\");\n");
if (!str_add_column(lp,"3 2 2"))
ERROR();
print_lp(lp);
press_ret();
printf("A column can be removed with:\n");
printf("del_column(lp,3);\n");
del_column(lp,3);
print_lp(lp);
press_ret();
printf("We can use automatic scaling with:\n");
printf("set_scaling(lp, SCALE_MEAN);\n");
set_scaling(lp, SCALE_MEAN);
print_lp(lp);
press_ret();
printf("The function get_mat(lprec *lp, int row, int column) returns a single\n");
printf("matrix element\n");
printf("%s get_mat(lp,2,3), get_mat(lp,1,1); gives\n","printf(\"%f %f\\n\",");
printf("%f %f\n", (double)get_mat(lp,2,3), (double)get_mat(lp,1,1));
printf("Notice that get_mat returns the value of the original unscaled problem\n");
press_ret();
printf("If there are any integer type variables, then only the rows are scaled\n");
printf("set_int(lp,3,FALSE);\n");
printf("set_scaling(lp, SCALE_MEAN);\n");
set_scaling(lp, SCALE_MEAN);
set_int(lp,3,FALSE);
print_lp(lp);
press_ret();
solve(lp);
printf("print_objective, print_solution gives the solution to the original problem\n");
print_objective(lp);
print_solution(lp, 1);
print_constraints(lp, 1);
press_ret();
printf("Scaling is turned off with unscale(lp);\n");
unscale(lp);
print_lp(lp);
press_ret();
printf("Now turn B&B debugging off and simplex tracing on with\n");
printf("set_debug(lp, FALSE), set_trace(lp, TRUE) and solve(lp)\n");
set_debug(lp, FALSE);
set_trace(lp, TRUE);
press_ret();
solve(lp);
printf("Where possible, lp_solve will start at the last found basis\n");
printf("We can reset the problem to the initial basis with\n");
printf("default_basis(lp). Now solve it again...\n");
press_ret();
default_basis(lp);
solve(lp);
printf("It is possible to give variables and constraints names\n");
printf("set_row_name(lp,1,\"speed\"); & set_col_name(lp,2,\"money\")\n");
if (!set_row_name(lp,1,"speed"))
ERROR();
if (!set_col_name(lp,2,"money"))
ERROR();
print_lp(lp);
printf("As you can see, all column and rows are assigned default names\n");
printf("If a column or constraint is deleted, the names shift place also:\n");
press_ret();
printf("del_column(lp,1);\n");
del_column(lp,1);
print_lp(lp);
press_ret();
delete_lp(lp);
#if FALSE
printf("A lp structure can be created and read from a .lp file\n");
printf("lp = read_lp(\"lp_examples/demo_lag.lp\", TRUE);\n");
printf("The verbose option is used\n");
if ((lp = read_LP("lp_examples/demo_lag.lp", TRUE, "test")) == NULL)
ERROR();
press_ret();
printf("lp is now:\n");
print_lp(lp);
press_ret();
printf("solution:\n");
set_debug(lp, TRUE);
solve(lp);
set_debug(lp, FALSE);
print_objective(lp);
print_solution(lp, 1);
print_constraints(lp, 1);
press_ret();
printf("You can see that branch & bound was used in this problem\n");
printf("Now remove the last constraint and use lagrangian relaxation\n");
printf("del_constraint(lp,6);\n");
printf("str_add_lag_con(lp, \"1 1 1 0 0 0\", LE, 2);\n");
del_constraint(lp,6);
if (!str_add_lag_con(lp, "1 1 1 0 0 0", LE, 2))
ERROR();
print_lp(lp);
printf("Lagrangian relaxation is used in some heuristics. It is now possible\n");
printf("to get a feasible integer solution without usage of branch & bound.\n");
printf("Use lag_solve(lp, 0, 30); 0 is the initial bound, 30 the maximum\n");
printf("number of iterations, the last variable turns the verbose mode on.\n");
press_ret();
set_lag_trace(lp, TRUE);
printf("%d\n",lag_solve(lp, 0, 30));
printf("The returncode of lag_solve is 6 or FEAS_FOUND. this means that a feasible\n");
printf("solution has been found. For a list of other possible return values\n");
printf("see the help file. Print this solution with print_objective, print_solution\n");
print_objective(lp);
print_solution(lp, 1);
print_constraints(lp, 1);
delete_lp(lp);
press_ret();
#endif
#if defined FORTIFY
Fortify_LeaveScope();
#endif
return(0);
}

View File

@ -1,19 +0,0 @@
Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo", "demo.vcproj", "{CED6B89F-02F2-4DB1-8610-4F12A6D02F54}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{CED6B89F-02F2-4DB1-8610-4F12A6D02F54}.Debug|Win32.ActiveCfg = Debug|Win32
{CED6B89F-02F2-4DB1-8610-4F12A6D02F54}.Debug|Win32.Build.0 = Debug|Win32
{CED6B89F-02F2-4DB1-8610-4F12A6D02F54}.Release|Win32.ActiveCfg = Release|Win32
{CED6B89F-02F2-4DB1-8610-4F12A6D02F54}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -1,311 +0,0 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="demo"
ProjectGUID="{CED6B89F-02F2-4DB1-8610-4F12A6D02F54}"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Release|Win32"
OutputDirectory=".\Release"
IntermediateDirectory=".\Release"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Release/demo.tlb"
/>
<Tool
Name="VCCLCompilerTool"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..;..\bfp;..\bfp\bfp_etaPFI;..\colamd;..\shared"
PreprocessorDefinitions="NDEBUG,WIN32,_CONSOLE,MSDOS,CHECK_SOLUTION,PARSER_LP,_CRT_SECURE_NO_DEPRECATE,_CRT_NONSTDC_NO_DEPRECATE,_SCL_SECURE_NO_DEPRECATE"
StringPooling="true"
RuntimeLibrary="0"
StructMemberAlignment="4"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="0"
PrecompiledHeaderFile=".\Release/demo.pch"
AssemblerListingLocation=".\Release/"
ObjectFile=".\Release/"
ProgramDataBaseFileName=".\Release/"
WarningLevel="3"
SuppressStartupBanner="true"
CompileAs="1"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="2067"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="odbc32.lib odbccp32.lib"
OutputFile=".\Release/demo.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
ProgramDatabaseFile=".\Release/demo.pdb"
SubSystem="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\Debug"
IntermediateDirectory=".\Debug"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Debug/demo.tlb"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..;..\bfp;..\bfp\bfp_etaPFI;..\colamd;..\shared"
PreprocessorDefinitions="_DEBUG,WIN32,_CONSOLE,MSDOS,CHECK_SOLUTION,FORTIFY,PARSER_LP,NORETURN,_CRT_SECURE_NO_DEPRECATE,_CRT_NONSTDC_NO_DEPRECATE,_SCL_SECURE_NO_DEPRECATE"
RuntimeLibrary="1"
StructMemberAlignment="4"
UsePrecompiledHeader="0"
PrecompiledHeaderFile=".\Debug/demo.pch"
AssemblerListingLocation=".\Debug/"
ObjectFile=".\Debug/"
ProgramDataBaseFileName=".\Debug/"
WarningLevel="3"
SuppressStartupBanner="true"
DebugInformationFormat="4"
CompileAs="1"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="2067"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="odbc32.lib odbccp32.lib"
OutputFile=".\Debug/demo.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
GenerateDebugInformation="true"
ProgramDatabaseFile=".\Debug/demo.pdb"
SubSystem="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<File
RelativePath="..\colamd\colamd.c"
>
</File>
<File
RelativePath="..\shared\commonlib.c"
>
</File>
<File
RelativePath="demo.c"
>
</File>
<File
RelativePath="..\fortify.c"
>
</File>
<File
RelativePath="..\ini.c"
>
</File>
<File
RelativePath="..\lp_crash.c"
>
</File>
<File
RelativePath="..\bfp\bfp_etaPFI\lp_etaPFI.c"
>
</File>
<File
RelativePath="..\lp_Hash.c"
>
</File>
<File
RelativePath="..\lp_lib.c"
>
</File>
<File
RelativePath="..\lp_matrix.c"
>
</File>
<File
RelativePath="..\lp_MDO.c"
>
</File>
<File
RelativePath="..\lp_mipbb.c"
>
</File>
<File
RelativePath="..\lp_MPS.c"
>
</File>
<File
RelativePath="..\lp_params.c"
>
</File>
<File
RelativePath="..\lp_presolve.c"
>
</File>
<File
RelativePath="..\lp_price.c"
>
</File>
<File
RelativePath="..\lp_pricePSE.c"
>
</File>
<File
RelativePath="..\lp_report.c"
>
</File>
<File
RelativePath="..\lp_rlp.c"
>
</File>
<File
RelativePath="..\lp_scale.c"
>
</File>
<File
RelativePath="..\lp_simplex.c"
>
</File>
<File
RelativePath="..\lp_SOS.c"
>
</File>
<File
RelativePath="..\lp_utils.c"
>
</File>
<File
RelativePath="..\lp_wlp.c"
>
</File>
<File
RelativePath="..\shared\mmio.c"
>
</File>
<File
RelativePath="..\shared\myblas.c"
>
</File>
<File
RelativePath="..\yacc_read.c"
>
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -1,19 +0,0 @@
Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo", "demolib.vcproj", "{CED6B89F-02F2-4DB1-8610-4F12A6D02F54}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{CED6B89F-02F2-4DB1-8610-4F12A6D02F54}.Debug|Win32.ActiveCfg = Debug|Win32
{CED6B89F-02F2-4DB1-8610-4F12A6D02F54}.Debug|Win32.Build.0 = Debug|Win32
{CED6B89F-02F2-4DB1-8610-4F12A6D02F54}.Release|Win32.ActiveCfg = Release|Win32
{CED6B89F-02F2-4DB1-8610-4F12A6D02F54}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -1,214 +0,0 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="demo"
ProjectGUID="{CED6B89F-02F2-4DB1-8610-4F12A6D02F54}"
RootNamespace="demo"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Release|Win32"
OutputDirectory=".\Release"
IntermediateDirectory=".\Release"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Release/demo.tlb"
/>
<Tool
Name="VCCLCompilerTool"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..;..\colamd"
PreprocessorDefinitions="NDEBUG,WIN32,_CONSOLE,MSDOS,CHECK_SOLUTION,PARSER_LP,_CRT_SECURE_NO_DEPRECATE,_CRT_NONSTDC_NO_DEPRECATE,_SCL_SECURE_NO_DEPRECATE"
StringPooling="true"
RuntimeLibrary="0"
StructMemberAlignment="4"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="0"
PrecompiledHeaderFile=".\Release/demo.pch"
AssemblerListingLocation=".\Release/"
ObjectFile=".\Release/"
ProgramDataBaseFileName=".\Release/"
WarningLevel="3"
SuppressStartupBanner="true"
CompileAs="1"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="2067"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="odbc32.lib odbccp32.lib liblpsolve55.lib"
OutputFile=".\Release/demo.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
AdditionalLibraryDirectories="..\lpsolve55"
ProgramDatabaseFile=".\Release/demo.pdb"
SubSystem="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\Debug"
IntermediateDirectory=".\Debug"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Debug/demo.tlb"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=".."
PreprocessorDefinitions="_DEBUG,WIN32,_CONSOLE,NOFORTIFY"
RuntimeLibrary="1"
StructMemberAlignment="4"
UsePrecompiledHeader="0"
PrecompiledHeaderFile=".\Debug/demo.pch"
AssemblerListingLocation=".\Debug/"
ObjectFile=".\Debug/"
ProgramDataBaseFileName=".\Debug/"
WarningLevel="3"
SuppressStartupBanner="true"
DebugInformationFormat="4"
CompileAs="1"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="2067"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="odbc32.lib odbccp32.lib liblpsolve5d.lib"
OutputFile=".\Debug/demo.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
AdditionalLibraryDirectories="..\lpsolve55"
GenerateDebugInformation="true"
ProgramDatabaseFile=".\Debug/demo.pdb"
SubSystem="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<File
RelativePath="demo.c"
>
</File>
<File
RelativePath="..\fortify.c"
>
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -1,6 +0,0 @@
This directory contains the files to build a demo program
To build the program under Windows with the Visual C/C++ compiler, use cvc6.bat (also works for VS.NET)
To build the program under DOS/Windows with the gcc compiler, use cgcc.bat
To build the program under Linux/Unix, use sh ccc
To build the program under Mac OS X 10.3.5, use sh ccc.osx

File diff suppressed because it is too large Load Diff

View File

@ -1,293 +0,0 @@
#ifndef __FORTIFY_H__
#define __FORTIFY_H__
/*
* FILE:
* fortify.h
*
* DESCRIPTION:
* Header file for fortify.c - A fortified shell for malloc, realloc,
* calloc, strdup, getcwd, tempnam & free
*
* WRITTEN:
* spb 29/4/94
*
* VERSION:
* 1.0 29/4/94
*/
#include <stdlib.h>
#include "declare.h"
#if defined HP9000 || defined AViiON || defined ALPHA || defined SIGNED_UNKNOWN
# define signed
#endif
#ifdef __cplusplus
extern "C" {
#endif
#ifdef FORTIFY
typedef void (*OutputFuncPtr) __OF((char *));
extern char *_Fortify_file;
extern int _Fortify_line;
#define Fortify_FILE(file) _Fortify_file=file
#define Fortify_LINE(line) _Fortify_line=line
#define _Fortify_FILE (_Fortify_file==(char *) 0 ? __FILE__ : _Fortify_file)
#define _Fortify_LINE (_Fortify_line==0 ? __LINE__ : _Fortify_line)
void _Fortify_Init __OF((char *file, unsigned long line));
void *_Fortify_malloc __OF((size_t size, char *file, unsigned long line));
void *_Fortify_realloc __OF((void *ptr, size_t new_size, char *file, unsigned long line));
void *_Fortify_calloc __OF((size_t nitems, size_t size, char *file, unsigned long line));
char *_Fortify_strdup __OF((char *str, char *file, unsigned long line));
void *_Fortify_memcpy __OF((void *to, void *from, size_t size, char *file, unsigned long line));
void *_Fortify_memmove __OF((void *to, void *from, size_t size, char *file, unsigned long line));
void *_Fortify_memccpy __OF((void *to, void *from, int c, size_t size, char *file, unsigned long line));
void *_Fortify_memset __OF((void *buffer, int c, size_t size, char *file, unsigned long line));
void *_Fortify_memchr __OF((void *buffer, int c, size_t size, char *file, unsigned long line));
int _Fortify_memcmp __OF((void *buffer1, void *buffer2, size_t size, char *file, unsigned long line));
int _Fortify_memicmp __OF((void *buffer1, void *buffer2, size_t size, char *file, unsigned long line));
char *_Fortify_strchr __OF((char *buffer, int c, char *file, unsigned long line));
char *_Fortify_strrchr __OF((char *buffer, int c, char *file, unsigned long line));
char *_Fortify_strlwr __OF((char *buffer, char *file, unsigned long line));
char *_Fortify_strupr __OF((char *buffer, char *file, unsigned long line));
char *_Fortify_strrev __OF((char *buffer, char *file, unsigned long line));
char *_Fortify_strset __OF((char *buffer, int c, char *file, unsigned long line));
char *_Fortify_strnset __OF((char *buffer, int c, size_t size, char *file, unsigned long line));
char *_Fortify_strstr __OF((char *to, char *from, char *file, unsigned long line));
char *_Fortify_strcpy __OF((char *to, char *from, char *file, unsigned long line));
char *_Fortify_strncpy __OF((char *to, char *from, size_t size, char *file, unsigned long line));
int _Fortify_strcmp __OF((char *buffer1, char *buffer2, char *file, unsigned long line));
double _Fortify_strtod __OF((char *buffer1, char **buffer2, char *file, unsigned long line));
long _Fortify_strtol __OF((char *buffer1, char **buffer2, int n, char *file, unsigned long line));
int _Fortify_atoi __OF((char *buffer1, char *file, unsigned long line));
long _Fortify_atol __OF((char *buffer1, char *file, unsigned long line));
double _Fortify_atof __OF((char *buffer1, char *file, unsigned long line));
unsigned long _Fortify_strtoul __OF((char *buffer1, char **buffer2, int n, char *file, unsigned long line));
size_t _Fortify_strcspn __OF((char *buffer1, char *buffer2, char *file, unsigned long line));
int _Fortify_strcoll __OF((char *buffer1, char *buffer2, char *file, unsigned long line));
int _Fortify_strcmpi __OF((char *buffer1, char *buffer2, char *file, unsigned long line));
int _Fortify_strncmp __OF((char *buffer1, char *buffer2, size_t size, char *file, unsigned long line));
int _Fortify_strnicmp __OF((char *buffer1, char *buffer2, size_t size, char *file, unsigned long line));
char *_Fortify_strcat __OF((char *buffer1, char *buffer2, char *file, unsigned long line));
char *_Fortify_strpbrk __OF((char *buffer1, char *buffer2, char *file, unsigned long line));
size_t _Fortify_strlen __OF((char *buffer, char *file, unsigned long line));
char *_Fortify_getcwd __OF((char *buf, int size, char *file, unsigned long line));
char *_Fortify_tempnam __OF((char *dir, char *pfx, char *file, unsigned long line));
void _Fortify_free __OF((void *uptr, char *file, unsigned long line));
int _Fortify_OutputAllMemory __OF((char *file, unsigned long line));
int _Fortify_CheckAllMemory __OF((char *file, unsigned long line));
int _Fortify_CheckPointer __OF((void *uptr, char *file, unsigned long line));
int _Fortify_Disable __OF((char *file, unsigned long line, int how));
int _Fortify_SetMallocFailRate __OF((int Percent));
int _Fortify_EnterScope __OF((char *file, unsigned long line));
int _Fortify_LeaveScope __OF((char *file, unsigned long line));
int _Fortify_DumpAllMemory __OF((int scope, char *file, unsigned long line));
typedef void (*Fortify_OutputFuncPtr) __OF((/* const */ char *));
Fortify_OutputFuncPtr _Fortify_SetOutputFunc __OF((Fortify_OutputFuncPtr Output));
#endif /* FORTIFY */
#ifdef __cplusplus
}
#endif
#ifndef __FORTIFY_C__ /* Only define the macros if we're NOT in fortify.c */
#ifdef FORTIFY /* Add file and line information to the fortify calls */
#if defined malloc
# undef malloc
#endif
#if defined realloc
# undef realloc
#endif
#if defined calloc
# undef calloc
#endif
#if defined strdup
# undef strdup
#endif
#if defined memcpy
# undef memcpy
#endif
#if defined memmove
# undef memmove
#endif
#if defined memccpy
# undef memccpy
#endif
#if defined memset
# undef memset
#endif
#if defined memchr
# undef memchr
#endif
#if defined memcmp
# undef memcmp
#endif
#if defined memicmp
# undef memicmp
#endif
#if defined strcoll
# undef strcoll
#endif
#if defined strcspn
# undef strcspn
#endif
#if defined strcmp
# undef strcmp
#endif
#if defined strcmpi
# undef strcmpi
#endif
#if defined stricmp
# undef stricmp
#endif
#if defined strncmp
# undef strncmp
#endif
#if defined strnicmp
# undef strnicmp
#endif
#if defined strlwr
# undef strlwr
#endif
#if defined strupr
# undef strupr
#endif
#if defined strrev
# undef strrev
#endif
#if defined strchr
# undef strchr
#endif
#if defined strrchr
# undef strrchr
#endif
#if defined strcat
# undef strcat
#endif
#if defined strpbrk
# undef strpbrk
#endif
#if defined strcpy
# undef strcpy
#endif
#if defined atoi
# undef atoi
#endif
#if defined atol
# undef atol
#endif
#if defined atof
# undef atof
#endif
#if defined strtol
# undef strtol
#endif
#if defined strtoul
# undef strtoul
#endif
#if defined strtod
# undef strtod
#endif
#if defined strstr
# undef strstr
#endif
#if defined strncpy
# undef strncpy
#endif
#if defined strset
# undef strset
#endif
#if defined strnset
# undef strnset
#endif
#if defined strlen
# undef strlen
#endif
#if defined getcwd
# undef getcwd
#endif
#if defined tempnam
# undef tempnam
#endif
#if defined free
# undef free
#endif
#define malloc(size) _Fortify_malloc(size, _Fortify_FILE, _Fortify_LINE)
#define realloc(ptr,new_size) _Fortify_realloc(ptr, new_size, _Fortify_FILE, _Fortify_LINE)
#define calloc(num,size) _Fortify_calloc(num, size, _Fortify_FILE, _Fortify_LINE)
#define strdup(str) _Fortify_strdup(str, _Fortify_FILE, _Fortify_LINE)
#define memcpy(to,from,size) _Fortify_memcpy((void *)(to),(void *)(from),size, _Fortify_FILE, _Fortify_LINE)
#define memmove(to,from,size) _Fortify_memmove((void *)(to),(void *)(from),size, _Fortify_FILE, _Fortify_LINE)
#define memccpy(to,from,c,size) _Fortify_memccpy((void *)(to),(void *)(from),c,size, _Fortify_FILE, _Fortify_LINE)
#define memset(buffer,c,size) _Fortify_memset(buffer,c,size, _Fortify_FILE, _Fortify_LINE)
#define memchr(buffer,c,size) _Fortify_memchr(buffer,c,size, _Fortify_FILE, _Fortify_LINE)
#define memcmp(buffer1,buffer2,size) _Fortify_memcmp((void *)buffer1,(void *)buffer2,size, _Fortify_FILE, _Fortify_LINE)
#define memicmp(buffer1,buffer2,size) _Fortify_memicmp((void *)buffer1,(void *)buffer2,size, _Fortify_FILE, _Fortify_LINE)
#define strlwr(buffer) _Fortify_strlwr(buffer, _Fortify_FILE, _Fortify_LINE)
#define strupr(buffer) _Fortify_strupr(buffer, _Fortify_FILE, _Fortify_LINE)
#define strrev(buffer) _Fortify_strrev(buffer, _Fortify_FILE, _Fortify_LINE)
#define strchr(buffer,c) _Fortify_strchr(buffer,c, _Fortify_FILE, _Fortify_LINE)
#define strrchr(buffer,c) _Fortify_strrchr(buffer,c, _Fortify_FILE, _Fortify_LINE)
#define strset(buffer,c) _Fortify_strset(buffer,c, _Fortify_FILE, _Fortify_LINE)
#define strnset(buffer,c) _Fortify_strnset(buffer,c, _Fortify_FILE, _Fortify_LINE)
#define strstr(buffer1,buffer2) _Fortify_strstr(buffer1,buffer2, _Fortify_FILE, _Fortify_LINE)
#define atoi(buffer) _Fortify_atoi(buffer, _Fortify_FILE, _Fortify_LINE)
#define atol(buffer) _Fortify_atol(buffer, _Fortify_FILE, _Fortify_LINE)
#define atof(buffer) _Fortify_atof(buffer, _Fortify_FILE, _Fortify_LINE)
#define strtol(buffer1,buffer2,n) _Fortify_strtol(buffer1,buffer2,n, _Fortify_FILE, _Fortify_LINE)
#define strtoul(buffer1,buffer2,n) _Fortify_strtoul(buffer1,buffer2,n, _Fortify_FILE, _Fortify_LINE)
#define strtod(buffer1,buffer2) _Fortify_strtod(buffer1,buffer2, _Fortify_FILE, _Fortify_LINE)
#define strcpy(to,from) _Fortify_strcpy((char *)(to),(char *)(from), _Fortify_FILE, _Fortify_LINE)
#define strncpy(to,from,size) _Fortify_strncpy((char *)(to),(char *)(from),size, _Fortify_FILE, _Fortify_LINE)
#define strcoll(buffer1,buffer2) _Fortify_strcoll((char *)(buffer1),(char *)(buffer2), _Fortify_FILE, _Fortify_LINE)
#define strcspn(buffer1,buffer2) _Fortify_strcspn((char*)(buffer1),(char *)(buffer2), _Fortify_FILE, _Fortify_LINE)
#define strcmp(buffer1,buffer2) _Fortify_strcmp((char *)(buffer1),(char *)(buffer2), _Fortify_FILE, _Fortify_LINE)
#define strcmpi(buffer1,buffer2) _Fortify_strcmpi((char *)(buffer1),(char *)(buffer2), _Fortify_FILE, _Fortify_LINE)
#define stricmp(buffer1,buffer2) _Fortify_strcmpi((char *)(buffer1),(char *)(buffer2), _Fortify_FILE, _Fortify_LINE)
#define strncmp(buffer1,buffer2,size) _Fortify_strncmp((char *)(buffer1),(char *)(buffer2),size, _Fortify_FILE, _Fortify_LINE)
#define strnicmp(buffer1,buffer2,size) _Fortify_strnicmp((char *)(buffer1),(char *)(buffer2),size, _Fortify_FILE, _Fortify_LINE)
#define strcat(buffer1,buffer2) _Fortify_strcat((char *)(buffer1),(char *)(buffer2), _Fortify_FILE, _Fortify_LINE)
#define strpbrk(buffer1,buffer2) _Fortify_strpbrk((char *)(buffer1),(char *)(buffer2), _Fortify_FILE, _Fortify_LINE)
#define strlen(buffer) _Fortify_strlen((char*)(buffer), _Fortify_FILE, _Fortify_LINE)
#define getcwd(buf,size) _Fortify_getcwd(buf, size, _Fortify_FILE, _Fortify_LINE)
#define tempnam(dir,pfx) _Fortify_tempnam(dir, pfx, _Fortify_FILE, _Fortify_LINE)
#define free(ptr) _Fortify_free(ptr, _Fortify_FILE, _Fortify_LINE)
#define Fortify_Init() _Fortify_Init(_Fortify_FILE, _Fortify_LINE)
#define Fortify_OutputAllMemory() _Fortify_OutputAllMemory(_Fortify_FILE, _Fortify_LINE)
#define Fortify_CheckAllMemory() _Fortify_CheckAllMemory(_Fortify_FILE, _Fortify_LINE)
#define Fortify_CheckPointer(ptr) _Fortify_CheckPointer(ptr, _Fortify_FILE, _Fortify_LINE)
#define Fortify_Disable(how) _Fortify_Disable(_Fortify_FILE, _Fortify_LINE,how)
#define Fortify_EnterScope() _Fortify_EnterScope(_Fortify_FILE, _Fortify_LINE)
#define Fortify_LeaveScope() _Fortify_LeaveScope(_Fortify_FILE, _Fortify_LINE)
#define Fortify_DumpAllMemory(s) _Fortify_DumpAllMemory(s,_Fortify_FILE, _Fortify_LINE)
#else /* FORTIFY Define the special fortify functions away to nothing */
#define Fortify_FILE(file)
#define Fortify_LINE(line)
#define Fortify_Init()
#define Fortify_OutputAllMemory() 0
#define Fortify_CheckAllMemory() 0
#define Fortify_CheckPointer(ptr) 1
#define Fortify_Disable(how) 1
#define Fortify_SetOutputFunc() 0
#define Fortify_SetMallocFailRate(p) 0
#define Fortify_EnterScope() 0
#define Fortify_LeaveScope() 0
#define Fortify_DumpAllMemory(s) 0
#endif /* FORTIFY */
#endif /* __FORTIFY_C__ */
#endif /* __FORTIFY_H__ */

View File

@ -1,76 +0,0 @@
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include "lp_lib.h"
#include "ini.h"
FILE *ini_create(char *filename)
{
FILE *fp;
fp = fopen(filename, "w");
return(fp);
}
FILE *ini_open(char *filename)
{
FILE *fp;
fp = fopen(filename, "r");
return(fp);
}
void ini_writecomment(FILE *fp, char *comment)
{
fprintf(fp, "; %s\n", comment);
}
void ini_writeheader(FILE *fp, char *header, int addnewline)
{
if((addnewline) && (ftell(fp) > 0))
fputs("\n", fp);
fprintf(fp, "[%s]\n", header);
}
void ini_writedata(FILE *fp, char *name, char *data)
{
if(name != NULL)
fprintf(fp, "%s=%s\n", name, data);
else
fprintf(fp, "%s\n", data);
}
int ini_readdata(FILE *fp, char *data, int szdata, int withcomment)
{
int l;
char *ptr;
if(fgets(data, szdata, fp) == NULL)
return(0);
if(!withcomment) {
ptr = strchr(data, ';');
if(ptr != NULL)
*ptr = 0;
}
l = strlen(data);
while((l > 0) && (isspace(data[l - 1])))
l--;
data[l] = 0;
if((l >= 2) && (data[0] == '[') && (data[l - 1] == ']')) {
memcpy(data, data + 1, l - 2);
data[l - 2] = 0;
return(1);
}
return(2);
}
void ini_close(FILE *fp)
{
fclose(fp);
}

View File

@ -1,17 +0,0 @@
#include <stdio.h>
#ifdef __cplusplus
__EXTERN_C {
#endif
extern FILE *ini_create(char *filename);
extern FILE *ini_open(char *filename);
extern void ini_writecomment(FILE *fp, char *comment);
extern void ini_writeheader(FILE *fp, char *header, int addnewline);
extern void ini_writedata(FILE *fp, char *name, char *data);
extern int ini_readdata(FILE *fp, char *data, int szdata, int withcomment);
extern void ini_close(FILE *fp);
#ifdef __cplusplus
}
#endif

View File

@ -1,238 +0,0 @@
#include <stdlib.h>
#include <string.h>
#include "lp_lib.h"
#include "lp_utils.h"
#include "lp_report.h"
#include "lp_Hash.h"
#ifdef FORTIFY
# include "lp_fortify.h"
#endif
#define HASH_START_SIZE 5000 /* Hash table size for row and column name storage */
#define NUMHASHPRIMES 45
STATIC hashtable *create_hash_table(int size, int base)
{
int i;
int HashPrimes[ ] = {
29, 229, 883, 1671, 2791, 4801, 8629, 10007,
15289, 25303, 34843, 65269, 99709, 129403, 147673, 166669,
201403, 222163, 242729, 261431, 303491, 320237, 402761, 501131,
602309, 701507, 800999, 900551, 1000619, 1100837, 1200359, 1300021,
1400017, 1500007, 1750009, 2000003, 2500009, 3000017, 4000037, 5000011,
6000011, 7000003, 8000009, 9000011, 9999991};
hashtable *ht;
/* Find a good size for the hash table */
if(size < HASH_START_SIZE)
size = HASH_START_SIZE;
for(i = 0; i < NUMHASHPRIMES-1; i++)
if(HashPrimes[i] > size)
break;
size = HashPrimes[i];
/* Then allocate and initialize memory */
ht = (hashtable *) calloc(1 , sizeof(*ht));
ht->table = (hashelem **) calloc(size, sizeof(*(ht->table)));
ht->size = size;
ht->base = base;
ht->count = base-1;
return(ht);
}
STATIC void free_hash_item(hashelem **hp)
{
free((*hp)->name);
free(*hp);
*hp = NULL;
}
STATIC void free_hash_table(hashtable *ht)
{
hashelem *hp, *thp;
hp = ht->first;
while(hp != NULL) {
thp = hp;
hp = hp->nextelem;
free_hash_item(&thp);
}
free(ht->table);
free(ht);
}
/* make a good hash function for any int size */
/* inspired by Aho, Sethi and Ullman, Compilers ..., p436 */
#define HASH_1 sizeof(unsigned int)
#define HASH_2 (sizeof(unsigned int) * 6)
#define HASH_3 (((unsigned int)0xF0) << ((sizeof(unsigned int) - 1) * CHAR_BIT))
STATIC int hashval(const char *string, int size)
{
unsigned int result = 0, tmp;
for(; *string; string++) {
result = (result << HASH_1) + *string;
if((tmp = result & HASH_3) != 0) {
/* if any of the most significant bits is on */
result ^= tmp >> HASH_2; /* xor them in in a less significant part */
result ^= tmp; /* and reset the most significant bits to 0 */
}
}
return(result % size);
} /* hashval */
STATIC hashelem *findhash(const char *name, hashtable *ht)
{
hashelem *h_tab_p;
for(h_tab_p = ht->table[hashval(name, ht->size)];
h_tab_p != NULL;
h_tab_p = h_tab_p->next)
if(strcmp(name, h_tab_p->name) == 0) /* got it! */
break;
return(h_tab_p);
} /* findhash */
STATIC hashelem *puthash(const char *name, int index, hashelem **list, hashtable *ht)
{
hashelem *hp = NULL;
int hashindex;
if(list != NULL) {
hp = list[index];
if(hp != NULL)
list[index] = NULL;
}
if((hp = findhash(name, ht)) == NULL) {
hashindex = hashval(name, ht->size);
hp = (hashelem *) calloc(1, sizeof(*hp));
allocCHAR(NULL, &hp->name, (int) (strlen(name) + 1), FALSE);
strcpy(hp->name, name);
hp->index = index;
ht->count++;
if(list != NULL)
list[index] = hp;
hp->next = ht->table[hashindex];
ht->table[hashindex] = hp;
if(ht->first == NULL)
ht->first = hp;
if(ht->last != NULL)
ht->last->nextelem = hp;
ht->last = hp;
}
return(hp);
}
STATIC void drophash(const char *name, hashelem **list, hashtable *ht) {
hashelem *hp, *hp1, *hp2;
int hashindex;
if((hp = findhash(name, ht)) != NULL) {
hashindex = hashval(name, ht->size);
if((hp1 = ht->table[hashindex]) != NULL) {
hp2 = NULL;
while((hp1 != NULL) && (hp1 != hp)) {
hp2 = hp1;
hp1 = hp1->next;
}
if(hp1 == hp) {
if(hp2 != NULL)
hp2->next = hp->next;
else
ht->table[hashindex] = hp->next;
}
hp1 = ht->first;
hp2 = NULL;
while((hp1 != NULL) && (hp1 != hp)) {
hp2 = hp1;
hp1 = hp1->nextelem;
}
if(hp1 == hp) {
if(hp2 != NULL)
hp2->nextelem = hp->nextelem;
else {
ht->first = hp->nextelem;
if (ht->first == NULL)
ht->last = NULL;
}
}
if(list != NULL)
list[hp->index] = NULL;
free_hash_item(&hp);
ht->count--;
}
}
}
STATIC hashtable *copy_hash_table(hashtable *ht, hashelem **list, int newsize)
{
hashtable *copy;
hashelem *elem, *new_elem;
if(newsize < ht->size)
newsize = ht->size;
copy = create_hash_table(newsize, ht->base);
if (copy != NULL) {
elem = ht->first;
while (elem != NULL) {
if((new_elem = puthash(elem->name, elem->index, list, copy)) == NULL) {
free_hash_table(copy);
return(NULL);
}
elem = elem ->nextelem;
}
}
return(copy);
}
STATIC int find_row(lprec *lp, char *name, MYBOOL Unconstrained_rows_found)
{
hashelem *hp;
if (lp->rowname_hashtab != NULL)
hp = findhash(name, lp->rowname_hashtab);
else
hp = NULL;
if (hp == NULL) {
if(Unconstrained_rows_found) { /* just ignore them in this case */
return(-1);
}
else {
return(-1);
}
}
return(hp->index);
}
STATIC int find_var(lprec *lp, char *name, MYBOOL verbose)
{
hashelem *hp;
if (lp->colname_hashtab != NULL)
hp = findhash(name, lp->colname_hashtab);
else
hp = NULL;
if (hp == NULL) {
if(verbose)
report(lp, SEVERE, "find_var: Unknown variable name '%s'\n", name);
return(-1);
}
return(hp->index);
}

View File

@ -1,43 +0,0 @@
#ifndef HEADER_lp_hash
#define HEADER_lp_hash
/* For row and column name hash tables */
typedef struct _hashelem
{
char *name;
int index;
struct _hashelem *next;
struct _hashelem *nextelem;
} hashelem;
typedef struct _hashtable
{
hashelem **table;
int size;
int base;
int count;
struct _hashelem *first;
struct _hashelem *last;
} hashtable;
#ifdef __cplusplus
extern "C" {
#endif
STATIC hashtable *create_hash_table(int size, int base);
STATIC void free_hash_table(hashtable *ht);
STATIC hashelem *findhash(const char *name, hashtable *ht);
STATIC hashelem *puthash(const char *name, int index, hashelem **list, hashtable *ht);
STATIC void drophash(const char *name, hashelem **list, hashtable *ht);
STATIC void free_hash_item(hashelem **hp);
STATIC hashtable *copy_hash_table(hashtable *ht, hashelem **list, int newsize);
STATIC int find_var(lprec *lp, char *name, MYBOOL verbose);
STATIC int find_row(lprec *lp, char *name, MYBOOL Unconstrained_rows_found);
#ifdef __cplusplus
}
#endif
#endif /* HEADER_lp_hash */

View File

@ -1,241 +0,0 @@
/*
Minimum matrix inverse fill-in modules - interface for lp_solve v5.0+
----------------------------------------------------------------------------------
Author: Kjell Eikland
Contact: kjell.eikland@broadpark.no
License terms: LGPL.
Requires: string.h, colamd.h, lp_lib.h
Release notes:
v1.0 1 September 2003 Preprocessing routines for minimum fill-in column
ordering for inverse factorization using the open
source COLAMD library. Suitable for the dense parts
of both the product form and LU factorization inverse
methods.
v1.1 1 July 2004 Renamed from lp_colamdMDO to lp_MDO.
----------------------------------------------------------------------------------
*/
#include <string.h>
#include "commonlib.h"
#include "lp_lib.h"
#include "colamd.h"
#include "lp_MDO.h"
#ifdef FORTIFY
# include "lp_fortify.h"
#endif
STATIC MYBOOL includeMDO(MYBOOL *usedpos, int item)
{
/* Legend: TRUE => A basic slack variable already in the basis
FALSE => A column free for being pivoted in
AUTOMATIC+TRUE => A row-singleton user column pivoted into the basis
AUTOMATIC+FALSE => A column-singleton user column pivoted into the basis */
/* Handle case where we are processing all columns */
if(usedpos == NULL)
return( TRUE );
else {
/* Otherwise do the selective case */
MYBOOL test = usedpos[item];
#if 1
return( test != TRUE );
#else
test = test & TRUE;
return( test == FALSE );
#endif
}
}
STATIC int prepareMDO(lprec *lp, MYBOOL *usedpos, int *colorder, int *data, int *rowmap)
/* This routine prepares data structures for colamd(). It is called twice, the first
time to count applicable non-zero elements by column, and the second time to fill in
the row indexes of the non-zero values from the first call. Note that the colamd()
row index base is 0 (which suits lp_solve fine). */
{
int i, ii, j, k, kk;
int nrows = lp->rows+1, ncols = colorder[0];
int offset = 0, Bnz = 0, Tnz;
MYBOOL dotally = (MYBOOL) (rowmap == NULL);
MATrec *mat = lp->matA;
REAL hold;
REAL *value;
int *rownr;
if(dotally)
data[0] = 0;
Tnz = nrows - ncols;
for(j = 1; j <= ncols; j++) {
kk = colorder[j];
/* Process slacks */
if(kk <= lp->rows) {
if(includeMDO(usedpos, kk)) {
if(!dotally)
data[Bnz] = rowmap[kk]+offset;
Bnz++;
}
Tnz++;
}
/* Process user columns */
else {
k = kk - lp->rows;
i = mat->col_end[k-1];
ii= mat->col_end[k];
Tnz += ii-i;
#ifdef Paranoia
if(i >= ii)
lp->report(lp, SEVERE, "prepareMDO: Encountered empty basic column %d\n", k);
#endif
/* Detect if we need to do phase 1 adjustments of zero-valued OF variable */
rownr = &COL_MAT_ROWNR(i);
value = &COL_MAT_VALUE(i);
hold = 0;
if((*rownr > 0) && includeMDO(usedpos, 0) && modifyOF1(lp, kk, &hold, 1.0)) {
if(!dotally)
data[Bnz] = offset;
Bnz++;
}
/* Loop over all NZ-variables */
for(; i < ii;
i++, value += matValueStep, rownr += matRowColStep) {
if(!includeMDO(usedpos, *rownr))
continue;
/* See if we need to change phase 1 OF value */
if(*rownr == 0) {
hold = *value;
if(!modifyOF1(lp, kk, &hold, 1.0))
continue;
}
/* Tally uneliminated constraint row values */
if(!dotally)
data[Bnz] = rowmap[*rownr]+offset;
Bnz++;
}
}
if(dotally)
data[j] = Bnz;
}
return( Tnz );
}
STATIC MYBOOL verifyMDO(lprec *lp, int *col_end, int *row_nr, int rowmax, int colmax)
{
int i, j, n, err = 0;
for(i = 1; i <= colmax; i++) {
n = 0;
for(j = col_end[i-1]; (j < col_end[i]) && (err == 0); j++, n++) {
if(row_nr[j] < 0 || row_nr[j] > rowmax)
err = 1;
if(n > 0 && row_nr[j] <= row_nr[j-1])
err = 2;
n++;
}
}
if(err != 0)
lp->report(lp, SEVERE, "verifyMDO: Invalid MDO input structure generated (error %d)\n", err);
return( (MYBOOL) (err == 0) );
}
void *mdo_calloc(size_t size, size_t count)
{
return ( calloc(size, count) );
}
void mdo_free(void *mem)
{
free( mem );
}
int __WINAPI getMDO(lprec *lp, MYBOOL *usedpos, int *colorder, int *size, MYBOOL symmetric)
{
int error = FALSE;
int nrows = lp->rows+1, ncols = colorder[0];
int i, j, kk, n;
int *col_end, *row_map = NULL;
int Bnz, Blen, *Brows = NULL;
int stats[COLAMD_STATS];
double knobs[COLAMD_KNOBS];
/* Tally the non-zero counts of the unused columns/rows of the
basis matrix and store corresponding "net" starting positions */
allocINT(lp, &col_end, ncols+1, FALSE);
n = prepareMDO(lp, usedpos, colorder, col_end, NULL);
Bnz = col_end[ncols];
/* Check that we have unused basic columns, otherwise skip analysis */
if(ncols == 0 || Bnz == 0)
goto Transfer;
/* Get net number of rows and fill mapper */
allocINT(lp, &row_map, nrows, FALSE);
nrows = 0;
for(i = 0; i <= lp->rows; i++) {
row_map[i] = i-nrows;
/* Increment eliminated row counter if necessary */
if(!includeMDO(usedpos, i))
nrows++;
}
nrows = lp->rows+1 - nrows;
/* Store row indeces of non-zero values in the basic columns */
Blen = colamd_recommended(Bnz, nrows, ncols);
allocINT(lp, &Brows, Blen, FALSE);
prepareMDO(lp, usedpos, colorder, Brows, row_map);
#ifdef Paranoia
verifyMDO(lp, col_end, Brows, nrows, ncols);
#endif
/* Compute the MDO */
#if 1
colamd_set_defaults(knobs);
knobs [COLAMD_DENSE_ROW] = 0.2+0.2 ; /* default changed for UMFPACK */
knobs [COLAMD_DENSE_COL] = knobs [COLAMD_DENSE_ROW];
if(symmetric && (nrows == ncols)) {
MEMCOPY(colorder, Brows, ncols + 1);
error = !symamd(nrows, colorder, col_end, Brows, knobs, stats, mdo_calloc, mdo_free);
}
else
error = !colamd(nrows, ncols, Blen, Brows, col_end, knobs, stats);
#else
if(symmetric && (nrows == ncols)) {
MEMCOPY(colorder, Brows, ncols + 1);
error = !symamd(nrows, colorder, col_end, Brows, knobs, stats, mdo_calloc, mdo_free);
}
else
error = !colamd(nrows, ncols, Blen, Brows, col_end, (double *) NULL, stats);
#endif
/* Transfer the estimated optimal ordering, adjusting for index offsets */
Transfer:
if(error)
error = stats[COLAMD_STATUS];
else {
MEMCOPY(Brows, colorder, ncols + 1);
for(j = 0; j < ncols; j++) {
kk = col_end[j];
n = Brows[kk+1];
colorder[j+1] = n;
}
}
/* Free temporary vectors */
FREE(col_end);
if(row_map != NULL)
FREE(row_map);
if(Brows != NULL)
FREE(Brows);
if(size != NULL)
*size = ncols;
return( error );
}

View File

@ -1,18 +0,0 @@
#ifndef HEADER_MDO
#define HEADER_MDO
#include "lp_types.h"
#ifdef __cplusplus
extern "C" {
#endif
int __WINAPI getMDO(lprec *lp, MYBOOL *usedpos, int *colorder, int *size, MYBOOL symmetric);
#ifdef __cplusplus
}
#endif
#endif /* HEADER_MDO */

File diff suppressed because it is too large Load Diff

View File

@ -1,33 +0,0 @@
#ifndef HEADER_lp_MPS
#define HEADER_lp_MPS
#include "lp_types.h"
/* For MPS file reading and writing */
#define ROWNAMEMASK "R%d"
#define ROWNAMEMASK2 "r%d"
#define COLNAMEMASK "C%d"
#define COLNAMEMASK2 "c%d"
#ifdef __cplusplus
extern "C" {
#endif
/* Read an MPS file */
MYBOOL MPS_readfile(lprec **newlp, char *filename, int typeMPS, int verbose);
MYBOOL __WINAPI MPS_readhandle(lprec **newlp, FILE *filehandle, int typeMPS, int verbose);
/* Write a MPS file to output */
MYBOOL MPS_writefile(lprec *lp, int typeMPS, char *filename);
MYBOOL MPS_writehandle(lprec *lp, int typeMPS, FILE *output);
/* Read and write BAS files */
MYBOOL MPS_readBAS(lprec *lp, int typeMPS, char *filename, char *info);
MYBOOL MPS_writeBAS(lprec *lp, int typeMPS, char *filename);
#ifdef __cplusplus
}
#endif
#endif /* HEADER_lp_MPS */

File diff suppressed because it is too large Load Diff

View File

@ -1,108 +0,0 @@
#ifndef HEADER_lp_SOS
#define HEADER_lp_SOS
/* Specially Ordered Sets (SOS) prototypes and settings */
/* ------------------------------------------------------------------------- */
#include "lp_types.h"
#include "lp_utils.h"
#include "lp_matrix.h"
/* SOS constraint defines */
/* ------------------------------------------------------------------------- */
#define SOS1 1
#define SOS2 2
#define SOS3 -1
#define SOSn MAXINT32
#define SOS_START_SIZE 10 /* Start size of SOS_list array; realloced if needed */
/* Define SOS_is_feasible() return values */
/* ------------------------------------------------------------------------- */
#define SOS3_INCOMPLETE -2
#define SOS_INCOMPLETE -1
#define SOS_COMPLETE 0
#define SOS_INFEASIBLE 1
#define SOS_INTERNALERROR 2
typedef struct _SOSgroup SOSgroup;
typedef struct _SOSrec
{
SOSgroup *parent;
int tagorder;
char *name;
int type;
MYBOOL isGUB;
int size;
int priority;
int *members;
REAL *weights;
int *membersSorted;
int *membersMapped;
} SOSrec;
/* typedef */ struct _SOSgroup
{
lprec *lp; /* Pointer to owner */
SOSrec **sos_list; /* Array of pointers to SOS lists */
int sos_alloc; /* Size allocated to specially ordered sets (SOS1, SOS2...) */
int sos_count; /* Number of specially ordered sets (SOS1, SOS2...) */
int maxorder; /* The highest-order SOS in the group */
int sos1_count; /* Number of the lowest order SOS in the group */
int *membership; /* Array of variable-sorted indeces to SOSes that the variable is member of */
int *memberpos; /* Starting positions of the each column's membership list */
} /* SOSgroup */;
#ifdef __cplusplus
extern "C" {
#endif
/* SOS storage structure */
STATIC SOSgroup *create_SOSgroup(lprec *lp);
STATIC void resize_SOSgroup(SOSgroup *group);
STATIC int append_SOSgroup(SOSgroup *group, SOSrec *SOS);
STATIC int clean_SOSgroup(SOSgroup *group, MYBOOL forceupdatemap);
STATIC void free_SOSgroup(SOSgroup **group);
STATIC SOSrec *create_SOSrec(SOSgroup *group, char *name, int type, int priority, int size, int *variables, REAL *weights);
STATIC MYBOOL delete_SOSrec(SOSgroup *group, int sosindex);
STATIC int append_SOSrec(SOSrec *SOS, int size, int *variables, REAL *weights);
STATIC void free_SOSrec(SOSrec *SOS);
/* SOS utilities */
STATIC int make_SOSchain(lprec *lp, MYBOOL forceresort);
STATIC int SOS_member_updatemap(SOSgroup *group);
STATIC MYBOOL SOS_member_sortlist(SOSgroup *group, int sosindex);
STATIC MYBOOL SOS_shift_col(SOSgroup *group, int sosindex, int column, int delta, LLrec *usedmap, MYBOOL forceresort);
int SOS_member_delete(SOSgroup *group, int sosindex, int member);
int SOS_get_type(SOSgroup *group, int sosindex);
int SOS_infeasible(SOSgroup *group, int sosindex);
int SOS_member_index(SOSgroup *group, int sosindex, int member);
int SOS_member_count(SOSgroup *group, int sosindex);
int SOS_memberships(SOSgroup *group, int column);
int *SOS_get_candidates(SOSgroup *group, int sosindex, int column, MYBOOL excludetarget, REAL *upbound, REAL *lobound);
int SOS_is_member(SOSgroup *group, int sosindex, int column);
MYBOOL SOS_is_member_of_type(SOSgroup *group, int column, int sostype);
MYBOOL SOS_set_GUB(SOSgroup *group, int sosindex, MYBOOL state);
MYBOOL SOS_is_GUB(SOSgroup *group, int sosindex);
MYBOOL SOS_is_marked(SOSgroup *group, int sosindex, int column);
MYBOOL SOS_is_active(SOSgroup *group, int sosindex, int column);
MYBOOL SOS_is_full(SOSgroup *group, int sosindex, int column, MYBOOL activeonly);
MYBOOL SOS_can_activate(SOSgroup *group, int sosindex, int column);
MYBOOL SOS_set_marked(SOSgroup *group, int sosindex, int column, MYBOOL asactive);
MYBOOL SOS_unmark(SOSgroup *group, int sosindex, int column);
int SOS_fix_unmarked(SOSgroup *group, int sosindex, int variable, REAL *bound, REAL value,
MYBOOL isupper, int *diffcount, DeltaVrec *changelog);
int SOS_fix_list(SOSgroup *group, int sosindex, int variable, REAL *bound,
int *varlist, MYBOOL isleft, DeltaVrec *changelog);
int SOS_is_satisfied(SOSgroup *group, int sosindex, REAL *solution);
MYBOOL SOS_is_feasible(SOSgroup *group, int sosindex, REAL *solution);
#ifdef __cplusplus
}
#endif
#endif /* HEADER_lp_SOS */

View File

@ -1,727 +0,0 @@
/*
----------------------------------------------------------------------------------
Crash management routines in lp_solve v5.0+
----------------------------------------------------------------------------------
Author: Kjell Eikland
Contact: kjell.eikland@broadpark.no
License terms: LGPL.
Requires: lp_lib.h, lp_utils.h, lp_matrix.h
Release notes:
v1.0.0 1 April 2004 First version.
v1.1.0 20 July 2004 Reworked with flexible matrix storage model.
----------------------------------------------------------------------------------
*/
#include <string.h>
#include "commonlib.h"
#include "lp_lib.h"
#include "lp_scale.h"
#include "lp_utils.h"
#include "lp_report.h"
#include "lp_matrix.h"
#include "lp_crash.h"
#ifdef FORTIFY
# include "lp_fortify.h"
#endif
MYBOOL crash_basis(lprec *lp)
{
int i;
MATrec *mat = lp->matA;
MYBOOL ok = TRUE;
/* Initialize basis indicators */
if(lp->basis_valid)
lp->var_basic[0] = FALSE;
else
default_basis(lp);
/* Set initial partial pricing blocks */
if(lp->rowblocks != NULL)
lp->rowblocks->blocknow = 1;
if(lp->colblocks != NULL)
lp->colblocks->blocknow = ((lp->crashmode == CRASH_NONE) || (lp->colblocks->blockcount == 1) ? 1 : 2);
/* Construct a basis that is in some measure the "most feasible" */
if((lp->crashmode == CRASH_MOSTFEASIBLE) && mat_validate(mat)) {
/* The logic here follows Maros */
LLrec *rowLL = NULL, *colLL = NULL;
int ii, rx, cx, ix, nz;
REAL wx, tx, *rowMAX = NULL, *colMAX = NULL;
int *rowNZ = NULL, *colNZ = NULL, *rowWT = NULL, *colWT = NULL;
REAL *value;
int *rownr, *colnr;
report(lp, NORMAL, "crash_basis: 'Most feasible' basis crashing selected\n");
/* Tally row and column non-zero counts */
ok = allocINT(lp, &rowNZ, lp->rows+1, TRUE) &&
allocINT(lp, &colNZ, lp->columns+1, TRUE) &&
allocREAL(lp, &rowMAX, lp->rows+1, FALSE) &&
allocREAL(lp, &colMAX, lp->columns+1, FALSE);
if(!ok)
goto Finish;
nz = mat_nonzeros(mat);
rownr = &COL_MAT_ROWNR(0);
colnr = &COL_MAT_COLNR(0);
value = &COL_MAT_VALUE(0);
for(i = 0; i < nz;
i++, rownr += matRowColStep, colnr += matRowColStep, value += matValueStep) {
rx = *rownr;
cx = *colnr;
wx = fabs(*value);
rowNZ[rx]++;
colNZ[cx]++;
if(i == 0) {
rowMAX[rx] = wx;
colMAX[cx] = wx;
colMAX[0] = wx;
}
else {
SETMAX(rowMAX[rx], wx);
SETMAX(colMAX[cx], wx);
SETMAX(colMAX[0], wx);
}
}
/* Reduce counts for small magnitude to preserve stability */
rownr = &COL_MAT_ROWNR(0);
colnr = &COL_MAT_COLNR(0);
value = &COL_MAT_VALUE(0);
for(i = 0; i < nz;
i++, rownr += matRowColStep, colnr += matRowColStep, value += matValueStep) {
rx = *rownr;
cx = *colnr;
wx = fabs(*value);
#ifdef CRASH_SIMPLESCALE
if(wx < CRASH_THRESHOLD * colMAX[0]) {
rowNZ[rx]--;
colNZ[cx]--;
}
#else
if(wx < CRASH_THRESHOLD * rowMAX[rx])
rowNZ[rx]--;
if(wx < CRASH_THRESHOLD * colMAX[cx])
colNZ[cx]--;
#endif
}
/* Set up priority tables */
ok = allocINT(lp, &rowWT, lp->rows+1, TRUE);
createLink(lp->rows, &rowLL, NULL);
ok &= (rowLL != NULL);
if(!ok)
goto Finish;
for(i = 1; i <= lp->rows; i++) {
if(get_constr_type(lp, i)==EQ)
ii = 3;
else if(lp->upbo[i] < lp->infinite)
ii = 2;
else if(fabs(lp->rhs[i]) < lp->infinite)
ii = 1;
else
ii = 0;
rowWT[i] = ii;
if(ii > 0)
appendLink(rowLL, i);
}
ok = allocINT(lp, &colWT, lp->columns+1, TRUE);
createLink(lp->columns, &colLL, NULL);
ok &= (colLL != NULL);
if(!ok)
goto Finish;
for(i = 1; i <= lp->columns; i++) {
ix = lp->rows+i;
if(is_unbounded(lp, i))
ii = 3;
else if(lp->upbo[ix] >= lp->infinite)
ii = 2;
else if(fabs(lp->upbo[ix]-lp->lowbo[ix]) > lp->epsmachine)
ii = 1;
else
ii = 0;
colWT[i] = ii;
if(ii > 0)
appendLink(colLL, i);
}
/* Loop over all basis variables */
for(i = 1; i <= lp->rows; i++) {
/* Select row */
rx = 0;
wx = -lp->infinite;
for(ii = firstActiveLink(rowLL); ii > 0; ii = nextActiveLink(rowLL, ii)) {
tx = rowWT[ii] - CRASH_SPACER*rowNZ[ii];
if(tx > wx) {
rx = ii;
wx = tx;
}
}
if(rx == 0)
break;
removeLink(rowLL, rx);
/* Select column */
cx = 0;
wx = -lp->infinite;
for(ii = mat->row_end[rx-1]; ii < mat->row_end[rx]; ii++) {
/* Update NZ column counts for row selected above */
tx = fabs(ROW_MAT_VALUE(ii));
ix = ROW_MAT_COLNR(ii);
#ifdef CRASH_SIMPLESCALE
if(tx >= CRASH_THRESHOLD * colMAX[0])
#else
if(tx >= CRASH_THRESHOLD * colMAX[ix])
#endif
colNZ[ix]--;
if(!isActiveLink(colLL, ix) || (tx < CRASH_THRESHOLD * rowMAX[rx]))
continue;
/* Now do the test for best pivot */
tx = my_sign(lp->orig_obj[ix]) - my_sign(ROW_MAT_VALUE(ii));
tx = colWT[ix] + CRASH_WEIGHT*tx - CRASH_SPACER*colNZ[ix];
if(tx > wx) {
cx = ix;
wx = tx;
}
}
if(cx == 0)
break;
removeLink(colLL, cx);
/* Update row NZ counts */
ii = mat->col_end[cx-1];
rownr = &COL_MAT_ROWNR(ii);
value = &COL_MAT_VALUE(ii);
for(; ii < mat->col_end[cx];
ii++, rownr += matRowColStep, value += matValueStep) {
wx = fabs(*value);
ix = *rownr;
#ifdef CRASH_SIMPLESCALE
if(wx >= CRASH_THRESHOLD * colMAX[0])
#else
if(wx >= CRASH_THRESHOLD * rowMAX[ix])
#endif
rowNZ[ix]--;
}
/* Set new basis variable */
set_basisvar(lp, rx, lp->rows+cx);
}
/* Clean up */
Finish:
FREE(rowNZ);
FREE(colNZ);
FREE(rowMAX);
FREE(colMAX);
FREE(rowWT);
FREE(colWT);
freeLink(&rowLL);
freeLink(&colLL);
}
/* Construct a basis that is in some measure the "least degenerate" */
else if((lp->crashmode == CRASH_LEASTDEGENERATE) && mat_validate(mat)) {
/* The logic here follows Maros */
LLrec *rowLL = NULL, *colLL = NULL;
int ii, rx, cx, ix, nz, *merit = NULL;
REAL *value, wx, hold, *rhs = NULL, *eta = NULL;
int *rownr, *colnr;
report(lp, NORMAL, "crash_basis: 'Least degenerate' basis crashing selected\n");
/* Create temporary arrays */
ok = allocINT(lp, &merit, lp->columns + 1, FALSE) &&
allocREAL(lp, &eta, lp->rows + 1, FALSE) &&
allocREAL(lp, &rhs, lp->rows + 1, FALSE);
createLink(lp->columns, &colLL, NULL);
createLink(lp->rows, &rowLL, NULL);
ok &= (colLL != NULL) && (rowLL != NULL);
if(!ok)
goto FinishLD;
MEMCOPY(rhs, lp->orig_rhs, lp->rows + 1);
for(i = 1; i <= lp->columns; i++)
appendLink(colLL, i);
for(i = 1; i <= lp->rows; i++)
appendLink(rowLL, i);
/* Loop until we have found enough new bases */
while(colLL->count > 0) {
/* Tally non-zeros matching in RHS and each active column */
nz = mat_nonzeros(mat);
rownr = &COL_MAT_ROWNR(0);
colnr = &COL_MAT_COLNR(0);
ii = 0;
MEMCLEAR(merit, lp->columns + 1);
for(i = 0; i < nz;
i++, rownr += matRowColStep, colnr += matRowColStep) {
rx = *rownr;
cx = *colnr;
if(isActiveLink(colLL, cx) && (rhs[rx] != 0)) {
merit[cx]++;
ii++;
}
}
if(ii == 0)
break;
/* Find maximal match; break ties with column length */
i = firstActiveLink(colLL);
cx = i;
for(i = nextActiveLink(colLL, i); i != 0; i = nextActiveLink(colLL, i)) {
if(merit[i] >= merit[cx]) {
if((merit[i] > merit[cx]) || (mat_collength(mat, i) > mat_collength(mat, cx)))
cx = i;
}
}
/* Determine the best pivot row */
i = mat->col_end[cx-1];
nz = mat->col_end[cx];
rownr = &COL_MAT_ROWNR(i);
value = &COL_MAT_VALUE(i);
rx = 0;
wx = 0;
MEMCLEAR(eta, lp->rows + 1);
for(; i < nz;
i++, rownr += matRowColStep, value += matValueStep) {
ix = *rownr;
hold = *value;
eta[ix] = rhs[ix] / hold;
hold = fabs(hold);
if(isActiveLink(rowLL, ix) && (hold > wx)) {
wx = hold;
rx = ix;
}
}
/* Set new basis variable */
if(rx > 0) {
/* We have to update the rhs vector for the implied transformation
in order to be able to find the new RHS non-zero pattern */
for(i = 1; i <= lp->rows; i++)
rhs[i] -= wx * eta[i];
rhs[rx] = wx;
/* Do the exchange */
set_basisvar(lp, rx, lp->rows+cx);
removeLink(rowLL, rx);
}
removeLink(colLL, cx);
}
/* Clean up */
FinishLD:
FREE(merit);
FREE(rhs);
freeLink(&rowLL);
freeLink(&colLL);
}
return( ok );
}
#if 0
MYBOOL __WINAPI guess_basis(lprec *lp, REAL *guessvector, int *basisvector)
{
MYBOOL status = FALSE;
REAL *values = NULL, *violation = NULL,
*value, error, upB, loB, sortorder = 1.0;
int i, n, *rownr, *colnr;
MATrec *mat = lp->matA;
if(!mat_validate(lp->matA))
return( status );
/* Create helper arrays */
if(!allocREAL(lp, &values, lp->sum+1, TRUE) ||
!allocREAL(lp, &violation, lp->sum+1, TRUE))
goto Finish;
/* Compute values of slack variables for given guess vector */
i = 0;
n = get_nonzeros(lp);
rownr = &COL_MAT_ROWNR(i);
colnr = &COL_MAT_COLNR(i);
value = &COL_MAT_VALUE(i);
for(; i < n; i++, rownr += matRowColStep, colnr += matRowColStep, value += matValueStep)
values[*rownr] += unscaled_mat(lp, my_chsign(is_chsign(lp, *rownr), *value), *rownr, *colnr) *
guessvector[*colnr];
MEMMOVE(values+lp->rows+1, guessvector+1, lp->columns);
/* Initialize constraint bound violation measures */
for(i = 1; i <= lp->rows; i++) {
upB = get_rh_upper(lp, i);
loB = get_rh_lower(lp, i);
error = values[i] - upB;
if(error > lp->epsprimal)
violation[i] = sortorder*error;
else {
error = loB - values[i];
if(error > lp->epsprimal)
violation[i] = sortorder*error;
else if(is_infinite(lp, loB) && is_infinite(lp, upB))
;
else if(is_infinite(lp, upB))
violation[i] = sortorder*(loB - values[i]);
else if(is_infinite(lp, loB))
violation[i] = sortorder*(values[i] - upB);
else
violation[i] = - sortorder*MAX(upB - values[i], values[i] - loB);
}
basisvector[i] = i;
}
/* Initialize user variable bound violation measures */
for(i = 1; i <= lp->columns; i++) {
n = lp->rows+i;
upB = get_upbo(lp, i);
loB = get_lowbo(lp, i);
error = guessvector[i] - upB;
if(error > lp->epsprimal)
violation[n] = sortorder*error;
else {
error = loB - values[n];
if(error > lp->epsprimal)
violation[n] = sortorder*error;
else if(is_infinite(lp, loB) && is_infinite(lp, upB))
;
else if(is_infinite(lp, upB))
violation[n] = sortorder*(loB - values[n]);
else if(is_infinite(lp, loB))
violation[n] = sortorder*(values[n] - upB);
else
violation[n] = - sortorder*MAX(upB - values[n], values[n] - loB);
}
basisvector[n] = n;
}
/* Sort decending by violation; this means that variables with
the largest violations will be designated as basic */
sortByREAL(basisvector, violation, lp->sum, 1, FALSE);
/* Adjust the non-basic indeces for the (proximal) bound state */
error = lp->epsprimal;
for(i = lp->rows+1, rownr = basisvector+i; i <= lp->sum; i++, rownr++) {
if(*rownr <= lp->rows) {
if(values[*rownr] <= get_rh_lower(lp, *rownr)+error)
*rownr = -(*rownr);
}
else
if(values[i] <= get_lowbo(lp, (*rownr)-lp->rows)+error)
*rownr = -(*rownr);
}
/* Clean up and return status */
status = (MYBOOL) (violation[1] == 0);
Finish:
FREE(values);
FREE(violation);
return( status );
}
#endif
#if 0
MYBOOL __WINAPI guess_basis(lprec *lp, REAL *guessvector, int *basisvector)
{
MYBOOL *isnz, status = FALSE;
REAL *values = NULL, *violation = NULL,
eps = lp->epsprimal,
*value, error, upB, loB, sortorder = 1.0;
int i, j, n, *rownr, *colnr, *slkpos,
nrows = lp->rows, ncols = lp->columns;
MATrec *mat = lp->matA;
if(!mat_validate(mat))
return( status );
/* Create helper arrays */
if(!allocREAL(lp, &values, lp->sum+1, TRUE) ||
!allocREAL(lp, &violation, lp->sum+1, TRUE))
goto Finish;
/* Compute values of slack variables for given guess vector */
i = 0;
n = get_nonzeros(lp);
rownr = &COL_MAT_ROWNR(i);
colnr = &COL_MAT_COLNR(i);
value = &COL_MAT_VALUE(i);
for(; i < n; i++, rownr += matRowColStep, colnr += matRowColStep, value += matValueStep)
values[*rownr] += unscaled_mat(lp, my_chsign(is_chsign(lp, *rownr), *value), *rownr, *colnr) *
guessvector[*colnr];
MEMMOVE(values+nrows+1, guessvector+1, ncols);
/* Initialize constraint bound violation measures (expressed as positive values) */
for(i = 1; i <= nrows; i++) {
upB = get_rh_upper(lp, i);
loB = get_rh_lower(lp, i);
error = values[i] - upB;
if(error > eps)
violation[i] = sortorder*error;
else {
error = loB - values[i];
if(error > eps)
violation[i] = sortorder*error;
else if(my_infinite(lp, loB) && my_infinite(lp, upB))
;
else if(my_infinite(lp, upB))
violation[i] = sortorder*(loB - values[i]);
else if(my_infinite(lp, loB))
violation[i] = sortorder*(values[i] - upB);
else
violation[i] = -sortorder*MAX(upB - values[i], values[i] - loB);
}
basisvector[i] = i;
}
/* Initialize user variable bound violation measures (expressed as positive values) */
for(i = 1; i <= ncols; i++) {
n = nrows+i;
upB = get_upbo(lp, i);
loB = get_lowbo(lp, i);
error = guessvector[i] - upB;
if(error > eps)
violation[n] = sortorder*error;
else {
error = loB - values[n];
if(error > eps)
violation[n] = sortorder*error;
else if(my_infinite(lp, loB) && my_infinite(lp, upB))
;
else if(my_infinite(lp, upB))
violation[n] = sortorder*(loB - values[n]);
else if(my_infinite(lp, loB))
violation[n] = sortorder*(values[n] - upB);
else
violation[n] = -sortorder*MAX(upB - values[n], values[n] - loB);
}
basisvector[n] = n;
}
/* Sort decending by violation; this means that variables with
the largest violations will be designated as basic */
sortByREAL(basisvector, violation, lp->sum, 1, FALSE);
error = violation[1];
/* Adjust the non-basic indeces for the (proximal) bound state */
for(i = nrows+1, rownr = basisvector+i; i <= lp->sum; i++, rownr++) {
if(*rownr <= nrows) {
if(values[*rownr] <= get_rh_lower(lp, *rownr)+eps)
*rownr = -(*rownr);
}
else
if(values[i] <= get_lowbo(lp, (*rownr)-nrows)+eps)
*rownr = -(*rownr);
}
#if 1
/* Let us check for obvious row singularities and try to fix these;
First assemble necessary basis statistics... */
isnz = (MYBOOL *) values;
MEMCLEAR(isnz, nrows+1);
slkpos = (int *) violation;
MEMCLEAR(slkpos, nrows+1);
for(i = 1; i <= nrows; i++) {
j = abs(basisvector[i]);
if(j <= nrows) {
isnz[j] = TRUE;
slkpos[j] = i;
}
else {
j-= nrows;
j = mat->col_end[j-1];
isnz[COL_MAT_ROWNR(j)] = TRUE;
/*isnz[COL_MAT_ROWNR(j+1)] = TRUE;*/
}
}
for(; i <= lp->sum; i++) {
j = abs(basisvector[i]);
if(j <= nrows)
slkpos[j] = i;
}
/* ...then set the corresponding slacks basic for row rank deficient positions */
for(j = 1; j <= nrows; j++) {
#ifdef Paranoia
if(slkpos[j] == 0)
report(lp, SEVERE, "guess_basis: Internal error");
#endif
if(!isnz[j]) {
isnz[j] = TRUE;
i = slkpos[j];
swapINT(&basisvector[i], &basisvector[j]);
basisvector[j] = abs(basisvector[j]);
}
}
#endif
/* Clean up and return status */
status = (MYBOOL) (error <= eps);
Finish:
FREE(values);
FREE(violation);
return( status );
}
#endif
MYBOOL __WINAPI guess_basis(lprec *lp, REAL *guessvector, int *basisvector)
{
MYBOOL *isnz, status = FALSE;
REAL *values = NULL, *violation = NULL,
eps = lp->epsprimal,
*value, error, upB, loB, sortorder = 1.0;
int i, j, jj, n, *rownr, *colnr, *slkpos,
nrows = lp->rows, ncols = lp->columns;
MATrec *mat = lp->matA;
if(!mat_validate(mat))
return( status );
/* Create helper arrays */
if(!allocREAL(lp, &values, lp->sum+1, TRUE) ||
!allocREAL(lp, &violation, lp->sum+1, TRUE))
goto Finish;
/* Compute values of slack variables for given guess vector */
i = 0;
n = get_nonzeros(lp);
rownr = &COL_MAT_ROWNR(i);
colnr = &COL_MAT_COLNR(i);
value = &COL_MAT_VALUE(i);
for(; i < n; i++, rownr += matRowColStep, colnr += matRowColStep, value += matValueStep)
values[*rownr] += unscaled_mat(lp, my_chsign(is_chsign(lp, *rownr), *value), *rownr, *colnr) *
guessvector[*colnr];
MEMMOVE(values+nrows+1, guessvector+1, ncols);
/* Initialize constraint bound violation measures (expressed as positive values) */
for(i = 1; i <= nrows; i++) {
upB = get_rh_upper(lp, i);
loB = get_rh_lower(lp, i);
error = values[i] - upB;
if(error > -eps)
violation[i] = sortorder*MAX(0,error);
else {
error = loB - values[i];
if(error > -eps)
violation[i] = sortorder*MAX(0,error);
else if(my_infinite(lp, loB) && my_infinite(lp, upB))
;
else if(my_infinite(lp, upB))
violation[i] = sortorder*(loB - values[i]);
else if(my_infinite(lp, loB))
violation[i] = sortorder*(values[i] - upB);
else
violation[i] = -sortorder*MAX(upB - values[i], values[i] - loB);
}
basisvector[i] = i;
}
/* Initialize user variable bound violation measures (expressed as positive values) */
for(i = 1; i <= ncols; i++) {
n = nrows+i;
upB = get_upbo(lp, i);
loB = get_lowbo(lp, i);
error = guessvector[i] - upB;
if(error > -eps)
violation[n] = sortorder*MAX(0,error);
else {
error = loB - values[n];
if(error > -eps)
violation[n] = sortorder*MAX(0,error);
else if(my_infinite(lp, loB) && my_infinite(lp, upB))
;
else if(my_infinite(lp, upB))
violation[n] = sortorder*(loB - values[n]);
else if(my_infinite(lp, loB))
violation[n] = sortorder*(values[n] - upB);
else
violation[n] = -sortorder*MAX(upB - values[n], values[n] - loB);
}
basisvector[n] = n;
}
/* Sort decending by violation; this means that variables with
the largest violations will be designated as basic */
sortByREAL(basisvector, violation, lp->sum, 1, FALSE);
error = violation[1];
/* Adjust the non-basic indeces for the (proximal) bound state */
for(i = nrows+1, rownr = basisvector+i; i <= lp->sum; i++, rownr++) {
if(*rownr <= nrows) {
values[*rownr] -= lp->orig_rhs[*rownr];
if(values[*rownr] <= eps)
*rownr = -(*rownr);
}
else
if(values[i] <= get_lowbo(lp, (*rownr)-nrows)+eps)
*rownr = -(*rownr);
}
/* Let us check for obvious row singularities and try to fix these;
First assemble necessary basis statistics... */
isnz = (MYBOOL *) values;
MEMCLEAR(isnz, nrows+1);
slkpos = (int *) violation;
MEMCLEAR(slkpos, nrows+1);
for(i = 1; i <= nrows; i++) {
j = abs(basisvector[i]);
if(j <= nrows) {
isnz[j] = TRUE;
slkpos[j] = i;
}
else {
j-= nrows;
jj = mat->col_end[j-1];
isnz[COL_MAT_ROWNR(jj)] = TRUE;
/* if(++jj < mat->col_end[j])
isnz[COL_MAT_ROWNR(jj)] = TRUE; */
}
}
for(; i <= lp->sum; i++) {
j = abs(basisvector[i]);
if(j <= nrows)
slkpos[j] = i;
}
/* ...then set the corresponding slacks basic for row rank deficient positions */
for(j = 1; j <= nrows; j++) {
#ifdef Paranoia
if(slkpos[j] == 0)
report(lp, SEVERE, "guess_basis: Internal error");
#endif
if(!isnz[j]) {
isnz[j] = TRUE;
i = slkpos[j];
swapINT(&basisvector[i], &basisvector[j]);
basisvector[j] = abs(basisvector[j]);
}
}
/* Lastly normalize all basic variables to be coded as lower-bounded */
for(i = 1; i <= nrows; i++)
basisvector[i] = -abs(basisvector[i]);
/* Clean up and return status */
status = (MYBOOL) (error <= eps);
Finish:
FREE(values);
FREE(violation);
return( status );
}

View File

@ -1,27 +0,0 @@
#ifndef HEADER_lp_crash
#define HEADER_lp_crash
#include "lp_types.h"
#define CRASH_SIMPLESCALE /* Specify if we should use a simple absolute scaling threshold */
#define CRASH_THRESHOLD 0.167
#define CRASH_SPACER 10
#define CRASH_WEIGHT 0.500
#ifdef __cplusplus
__EXTERN_C {
#endif
STATIC MYBOOL crash_basis(lprec *lp);
#ifdef __cplusplus
}
#endif
#endif /* HEADER_lp_crash */

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +0,0 @@
#ifdef FORTIFY
#include "fortify.h"
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,257 +0,0 @@
#ifndef HEADER_lp_matrix
#define HEADER_lp_matrix
#include "lp_types.h"
#include "lp_utils.h"
/* Sparse matrix element (ordered columnwise) */
typedef struct _MATitem
{
int rownr;
int colnr;
REAL value;
} MATitem;
/* Constants for matrix product rounding options */
#define MAT_ROUNDNONE 0
#define MAT_ROUNDABS 1
#define MAT_ROUNDREL 2
#define MAT_ROUNDABSREL (MAT_ROUNDABS + MAT_ROUNDREL)
#define MAT_ROUNDRC 4
#define MAT_ROUNDRCMIN 1.0 /* lp->epspivot */
#if 1
#define MAT_ROUNDDEFAULT MAT_ROUNDREL /* Typically increases performance */
#else
#define MAT_ROUNDDEFAULT MAT_ROUNDABS /* Probably gives more precision */
#endif
/* Compiler option development features */
/*#define DebugInv*/ /* Report array values at factorization/inversion */
#define NoLoopUnroll /* Do not do loop unrolling */
#define DirectArrayOF /* Reference lp->obj[] array instead of function call */
/* Matrix column access macros to be able to easily change storage model */
#define CAM_Record 0
#define CAM_Vector 1
#if 0
#define MatrixColAccess CAM_Record
#else
#define MatrixColAccess CAM_Vector
#endif
#if MatrixColAccess==CAM_Record
#define SET_MAT_ijA(item,i,j,A) mat->col_mat[item].rownr = i; \
mat->col_mat[item].colnr = j; \
mat->col_mat[item].value = A
#define COL_MAT_COLNR(item) (mat->col_mat[item].colnr)
#define COL_MAT_ROWNR(item) (mat->col_mat[item].rownr)
#define COL_MAT_VALUE(item) (mat->col_mat[item].value)
#define COL_MAT_COPY(left,right) mat->col_mat[left] = mat->col_mat[right]
#define COL_MAT_MOVE(to,from,rec) MEMMOVE(&(mat->col_mat[to]),&(mat->col_mat[from]),rec)
#define COL_MAT2_COLNR(item) (mat2->col_mat[item].colnr)
#define COL_MAT2_ROWNR(item) (mat2->col_mat[item].rownr)
#define COL_MAT2_VALUE(item) (mat2->col_mat[item].value)
#define matRowColStep (sizeof(MATitem)/sizeof(int))
#define matValueStep (sizeof(MATitem)/sizeof(REAL))
#else /* if MatrixColAccess==CAM_Vector */
#define SET_MAT_ijA(item,i,j,A) mat->col_mat_rownr[item] = i; \
mat->col_mat_colnr[item] = j; \
mat->col_mat_value[item] = A
#define COL_MAT_COLNR(item) (mat->col_mat_colnr[item])
#define COL_MAT_ROWNR(item) (mat->col_mat_rownr[item])
#define COL_MAT_VALUE(item) (mat->col_mat_value[item])
#define COL_MAT_COPY(left,right) COL_MAT_COLNR(left) = COL_MAT_COLNR(right); \
COL_MAT_ROWNR(left) = COL_MAT_ROWNR(right); \
COL_MAT_VALUE(left) = COL_MAT_VALUE(right)
#define COL_MAT_MOVE(to,from,rec) MEMMOVE(&COL_MAT_COLNR(to),&COL_MAT_COLNR(from),rec); \
MEMMOVE(&COL_MAT_ROWNR(to),&COL_MAT_ROWNR(from),rec); \
MEMMOVE(&COL_MAT_VALUE(to),&COL_MAT_VALUE(from),rec)
#define COL_MAT2_COLNR(item) (mat2->col_mat_colnr[item])
#define COL_MAT2_ROWNR(item) (mat2->col_mat_rownr[item])
#define COL_MAT2_VALUE(item) (mat2->col_mat_value[item])
#define matRowColStep 1
#define matValueStep 1
#endif
/* Matrix row access macros to be able to easily change storage model */
#define RAM_Index 0
#define RAM_FullCopy 1
#define MatrixRowAccess RAM_Index
#if MatrixRowAccess==RAM_Index
#define ROW_MAT_COLNR(item) COL_MAT_COLNR(mat->row_mat[item])
#define ROW_MAT_ROWNR(item) COL_MAT_ROWNR(mat->row_mat[item])
#define ROW_MAT_VALUE(item) COL_MAT_VALUE(mat->row_mat[item])
#elif MatrixColAccess==CAM_Record
#define ROW_MAT_COLNR(item) (mat->row_mat[item].colnr)
#define ROW_MAT_ROWNR(item) (mat->row_mat[item].rownr)
#define ROW_MAT_VALUE(item) (mat->row_mat[item].value)
#else /* if MatrixColAccess==CAM_Vector */
#define ROW_MAT_COLNR(item) (mat->row_mat_colnr[item])
#define ROW_MAT_ROWNR(item) (mat->row_mat_rownr[item])
#define ROW_MAT_VALUE(item) (mat->row_mat_value[item])
#endif
typedef struct _MATrec
{
/* Owner reference */
lprec *lp;
/* Active dimensions */
int rows;
int columns;
/* Allocated memory */
int rows_alloc;
int columns_alloc;
int mat_alloc; /* The allocated size for matrix sized structures */
/* Sparse problem matrix storage */
#if MatrixColAccess==CAM_Record
MATitem *col_mat; /* mat_alloc : The sparse data storage */
#else /*MatrixColAccess==CAM_Vector*/
int *col_mat_colnr;
int *col_mat_rownr;
REAL *col_mat_value;
#endif
int *col_end; /* columns_alloc+1 : col_end[i] is the index of the
first element after column i; column[i] is stored
in elements col_end[i-1] to col_end[i]-1 */
int *col_tag; /* user-definable tag associated with each column */
#if MatrixRowAccess==RAM_Index
int *row_mat; /* mat_alloc : From index 0, row_mat contains the
row-ordered index of the elements of col_mat */
#elif MatrixColAccess==CAM_Record
MATitem *row_mat; /* mat_alloc : From index 0, row_mat contains the
row-ordered copy of the elements in col_mat */
#else /*if MatrixColAccess==CAM_Vector*/
int *row_mat_colnr;
int *row_mat_rownr;
REAL *row_mat_value;
#endif
int *row_end; /* rows_alloc+1 : row_end[i] is the index of the
first element in row_mat after row i */
int *row_tag; /* user-definable tag associated with each row */
REAL *colmax; /* Array of maximum values of each column */
REAL *rowmax; /* Array of maximum values of each row */
REAL epsvalue; /* Zero element rejection threshold */
REAL infnorm; /* The largest absolute value in the matrix */
REAL dynrange;
MYBOOL row_end_valid; /* TRUE if row_end & row_mat are valid */
MYBOOL is_roworder; /* TRUE if the current (temporary) matrix order is row-wise */
} MATrec;
typedef struct _DeltaVrec
{
lprec *lp;
int activelevel;
MATrec *tracker;
} DeltaVrec;
#ifdef __cplusplus
__EXTERN_C {
#endif
/* Sparse matrix routines */
STATIC MATrec *mat_create(lprec *lp, int rows, int columns, REAL epsvalue);
STATIC MYBOOL mat_memopt(MATrec *mat, int rowextra, int colextra, int nzextra);
STATIC void mat_free(MATrec **matrix);
STATIC MYBOOL inc_matrow_space(MATrec *mat, int deltarows);
STATIC int mat_mapreplace(MATrec *mat, LLrec *rowmap, LLrec *colmap, MATrec *insmat);
STATIC int mat_matinsert(MATrec *mat, MATrec *insmat);
STATIC int mat_zerocompact(MATrec *mat);
STATIC int mat_rowcompact(MATrec *mat, MYBOOL dozeros);
STATIC int mat_colcompact(MATrec *mat, int prev_rows, int prev_cols);
STATIC MYBOOL inc_matcol_space(MATrec *mat, int deltacols);
STATIC MYBOOL inc_mat_space(MATrec *mat, int mindelta);
STATIC int mat_shiftrows(MATrec *mat, int *bbase, int delta, LLrec *varmap);
STATIC int mat_shiftcols(MATrec *mat, int *bbase, int delta, LLrec *varmap);
STATIC MATrec *mat_extractmat(MATrec *mat, LLrec *rowmap, LLrec *colmap, MYBOOL negated);
STATIC int mat_appendrow(MATrec *mat, int count, REAL *row, int *colno, REAL mult, MYBOOL checkrowmode);
STATIC int mat_appendcol(MATrec *mat, int count, REAL *column, int *rowno, REAL mult, MYBOOL checkrowmode);
MYBOOL mat_get_data(lprec *lp, int matindex, MYBOOL isrow, int **rownr, int **colnr, REAL **value);
MYBOOL mat_set_rowmap(MATrec *mat, int row_mat_index, int rownr, int colnr, int col_mat_index);
STATIC MYBOOL mat_indexrange(MATrec *mat, int index, MYBOOL isrow, int *startpos, int *endpos);
STATIC MYBOOL mat_validate(MATrec *mat);
STATIC MYBOOL mat_equalRows(MATrec *mat, int baserow, int comprow);
STATIC int mat_findelm(MATrec *mat, int row, int column);
STATIC int mat_findins(MATrec *mat, int row, int column, int *insertpos, MYBOOL validate);
STATIC void mat_multcol(MATrec *mat, int col_nr, REAL mult, MYBOOL DoObj);
STATIC REAL mat_getitem(MATrec *mat, int row, int column);
STATIC MYBOOL mat_setitem(MATrec *mat, int row, int column, REAL value);
STATIC MYBOOL mat_additem(MATrec *mat, int row, int column, REAL delta);
STATIC MYBOOL mat_setvalue(MATrec *mat, int Row, int Column, REAL Value, MYBOOL doscale);
STATIC int mat_nonzeros(MATrec *mat);
STATIC int mat_collength(MATrec *mat, int colnr);
STATIC int mat_rowlength(MATrec *mat, int rownr);
STATIC void mat_multrow(MATrec *mat, int row_nr, REAL mult);
STATIC void mat_multadd(MATrec *mat, REAL *lhsvector, int varnr, REAL mult);
STATIC MYBOOL mat_setrow(MATrec *mat, int rowno, int count, REAL *row, int *colno, MYBOOL doscale, MYBOOL checkrowmode);
STATIC MYBOOL mat_setcol(MATrec *mat, int colno, int count, REAL *column, int *rowno, MYBOOL doscale, MYBOOL checkrowmode);
STATIC MYBOOL mat_mergemat(MATrec *target, MATrec *source, MYBOOL usecolmap);
STATIC int mat_checkcounts(MATrec *mat, int *rownum, int *colnum, MYBOOL freeonexit);
STATIC int mat_expandcolumn(MATrec *mat, int colnr, REAL *column, int *nzlist, MYBOOL signedA);
STATIC MYBOOL mat_computemax(MATrec *mat);
STATIC MYBOOL mat_transpose(MATrec *mat);
/* Refactorization and recomputation routine */
MYBOOL __WINAPI invert(lprec *lp, MYBOOL shiftbounds, MYBOOL final);
/* Vector compression and expansion routines */
STATIC MYBOOL vec_compress(REAL *densevector, int startpos, int endpos, REAL epsilon, REAL *nzvector, int *nzindex);
STATIC MYBOOL vec_expand(REAL *nzvector, int *nzindex, REAL *densevector, int startpos, int endpos);
/* Sparse matrix products */
STATIC MYBOOL get_colIndexA(lprec *lp, int varset, int *colindex, MYBOOL append);
STATIC int prod_Ax(lprec *lp, int *coltarget, REAL *input, int *nzinput, REAL roundzero, REAL ofscalar, REAL *output, int *nzoutput, int roundmode);
STATIC int prod_xA(lprec *lp, int *coltarget, REAL *input, int *nzinput, REAL roundzero, REAL ofscalar, REAL *output, int *nzoutput, int roundmode);
STATIC MYBOOL prod_xA2(lprec *lp, int *coltarget, REAL *prow, REAL proundzero, int *pnzprow,
REAL *drow, REAL droundzero, int *dnzdrow, REAL ofscalar, int roundmode);
/* Equation solution */
STATIC MYBOOL fimprove(lprec *lp, REAL *pcol, int *nzidx, REAL roundzero);
STATIC void ftran(lprec *lp, REAL *rhsvector, int *nzidx, REAL roundzero);
STATIC MYBOOL bimprove(lprec *lp, REAL *rhsvector, int *nzidx, REAL roundzero);
STATIC void btran(lprec *lp, REAL *rhsvector, int *nzidx, REAL roundzero);
/* Combined equation solution and matrix product for simplex operations */
STATIC MYBOOL fsolve(lprec *lp, int varin, REAL *pcol, int *nzidx, REAL roundzero, REAL ofscalar, MYBOOL prepareupdate);
STATIC MYBOOL bsolve(lprec *lp, int row_nr, REAL *rhsvector, int *nzidx, REAL roundzero, REAL ofscalar);
STATIC void bsolve_xA2(lprec *lp, int* coltarget,
int row_nr1, REAL *vector1, REAL roundzero1, int *nzvector1,
int row_nr2, REAL *vector2, REAL roundzero2, int *nzvector2, int roundmode);
/* Change-tracking routines (primarily for B&B and presolve) */
STATIC DeltaVrec *createUndoLadder(lprec *lp, int levelitems, int maxlevels);
STATIC int incrementUndoLadder(DeltaVrec *DV);
STATIC MYBOOL modifyUndoLadder(DeltaVrec *DV, int itemno, REAL target[], REAL newvalue);
STATIC int countsUndoLadder(DeltaVrec *DV);
STATIC int restoreUndoLadder(DeltaVrec *DV, REAL target[]);
STATIC int decrementUndoLadder(DeltaVrec *DV);
STATIC MYBOOL freeUndoLadder(DeltaVrec **DV);
/* Specialized presolve undo functions */
STATIC MYBOOL appendUndoPresolve(lprec *lp, MYBOOL isprimal, REAL beta, int colnrDep);
STATIC MYBOOL addUndoPresolve(lprec *lp, MYBOOL isprimal, int colnrElim, REAL alpha, REAL beta, int colnrDep);
#ifdef __cplusplus
}
#endif
#endif /* HEADER_lp_matrix */

File diff suppressed because it is too large Load Diff

View File

@ -1,64 +0,0 @@
#ifndef HEADER_lp_mipbb
#define HEADER_lp_mipbb
#include "lp_types.h"
#include "lp_utils.h"
/* Bounds storage for B&B routines */
typedef struct _BBrec
{
struct _BBrec *parent;
struct _BBrec *child;
lprec *lp;
int varno;
int vartype;
int lastvarcus; /* Count of non-int variables of the previous branch */
int lastrcf;
int nodesleft;
int nodessolved;
int nodestatus;
REAL noderesult;
REAL lastsolution; /* Optimal solution of the previous branch */
REAL sc_bound;
REAL *upbo, *lowbo;
REAL UPbound, LObound;
int UBtrack, LBtrack; /* Signals that incoming bounds were changed */
MYBOOL contentmode; /* Flag indicating if we "own" the bound vectors */
MYBOOL sc_canset;
MYBOOL isSOS;
MYBOOL isGUB;
int *varmanaged; /* Extended list of variables managed by this B&B level */
MYBOOL isfloor; /* State variable indicating the active B&B bound */
MYBOOL UBzerobased; /* State variable indicating if bounds have been rebased */
} BBrec;
#ifdef __cplusplus
extern "C" {
#endif
STATIC BBrec *create_BB(lprec *lp, BBrec *parentBB, MYBOOL dofullcopy);
STATIC BBrec *push_BB(lprec *lp, BBrec *parentBB, int varno, int vartype, int varcus);
STATIC MYBOOL initbranches_BB(BBrec *BB);
STATIC MYBOOL fillbranches_BB(BBrec *BB);
STATIC MYBOOL nextbranch_BB(BBrec *BB);
STATIC MYBOOL strongbranch_BB(lprec *lp, BBrec *BB, int varno, int vartype, int varcus);
STATIC MYBOOL initcuts_BB(lprec *lp);
STATIC int updatecuts_BB(lprec *lp);
STATIC MYBOOL freecuts_BB(lprec *lp);
STATIC BBrec *findself_BB(BBrec *BB);
STATIC int solve_LP(lprec *lp, BBrec *BB);
STATIC int rcfbound_BB(BBrec *BB, int varno, MYBOOL isINT, REAL *newbound, MYBOOL *isfeasible);
STATIC MYBOOL findnode_BB(BBrec *BB, int *varno, int *vartype, int *varcus);
STATIC int solve_BB(BBrec *BB);
STATIC MYBOOL free_BB(BBrec **BB);
STATIC BBrec *pop_BB(BBrec *BB);
STATIC int run_BB(lprec *lp);
#ifdef __cplusplus
}
#endif
#endif /* HEADER_lp_mipbb */

View File

@ -1,691 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <errno.h>
#include "commonlib.h"
#include "lp_lib.h"
#include "lp_report.h"
#include "ini.h"
typedef int (__WINAPI int_get_function)(lprec *lp);
typedef long (__WINAPI long_get_function)(lprec *lp);
typedef MYBOOL (__WINAPI MYBOOL_get_function)(lprec *lp);
typedef REAL (__WINAPI REAL_get_function)(lprec *lp);
typedef void (__WINAPI int_set_function)(lprec *lp, int value);
typedef void (__WINAPI long_set_function)(lprec *lp, long value);
typedef void (__WINAPI MYBOOL_set_function)(lprec *lp, MYBOOL value);
typedef void (__WINAPI REAL_set_function)(lprec *lp, REAL value);
#define intfunction 1
#define longfunction 2
#define MYBOOLfunction 3
#define REALfunction 4
#define setvalues(values, basemask) values, sizeof(values) / sizeof(*values), basemask
#define setNULLvalues NULL, 0, 0
#define setvalue(value) value, #value
#define setintfunction(get_function, set_function) get_function, set_function, intfunction
#define setlongfunction(get_function, set_function) (int_get_function *) get_function, (int_set_function *) set_function, longfunction
#define setMYBOOLfunction(get_function, set_function) (int_get_function *) get_function, (int_set_function *) set_function, MYBOOLfunction
#define setREALfunction(get_function, set_function) (int_get_function *) get_function, (int_set_function *) set_function, REALfunction
#define WRITE_COMMENTED 0
#define WRITE_ACTIVE 1
struct _values {
int value;
char *svalue;
};
struct _functions {
char *par; /* name of parameter in ini file */
union {
int_get_function *int_get_function; /* set via setintfunction */
long_get_function *long_get_function; /* set via setlongfunction */
MYBOOL_get_function *MYBOOL_get_function; /* set via setMYBOOLfunction */
REAL_get_function *REAL_get_function; /* set via setREALfunction */
} get_function;
union {
int_set_function *int_set_function; /* set via setintfunction */
long_set_function *long_set_function; /* set via setlongfunction */
MYBOOL_set_function *MYBOOL_set_function; /* set via setMYBOOLfunction */
REAL_set_function *REAL_set_function; /* set via setREALfunction */
} set_function;
int type; /* set via set*function */
struct _values *values; /* set via setvalues to a structure of _values */
int elements; /* or via setNULLvalues if the value is shown as is */
unsigned int basemask;
int mask; /* WRITE_ACTIVE or WRITE_COMMENTED */
};
static struct _values anti_degen[] =
{
{ setvalue(ANTIDEGEN_NONE) },
{ setvalue(ANTIDEGEN_FIXEDVARS) },
{ setvalue(ANTIDEGEN_COLUMNCHECK) },
{ setvalue(ANTIDEGEN_STALLING) },
{ setvalue(ANTIDEGEN_NUMFAILURE) },
{ setvalue(ANTIDEGEN_LOSTFEAS) },
{ setvalue(ANTIDEGEN_INFEASIBLE) },
{ setvalue(ANTIDEGEN_DYNAMIC) },
{ setvalue(ANTIDEGEN_DURINGBB) },
{ setvalue(ANTIDEGEN_RHSPERTURB) },
{ setvalue(ANTIDEGEN_BOUNDFLIP) },
};
static struct _values basiscrash[] =
{
{ setvalue(CRASH_NONE) },
/* { setvalue(CRASH_NONBASICBOUNDS) }, */ /* not yet implemented */
{ setvalue(CRASH_MOSTFEASIBLE) },
{ setvalue(CRASH_LEASTDEGENERATE) },
};
static struct _values bb_floorfirst[] =
{
{ setvalue(BRANCH_CEILING) },
{ setvalue(BRANCH_FLOOR) },
{ setvalue(BRANCH_AUTOMATIC) },
};
static struct _values bb_rule[] =
{
{ setvalue(NODE_FIRSTSELECT) },
{ setvalue(NODE_GAPSELECT) },
{ setvalue(NODE_RANGESELECT) },
{ setvalue(NODE_FRACTIONSELECT) },
{ setvalue(NODE_PSEUDOCOSTSELECT) },
{ setvalue(NODE_PSEUDONONINTSELECT) },
{ setvalue(NODE_PSEUDORATIOSELECT) },
{ setvalue(NODE_USERSELECT) },
{ setvalue(NODE_WEIGHTREVERSEMODE) },
{ setvalue(NODE_BRANCHREVERSEMODE) },
{ setvalue(NODE_GREEDYMODE) },
{ setvalue(NODE_PSEUDOCOSTMODE) },
{ setvalue(NODE_DEPTHFIRSTMODE) },
{ setvalue(NODE_RANDOMIZEMODE) },
{ setvalue(NODE_GUBMODE) },
{ setvalue(NODE_DYNAMICMODE) },
{ setvalue(NODE_RESTARTMODE) },
{ setvalue(NODE_BREADTHFIRSTMODE) },
{ setvalue(NODE_AUTOORDER) },
{ setvalue(NODE_RCOSTFIXING) },
{ setvalue(NODE_STRONGINIT) },
};
static struct _values improve[] =
{
{ setvalue(IMPROVE_NONE) },
{ setvalue(IMPROVE_SOLUTION) },
{ setvalue(IMPROVE_DUALFEAS) },
{ setvalue(IMPROVE_THETAGAP) },
{ setvalue(IMPROVE_BBSIMPLEX) },
};
static REAL __WINAPI get_mip_gap_abs(lprec *lp)
{
return(get_mip_gap(lp, TRUE));
}
static REAL __WINAPI get_mip_gap_rel(lprec *lp)
{
return(get_mip_gap(lp, FALSE));
}
static void __WINAPI set_mip_gap_abs(lprec *lp, REAL mip_gap)
{
set_mip_gap(lp, TRUE, mip_gap);
}
static void __WINAPI set_mip_gap_rel(lprec *lp, REAL mip_gap)
{
set_mip_gap(lp, FALSE, mip_gap);
}
static struct _values pivoting[] =
{
{ setvalue(PRICER_FIRSTINDEX) },
{ setvalue(PRICER_DANTZIG) },
{ setvalue(PRICER_DEVEX) },
{ setvalue(PRICER_STEEPESTEDGE) },
{ setvalue(PRICE_PRIMALFALLBACK) },
{ setvalue(PRICE_MULTIPLE) },
{ setvalue(PRICE_PARTIAL) },
{ setvalue(PRICE_ADAPTIVE) },
{ setvalue(PRICE_RANDOMIZE) },
{ setvalue(PRICE_AUTOPARTIAL) },
{ setvalue(PRICE_LOOPLEFT) },
{ setvalue(PRICE_LOOPALTERNATE) },
{ setvalue(PRICE_HARRISTWOPASS) },
{ setvalue(PRICE_TRUENORMINIT) },
};
static struct _values presolving[] =
{
{ setvalue(PRESOLVE_NONE) },
{ setvalue(PRESOLVE_ROWS) },
{ setvalue(PRESOLVE_COLS) },
{ setvalue(PRESOLVE_LINDEP) },
{ setvalue(PRESOLVE_AGGREGATE) },
{ setvalue(PRESOLVE_SPARSER) },
{ setvalue(PRESOLVE_SOS) },
{ setvalue(PRESOLVE_REDUCEMIP) },
{ setvalue(PRESOLVE_KNAPSACK) },
{ setvalue(PRESOLVE_ELIMEQ2) },
{ setvalue(PRESOLVE_IMPLIEDFREE) },
{ setvalue(PRESOLVE_REDUCEGCD) },
{ setvalue(PRESOLVE_PROBEFIX) },
{ setvalue(PRESOLVE_PROBEREDUCE) },
{ setvalue(PRESOLVE_ROWDOMINATE) },
{ setvalue(PRESOLVE_COLDOMINATE) },
{ setvalue(PRESOLVE_MERGEROWS) },
{ setvalue(PRESOLVE_IMPLIEDSLK) },
{ setvalue(PRESOLVE_COLFIXDUAL) },
{ setvalue(PRESOLVE_BOUNDS) },
{ setvalue(PRESOLVE_DUALS) },
{ setvalue(PRESOLVE_SENSDUALS) },
};
static char *STRLWR(char *str)
{
char *ptr;
for(ptr = str; *ptr; ptr++)
*ptr = (char) tolower((unsigned char) *ptr);
return(str);
}
static char *STRUPR(char *str)
{
char *ptr;
for(ptr = str; *ptr; ptr++)
*ptr = (char) toupper((unsigned char) *ptr);
return(str);
}
static void __WINAPI set_presolve1(lprec *lp, int do_presolve)
{
set_presolve(lp, do_presolve, get_presolveloops(lp));
}
static void __WINAPI set_presolve2(lprec *lp, int maxloops)
{
set_presolve(lp, get_presolve(lp), maxloops);
}
static struct _values print_sol[] =
{
{ FALSE, "0" },
{ TRUE, "1" },
{ setvalue(AUTOMATIC) },
};
static struct _values scaling[] =
{
{ setvalue(SCALE_NONE) },
{ setvalue(SCALE_EXTREME) },
{ setvalue(SCALE_RANGE) },
{ setvalue(SCALE_MEAN) },
{ setvalue(SCALE_GEOMETRIC) },
{ setvalue(SCALE_CURTISREID) },
{ setvalue(SCALE_QUADRATIC) },
{ setvalue(SCALE_LOGARITHMIC) },
{ setvalue(SCALE_USERWEIGHT) },
{ setvalue(SCALE_POWER2) },
{ setvalue(SCALE_EQUILIBRATE) },
{ setvalue(SCALE_INTEGERS) },
{ setvalue(SCALE_DYNUPDATE) },
{ setvalue(SCALE_ROWSONLY) },
{ setvalue(SCALE_COLSONLY) },
};
static struct _values simplextype[] =
{
{ setvalue(SIMPLEX_PRIMAL_PRIMAL) },
{ setvalue(SIMPLEX_DUAL_PRIMAL) },
{ setvalue(SIMPLEX_PRIMAL_DUAL) },
{ setvalue(SIMPLEX_DUAL_DUAL) },
};
static struct _values verbose[] =
{
{ setvalue(NEUTRAL) },
{ setvalue(CRITICAL) },
{ setvalue(SEVERE) },
{ setvalue(IMPORTANT) },
{ setvalue(NORMAL) },
{ setvalue(DETAILED) },
{ setvalue(FULL) },
};
static struct _functions functions[] =
{
/* solve options */
{ "ANTI_DEGEN", setintfunction(get_anti_degen, set_anti_degen), setvalues(anti_degen, ~0), WRITE_ACTIVE },
{ "BASISCRASH", setintfunction(get_basiscrash, set_basiscrash), setvalues(basiscrash, ~0), WRITE_ACTIVE },
{ "IMPROVE", setintfunction(get_improve, set_improve), setvalues(improve, ~0), WRITE_ACTIVE },
{ "MAXPIVOT", setintfunction(get_maxpivot, set_maxpivot), setNULLvalues, WRITE_ACTIVE },
{ "NEGRANGE", setREALfunction(get_negrange, set_negrange), setNULLvalues, WRITE_ACTIVE },
{ "PIVOTING", setintfunction(get_pivoting, set_pivoting), setvalues(pivoting, PRICER_LASTOPTION), WRITE_ACTIVE },
{ "PRESOLVE", setintfunction(get_presolve, set_presolve1), setvalues(presolving, ~0), WRITE_ACTIVE },
{ "PRESOLVELOOPS", setintfunction(get_presolveloops, set_presolve2), setNULLvalues, WRITE_ACTIVE },
{ "SCALELIMIT", setREALfunction(get_scalelimit, set_scalelimit), setNULLvalues, WRITE_ACTIVE },
{ "SCALING", setintfunction(get_scaling, set_scaling), setvalues(scaling, SCALE_CURTISREID), WRITE_ACTIVE },
{ "SIMPLEXTYPE", setintfunction(get_simplextype, set_simplextype), setvalues(simplextype, ~0), WRITE_ACTIVE },
{ "OBJ_IN_BASIS", setMYBOOLfunction(is_obj_in_basis, set_obj_in_basis), setNULLvalues, WRITE_COMMENTED },
/* B&B options */
{ "BB_DEPTHLIMIT", setintfunction(get_bb_depthlimit, set_bb_depthlimit), setNULLvalues, WRITE_ACTIVE },
{ "BB_FLOORFIRST", setintfunction(get_bb_floorfirst, set_bb_floorfirst), setvalues(bb_floorfirst, ~0), WRITE_ACTIVE },
{ "BB_RULE", setintfunction(get_bb_rule, set_bb_rule), setvalues(bb_rule, NODE_STRATEGYMASK), WRITE_ACTIVE },
{ "BREAK_AT_FIRST", setMYBOOLfunction(is_break_at_first, set_break_at_first), setNULLvalues, WRITE_COMMENTED },
{ "BREAK_AT_VALUE", setREALfunction(get_break_at_value, set_break_at_value), setNULLvalues, WRITE_COMMENTED },
{ "MIP_GAP_ABS", setREALfunction(get_mip_gap_abs, set_mip_gap_abs), setNULLvalues, WRITE_ACTIVE },
{ "MIP_GAP_REL", setREALfunction(get_mip_gap_rel, set_mip_gap_rel), setNULLvalues, WRITE_ACTIVE },
{ "EPSINT", setREALfunction(get_epsint, set_epsint), setNULLvalues, WRITE_ACTIVE },
/* tolerances, values */
{ "EPSB", setREALfunction(get_epsb, set_epsb), setNULLvalues, WRITE_ACTIVE },
{ "EPSD", setREALfunction(get_epsd, set_epsd), setNULLvalues, WRITE_ACTIVE },
{ "EPSEL", setREALfunction(get_epsel, set_epsel), setNULLvalues, WRITE_ACTIVE },
{ "EPSPERTURB", setREALfunction(get_epsperturb, set_epsperturb), setNULLvalues, WRITE_ACTIVE },
{ "EPSPIVOT", setREALfunction(get_epspivot, set_epspivot), setNULLvalues, WRITE_ACTIVE },
{ "INFINITE", setREALfunction(get_infinite, set_infinite), setNULLvalues, WRITE_ACTIVE },
/* read-only options */
{ "DEBUG", setMYBOOLfunction(is_debug, set_debug), setNULLvalues, WRITE_COMMENTED },
{ "OBJ_BOUND", setREALfunction(get_obj_bound, set_obj_bound), setNULLvalues, WRITE_COMMENTED },
{ "PRINT_SOL", setintfunction(get_print_sol, set_print_sol), setvalues(print_sol, ~0), WRITE_COMMENTED },
{ "TIMEOUT", setlongfunction(get_timeout, set_timeout), setNULLvalues, WRITE_COMMENTED },
{ "TRACE", setMYBOOLfunction(is_trace, set_trace), setNULLvalues, WRITE_COMMENTED },
{ "VERBOSE", setintfunction(get_verbose, set_verbose), setvalues(verbose, ~0), WRITE_COMMENTED },
};
static void write_params1(lprec *lp, FILE *fp, char *header, int newline)
{
int ret = 0, ret2, i, j, k, value, value2, elements, majorversion, minorversion, release, build;
unsigned int basemask;
REAL a = 0;
char buf[4096], par[20];
ini_writeheader(fp, header, newline);
lp_solve_version(&majorversion, &minorversion, &release, &build);
sprintf(buf, "lp_solve version %d.%d settings\n", majorversion, minorversion);
ini_writecomment(fp, buf);
for(i = 0; i < sizeof(functions) / sizeof(*functions); i++) {
switch(functions[i].type) {
case intfunction:
if(functions[i].get_function.int_get_function == NULL)
continue;
ret = functions[i].get_function.int_get_function(lp);
break;
case longfunction:
if(functions[i].get_function.long_get_function == NULL)
continue;
ret = functions[i].get_function.long_get_function(lp);
break;
case MYBOOLfunction:
if(functions[i].get_function.MYBOOL_get_function == NULL)
continue;
ret = (int) functions[i].get_function.MYBOOL_get_function(lp);
break;
case REALfunction:
if(functions[i].get_function.REAL_get_function == NULL)
continue;
a = functions[i].get_function.REAL_get_function(lp);
break;
}
buf[0] = 0;
if(functions[i].values == NULL) {
switch(functions[i].type) {
case intfunction:
case longfunction:
case MYBOOLfunction:
sprintf(buf, "%d", ret);
break;
case REALfunction:
sprintf(buf, "%g", a);
break;
}
}
else {
elements = functions[i].elements;
basemask = functions[i].basemask;
for(j = 0; j < elements; j++) {
value = functions[i].values[j].value;
ret2 = ret;
if(((unsigned int) value) < basemask)
ret2 &= basemask;
if(value == 0) {
if(ret2 == 0) {
if(*buf)
strcat(buf, " + ");
strcat(buf, functions[i].values[j].svalue);
}
}
else if((ret2 & value) == value) {
for(k = 0; k < elements; k++) {
value2 = functions[i].values[k].value;
if((k != j) && (value2 > value) && ((value2 & value) == value) && ((ret2 & value2) == value2))
break;
}
if(k == elements) {
if(*buf)
strcat(buf, " + ");
strcat(buf, functions[i].values[j].svalue);
}
}
}
}
if(functions[i].mask & WRITE_ACTIVE)
par[0] = 0;
else
strcpy(par, ";");
strcat(par, functions[i].par);
ini_writedata(fp, STRLWR(par), buf);
}
}
static void readoptions(char *options, char **header)
{
char *ptr1, *ptr2;
if(options != NULL) {
ptr1 = options;
while(*ptr1) {
ptr2 = strchr(ptr1, '-');
if(ptr2 == NULL)
break;
ptr2++;
if(tolower((unsigned char) *ptr2) == 'h') {
for(++ptr2; (*ptr2) && (isspace(*ptr2)); ptr2++);
for(ptr1 = ptr2; (*ptr1) && (!isspace(*ptr1)); ptr1++);
*header = (char *) calloc(1 + (int) (ptr1 - ptr2), 1);
memcpy(*header, ptr2, (int) (ptr1 - ptr2));
}
}
}
if(*header == NULL)
*header = strdup("Default");
}
MYBOOL __WINAPI write_params(lprec *lp, char *filename, char *options)
{
int k, ret, params_written;
FILE *fp, *fp0;
int state = 0, looping, newline;
char buf[4096], *filename0, *ptr1, *ptr2, *header = NULL;
readoptions(options, &header);
k = strlen(filename);
filename0 = (char *) malloc(k + 1 + 1);
strcpy(filename0, filename);
ptr1 = strrchr(filename0, '.');
ptr2 = strrchr(filename0, '\\');
if((ptr1 == NULL) || ((ptr2 != NULL) && (ptr1 < ptr2)))
ptr1 = filename0 + k;
memmove(ptr1 + 1, ptr1, k + 1 - (int) (ptr1 - filename0));
ptr1[0] = '_';
if(rename(filename, filename0)) {
switch(errno) {
case ENOENT: /* File or path specified by oldname not found */
FREE(filename0);
filename0 = NULL;
break;
case EACCES: /* File or directory specified by newname already exists or could not be created (invalid path); or oldname is a directory and newname specifies a different path. */
FREE(filename0);
FREE(header);
return(FALSE);
break;
}
}
if((fp = ini_create(filename)) == NULL)
ret = FALSE;
else {
params_written = FALSE;
newline = TRUE;
if(filename0 != NULL) {
fp0 = ini_open(filename0);
if(fp0 == NULL) {
rename(filename0, filename);
FREE(filename0);
FREE(header);
return(FALSE);
}
looping = TRUE;
while(looping) {
switch(ini_readdata(fp0, buf, sizeof(buf), TRUE)) {
case 0: /* End of file */
looping = FALSE;
break;
case 1: /* header */
ptr1 = strdup(buf);
STRUPR(buf);
ptr2 = strdup(header);
STRUPR(ptr2);
if(strcmp(buf, ptr2) == 0) {
write_params1(lp, fp, ptr1, newline);
params_written = TRUE;
newline = TRUE;
state = 1;
}
else {
state = 0;
ini_writeheader(fp, ptr1, newline);
newline = TRUE;
}
FREE(ptr2);
FREE(ptr1);
break;
case 2: /* data */
if(state == 0) {
ini_writedata(fp, NULL, buf);
newline = (*buf != 0);
}
break;
}
}
ini_close(fp0);
}
if(!params_written)
write_params1(lp, fp, header, newline);
ini_close(fp);
ret = TRUE;
}
if(filename0 != NULL) {
remove(filename0);
FREE(filename0);
}
FREE(header);
return( (MYBOOL) ret );
}
MYBOOL __WINAPI read_params(lprec *lp, char *filename, char *options)
{
int ret, looping, line;
FILE *fp;
hashtable *hashfunctions, *hashparameters;
hashelem *hp;
int i, j, elements, n, intvalue, state = 0;
REAL REALvalue;
char buf[4096], *header = NULL, *ptr, *ptr1, *ptr2;
if((fp = ini_open(filename)) == NULL)
ret = FALSE;
else {
/* create hashtable of all callable commands to find them quickly */
hashfunctions = create_hash_table(sizeof(functions) / sizeof(*functions), 0);
for (n = 0, i = 0; i < (int) (sizeof(functions)/sizeof(*functions)); i++) {
puthash(functions[i].par, i, NULL, hashfunctions);
if(functions[i].values != NULL)
n += functions[i].elements;
}
/* create hashtable of all arguments to find them quickly */
hashparameters = create_hash_table(n, 0);
for (n = 0, i = 0; i < (int) (sizeof(functions)/sizeof(*functions)); i++) {
if(functions[i].values != NULL) {
elements = functions[i].elements;
for(j = 0; j < elements; j++)
if((strcmp(functions[i].values[j].svalue, "0") != 0) &&
(strcmp(functions[i].values[j].svalue, "1") != 0))
puthash(functions[i].values[j].svalue, j, NULL, hashparameters);
}
}
readoptions(options, &header);
STRUPR(header);
ret = looping = TRUE;
line = 0;
while((ret) && (looping)) {
line++;
switch(ini_readdata(fp, buf, sizeof(buf), FALSE)) {
case 0: /* End of file */
looping = FALSE;
break;
case 1: /* header */
switch(state) {
case 0:
STRUPR(buf);
if(strcmp(buf, header) == 0)
state = 1;
break;
case 1:
looping = FALSE;
break;
}
break;
case 2: /* data */
if(state == 1) {
for(ptr = buf; (*ptr) && (isspace(*ptr)); ptr++);
}
else
ptr = NULL;
if((ptr != NULL) && (*ptr)) {
STRUPR(buf);
ptr = strchr(buf, '=');
if(ptr == NULL) {
report(lp, IMPORTANT, "read_params: No equal sign on line %d\n", line);
ret = FALSE;
}
else {
*ptr = 0;
for(ptr1 = buf; isspace(*ptr1); ptr1++);
for(ptr2 = ptr - 1; (ptr2 >= ptr1) && (isspace(*ptr2)); ptr2--);
if(ptr2 <= ptr1) {
report(lp, IMPORTANT, "read_params: No parameter name before equal sign on line %d\n", line);
ret = FALSE;
}
else {
ptr2[1] = 0;
hp = findhash(ptr1, hashfunctions);
if(hp == NULL) {
report(lp, IMPORTANT, "read_params: Unknown parameter name (%s) before equal sign on line %d\n", ptr1, line);
ret = FALSE;
}
else {
i = hp->index;
ptr1 = ++ptr;
intvalue = 0;
REALvalue = 0;
if(functions[i].values == NULL) {
switch(functions[i].type) {
case intfunction:
case longfunction:
case MYBOOLfunction:
intvalue = strtol(ptr1, &ptr2, 10);
while((*ptr2) && (isspace(*ptr2)))
ptr2++;
if(*ptr2) {
report(lp, IMPORTANT, "read_params: Invalid integer value on line %d\n", line);
ret = FALSE;
}
break;
case REALfunction:
REALvalue = strtod(ptr1, &ptr2);
while((*ptr2) && (isspace(*ptr2)))
ptr2++;
if(*ptr2) {
report(lp, IMPORTANT, "read_params: Invalid real value on line %d\n", line);
ret = FALSE;
}
break;
}
}
else {
while(ret) {
ptr = strchr(ptr1, '+');
if(ptr == NULL)
ptr = ptr1 + strlen(ptr1);
for(; isspace(*ptr1); ptr1++);
for(ptr2 = ptr - 1; (ptr2 >= ptr1) && (isspace(*ptr2)); ptr2--);
if(ptr2 <= ptr1)
break;
else {
ptr2[1] = 0;
hp = findhash(ptr1, hashparameters);
if (hp == NULL) {
report(lp, IMPORTANT, "read_params: Invalid parameter name (%s) on line %d\n", ptr1, line);
ret = FALSE;
}
else {
j = hp->index;
if((j >= functions[i].elements) ||
(strcmp(functions[i].values[j].svalue, ptr1))) {
report(lp, IMPORTANT, "read_params: Inappropriate parameter name (%s) on line %d\n", ptr1, line);
ret = FALSE;
}
else {
intvalue += functions[i].values[j].value;
}
}
ptr1 = ptr + 1;
}
}
}
if(ret) {
switch(functions[i].type) {
case intfunction:
functions[i].set_function.int_set_function(lp, intvalue);
break;
case longfunction:
functions[i].set_function.long_set_function(lp, intvalue);
break;
case MYBOOLfunction:
functions[i].set_function.MYBOOL_set_function(lp, (MYBOOL) intvalue);
break;
case REALfunction:
functions[i].set_function.REAL_set_function(lp, REALvalue);
break;
}
}
}
}
}
}
break;
}
}
FREE(header);
free_hash_table(hashfunctions);
free_hash_table(hashparameters);
ini_close(fp);
}
return( (MYBOOL) ret );
}

File diff suppressed because it is too large Load Diff

View File

@ -1,126 +0,0 @@
#ifndef HEADER_lp_presolve
#define HEADER_lp_presolve
#include "lp_types.h"
#include "lp_matrix.h"
/* -------------------------------------------------------------------------------------------- */
/* Defines for various presolve options */
/* -------------------------------------------------------------------------------------------- */
#define MAX_PSMERGELOOPS 2 /* Max loops to merge compatible constraints */
#define MAX_PSLINDEPLOOPS 1 /* Max loops to detect linearly dependendent constraints */
#define MAX_PSBOUNDTIGHTENLOOPS 5 /* Maximumn number of loops to allow bound tightenings */
#define MIN_SOS1LENGTH 4 /* Minimum length of a constraint for conversion to SOS1 */
#if 1
#define PRESOLVE_EPSVALUE (0.1*lp->epsprimal)
#else
#define PRESOLVE_EPSVALUE lp->epsvalue
#endif
#define PRESOLVE_EPSPIVOT 1.0e-3 /* Looses robustness at values smaller than ~1.0e-3 */
#define PRESOLVE_BOUNDSLACK 10 /* Extra error recovery/tolerance margin */
#define DoPresolveRounding /* Use absolute and directed rounding (disable at own risk) */
/*#define DoPresolveRelativeTest*/
/*#define PresolveForceUpdateMax*/
/*#define DualFeasibilityLogicEQ2*/ /* Add low-order feasibility/accuracy logic to elimEQ2 */
#define DivisorIntegralityLogicEQ2 /* Always prefer integer divisors */
#define FindImpliedEqualities /* Detect equalities (default is enabled) */
#define Eq2Reldiff
/*#define SavePresolveEliminated */ /* Enable to activate storage of eliminated matrix data */
/*#define UseDualPresolve */ /* Enable to use full dual information for presolve */
typedef struct _psrec
{
LLrec *varmap;
int **next;
int *empty;
int *plucount;
int *negcount;
int *pluneg;
int *infcount;
REAL *plulower;
REAL *neglower;
REAL *pluupper;
REAL *negupper;
int allocsize;
} psrec;
typedef struct _presolverec
{
psrec *rows;
psrec *cols;
LLrec *EQmap;
LLrec *LTmap;
LLrec *INTmap;
REAL *pv_upbo;
REAL *pv_lobo;
REAL *dv_upbo;
REAL *dv_lobo;
lprec *lp;
REAL epsvalue;
REAL epspivot;
int innerloops;
int middleloops;
int outerloops;
int nzdeleted;
MYBOOL forceupdate;
} presolverec;
#ifdef __cplusplus
extern "C" {
#endif
/* Put function headers here */
STATIC MYBOOL presolve_createUndo(lprec *lp);
STATIC MYBOOL presolve_rebuildUndo(lprec *lp, MYBOOL isprimal);
STATIC MYBOOL inc_presolve_space(lprec *lp, int delta, MYBOOL isrows);
STATIC MYBOOL presolve_setOrig(lprec *lp, int orig_rows, int orig_cols);
STATIC MYBOOL presolve_colfix(presolverec *psdata, int colnr, REAL newvalue, MYBOOL remove, int *tally);
STATIC MYBOOL presolve_fillUndo(lprec *lp, int orig_rows, int orig_cols, MYBOOL setOrig);
STATIC MYBOOL presolve_freeUndo(lprec *lp);
STATIC MYBOOL presolve_updatesums(presolverec *psdata);
INLINE int presolve_nextrow(presolverec *psdata, int colnr, int *previtem);
INLINE int presolve_nextcol(presolverec *psdata, int rownr, int *previtem);
STATIC presolverec *presolve_init(lprec *lp);
STATIC void presolve_free(presolverec **psdata);
STATIC int presolve_shrink(presolverec *psdata, int *nConRemove, int *nVarRemove);
STATIC void presolve_rowremove(presolverec *psdata, int rownr, MYBOOL allowcoldelete);
STATIC int presolve_colremove(presolverec *psdata, int colnr, MYBOOL allowrowdelete);
STATIC MYBOOL presolve_colfixdual(presolverec *psdata, int colnr, REAL *fixValue, int *status);
INLINE int presolve_rowlength(presolverec *psdata, int rownr)
{
int *items = psdata->rows->next[rownr];
if(items == NULL)
return( 0 );
else
return( items[0] );
}
INLINE int presolve_collength(presolverec *psdata, int colnr)
{
int *items = psdata->cols->next[colnr];
if(items == NULL)
return( 0 );
else
return( items[0] );
}
STATIC int presolve(lprec *lp);
STATIC MYBOOL postsolve(lprec *lp, int status);
#ifdef __cplusplus
}
#endif
#endif /* HEADER_lp_presolve */

File diff suppressed because it is too large Load Diff

View File

@ -1,99 +0,0 @@
#ifndef HEADER_lp_price
#define HEADER_lp_price
/* Local defines */
/* ------------------------------------------------------------------------- */
#define UseSortOnBound_Improve
/*#define UseSortOnBound_Substitute*/
#if 0 /* Stricter feasibility-preserving tolerance; use w/ *_UseRejectionList */
#define UseRelativeFeasibility /* Use machine-precision and A-scale data */
#endif
#if 0 /* Stricter pivot-selection criteria; use w/ *UseRejectionList */
#define UseRelativePivot_Primal /* In rowprim based on A-scale data */
#define UseRelativePivot_Dual /* In coldual based on A-scale data */
#endif
/* Include required library headers */
/* ------------------------------------------------------------------------- */
#include "lp_types.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Comparison and validity routines */
int CMP_CALLMODEL compareImprovementVar(const pricerec *current, const pricerec *candidate);
int CMP_CALLMODEL compareSubstitutionVar(const pricerec *current, const pricerec *candidate);
int CMP_CALLMODEL compareBoundFlipVar(const pricerec *current, const pricerec *candidate);
STATIC int addCandidateVar(pricerec *candidate, multirec *multi, findCompare_func findCompare, MYBOOL allowSortedExpand);
STATIC MYBOOL collectMinorVar(pricerec *candidate, multirec *longsteps, MYBOOL isphase2, MYBOOL isbatch);
STATIC MYBOOL validImprovementVar(pricerec *candidate);
STATIC MYBOOL validSubstitutionVar(pricerec *candidate);
/* Row+column selection routines */
STATIC MYBOOL findImprovementVar(pricerec *current, pricerec *candidate, MYBOOL collectMP, int *candidatecount);
STATIC MYBOOL findSubstitutionVar(pricerec *current, pricerec *candidate, int *candidatecount);
INLINE REAL normalizeEdge(lprec *lp, int item, REAL edge, MYBOOL isdual);
STATIC void makePriceLoop(lprec *lp, int *start, int *end, int *delta);
/* Computation of reduced costs */
STATIC void update_reducedcosts(lprec *lp, MYBOOL isdual, int leave_nr, int enter_nr, REAL *prow, REAL *drow);
STATIC void compute_reducedcosts(lprec *lp, MYBOOL isdual, int row_nr, int *coltarget, MYBOOL dosolve,
REAL *prow, int *nzprow,
REAL *drow, int *nzdrow,
int roundmode);
/* Leaving variable selection and entering column pricing loops */
STATIC int find_rowReplacement(lprec *lp, int rownr, REAL *prow, int *nzprow);
STATIC int colprim(lprec *lp, REAL *drow, int *nzdrow,
MYBOOL skipupdate, int partialloop, int *candidatecount, MYBOOL updateinfeas, REAL *xviol);
STATIC int rowprim(lprec *lp, int colnr, LREAL *theta, REAL *pcol, int *nzpcol, MYBOOL forceoutEQ, REAL *xviol);
STATIC int rowdual(lprec *lp, REAL *rhvec, MYBOOL forceoutEQ, MYBOOL updateinfeas, REAL *xviol);
STATIC int coldual(lprec *lp, int row_nr,
REAL *prow, int *nzprow, REAL *drow, int *nzdrow,
MYBOOL dualphase1, MYBOOL skipupdate,
int *candidatecount, REAL *xviol);
/* Partial pricing management routines */
STATIC partialrec *partial_createBlocks(lprec *lp, MYBOOL isrow);
STATIC int partial_countBlocks(lprec *lp, MYBOOL isrow);
STATIC int partial_activeBlocks(lprec *lp, MYBOOL isrow);
STATIC void partial_freeBlocks(partialrec **blockdata);
/* Partial pricing utility routines */
STATIC int partial_findBlocks(lprec *lp, MYBOOL autodefine, MYBOOL isrow);
STATIC int partial_blockStart(lprec *lp, MYBOOL isrow);
STATIC int partial_blockEnd(lprec *lp, MYBOOL isrow);
STATIC int partial_blockNextPos(lprec *lp, int block, MYBOOL isrow);
STATIC MYBOOL partial_blockStep(lprec *lp, MYBOOL isrow);
STATIC MYBOOL partial_isVarActive(lprec *lp, int varno, MYBOOL isrow);
/* Multiple pricing / dual long step management routines */
STATIC multirec *multi_create(lprec *lp, MYBOOL truncinf);
STATIC MYBOOL multi_resize(multirec *multi, int blocksize, int blockdiv, MYBOOL doVlist, MYBOOL doIset);
STATIC int multi_restart(multirec *multi);
STATIC int multi_size(multirec *multi);
STATIC int multi_used(multirec *multi);
STATIC MYBOOL multi_truncatingvar(multirec *multi, int varnr);
STATIC MYBOOL multi_mustupdate(multirec *multi);
STATIC void multi_valueInit(multirec *multi, REAL step_base, REAL obj_base);
STATIC REAL *multi_valueList(multirec *multi);
STATIC int *multi_indexSet(multirec *multi, MYBOOL regenerate);
STATIC int multi_getvar(multirec *multi, int item);
STATIC MYBOOL multi_recompute(multirec *multi, int index, MYBOOL isphase2, MYBOOL fullupdate);
STATIC MYBOOL multi_removevar(multirec *multi, int varnr);
STATIC int multi_enteringvar(multirec *multi, pricerec *current, int priority);
STATIC REAL multi_enteringtheta(multirec *multi);
STATIC void multi_free(multirec **multi);
STATIC int multi_populateSet(multirec *multi, int **list, int excludenr);
#ifdef __cplusplus
}
#endif
#endif /* HEADER_lp_price */

View File

@ -1,536 +0,0 @@
#include <string.h>
#include "commonlib.h"
#include "lp_lib.h"
#include "lp_report.h"
#include "lp_pricePSE.h"
#ifdef FORTIFY
# include "lp_fortify.h"
#endif
/*
Advanced simplex price scaling modules - w/interface for lp_solve v5.0+
----------------------------------------------------------------------------------
Author: Kjell Eikland
Contact: kjell.eikland@broadpark.no
License terms: LGPL.
Requires: lp_lib.h
Release notes:
v1.0.0 1 September 2003 Implementation of DEVEX and STEEPEST EDGE
routines for the primal and dual simplex.
v1.0.1 1 January 2004 Made initial value of weight of ingoing
variable for the standard mode of DEVEX
consistent with the initialization at restart;
original version could at worst contribute
to cycling.
v1.0.2 23 March 2004 Added floors to Steepest Edge updates and
moved tests for tiny update higher. Previous
logic can be simulated by disabling the compiler
define ApplySteepestEdgeMinimum.
v1.1.0 1 July 2004 Renamed from lp_pricerPSE to lp_pricePSE in
conjuction with the creation of a separate
price library.
v1.2.0 1 March 2005 Changed memory allocation routines to use
standard lp_solve functions, improve error handling
and return boolean status values.
----------------------------------------------------------------------------------
*/
INLINE MYBOOL applyPricer(lprec *lp)
{
int rule = get_piv_rule(lp);
return( (MYBOOL) ((rule == PRICER_DEVEX) || (rule == PRICER_STEEPESTEDGE)) );
}
STATIC void simplexPricer(lprec *lp, MYBOOL isdual)
{
if(lp->edgeVector != NULL)
lp->edgeVector[0] = (REAL) isdual;
}
STATIC void freePricer(lprec *lp)
{
FREE(lp->edgeVector);
}
STATIC MYBOOL resizePricer(lprec *lp)
{
if(!applyPricer(lp))
return( TRUE );
/* Reallocate vector for new size */
if(!allocREAL(lp, &(lp->edgeVector), lp->sum_alloc+1, AUTOMATIC))
return( FALSE );
/* Signal that we have not yet initialized the price vector */
MEMCLEAR(lp->edgeVector, lp->sum_alloc+1);
lp->edgeVector[0] = -1;
return( TRUE );
}
STATIC MYBOOL initPricer(lprec *lp)
{
if(!applyPricer(lp))
return( FALSE );
/* Free any pre-existing pricer */
freePricer(lp);
/* Allocate vector to fit current problem size */
return( resizePricer(lp) );
}
STATIC REAL getPricer(lprec *lp, int item, MYBOOL isdual)
{
REAL value = 1.0;
if(!applyPricer(lp))
return( value );
value = *lp->edgeVector;
/* Make sure we have a price vector to use */
if(value < 0) {
#ifdef Paranoia
report(lp, SEVERE, "getPricer: Called without having being initialized!\n");
#endif
return( 1.0 );
}
/* We may be calling the primal from the dual (and vice-versa) for validation
of feasibility; ignore calling origin and simply return 1 */
else if(isdual != value) {
return( 1.0 );
}
/* Do the normal norm retrieval */
else {
if(isdual)
item = lp->var_basic[item];
value = lp->edgeVector[item];
if(value == 0) {
value = 1.0;
report(lp, SEVERE, "getPricer: Detected a zero-valued price at index %d\n", item);
}
#ifdef Paranoia
else if(value < 0)
report(lp, SEVERE, "getPricer: Invalid %s reduced cost norm %g at index %d\n",
my_if(isdual, "dual", "primal"), value, item);
#endif
/* Return the norm */
return( sqrt(value) );
}
}
STATIC MYBOOL restartPricer(lprec *lp, MYBOOL isdual)
{
REAL *sEdge = NULL, seNorm, hold;
int i, j, m;
MYBOOL isDEVEX, ok = applyPricer(lp);
if(!ok)
return( ok );
/* Store the active/current pricing type */
if(isdual == AUTOMATIC)
isdual = (MYBOOL) lp->edgeVector[0];
else
lp->edgeVector[0] = isdual;
m = lp->rows;
/* Determine strategy and check if we have strategy fallback for the primal */
isDEVEX = is_piv_rule(lp, PRICER_DEVEX);
if(!isDEVEX && !isdual)
isDEVEX = is_piv_mode(lp, PRICE_PRIMALFALLBACK);
/* Check if we only need to do the simple DEVEX initialization */
if(!is_piv_mode(lp, PRICE_TRUENORMINIT)) {
if(isdual) {
for(i = 1; i <= m; i++)
lp->edgeVector[lp->var_basic[i]] = 1.0;
}
else {
for(i = 1; i <= lp->sum; i++)
if(!lp->is_basic[i])
lp->edgeVector[i] = 1.0;
}
return( ok );
}
/* Otherwise do the full Steepest Edge norm initialization */
ok = allocREAL(lp, &sEdge, m+1, FALSE);
if(!ok)
return( ok );
if(isdual) {
/* Extract the rows of the basis inverse and compute their squared norms */
for(i = 1; i <= m; i++) {
bsolve(lp, i, sEdge, NULL, 0, 0.0);
/* Compute the edge norm */
seNorm = 0;
for(j = 1; j <= m; j++) {
hold = sEdge[j];
seNorm += hold*hold;
}
j = lp->var_basic[i];
lp->edgeVector[j] = seNorm;
}
}
else {
/* Solve a=Bb for b over all non-basic variables and compute their squared norms */
for(i = 1; i <= lp->sum; i++) {
if(lp->is_basic[i])
continue;
fsolve(lp, i, sEdge, NULL, 0, 0.0, FALSE);
/* Compute the edge norm */
seNorm = 1;
for(j = 1; j <= m; j++) {
hold = sEdge[j];
seNorm += hold*hold;
}
lp->edgeVector[i] = seNorm;
}
}
FREE(sEdge);
return( ok );
}
STATIC MYBOOL formWeights(lprec *lp, int colnr, REAL *pcol, REAL **w)
/* This computes Bw = a, where B is the basis and a is a column of A */
{
MYBOOL ok = allocREAL(lp, w, lp->rows+1, FALSE);
if(ok) {
if(pcol == NULL)
fsolve(lp, colnr, *w, NULL, 0.0, 0.0, FALSE);
else {
MEMCOPY(*w, pcol, lp->rows+1);
/* *w[0] = 0; */ /* Test */
}
}
/*
if(pcol != NULL) {
REAL cEdge, hold;
int i;
cEdge = 0;
for(i = 1; i <= m; i++) {
hold = *w[i]-pcol[i];
cEdge += hold*hold;
}
cEdge /= m;
cEdge = sqrt(cEdge);
if(cEdge > lp->epspivot)
report(lp, SEVERE, "updatePricer: MRS error is %g\n", cEdge);
}
*/
return(ok);
}
STATIC void freeWeights(REAL *w)
{
FREE(w);
}
STATIC MYBOOL updatePricer(lprec *lp, int rownr, int colnr, REAL *pcol, REAL *prow, int *nzprow)
{
REAL *vEdge = NULL, cEdge, hold, *newEdge, *w = NULL;
int i, m, n, exitcol, errlevel = DETAILED;
MYBOOL forceRefresh = FALSE, isDual, isDEVEX, ok = FALSE;
if(!applyPricer(lp))
return(ok);
/* Make sure we have something to update */
hold = lp->edgeVector[0];
if(hold < 0)
return(ok);
isDual = (MYBOOL) (hold > 0);
/* Do common initializations and computations */
m = lp->rows;
n = lp->sum;
isDEVEX = is_piv_rule(lp, PRICER_DEVEX);
exitcol = lp->var_basic[rownr];
/* Solve/copy Bw = a */
#if 0
ok = formWeights(lp, colnr, NULL, &w); /* Compute from scratch - Experimental */
#else
ok = formWeights(lp, colnr, pcol, &w); /* Use previously computed values */
#endif
if(!ok)
return( ok );
/* Price norms for the dual simplex - the basic columns */
if(isDual) {
REAL rw;
int targetcol;
/* Don't need to compute cross-products with DEVEX */
if(!isDEVEX) {
ok = allocREAL(lp, &vEdge, m+1, FALSE);
if(!ok)
return( ok );
/* Extract the row of the inverse containing the leaving variable
and then form the dot products against the other variables, i.e. "Tau" */
#if 0 /* Extract row explicitly */
bsolve(lp, rownr, vEdge, 0, 0.0);
#else /* Reuse previously extracted row data */
MEMCOPY(vEdge, prow, m+1);
vEdge[0] = 0;
#endif
lp->bfp_ftran_normal(lp, vEdge, NULL);
}
/* Update the squared steepest edge norms; first store some constants */
cEdge = lp->edgeVector[exitcol];
rw = w[rownr];
if(fabs(rw) < lp->epspivot) {
forceRefresh = TRUE;
goto Finish2;
}
/* Deal with the variable entering the basis to become a new leaving candidate */
hold = 1 / rw;
lp->edgeVector[colnr] = (hold*hold) * cEdge;
#ifdef Paranoia
if(lp->edgeVector[colnr] <= lp->epsmachine)
report(lp, errlevel, "updatePricer: Invalid dual norm %g at entering index %d - iteration %.0f\n",
lp->edgeVector[colnr], rownr, (double) (lp->total_iter+lp->current_iter));
#endif
/* Then loop over all basic variables, but skip the leaving row */
for(i = 1; i <= m; i++) {
if(i == rownr)
continue;
targetcol = lp->var_basic[i];
hold = w[i];
if(hold == 0)
continue;
hold /= rw;
if(fabs(hold) < lp->epsmachine)
continue;
newEdge = &(lp->edgeVector[targetcol]);
*newEdge += (hold*hold) * cEdge;
if(isDEVEX) {
if((*newEdge) > DEVEX_RESTARTLIMIT) {
forceRefresh = TRUE;
break;
}
}
else {
*newEdge -= 2*hold*vEdge[i];
#ifdef xxApplySteepestEdgeMinimum
SETMAX(*newEdge, hold*hold+1); /* Kludge; use the primal lower bound */
#else
if(*newEdge <= 0) {
report(lp, errlevel, "updatePricer: Invalid dual norm %g at index %d - iteration %.0f\n",
*newEdge, i, (double) (lp->total_iter+lp->current_iter));
forceRefresh = TRUE;
break;
}
#endif
}
}
}
/* Price norms for the primal simplex - the non-basic columns */
else {
REAL *vTemp = NULL, *vAlpha = NULL, cAlpha;
int *coltarget;
ok = allocREAL(lp, &vTemp, m+1, TRUE) &&
allocREAL(lp, &vAlpha, n+1, TRUE);
if(!ok)
return( ok );
/* Check if we have strategy fallback for the primal */
if(!isDEVEX)
isDEVEX = is_piv_mode(lp, PRICE_PRIMALFALLBACK);
/* Initialize column target array */
coltarget = (int *) mempool_obtainVector(lp->workarrays, lp->sum+1, sizeof(*coltarget));
ok = get_colIndexA(lp, SCAN_SLACKVARS+SCAN_USERVARS+USE_NONBASICVARS, coltarget, FALSE);
if(!ok) {
mempool_releaseVector(lp->workarrays, (char *) coltarget, FALSE);
return( ok );
}
/* Don't need to compute cross-products with DEVEX */
if(!isDEVEX) {
ok = allocREAL(lp, &vEdge, n+1, TRUE);
if(!ok)
return( ok );
/* Compute v and then N'v */
MEMCOPY(vTemp, w, m+1);
bsolve(lp, -1, vTemp, NULL, lp->epsmachine*DOUBLEROUND, 0.0);
vTemp[0] = 0;
prod_xA(lp, coltarget, vTemp, NULL, lp->epsmachine, 0.0,
vEdge, NULL, MAT_ROUNDDEFAULT);
}
/* Compute Sigma and then Alpha */
bsolve(lp, rownr, vTemp, NULL, 0*DOUBLEROUND, 0.0);
vTemp[0] = 0;
prod_xA(lp, coltarget, vTemp, NULL, lp->epsmachine, 0.0,
vAlpha, NULL, MAT_ROUNDDEFAULT);
mempool_releaseVector(lp->workarrays, (char *) coltarget, FALSE);
/* Update the squared steepest edge norms; first store some constants */
cEdge = lp->edgeVector[colnr];
cAlpha = vAlpha[colnr];
if(fabs(cAlpha) < lp->epspivot) {
forceRefresh = TRUE;
goto Finish1;
}
/* Deal with the variable leaving the basis to become a new entry candidate */
hold = 1 / cAlpha;
lp->edgeVector[exitcol] = (hold*hold) * cEdge;
#ifdef Paranoia
if(lp->edgeVector[exitcol] <= lp->epsmachine)
report(lp, errlevel, "updatePricer: Invalid primal norm %g at leaving index %d - iteration %.0f\n",
lp->edgeVector[exitcol], exitcol, (double) (lp->total_iter+lp->current_iter));
#endif
/* Then loop over all non-basic variables, but skip the entering column */
for(i = 1; i <= lp->sum; i++) {
if(lp->is_basic[i] || (i == colnr))
continue;
hold = vAlpha[i];
if(hold == 0)
continue;
hold /= cAlpha;
if(fabs(hold) < lp->epsmachine)
continue;
newEdge = &(lp->edgeVector[i]);
*newEdge += (hold*hold) * cEdge;
if(isDEVEX) {
if((*newEdge) > DEVEX_RESTARTLIMIT) {
forceRefresh = TRUE;
break;
}
}
else {
*newEdge -= 2*hold*vEdge[i];
#ifdef ApplySteepestEdgeMinimum
SETMAX(*newEdge, hold*hold+1);
#else
if(*newEdge < 0) {
report(lp, errlevel, "updatePricer: Invalid primal norm %g at index %d - iteration %.0f\n",
*newEdge, i, (double) (lp->total_iter+lp->current_iter));
if(lp->spx_trace)
report(lp, errlevel, "Error detail: (RelAlpha=%g, vEdge=%g, cEdge=%g)\n", hold, vEdge[i], cEdge);
forceRefresh = TRUE;
break;
}
#endif
}
}
Finish1:
FREE(vAlpha);
FREE(vTemp);
}
Finish2:
FREE(vEdge);
freeWeights(w);
if(forceRefresh)
ok = restartPricer(lp, AUTOMATIC);
else
ok = TRUE;
return( ok );
}
STATIC MYBOOL verifyPricer(lprec *lp)
{
REAL value;
int i, n;
MYBOOL ok = applyPricer(lp);
if(!ok)
return( ok );
ok = FALSE;
/* Verify */
if(lp->edgeVector == NULL)
return( ok );
value = *lp->edgeVector;
if(value < 0)
return( ok );
/* Check the primal */
n = 1;
if(value == 0) {
for(n = lp->sum; n > 0; n--) {
if(lp->is_basic[n])
continue;
value = lp->edgeVector[n];
if(value <= 0)
break;
}
}
/* Check the dual */
else {
for(i = lp->rows; i > 0; i--) {
n = lp->var_basic[i];
value = lp->edgeVector[n];
if(value <= 0)
break;
}
}
ok = (MYBOOL) (n == 0);
#ifdef Paranoia
if(!ok)
report(lp, SEVERE, "verifyPricer: Invalid norm %g at index %d\n",
value, n);
#endif
return( ok );
}

View File

@ -1,28 +0,0 @@
#ifndef HEADER_lp_pricePSE
#define HEADER_lp_pricePSE
#include "lp_types.h"
#define ApplySteepestEdgeMinimum
#ifdef __cplusplus
extern "C" {
#endif
/* Price norm management routines */
STATIC MYBOOL initPricer(lprec *lp);
INLINE MYBOOL applyPricer(lprec *lp);
STATIC void simplexPricer(lprec *lp, MYBOOL isdual);
STATIC void freePricer(lprec *lp);
STATIC MYBOOL resizePricer(lprec *lp);
STATIC REAL getPricer(lprec *lp, int item, MYBOOL isdual);
STATIC MYBOOL restartPricer(lprec *lp, MYBOOL isdual);
STATIC MYBOOL updatePricer(lprec *lp, int rownr, int colnr, REAL *pcol, REAL *prow, int *nzprow);
STATIC MYBOOL verifyPricer(lprec *lp);
#ifdef __cplusplus
}
#endif
#endif /* HEADER_lp_pricePSE */

View File

@ -1,789 +0,0 @@
/*
Mixed integer programming optimization drivers for lp_solve v5.0+
----------------------------------------------------------------------------------
Author: Michel Berkelaar (to lp_solve v3.2),
Kjell Eikland
Contact:
License terms: LGPL.
Requires: stdarg.h, lp_lib.h
Release notes:
v5.0.0 3 1 January 2004 New unit isolating reporting routines.
v5.2.0.0 1 December 2005 Addition of Matrix Market writing function.
----------------------------------------------------------------------------------
*/
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include "lp_lib.h"
#include "lp_scale.h"
#include "commonlib.h"
#include "lp_report.h"
#include "mmio.h"
#ifdef FORTIFY
# include "lp_fortify.h"
#endif
/* Define buffer-size controled function mapping */
# if defined _MSC_VER
# define vsnprintf _vsnprintf
# endif
/* Various reporting functions for lp_solve */
/* ------------------------------------------------------------------------- */
/* First define general utilties for reporting and output */
char * __VACALL explain(lprec *lp, char *format, ...)
{
char buff[DEF_STRBUFSIZE+1];
va_list ap;
va_start(ap, format);
vsnprintf(buff, DEF_STRBUFSIZE, format, ap);
allocCHAR(lp, &(lp->ex_status), (int) strlen(buff), AUTOMATIC);
strcpy(lp->ex_status, buff);
va_end(ap);
return( lp->ex_status );
}
void __VACALL report(lprec *lp, int level, char *format, ...)
{
static char buff[DEF_STRBUFSIZE+1];
static va_list ap;
if(lp == NULL) {
va_start(ap, format);
vfprintf(stderr, format, ap);
va_end(ap);
}
else if(level <= lp->verbose) {
va_start(ap, format);
if(lp->writelog != NULL) {
vsnprintf(buff, DEF_STRBUFSIZE, format, ap);
lp->writelog(lp, lp->loghandle, buff);
}
if(lp->outstream != NULL) {
vfprintf(lp->outstream, format, ap);
if(lp->outstream != stdout)
fflush(lp->outstream);
}
va_end(ap);
}
#ifdef xParanoia
if(level == CRITICAL)
raise(SIGSEGV);
#endif
}
STATIC void print_indent(lprec *lp)
{
int i;
report(lp, NEUTRAL, "%2d", lp->bb_level);
if(lp->bb_level < 50) /* useless otherwise */
for(i = lp->bb_level; i > 0; i--)
report(lp, NEUTRAL, "--");
else
report(lp, NEUTRAL, " *** too deep ***");
report(lp, NEUTRAL, "> ");
} /* print_indent */
STATIC void debug_print(lprec *lp, char *format, ...)
{
va_list ap;
if(lp->bb_trace) {
print_indent(lp);
va_start(ap, format);
if (lp == NULL)
{
vfprintf(stderr, format, ap);
fputc('\n', stderr);
}
else if(lp->debuginfo != NULL)
{
char buff[DEF_STRBUFSIZE+1];
vsnprintf(buff, DEF_STRBUFSIZE, format, ap);
lp->debuginfo(lp, lp->loghandle, buff);
}
va_end(ap);
}
} /* debug_print */
STATIC void debug_print_solution(lprec *lp)
{
int i;
if(lp->bb_trace)
for (i = lp->rows + 1; i <= lp->sum; i++) {
print_indent(lp);
report(lp, NEUTRAL, "%s " RESULTVALUEMASK "\n",
get_col_name(lp, i - lp->rows),
(double)lp->solution[i]);
}
} /* debug_print_solution */
STATIC void debug_print_bounds(lprec *lp, REAL *upbo, REAL *lowbo)
{
int i;
if(lp->bb_trace)
for(i = lp->rows + 1; i <= lp->sum; i++) {
if(lowbo[i] == upbo[i]) {
print_indent(lp);
report(lp, NEUTRAL, "%s = " RESULTVALUEMASK "\n", get_col_name(lp, i - lp->rows),
(double)lowbo[i]);
}
else {
if(lowbo[i] != 0) {
print_indent(lp);
report(lp, NEUTRAL, "%s > " RESULTVALUEMASK "\n", get_col_name(lp, i - lp->rows),
(double)lowbo[i]);
}
if(upbo[i] != lp->infinite) {
print_indent(lp);
report(lp, NEUTRAL, "%s < " RESULTVALUEMASK "\n", get_col_name(lp, i - lp->rows),
(double)upbo[i]);
}
}
}
} /* debug_print_bounds */
/* List a vector of LREAL values for the given index range */
void blockWriteLREAL(FILE *output, char *label, LREAL *vector, int first, int last)
{
int i, k = 0;
fprintf(output, label);
fprintf(output, "\n");
for(i = first; i <= last; i++) {
fprintf(output, " %18g", vector[i]);
k++;
if(my_mod(k, 4) == 0) {
fprintf(output, "\n");
k = 0;
}
}
if(my_mod(k, 4) != 0)
fprintf(output, "\n");
}
/* List the current user data matrix columns over the selected row range */
void blockWriteAMAT(FILE *output, const char *label, lprec* lp, int first, int last)
{
int i, j, k = 0;
int nzb, nze, jb;
double hold;
MATrec *mat = lp->matA;
if(!mat_validate(mat))
return;
if(first < 0)
first = 0;
if(last < 0)
last = lp->rows;
fprintf(output, label);
fprintf(output, "\n");
if(first == 0) {
for(j = 1; j <= lp->columns; j++) {
hold = get_mat(lp, 0, j);
fprintf(output, " %18g", hold);
k++;
if(my_mod(k, 4) == 0) {
fprintf(output, "\n");
k = 0;
}
}
if(my_mod(k, 4) != 0) {
fprintf(output, "\n");
k = 0;
}
first++;
}
nze = mat->row_end[first-1];
for(i = first; i <= last; i++) {
nzb = nze;
nze = mat->row_end[i];
if(nzb >= nze)
jb = lp->columns+1;
else
jb = ROW_MAT_COLNR(nzb);
for(j = 1; j <= lp->columns; j++) {
if(j < jb)
hold = 0;
else {
hold = get_mat(lp, i, j);
nzb++;
if(nzb < nze)
jb = ROW_MAT_COLNR(nzb);
else
jb = lp->columns+1;
}
fprintf(output, " %18g", hold);
k++;
if(my_mod(k, 4) == 0) {
fprintf(output, "\n");
k = 0;
}
}
if(my_mod(k, 4) != 0) {
fprintf(output, "\n");
k = 0;
}
}
if(my_mod(k, 4) != 0)
fprintf(output, "\n");
}
/* List the current basis matrix columns over the selected row range */
void blockWriteBMAT(FILE *output, const char *label, lprec* lp, int first, int last)
{
int i, j, jb, k = 0;
double hold;
if(first < 0)
first = 0;
if(last < 0)
last = lp->rows;
fprintf(output, label);
fprintf(output, "\n");
for(i = first; i <= last; i++) {
for(j = 1; j <= lp->rows; j++) {
jb = lp->var_basic[j];
if(jb <= lp->rows) {
if(jb == i)
hold = 1;
else
hold = 0;
}
else
hold = get_mat(lp, i, j);
if(i == 0)
modifyOF1(lp, jb, &hold, 1);
hold = unscaled_mat(lp, hold, i, jb);
fprintf(output, " %18g", hold);
k++;
if(my_mod(k, 4) == 0) {
fprintf(output, "\n");
k = 0;
}
}
if(my_mod(k, 4) != 0) {
fprintf(output, "\n");
k = 0;
}
}
if(my_mod(k, 4) != 0)
fprintf(output, "\n");
}
/* Do a generic readable data dump of key lp_solve model variables;
principally for run difference and debugging purposes */
MYBOOL REPORT_debugdump(lprec *lp, char *filename, MYBOOL livedata)
{
FILE *output = stdout;
MYBOOL ok;
ok = (MYBOOL) ((filename == NULL) || ((output = fopen(filename,"w")) != NULL));
if(!ok)
return(ok);
if((filename == NULL) && (lp->outstream != NULL))
output = lp->outstream;
fprintf(output, "\nGENERAL INFORMATION\n-------------------\n\n");
fprintf(output, "Model size: %d rows (%d equalities, %d Lagrangean), %d columns (%d integers, %d SC, %d SOS, %d GUB)\n",
lp->rows, lp->equalities, get_Lrows(lp), lp->columns,
lp->int_vars, lp->sc_vars, SOS_count(lp), GUB_count(lp));
fprintf(output, "Data size: %d model non-zeros, %d invB non-zeros (engine is %s)\n",
get_nonzeros(lp), my_if(lp->invB == NULL, 0, lp->bfp_nonzeros(lp, FALSE)), lp->bfp_name());
fprintf(output, "Internal sizes: %d rows allocated, %d columns allocated, %d columns used, %d eta length\n",
lp->rows_alloc, lp->columns_alloc, lp->columns, my_if(lp->invB == NULL, 0, lp->bfp_colcount(lp)));
fprintf(output, "Memory use: %d sparse matrix, %d eta\n",
lp->matA->mat_alloc, my_if(lp->invB == NULL, 0, lp->bfp_memallocated(lp)));
fprintf(output, "Parameters: Maximize=%d, Names used=%d, Scalingmode=%d, Presolve=%d, SimplexPivot=%d\n",
is_maxim(lp), lp->names_used, lp->scalemode, lp->do_presolve, lp->piv_strategy);
fprintf(output, "Precision: EpsValue=%g, EpsPrimal=%g, EpsDual=%g, EpsPivot=%g, EpsPerturb=%g\n",
lp->epsvalue, lp->epsprimal, lp->epsdual, lp->epspivot, lp->epsperturb);
fprintf(output, "Stability: AntiDegen=%d, Improvement=%d, Split variables at=%g\n",
lp->improve, lp->anti_degen, lp->negrange);
fprintf(output, "B&B settings: BB pivot rule=%d, BB branching=%s, BB strategy=%d, Integer precision=%g, MIP gaps=%g,%g\n",
lp->bb_rule, my_boolstr(lp->bb_varbranch), lp->bb_floorfirst, lp->epsint, lp->mip_absgap, lp->mip_relgap);
fprintf(output, "\nCORE DATA\n---------\n\n");
blockWriteINT(output, "Column starts", lp->matA->col_end, 0, lp->columns);
blockWriteINT(output, "row_type", lp->row_type, 0, lp->rows);
blockWriteREAL(output, "orig_rhs", lp->orig_rhs, 0, lp->rows);
blockWriteREAL(output, "orig_lowbo", lp->orig_lowbo, 0, lp->sum);
blockWriteREAL(output, "orig_upbo", lp->orig_upbo, 0, lp->sum);
blockWriteINT(output, "row_type", lp->row_type, 0, lp->rows);
blockWriteBOOL(output, "var_type", lp->var_type, 0, lp->columns, TRUE);
blockWriteAMAT(output, "A", lp, 0, lp->rows);
if(livedata) {
fprintf(output, "\nPROCESS DATA\n------------\n\n");
blockWriteREAL(output, "Active rhs", lp->rhs, 0, lp->rows);
blockWriteINT(output, "Basic variables", lp->var_basic, 0, lp->rows);
blockWriteBOOL(output, "is_basic", lp->is_basic, 0, lp->sum, TRUE);
blockWriteREAL(output, "lowbo", lp->lowbo, 0, lp->sum);
blockWriteREAL(output, "upbo", lp->upbo, 0, lp->sum);
if(lp->scalars != NULL)
blockWriteREAL(output, "scalars", lp->scalars, 0, lp->sum);
}
if(filename != NULL)
fclose(output);
return(ok);
}
/* High level reports for model results */
void REPORT_objective(lprec *lp)
{
if(lp->outstream == NULL)
return;
fprintf(lp->outstream, "\nValue of objective function: %g\n",
(double)lp->best_solution[0]);
fflush(lp->outstream);
}
void REPORT_solution(lprec *lp, int columns)
{
int i, j, n;
REAL value;
presolveundorec *psundo = lp->presolve_undo;
MYBOOL NZonly = (MYBOOL) ((lp->print_sol & AUTOMATIC) > 0);
if(lp->outstream == NULL)
return;
fprintf(lp->outstream, "\nActual values of the variables:\n");
if(columns <= 0)
columns = 2;
n = 0;
for(i = 1; i <= psundo->orig_columns; i++) {
j = psundo->orig_rows + i;
value = get_var_primalresult(lp, j);
if(NZonly && (fabs(value) < lp->epsprimal))
continue;
n = (n+1) % columns;
fprintf(lp->outstream, "%-20s %12g", get_origcol_name(lp, i), (double) value);
if(n == 0)
fprintf(lp->outstream, "\n");
else
fprintf(lp->outstream, " ");
}
fflush(lp->outstream);
} /* REPORT_solution */
void REPORT_constraints(lprec *lp, int columns)
{
int i, n;
REAL value;
MYBOOL NZonly = (MYBOOL) ((lp->print_sol & AUTOMATIC) > 0);
if(lp->outstream == NULL)
return;
if(columns <= 0)
columns = 2;
fprintf(lp->outstream, "\nActual values of the constraints:\n");
n = 0;
for(i = 1; i <= lp->rows; i++) {
value = (double)lp->best_solution[i];
if(NZonly && (fabs(value) < lp->epsprimal))
continue;
n = (n+1) % columns;
fprintf(lp->outstream, "%-20s %12g", get_row_name(lp, i), value);
if(n == 0)
fprintf(lp->outstream, "\n");
else
fprintf(lp->outstream, " ");
}
fflush(lp->outstream);
}
void REPORT_duals(lprec *lp)
{
int i;
REAL *duals, *dualsfrom, *dualstill, *objfrom, *objtill, *objfromvalue;
MYBOOL ret;
if(lp->outstream == NULL)
return;
ret = get_ptr_sensitivity_objex(lp, &objfrom, &objtill, &objfromvalue, NULL);
if(ret) {
fprintf(lp->outstream, "\nObjective function limits:\n");
fprintf(lp->outstream, " From Till FromValue\n");
for(i = 1; i <= lp->columns; i++)
if(!is_splitvar(lp, i))
fprintf(lp->outstream, "%-20s %15.7g %15.7g %15.7g\n", get_col_name(lp, i),
(double)objfrom[i - 1], (double)objtill[i - 1], (double)objfromvalue[i - 1]);
}
ret = get_ptr_sensitivity_rhs(lp, &duals, &dualsfrom, &dualstill);
if(ret) {
fprintf(lp->outstream, "\nDual values with from - till limits:\n");
fprintf(lp->outstream, " Dual value From Till\n");
for(i = 1; i <= lp->sum; i++)
fprintf(lp->outstream, "%-20s %15.7g %15.7g %15.7g\n",
(i <= lp->rows) ? get_row_name(lp, i) : get_col_name(lp, i - lp->rows),
(double)duals[i - 1], (double)dualsfrom[i - 1], (double)dualstill[i - 1]);
fflush(lp->outstream);
}
}
/* Printing of sensitivity analysis reports */
void REPORT_extended(lprec *lp)
{
int i, j;
REAL hold;
REAL *duals, *dualsfrom, *dualstill, *objfrom, *objtill;
MYBOOL ret;
ret = get_ptr_sensitivity_obj(lp, &objfrom, &objtill);
report(lp, NORMAL, " \n");
report(lp, NORMAL, "Primal objective:\n");
report(lp, NORMAL, " \n");
report(lp, NORMAL, " Column name Value Objective Min Max\n");
report(lp, NORMAL, " --------------------------------------------------------------------------\n");
for(j = 1; j <= lp->columns; j++) {
hold = get_mat(lp,0,j);
report(lp, NORMAL, " %-25s " MPSVALUEMASK MPSVALUEMASK MPSVALUEMASK MPSVALUEMASK "\n",
get_col_name(lp,j),
my_precision(hold,lp->epsprimal),
my_precision(hold*lp->best_solution[lp->rows+j],lp->epsprimal),
my_precision((ret) ? objfrom[j - 1] : 0.0,lp->epsprimal),
my_precision((ret) ? objtill[j - 1] : 0.0,lp->epsprimal));
}
report(lp, NORMAL, " \n");
ret = get_ptr_sensitivity_rhs(lp, &duals, &dualsfrom, &dualstill);
report(lp, NORMAL, "Primal variables:\n");
report(lp, NORMAL, " \n");
report(lp, NORMAL, " Column name Value Slack Min Max\n");
report(lp, NORMAL, " --------------------------------------------------------------------------\n");
for(j = 1; j <= lp->columns; j++)
report(lp, NORMAL, " %-25s " MPSVALUEMASK MPSVALUEMASK MPSVALUEMASK MPSVALUEMASK "\n",
get_col_name(lp,j),
my_precision(lp->best_solution[lp->rows+j],lp->epsprimal),
my_precision(my_inflimit(lp, (ret) ? duals[lp->rows+j-1] : 0.0),lp->epsprimal),
my_precision((ret) ? dualsfrom[lp->rows+j-1] : 0.0,lp->epsprimal),
my_precision((ret) ? dualstill[lp->rows+j-1] : 0.0,lp->epsprimal));
report(lp, NORMAL, " \n");
report(lp, NORMAL, "Dual variables:\n");
report(lp, NORMAL, " \n");
report(lp, NORMAL, " Row name Value Slack Min Max\n");
report(lp, NORMAL, " --------------------------------------------------------------------------\n");
for(i = 1; i <= lp->rows; i++)
report(lp, NORMAL, " %-25s " MPSVALUEMASK MPSVALUEMASK MPSVALUEMASK MPSVALUEMASK "\n",
get_row_name(lp,i),
my_precision((ret) ? duals[i - 1] : 0.0, lp->epsprimal),
my_precision(lp->best_solution[i], lp->epsprimal),
my_precision((ret) ? dualsfrom[i - 1] : 0.0,lp->epsprimal),
my_precision((ret) ? dualstill[i - 1] : 0.0,lp->epsprimal));
report(lp, NORMAL, " \n");
}
/* A more readable lp-format report of the model; antiquated and not updated */
void REPORT_lp(lprec *lp)
{
int i, j;
if(lp->outstream == NULL)
return;
if(lp->matA->is_roworder) {
report(lp, IMPORTANT, "REPORT_lp: Cannot print lp while in row entry mode.\n");
return;
}
fprintf(lp->outstream, "Model name: %s\n", get_lp_name(lp));
fprintf(lp->outstream, " ");
for(j = 1; j <= lp->columns; j++)
fprintf(lp->outstream, "%8s ", get_col_name(lp,j));
fprintf(lp->outstream, "\n%simize ", (is_maxim(lp) ? "Max" : "Min"));
for(j = 1; j <= lp->columns; j++)
fprintf(lp->outstream, "%8g ", get_mat(lp, 0, j));
fprintf(lp->outstream, "\n");
for(i = 1; i <= lp->rows; i++) {
fprintf(lp->outstream, "%-9s ", get_row_name(lp, i));
for(j = 1; j <= lp->columns; j++)
fprintf(lp->outstream, "%8g ", get_mat(lp, i, j));
if(is_constr_type(lp, i, GE))
fprintf(lp->outstream, ">= ");
else if(is_constr_type(lp, i, LE))
fprintf(lp->outstream, "<= ");
else
fprintf(lp->outstream, " = ");
fprintf(lp->outstream, "%8g", get_rh(lp, i));
if(is_constr_type(lp, i, GE)) {
if(get_rh_upper(lp, i) < lp->infinite)
fprintf(lp->outstream, " %s = %8g", "upbo", get_rh_upper(lp, i));
}
else if(is_constr_type(lp, i, LE)) {
if(get_rh_lower(lp, i) > -lp->infinite)
fprintf(lp->outstream, " %s = %8g", "lowbo", get_rh_lower(lp, i));
}
fprintf(lp->outstream, "\n");
}
fprintf(lp->outstream, "Type ");
for(i = 1; i <= lp->columns; i++) {
if(is_int(lp,i))
fprintf(lp->outstream, " Int ");
else
fprintf(lp->outstream, " Real ");
}
fprintf(lp->outstream, "\nupbo ");
for(i = 1; i <= lp->columns; i++)
if(get_upbo(lp, i) >= lp->infinite)
fprintf(lp->outstream, " Inf ");
else
fprintf(lp->outstream, "%8g ", get_upbo(lp, i));
fprintf(lp->outstream, "\nlowbo ");
for(i = 1; i <= lp->columns; i++)
if(get_lowbo(lp, i) <= -lp->infinite)
fprintf(lp->outstream, " -Inf ");
else
fprintf(lp->outstream, "%8g ", get_lowbo(lp, i));
fprintf(lp->outstream, "\n");
fflush(lp->outstream);
}
/* Report the scaling factors used; extremely rarely used */
void REPORT_scales(lprec *lp)
{
int i, colMax;
colMax = lp->columns;
if(lp->outstream == NULL)
return;
if(lp->scaling_used) {
fprintf(lp->outstream, "\nScale factors:\n");
for(i = 0; i <= lp->rows + colMax; i++)
fprintf(lp->outstream, "%-20s scaled at %g\n",
(i <= lp->rows) ? get_row_name(lp, i) : get_col_name(lp, i - lp->rows),
(double)lp->scalars[i]);
}
fflush(lp->outstream);
}
/* Report the traditional tableau corresponding to the current basis */
MYBOOL REPORT_tableau(lprec *lp)
{
int j, row_nr, *coltarget;
REAL *prow = NULL;
FILE *stream = lp->outstream;
if(lp->outstream == NULL)
return(FALSE);
if(!lp->model_is_valid || !has_BFP(lp) ||
(get_total_iter(lp) == 0) || (lp->spx_status == NOTRUN)) {
lp->spx_status = NOTRUN;
return(FALSE);
}
if(!allocREAL(lp, &prow,lp->sum + 1, TRUE)) {
lp->spx_status = NOMEMORY;
return(FALSE);
}
fprintf(stream, "\n");
fprintf(stream, "Tableau at iter %.0f:\n", (double) get_total_iter(lp));
for(j = 1; j <= lp->sum; j++)
if (!lp->is_basic[j])
fprintf(stream, "%15d", (j <= lp->rows ?
(j + lp->columns) * ((lp->orig_upbo[j] == 0) ||
(is_chsign(lp, j)) ? 1 : -1) : j - lp->rows) *
(lp->is_lower[j] ? 1 : -1));
fprintf(stream, "\n");
coltarget = (int *) mempool_obtainVector(lp->workarrays, lp->columns+1, sizeof(*coltarget));
if(!get_colIndexA(lp, SCAN_USERVARS+USE_NONBASICVARS, coltarget, FALSE)) {
mempool_releaseVector(lp->workarrays, (char *) coltarget, FALSE);
return(FALSE);
}
for(row_nr = 1; (row_nr <= lp->rows + 1); row_nr++) {
if (row_nr <= lp->rows)
fprintf(stream, "%3d", (lp->var_basic[row_nr] <= lp->rows ?
(lp->var_basic[row_nr] + lp->columns) * ((lp->orig_upbo[lp->var_basic [row_nr]] == 0) ||
(is_chsign(lp, lp->var_basic[row_nr])) ? 1 : -1) : lp->var_basic[row_nr] - lp->rows) *
(lp->is_lower[lp->var_basic [row_nr]] ? 1 : -1));
else
fprintf(stream, " ");
bsolve(lp, row_nr <= lp->rows ? row_nr : 0, prow, NULL, lp->epsmachine*DOUBLEROUND, 1.0);
prod_xA(lp, coltarget, prow, NULL, lp->epsmachine, 1.0,
prow, NULL, MAT_ROUNDDEFAULT);
for(j = 1; j <= lp->rows + lp->columns; j++)
if (!lp->is_basic[j])
fprintf(stream, "%15.7f", prow[j] * (lp->is_lower[j] ? 1 : -1) *
(row_nr <= lp->rows ? 1 : -1));
fprintf(stream, "%15.7f", lp->rhs[row_nr <= lp->rows ? row_nr : 0] *
(double) ((row_nr <= lp->rows) || (is_maxim(lp)) ? 1 : -1));
fprintf(stream, "\n");
}
fflush(stream);
mempool_releaseVector(lp->workarrays, (char *) coltarget, FALSE);
FREE(prow);
return(TRUE);
}
void REPORT_constraintinfo(lprec *lp, char *datainfo)
{
int i, tally[ROWCLASS_MAX+1];
MEMCLEAR(tally, ROWCLASS_MAX+1);
for(i = 1; i <= lp->rows; i++)
tally[get_constr_class(lp, i)]++;
if(datainfo != NULL)
report(lp, NORMAL, "%s\n", datainfo);
for(i = 0; i <= ROWCLASS_MAX; i++)
if(tally[i] > 0)
report(lp, NORMAL, "%-15s %4d\n", get_str_constr_class(lp, i), tally[i]);
}
void REPORT_modelinfo(lprec *lp, MYBOOL doName, char *datainfo)
{
if(doName) {
report(lp, NORMAL, "\nModel name: '%s' - run #%-5d\n",
get_lp_name(lp), lp->solvecount);
report(lp, NORMAL, "Objective: %simize(%s)\n",
my_if(is_maxim(lp), "Max", "Min"), get_row_name(lp, 0));
report(lp, NORMAL, " \n");
}
if(datainfo != NULL)
report(lp, NORMAL, "%s\n", datainfo);
report(lp, NORMAL, "Model size: %7d constraints, %7d variables, %12d non-zeros.\n",
lp->rows, lp->columns, get_nonzeros(lp));
if(GUB_count(lp)+SOS_count(lp) > 0)
report(lp, NORMAL, "Var-types: %7d integer, %7d semi-cont., %7d SOS.\n",
lp->int_vars, lp->sc_vars, lp->sos_vars);
report(lp, NORMAL, "Sets: %7d GUB, %7d SOS.\n",
GUB_count(lp), SOS_count(lp));
}
/* Save a matrix column subset to a MatrixMarket formatted file,
say to export the basis matrix for further numerical analysis.
If colndx is NULL, then the full constraint matrix is assumed. */
MYBOOL REPORT_mat_mmsave(lprec *lp, char *filename, int *colndx, MYBOOL includeOF, char *infotext)
{
int n, m, nz, i, j, k, kk;
MATrec *mat = lp->matA;
MM_typecode matcode;
FILE *output = stdout;
MYBOOL ok;
REAL *acol = NULL;
int *nzlist = NULL;
/* Open file */
ok = (MYBOOL) ((filename == NULL) || ((output = fopen(filename,"w")) != NULL));
if(!ok)
return(ok);
if((filename == NULL) && (lp->outstream != NULL))
output = lp->outstream;
/* Compute column and non-zero counts */
if(colndx == lp->var_basic) {
if(!lp->basis_valid)
return( FALSE );
m = lp->rows;
}
else if(colndx != NULL)
m = colndx[0];
else
m = lp->columns;
n = lp->rows;
nz = 0;
for(j = 1; j <= m; j++) {
k = (colndx == NULL ? n + j : colndx[j]);
if(k > n) {
k -= lp->rows;
nz += mat_collength(mat, k);
if(includeOF && is_OF_nz(lp, k))
nz++;
}
else
nz++;
}
kk = 0;
if(includeOF) {
n++; /* Row count */
kk++; /* Row index offset */
}
/* Initialize */
mm_initialize_typecode(&matcode);
mm_set_matrix(&matcode);
mm_set_coordinate(&matcode);
mm_set_real(&matcode);
mm_write_banner(output, matcode);
mm_write_mtx_crd_size(output, n+kk, m, nz+(colndx == lp->var_basic ? 1 : 0));
/* Allocate working arrays for sparse column storage */
allocREAL(lp, &acol, n+2, FALSE);
allocINT(lp, &nzlist, n+2, FALSE);
/* Write the matrix non-zero values column-by-column.
NOTE: matrixMarket files use 1-based indeces,
i.e. first row of a vector has index 1, not 0. */
if(infotext != NULL) {
fprintf(output, "%%\n");
fprintf(output, "%% %s\n", infotext);
fprintf(output, "%%\n");
}
if(includeOF && (colndx == lp->var_basic))
fprintf(output, "%d %d %g\n", 1, 1, 1.0);
for(j = 1; j <= m; j++) {
k = (colndx == NULL ? lp->rows + j : colndx[j]);
if(k == 0)
continue;
nz = obtain_column(lp, k, acol, nzlist, NULL);
for(i = 1; i <= nz; i++) {
if(!includeOF && (nzlist[i] == 0))
continue;
fprintf(output, "%d %d %g\n", nzlist[i]+kk, j+kk, acol[i]);
}
}
fprintf(output, "%% End of MatrixMarket file\n");
/* Finish */
FREE(acol);
FREE(nzlist);
fclose(output);
return(ok);
}

View File

@ -1,42 +0,0 @@
#ifndef HEADER_lp_report
#define HEADER_lp_report
#ifdef __cplusplus
extern "C" {
#endif
/* General information functions */
char * __VACALL explain(lprec *lp, char *format, ...);
void __VACALL report(lprec *lp, int level, char *format, ...);
/* Prototypes for debugging and general data dumps */
void debug_print(lprec *lp, char *format, ...);
void debug_print_solution(lprec *lp);
void debug_print_bounds(lprec *lp, REAL *upbo, REAL *lowbo);
void blockWriteLREAL(FILE *output, char *label, LREAL *vector, int first, int last);
void blockWriteAMAT(FILE *output, const char *label, lprec* lp, int first, int last);
void blockWriteBMAT(FILE *output, const char *label, lprec* lp, int first, int last);
/* Model reporting headers */
void REPORT_objective(lprec *lp);
void REPORT_solution(lprec *lp, int columns);
void REPORT_constraints(lprec *lp, int columns);
void REPORT_duals(lprec *lp);
void REPORT_extended(lprec *lp);
/* Other rarely used, but sometimes extremely useful reports */
void REPORT_constraintinfo(lprec *lp, char *datainfo);
void REPORT_modelinfo(lprec *lp, MYBOOL doName, char *datainfo);
void REPORT_lp(lprec *lp);
MYBOOL REPORT_tableau(lprec *lp);
void REPORT_scales(lprec *lp);
MYBOOL REPORT_debugdump(lprec *lp, char *filename, MYBOOL livedata);
MYBOOL REPORT_mat_mmsave(lprec *lp, char *filename, int *colndx, MYBOOL includeOF, char *infotext);
#ifdef __cplusplus
}
#endif
#endif /* HEADER_lp_report */

View File

@ -1,7 +0,0 @@
flex -L -l lp_rlp.l
sed -e "s/yy/lp_yy/g" lex.yy.c >lp_rlp.h
del lex.yy.c
bison --no-lines -y lp_rlp.y
sed -e "s/yy/lp_yy/g" y.tab.c >lp_rlp.c
del y.tab.c

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,194 +0,0 @@
WS [ \r\n\t]+
LT [A-Za-z]
KR [A-Za-z0-9_\[\]\{\}/.&#$%~'@^]
DI [0-9]
INNM {DI}+
NM (({DI}+\.?{DI}*)|(\.{DI}+))([Ee][-+]?{DI}+)?
VR {LT}{KR}*(<{KR}+>)?
OPLE [<]?=?
OPGE [>]=?
EOW $|[*+-;<=>]|{WS}
INF [ \r\n\t]*[-+][Ii][Nn][Ff]([Ii][Nn][Ii][Tt]([Ee]|[Yy]))?/{EOW}
S_OP [-+ \t\n\r]+
MIN [mM][iI][nN]([iI][mM][iI][zZsS][eE])?[ \t]*:
MAX [mM][aA][xX]([iI][mM][iI][zZsS][eE])?[ \t]*:
INT ^[ \t]*[Ii][Nn][Tt]([Ee][Gg][Ee][Rr])?
BIN ^[ \t]*[Bb][Ii][Nn]([Aa][Rr][Yy])?
SEC ^[ \t]*([Ss][Ee][Cc])|([Ss][Ee][Mm][Ii]-[Cc][Oo][Nn][Tt][Ii][Nn][Uu][Oo][Uu][Ss])|([Ss][Ee][Mm][Ii])|([Ss][Ee][Mm][Ii][Ss])
SOS ^[ \t]*([Ss][Oo][Ss][12]*)|([Ss][Ee][Tt][Ss])
FREE ^[ \t]*[Ff][Rr][Ee][Ee]
LBL {VR}:
SOSD {LBL}:
%start COMMENT
%start LINECOMMENT
%%
<INITIAL>"/*" {
BEGIN COMMENT;
} /* begin skip comment */
<COMMENT>"*/" {
BEGIN INITIAL;
} /* end skip comment */
<COMMENT>. {
}
<COMMENT>\n {
}
<COMMENT>\r {
}
<INITIAL>"//" {
BEGIN LINECOMMENT;
} /* begin skip LINECOMMENT */
<LINECOMMENT>\n {
BEGIN INITIAL;
} /* end skip LINECOMMENT */
<LINECOMMENT>\r {
BEGIN INITIAL;
} /* end skip LINECOMMENT */
<LINECOMMENT>. {
}
<INITIAL>{WS} {
}
<INITIAL>"," {
return(COMMA);
}
<INITIAL>{MIN} {
return(MINIMISE);
}
<INITIAL>{MAX} {
return(MAXIMISE);
}
<INITIAL>{INNM} {
f = atof((char *)yytext);
return(INTCONS);
} /* f contains the last float */
<INITIAL>{NM} {
f = atof((char *)yytext);
return(CONS);
} /* f contains the last float */
<INITIAL>{INF} {
char *ptr;
f = DEF_INFINITE;
Sign = 0;
ptr = (char *)yytext;
while (isspace(*ptr)) ptr++;
if(*ptr == '-')
Sign = 1;
return(INF);
} /* f contains the last float */
<INITIAL>{S_OP} {
Sign = 0;
for(x = 0; x < yyleng; x++)
if(yytext[x] == '-' || yytext[x] == '+')
Sign = (Sign == (yytext[x] == '+'));
return (SIGN);
/* Sign is TRUE if the sign-string
represents a '-'. Otherwise Sign
is FALSE */
}
<INITIAL>{INT} {
if((!Within_int_decl) && (!Within_sec_decl) && (!Within_sos_decl) && (!Within_free_decl)) {
Within_int_decl = 1;
Within_sos_decl1 = FALSE;
}
return(SEC_INT);
}
<INITIAL>{BIN} {
if((!Within_int_decl) && (!Within_sec_decl) && (!Within_sos_decl) && (!Within_free_decl)) {
Within_int_decl = 2;
Within_sos_decl1 = FALSE;
}
return(SEC_BIN);
}
<INITIAL>{SEC} {
if((!Within_int_decl) && (!Within_sec_decl) && (!Within_sos_decl) && (!Within_free_decl)) {
Within_sec_decl = TRUE;
Within_sos_decl1 = FALSE;
}
return(SEC_SEC);
}
<INITIAL>{SOS} {
if(!Within_sos_decl)
SOStype0 = (short)atoi(((char *)yytext) + 3);
if((!Within_int_decl) && (!Within_sec_decl) && (!Within_sos_decl) && (!Within_free_decl))
Within_sos_decl = TRUE;
return(SEC_SOS);
}
<INITIAL>{SOSD} {
FREE(Last_var);
Last_var = strdup((char *)yytext);
Last_var[strlen(Last_var) - 2] = 0;
return(SOSDESCR);
}
<INITIAL>{FREE} {
if((!Within_int_decl) && (!Within_sec_decl) && (!Within_sos_decl) && (!Within_free_decl)) {
Within_free_decl = TRUE;
Within_sos_decl1 = FALSE;
}
return(SEC_FREE);
}
<INITIAL>{LBL} {
FREE(Last_var);
Last_var = strdup((char *)yytext);
Last_var[strlen(Last_var) - 1] = 0;
return(VARIABLECOLON);
}
<INITIAL>{VR} {
FREE(Last_var);
Last_var = strdup((char *)yytext);
return(VAR);
}
<INITIAL>":" {
return (COLON);
}
<INITIAL>"*" {
return(AR_M_OP);
}
<INITIAL>{OPLE} {
return(RE_OPLE);
}
<INITIAL>{OPGE} {
return(RE_OPGE);
}
<INITIAL>";" {
Within_int_decl = Within_sec_decl = Within_sos_decl = Within_free_decl = FALSE;
check_int_sec_sos_free_decl(Within_int_decl, Within_sec_decl, Within_sos_decl, Within_free_decl);
return(END_C);
}
<INITIAL>. {
report(NULL, CRITICAL, "LEX ERROR : %s lineno %d\n", yytext, yylineno);
return(UNDEFINED);
}
%%

View File

@ -1,723 +0,0 @@
/* ========================================================================= */
/* NAME : lp_rlp.y */
/* ========================================================================= */
%token VAR CONS INTCONS VARIABLECOLON INF SEC_INT SEC_BIN SEC_SEC SEC_SOS SOSDESCR SEC_FREE SIGN AR_M_OP RE_OPLE RE_OPGE END_C COMMA COLON MINIMISE MAXIMISE UNDEFINED
%{
#include <string.h>
#include <ctype.h>
#include "lpkit.h"
#include "yacc_read.h"
#ifdef FORTIFY
# include "lp_fortify.h"
#endif
static int HadVar0, HadVar1, HadVar2, HasAR_M_OP, do_add_row, Had_lineair_sum0, HadSign;
static char *Last_var = NULL, *Last_var0 = NULL;
static REAL f, f0, f1;
static int x;
static int state, state0;
static int Sign;
static int isign, isign0; /* internal_sign variable to make sure nothing goes wrong */
/* with lookahead */
static int make_neg; /* is true after the relational operator is seen in order */
/* to remember if lin_term stands before or after re_op */
static int Within_int_decl = FALSE; /* TRUE when we are within an int declaration */
static int Within_bin_decl = FALSE; /* TRUE when we are within an bin declaration */
static int Within_sec_decl = FALSE; /* TRUE when we are within a sec declaration */
static int Within_sos_decl = FALSE; /* TRUE when we are within a sos declaration */
static int Within_sos_decl1;
static int Within_free_decl = FALSE; /* TRUE when we are within a free declaration */
static short SOStype0; /* SOS type */
static short SOStype; /* SOS type */
static int SOSNr;
static int SOSweight = 0; /* SOS weight */
static int HadConstraint;
static int HadVar;
static int Had_lineair_sum;
extern FILE *yyin;
#define YY_FATAL_ERROR lex_fatal_error
/* let's please C++ users */
#ifdef __cplusplus
extern "C" {
#endif
static int wrap(void)
{
return(1);
}
static int __WINAPI lp_input_yyin(void *fpin, char *buf, int max_size)
{
int result;
if ( (result = fread( (char*)buf, sizeof(char), max_size, (FILE *) fpin)) < 0)
YY_FATAL_ERROR( "read() in flex scanner failed");
return(result);
}
static read_modeldata_func *lp_input;
#undef YY_INPUT
#define YY_INPUT(buf,result,max_size) result = lp_input((void *) yyin, buf, max_size);
#ifdef __cplusplus
};
#endif
#define yywrap wrap
#define yyerror read_error
#include "lp_rlp.h"
%}
%start inputfile
%%
EMPTY: /* EMPTY */
;
inputfile :
{
isign = 0;
make_neg = 0;
Sign = 0;
HadConstraint = FALSE;
HadVar = HadVar0 = FALSE;
}
objective_function
constraints
int_bin_sec_sos_free_declarations
;
/* start objective_function */
/*
objective_function: MAXIMISE real_of | MINIMISE real_of | real_of;
real_of: lineair_sum END_C;
lineair_sum: EMPTY | x_lineair_sum;
*/
objective_function: MAXIMISE real_of
{
set_obj_dir(TRUE);
}
| MINIMISE real_of
{
set_obj_dir(FALSE);
}
| real_of
;
real_of: lineair_sum
END_C
{
add_row();
HadConstraint = FALSE;
HadVar = HadVar0 = FALSE;
isign = 0;
make_neg = 0;
}
;
lineair_sum: EMPTY
| x_lineair_sum
;
/* end objective_function */
/* start constraints */
/*
constraints: EMPTY | x_constraints;
x_constraints: constraint | x_constraints constraint;
constraint: real_constraint | VARIABLECOLON real_constraint;
real_constraint: x_lineair_sum2 RE_OP x_lineair_sum3 optionalrange END_C;
optionalrange: EMPTY | RE_OP cons_term RHS_STORE;
RE_OP: RE_OPLE | RE_OPGE;
cons_term: x_SIGN REALCONS | INF;
x_lineair_sum2: EMPTY | x_lineair_sum3;
x_lineair_sum3: x_lineair_sum | INF RHS_STORE;
x_lineair_sum: x_lineair_sum1;
x_lineair_sum1: x_lineair_term | x_lineair_sum1 x_lineair_term;
x_lineair_term: x_SIGN x_lineair_term1;
x_lineair_term1: REALCONS | optional_AR_M_OP VAR;
x_SIGN: EMPTY | SIGN;
REALCONS: INTCONS | CONS;
optional_AR_M_OP: EMPTY | AR_M_OP;
*/
constraints: EMPTY
| x_constraints
;
x_constraints : constraint
| x_constraints
constraint
;
constraint : real_constraint
| VARIABLECOLON
{
if(!add_constraint_name(Last_var))
YYABORT;
HadConstraint = TRUE;
}
real_constraint
;
real_constraint : x_lineair_sum2
{
HadVar1 = HadVar0;
HadVar0 = FALSE;
}
RE_OP
{
if(!store_re_op((char *) yytext, HadConstraint, HadVar, Had_lineair_sum))
YYABORT;
make_neg = 1;
f1 = 0;
}
x_lineair_sum3
{
Had_lineair_sum0 = Had_lineair_sum;
Had_lineair_sum = TRUE;
HadVar2 = HadVar0;
HadVar0 = FALSE;
do_add_row = FALSE;
if(HadConstraint && !HadVar ) {
/* it is a range */
/* already handled */
}
else if(!HadConstraint && HadVar) {
/* it is a bound */
if(!store_bounds(TRUE))
YYABORT;
}
else {
/* it is a row restriction */
if(HadConstraint && HadVar)
store_re_op("", HadConstraint, HadVar, Had_lineair_sum); /* makes sure that data stored in temporary buffers is treated correctly */
do_add_row = TRUE;
}
}
optionalrange
END_C
{
if((!HadVar) && (!HadConstraint)) {
yyerror("parse error");
YYABORT;
}
if(do_add_row)
add_row();
HadConstraint = FALSE;
HadVar = HadVar0 = FALSE;
isign = 0;
make_neg = 0;
null_tmp_store(TRUE);
}
;
optionalrange: EMPTY
{
if((!HadVar1) && (Had_lineair_sum0))
if(!negate_constraint())
YYABORT;
}
| RE_OP
{
make_neg = 0;
isign = 0;
if(HadConstraint)
HadVar = Had_lineair_sum = FALSE;
HadVar0 = FALSE;
if(!store_re_op((char *) ((*yytext == '<') ? ">" : (*yytext == '>') ? "<" : yytext), HadConstraint, HadVar, Had_lineair_sum))
YYABORT;
}
cons_term
{
f -= f1;
}
RHS_STORE
{
if((HadVar1) || (!HadVar2) || (HadVar0)) {
yyerror("parse error");
YYABORT;
}
if(HadConstraint && !HadVar ) {
/* it is a range */
/* already handled */
if(!negate_constraint())
YYABORT;
}
else if(!HadConstraint && HadVar) {
/* it is a bound */
if(!store_bounds(TRUE))
YYABORT;
}
}
;
x_lineair_sum2: EMPTY
{
/* to allow a range */
/* constraint: < max */
if(!HadConstraint) {
yyerror("parse error");
YYABORT;
}
Had_lineair_sum = FALSE;
}
| x_lineair_sum3
{
Had_lineair_sum = TRUE;
}
;
x_lineair_sum3 : x_lineair_sum
| INF
{
isign = Sign;
}
RHS_STORE
;
x_lineair_sum:
{
state = state0 = 0;
}
x_lineair_sum1
{
if (state == 1) {
/* RHS_STORE */
if ( (isign0 || !make_neg)
&& !(isign0 && !make_neg)) /* but not both! */
f0 = -f0;
if(make_neg)
f1 += f0;
if(!rhs_store(f0, HadConstraint, HadVar, Had_lineair_sum))
YYABORT;
}
}
;
x_lineair_sum1 : x_lineair_term
| x_lineair_sum1
x_lineair_term
;
x_lineair_term : x_SIGN
x_lineair_term1
{
if ((HadSign || state == 1) && (state0 == 1)) {
/* RHS_STORE */
if ( (isign0 || !make_neg)
&& !(isign0 && !make_neg)) /* but not both! */
f0 = -f0;
if(make_neg)
f1 += f0;
if(!rhs_store(f0, HadConstraint, HadVar, Had_lineair_sum))
YYABORT;
}
if (state == 1) {
f0 = f;
isign0 = isign;
}
if (state == 2) {
if((HadSign) || (state0 != 1)) {
isign0 = isign;
f0 = 1.0;
}
if ( (isign0 || make_neg)
&& !(isign0 && make_neg)) /* but not both! */
f0 = -f0;
if(!var_store(Last_var, f0, HadConstraint, HadVar, Had_lineair_sum)) {
yyerror("var_store failed");
YYABORT;
}
HadConstraint |= HadVar;
HadVar = HadVar0 = TRUE;
}
state0 = state;
}
;
x_lineair_term1 : REALCONS
{
state = 1;
}
| optional_AR_M_OP
{
if ((HasAR_M_OP) && (state != 1)) {
yyerror("parse error");
YYABORT;
}
}
VAR
{
state = 2;
}
;
RE_OP: RE_OPLE | RE_OPGE
;
cons_term: x_SIGN
REALCONS
| INF
{
isign = Sign;
}
;
/* end constraints */
/* start common for objective & constraints */
REALCONS: INTCONS | CONS
;
x_SIGN: EMPTY
{
isign = 0;
HadSign = FALSE;
}
| SIGN
{
isign = Sign;
HadSign = TRUE;
}
;
optional_AR_M_OP: EMPTY
{
HasAR_M_OP = FALSE;
}
| AR_M_OP
{
HasAR_M_OP = TRUE;
}
;
RHS_STORE: EMPTY
{
if ( (isign || !make_neg)
&& !(isign && !make_neg)) /* but not both! */
f = -f;
if(!rhs_store(f, HadConstraint, HadVar, Had_lineair_sum))
YYABORT;
isign = 0;
}
;
/* end common for objective & constraints */
/* start int_bin_sec_sos_free_declarations */
int_bin_sec_sos_free_declarations:
EMPTY
| real_int_bin_sec_sos_free_decls
;
real_int_bin_sec_sos_free_decls: int_bin_sec_sos_free_declaration
| real_int_bin_sec_sos_free_decls int_bin_sec_sos_free_declaration
;
SEC_INT_BIN_SEC_SOS_FREE: SEC_INT | SEC_BIN | SEC_SEC | SEC_SOS | SEC_FREE
;
int_bin_sec_sos_free_declaration:
SEC_INT_BIN_SEC_SOS_FREE
{
Within_sos_decl1 = Within_sos_decl;
}
x_int_bin_sec_sos_free_declaration
;
xx_int_bin_sec_sos_free_declaration:
{
if((!Within_int_decl) && (!Within_sec_decl) && (!Within_sos_decl1) && (!Within_free_decl)) {
yyerror("parse error");
YYABORT;
}
SOStype = SOStype0;
check_int_sec_sos_free_decl(Within_int_decl, Within_sec_decl, Within_sos_decl1 = (Within_sos_decl1 ? 1 : 0), Within_free_decl);
}
optionalsos
vars
optionalsostype
END_C
{
if((Within_sos_decl1) && (SOStype == 0))
{
yyerror("Unsupported SOS type (0)");
YYABORT;
}
}
;
x_int_bin_sec_sos_free_declaration:
xx_int_bin_sec_sos_free_declaration
| x_int_bin_sec_sos_free_declaration xx_int_bin_sec_sos_free_declaration
;
optionalsos: EMPTY
| SOSDESCR
{
FREE(Last_var0);
Last_var0 = strdup(Last_var);
}
sosdescr
;
optionalsostype: EMPTY
{
if(Within_sos_decl1) {
set_sos_type(SOStype);
set_sos_weight((double) SOSweight, 1);
}
}
| RE_OPLE
INTCONS
{
if((Within_sos_decl1) && (!SOStype))
{
set_sos_type(SOStype = (short) (f + .1));
}
else
{
yyerror("SOS type not expected");
YYABORT;
}
}
optionalSOSweight
;
optionalSOSweight:EMPTY
{
set_sos_weight((double) SOSweight, 1);
}
| COLON
INTCONS
{
set_sos_weight(f, 1);
}
;
vars: EMPTY
| x_vars
;
x_vars : onevarwithoptionalweight
| x_vars
optionalcomma
onevarwithoptionalweight
;
optionalcomma: EMPTY
| COMMA
;
variable: EMPTY
{
if(Within_sos_decl1 == 1)
{
char buf[16];
SOSweight++;
sprintf(buf, "SOS%d", SOSweight);
storevarandweight(buf);
check_int_sec_sos_free_decl(Within_int_decl, Within_sec_decl, 2, Within_free_decl);
Within_sos_decl1 = 2;
SOSNr = 0;
}
storevarandweight(Last_var);
if(Within_sos_decl1 == 2)
{
SOSNr++;
set_sos_weight((double) SOSNr, 2);
}
}
;
variablecolon:
{
if(!Within_sos_decl1) {
yyerror("parse error");
YYABORT;
}
if(Within_sos_decl1 == 1) {
FREE(Last_var0);
Last_var0 = strdup(Last_var);
}
if(Within_sos_decl1 == 2)
{
storevarandweight(Last_var);
SOSNr++;
set_sos_weight((double) SOSNr, 2);
}
}
;
sosweight: EMPTY
{
if(Within_sos_decl1 == 1)
{
char buf[16];
SOSweight++;
sprintf(buf, "SOS%d", SOSweight);
storevarandweight(buf);
check_int_sec_sos_free_decl(Within_int_decl, Within_sec_decl, 2, Within_free_decl);
Within_sos_decl1 = 2;
SOSNr = 0;
storevarandweight(Last_var0);
SOSNr++;
}
set_sos_weight(f, 2);
}
;
sosdescr: EMPTY
{ /* SOS name */
if(Within_sos_decl1 == 1)
{
storevarandweight(Last_var0);
set_sos_type(SOStype);
check_int_sec_sos_free_decl(Within_int_decl, Within_sec_decl, 2, Within_free_decl);
Within_sos_decl1 = 2;
SOSNr = 0;
SOSweight++;
}
}
;
onevarwithoptionalweight:
VAR
variable
| VARIABLECOLON
variablecolon
INTCONSorVARIABLE
;
INTCONSorVARIABLE:REALCONS /* INTCONS */
sosweight
| sosdescr
x_onevarwithoptionalweight
;
x_onevarwithoptionalweight:
VAR
variable
| VARIABLECOLON
variablecolon
REALCONS /* INTCONS */
sosweight
;
/* end int_bin_sec_sos_free_declarations */
%%
static void yy_delete_allocated_memory(void)
{
/* free memory allocated by flex. Otherwise some memory is not freed.
This is a bit tricky. There is not much documentation about this, but a lot of
reports of memory that keeps allocated */
/* If you get errors on this function call, just comment it. This will only result
in some memory that is not being freed. */
# if defined YY_CURRENT_BUFFER
/* flex defines the macro YY_CURRENT_BUFFER, so you should only get here if lp_rlp.h is
generated by flex */
/* lex doesn't define this macro and thus should not come here, but lex doesn't has
this memory leak also ...*/
yy_delete_buffer(YY_CURRENT_BUFFER); /* comment this line if you have problems with it */
yy_init = 1; /* make sure that the next time memory is allocated again */
yy_start = 0;
# endif
FREE(Last_var);
FREE(Last_var0);
}
static int parse(void)
{
return(yyparse());
}
lprec *read_lp1(lprec *lp, void *userhandle, read_modeldata_func read_modeldata, int verbose, char *lp_name)
{
yyin = (FILE *) userhandle;
yyout = NULL;
yylineno = 1;
lp_input = read_modeldata;
return(yacc_read(lp, verbose, lp_name, &yylineno, parse, yy_delete_allocated_memory));
}
lprec * __WINAPI read_lp(FILE *filename, int verbose, char *lp_name)
{
return(read_lp1(NULL, filename, lp_input_yyin, verbose, lp_name));
}
lprec * __WINAPI read_lpex(void *userhandle, read_modeldata_func read_modeldata, int verbose, char *lp_name)
{
return(read_lp1(NULL, userhandle, read_modeldata, verbose, lp_name));
}
lprec *read_LP1(lprec *lp, char *filename, int verbose, char *lp_name)
{
FILE *fpin;
if((fpin = fopen(filename, "r")) != NULL) {
lp = read_lp1(lp, fpin, lp_input_yyin, verbose, lp_name);
fclose(fpin);
}
else
lp = NULL;
return(lp);
}
lprec * __WINAPI read_LP(char *filename, int verbose, char *lp_name)
{
return(read_LP1(NULL, filename, verbose, lp_name));
}
MYBOOL __WINAPI LP_readhandle(lprec **lp, FILE *filename, int verbose, char *lp_name)
{
if(lp != NULL)
*lp = read_lp1(*lp, filename, lp_input_yyin, verbose, lp_name);
return((lp != NULL) && (*lp != NULL));
}

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