Initial commit
This commit is contained in:
commit
2125f01f97
43
INSTALL
Normal file
43
INSTALL
Normal file
@ -0,0 +1,43 @@
|
||||
#######################################################################
|
||||
## ##
|
||||
## Compiling and installing libinum. ##
|
||||
## ##
|
||||
#######################################################################
|
||||
|
||||
* libinum should work on any POSIX compliant system, such as GNU/Linux or OSX.
|
||||
|
||||
* libinum is linked against the GNU MPFR, GNU GMP and pthread libraries.
|
||||
|
||||
* Compiling:
|
||||
Run
|
||||
make
|
||||
|
||||
The default paths can be modified by passing the appropriate arguments to
|
||||
make, as specified in the following table
|
||||
compiler : CC=/usr/bin/gcc
|
||||
linker : LD=/usr/bin/gcc
|
||||
archive : AR=/usr/bin/ar
|
||||
include : INCLUDE=
|
||||
lib paths : LIB=
|
||||
optimize : OPT=-O3
|
||||
|
||||
For example,
|
||||
make CC=/usr/local/bin/gcc INCLUDE=/usr/local/include LIBDIR=-L/usr/local/lib
|
||||
|
||||
In addition, libinum can be compiled as dynamic or static library, which is
|
||||
controlled by the STATIC option of the makefile.
|
||||
If STATIC=0 (default) then compile both
|
||||
If STATIC=1 then compile the static library
|
||||
If STATIC=2 then compile the dynamic library
|
||||
|
||||
|
||||
* Installing:
|
||||
Run
|
||||
make install
|
||||
|
||||
The default install prefix (/usr) can be changed by changing the PREFIX
|
||||
variable.
|
||||
|
||||
For example
|
||||
make install PREFIX=/usr/local
|
||||
|
165
LGPL3
Normal file
165
LGPL3
Normal file
@ -0,0 +1,165 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
|
||||
This version of the GNU Lesser General Public License incorporates
|
||||
the terms and conditions of version 3 of the GNU General Public
|
||||
License, supplemented by the additional permissions listed below.
|
||||
|
||||
0. Additional Definitions.
|
||||
|
||||
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||||
General Public License.
|
||||
|
||||
"The Library" refers to a covered work governed by this License,
|
||||
other than an Application or a Combined Work as defined below.
|
||||
|
||||
An "Application" is any work that makes use of an interface provided
|
||||
by the Library, but which is not otherwise based on the Library.
|
||||
Defining a subclass of a class defined by the Library is deemed a mode
|
||||
of using an interface provided by the Library.
|
||||
|
||||
A "Combined Work" is a work produced by combining or linking an
|
||||
Application with the Library. The particular version of the Library
|
||||
with which the Combined Work was made is also called the "Linked
|
||||
Version".
|
||||
|
||||
The "Minimal Corresponding Source" for a Combined Work means the
|
||||
Corresponding Source for the Combined Work, excluding any source code
|
||||
for portions of the Combined Work that, considered in isolation, are
|
||||
based on the Application, and not on the Linked Version.
|
||||
|
||||
The "Corresponding Application Code" for a Combined Work means the
|
||||
object code and/or source code for the Application, including any data
|
||||
and utility programs needed for reproducing the Combined Work from the
|
||||
Application, but excluding the System Libraries of the Combined Work.
|
||||
|
||||
1. Exception to Section 3 of the GNU GPL.
|
||||
|
||||
You may convey a covered work under sections 3 and 4 of this License
|
||||
without being bound by section 3 of the GNU GPL.
|
||||
|
||||
2. Conveying Modified Versions.
|
||||
|
||||
If you modify a copy of the Library, and, in your modifications, a
|
||||
facility refers to a function or data to be supplied by an Application
|
||||
that uses the facility (other than as an argument passed when the
|
||||
facility is invoked), then you may convey a copy of the modified
|
||||
version:
|
||||
|
||||
a) under this License, provided that you make a good faith effort to
|
||||
ensure that, in the event an Application does not supply the
|
||||
function or data, the facility still operates, and performs
|
||||
whatever part of its purpose remains meaningful, or
|
||||
|
||||
b) under the GNU GPL, with none of the additional permissions of
|
||||
this License applicable to that copy.
|
||||
|
||||
3. Object Code Incorporating Material from Library Header Files.
|
||||
|
||||
The object code form of an Application may incorporate material from
|
||||
a header file that is part of the Library. You may convey such object
|
||||
code under terms of your choice, provided that, if the incorporated
|
||||
material is not limited to numerical parameters, data structure
|
||||
layouts and accessors, or small macros, inline functions and templates
|
||||
(ten or fewer lines in length), you do both of the following:
|
||||
|
||||
a) Give prominent notice with each copy of the object code that the
|
||||
Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
4. Combined Works.
|
||||
|
||||
You may convey a Combined Work under terms of your choice that,
|
||||
taken together, effectively do not restrict modification of the
|
||||
portions of the Library contained in the Combined Work and reverse
|
||||
engineering for debugging such modifications, if you also do each of
|
||||
the following:
|
||||
|
||||
a) Give prominent notice with each copy of the Combined Work that
|
||||
the Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
c) For a Combined Work that displays copyright notices during
|
||||
execution, include the copyright notice for the Library among
|
||||
these notices, as well as a reference directing the user to the
|
||||
copies of the GNU GPL and this license document.
|
||||
|
||||
d) Do one of the following:
|
||||
|
||||
0) Convey the Minimal Corresponding Source under the terms of this
|
||||
License, and the Corresponding Application Code in a form
|
||||
suitable for, and under terms that permit, the user to
|
||||
recombine or relink the Application with a modified version of
|
||||
the Linked Version to produce a modified Combined Work, in the
|
||||
manner specified by section 6 of the GNU GPL for conveying
|
||||
Corresponding Source.
|
||||
|
||||
1) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (a) uses at run time
|
||||
a copy of the Library already present on the user's computer
|
||||
system, and (b) will operate properly with a modified version
|
||||
of the Library that is interface-compatible with the Linked
|
||||
Version.
|
||||
|
||||
e) Provide Installation Information, but only if you would otherwise
|
||||
be required to provide such information under section 6 of the
|
||||
GNU GPL, and only to the extent that such information is
|
||||
necessary to install and execute a modified version of the
|
||||
Combined Work produced by recombining or relinking the
|
||||
Application with a modified version of the Linked Version. (If
|
||||
you use option 4d0, the Installation Information must accompany
|
||||
the Minimal Corresponding Source and Corresponding Application
|
||||
Code. If you use option 4d1, you must provide the Installation
|
||||
Information in the manner specified by section 6 of the GNU GPL
|
||||
for conveying Corresponding Source.)
|
||||
|
||||
5. Combined Libraries.
|
||||
|
||||
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 that are not Applications and are not covered by this
|
||||
License, and convey such a combined library under terms of your
|
||||
choice, if you do both of the following:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work based
|
||||
on the Library, uncombined with any other library facilities,
|
||||
conveyed under the terms of this License.
|
||||
|
||||
b) Give prominent notice with the combined library that part of it
|
||||
is a work based on the Library, and explaining where to find the
|
||||
accompanying uncombined form of the same work.
|
||||
|
||||
6. Revised Versions of the GNU Lesser General Public License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions
|
||||
of the GNU 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 as you received it specifies that a certain numbered version
|
||||
of the GNU Lesser General Public License "or any later version"
|
||||
applies to it, you have the option of following the terms and
|
||||
conditions either of that published version or of any later version
|
||||
published by the Free Software Foundation. If the Library as you
|
||||
received it does not specify a version number of the GNU Lesser
|
||||
General Public License, you may choose any version of the GNU Lesser
|
||||
General Public License ever published by the Free Software Foundation.
|
||||
|
||||
If the Library as you received it specifies that a proxy can decide
|
||||
whether future versions of the GNU Lesser General Public License shall
|
||||
apply, that proxy's public statement of acceptance of any version is
|
||||
permanent authorization for you to choose that version for the
|
||||
Library.
|
202
LICENSE
Normal file
202
LICENSE
Normal file
@ -0,0 +1,202 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
120
Makefile
Normal file
120
Makefile
Normal file
@ -0,0 +1,120 @@
|
||||
## Copyright 2016 Ian Jauslin
|
||||
##
|
||||
## Licensed under the Apache License, Version 2.0 (the "License");
|
||||
## you may not use this file except in compliance with the License.
|
||||
## You may obtain a copy of the License at
|
||||
##
|
||||
## http://www.apache.org/licenses/LICENSE-2.0
|
||||
##
|
||||
## Unless required by applicable law or agreed to in writing, software
|
||||
## distributed under the License is distributed on an "AS IS" BASIS,
|
||||
## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
## See the License for the specific language governing permissions and
|
||||
## limitations under the License.
|
||||
|
||||
# whether to compile only the static library, only the dynamic library, or both
|
||||
# if static=0 then compile both
|
||||
# if static=2 then compile the dynamic library
|
||||
# if static=1 then compile the static library
|
||||
STATIC=0
|
||||
|
||||
VERSION=1.0
|
||||
|
||||
# products of the compilation
|
||||
PROJECT_SO=libinum.so.$(VERSION)
|
||||
PROJECT_LIBS=libinum.a
|
||||
PROJECT_DOCS=libinum-doc.html
|
||||
|
||||
# debug and optimization flags
|
||||
#DB= -ggdb
|
||||
OPT= -O3
|
||||
|
||||
# warning flags
|
||||
WARNINGS= -Wall -Wextra -Wno-strict-overflow -std=c99 -pedantic
|
||||
|
||||
# installation dirs
|
||||
PREFIX=/usr
|
||||
LIBDIR=$(PREFIX)/lib
|
||||
INCLUDEDIR=$(PREFIX)/include
|
||||
DOCDIR=$(PREFIX)/share/doc/libinum
|
||||
|
||||
# compiler
|
||||
CC=/usr/bin/gcc
|
||||
LD=$(CC)
|
||||
AR=/usr/bin/ar
|
||||
|
||||
# directories
|
||||
INCLUDE =
|
||||
LIB =
|
||||
|
||||
# flags
|
||||
override LDFLAGS +=$(LIB)
|
||||
override CFLAGS +=$(INCLUDE)$(DB) $(OPT) $(WARNINGS)
|
||||
|
||||
# build directories
|
||||
BUILDDIR=./build
|
||||
SRCDIR=./src
|
||||
OBJDIR=./objs
|
||||
|
||||
# objects
|
||||
LIBINUM_OBJS = $(addprefix $(OBJDIR)/, array.o integral.o utils.o polynomial.o polynomialMV.o root.o)
|
||||
|
||||
|
||||
ifeq ($(STATIC),1)
|
||||
# compile libinum.a
|
||||
PREREQ=static
|
||||
# install static lib
|
||||
INSTALLLIB=install-static
|
||||
else ifeq ($(STATIC),2)
|
||||
# compile libinum.so.$(VERSION)
|
||||
PREREQ=shared
|
||||
# install shared lib
|
||||
INSTALLLIB=install-shared
|
||||
else
|
||||
# compile both
|
||||
PREREQ=shared static
|
||||
# install both
|
||||
INSTALLLIB=install-shared install-static
|
||||
endif
|
||||
|
||||
|
||||
all: init $(PREREQ)
|
||||
|
||||
# create dirs
|
||||
init:
|
||||
@[ -d $(OBJDIR) ] || /bin/mkdir $(OBJDIR)
|
||||
@[ -d $(BUILDDIR) ] || /bin/mkdir $(BUILDDIR)
|
||||
|
||||
# static library
|
||||
static: $(PROJECT_LIBS)
|
||||
# shared library
|
||||
shared: $(PROJECT_SO)
|
||||
|
||||
libinum.a: $(LIBINUM_OBJS)
|
||||
$(AR) -rc $(BUILDDIR)/$@ $^
|
||||
|
||||
libinum.so.$(VERSION): $(LIBINUM_OBJS)
|
||||
$(LD) -shared -lm -lmpfr -lgmp -lpthread $(LDFLAGS) -o $(BUILDDIR)/$@ $^
|
||||
ln -fs ./libinum.so.$(VERSION) $(BUILDDIR)/libinum.so
|
||||
|
||||
%.o : ../$(SRCDIR)/%.c
|
||||
$(CC) -c $(CFLAGS) -fPIC $< -o $@
|
||||
|
||||
install: $(INSTALLLIB) all
|
||||
mkdir -p $(MANDIR) $(DOCDIR) $(INCLUDEDIR)/libinum
|
||||
cp -rL include/libinum/* $(INCLUDEDIR)/libinum/
|
||||
install -Dm644 include/libinum.h $(INCLUDEDIR)/
|
||||
cp -r doc/libinum-examples $(DOCDIR)/
|
||||
install -Dm644 $(addprefix doc/,$(PROJECT_DOCS)) $(DOCDIR)/
|
||||
|
||||
install-static: all
|
||||
mkdir -p $(LIBDIR)
|
||||
install -Dm755 $(addprefix $(BUILDDIR)/,$(PROJECT_LIBS)) $(LIBDIR)/
|
||||
install-shared: all
|
||||
mkdir -p $(LIBDIR)
|
||||
install -Dm755 $(addprefix $(BUILDDIR)/,$(PROJECT_SO)) $(LIBDIR)/
|
||||
for lib in $(PROJECT_SO); do ln -fs ./$$lib $(LIBDIR)/$${lib%.so.*}.so; done
|
||||
|
||||
clean:
|
||||
@rm -rf $(OBJDIR)
|
||||
@rm -rf $(BUILDDIR)
|
15
NOTICE
Normal file
15
NOTICE
Normal file
@ -0,0 +1,15 @@
|
||||
libinum
|
||||
Copyright 2016 Ian Jauslin
|
||||
|
||||
Numerical values may be represented as multi-precision floats using
|
||||
the GNU MPFR library, which is licensed under the GNU Lesser General
|
||||
Public License (LGPL) version 3 (see LGPL3 for a copy of the license).
|
||||
See
|
||||
http://www.mpfr.org/
|
||||
for details.
|
||||
|
||||
The GNU MPFR library is based on the GNU GMP library, which is licensed
|
||||
under the GNU Lesser General Public License (LGPL) version 3 (see LGPL3
|
||||
for a copy of the license). See
|
||||
http://www.gmplib.org/
|
||||
for details.
|
2332
doc/libinum-doc.html
Normal file
2332
doc/libinum-doc.html
Normal file
File diff suppressed because it is too large
Load Diff
1835
doc/libinum-doc.php
Normal file
1835
doc/libinum-doc.php
Normal file
File diff suppressed because it is too large
Load Diff
80
doc/libinum-examples/Makefile
Normal file
80
doc/libinum-examples/Makefile
Normal file
@ -0,0 +1,80 @@
|
||||
# whether to link dynamically
|
||||
# if static=0 then link dynamically
|
||||
# if static=2 then link statically
|
||||
# if static=1 then link libkondo statically but other libraries dynamically
|
||||
STATIC=1
|
||||
|
||||
VERSION=0.3.1
|
||||
|
||||
# products of the compilation
|
||||
PROJECT_BINS= root_newton integral_gauss-legendre
|
||||
|
||||
# debug and optimization flags
|
||||
#DB= -ggdb
|
||||
OPT= -O3
|
||||
|
||||
# warning flags
|
||||
WARNINGS= -Wall -Wextra -Wno-strict-overflow -std=c99 -pedantic -Wno-unused-parameter
|
||||
|
||||
# compiler
|
||||
CC=/usr/bin/gcc
|
||||
LD=$(CC)
|
||||
|
||||
# directories
|
||||
INCLUDE =
|
||||
LIB =
|
||||
#INCLUDE = -I../../include
|
||||
#LIB = -L../../build
|
||||
|
||||
# flags
|
||||
override LDFLAGS +=$(LIB)
|
||||
override CFLAGS +=$(INCLUDE) $(DB) $(OPT) $(WARNINGS)
|
||||
|
||||
# build directories
|
||||
BUILDDIR=./build
|
||||
SRCDIR=./src
|
||||
OBJDIR=./objs
|
||||
|
||||
# objects
|
||||
OBJS = $(addprefix $(OBJDIR)/, root_newton.o integral_gauss-legendre.o)
|
||||
|
||||
# flags which depend on whether to link statically or dynamically
|
||||
# lib flag
|
||||
LIBINUM_FLAG=-linum
|
||||
# additional library required for static linking
|
||||
XTRA_LIBS=
|
||||
|
||||
ifeq ($(STATIC),1)
|
||||
# libinum is linked against libm, libmpfr, libgmp and libpthread
|
||||
XTRA_LIBS=-lm -lmpfr -lgmp -lpthread
|
||||
# link binaries using the static library
|
||||
LIBINUM_FLAG=-l:libinum.a
|
||||
else ifeq ($(STATIC),2)
|
||||
# libinum is linked against libm, libmpfr, libgmp and libpthread
|
||||
XTRA_LIBS=-lm -lmpfr -lgmp -lpthread
|
||||
# link binaries statically
|
||||
override LDFLAGS += -static
|
||||
else
|
||||
# required flag for subsequent dynamic linking
|
||||
override CFLAGS += -fPIC
|
||||
endif
|
||||
|
||||
|
||||
all: init $(PROJECT_BINS)
|
||||
|
||||
# create dirs
|
||||
init:
|
||||
@[ -d $(OBJDIR) ] || /bin/mkdir $(OBJDIR)
|
||||
@[ -d $(BUILDDIR) ] || /bin/mkdir $(BUILDDIR)
|
||||
|
||||
root_newton:
|
||||
$(CC) -c $(CFLAGS) src/$@.c -o objs/$@.o
|
||||
$(LD) $(LDFLAGS) -o $(BUILDDIR)/$@ objs/$@.o $(LIBINUM_FLAG) $(XTRA_LIBS)
|
||||
|
||||
integral_gauss-legendre:
|
||||
$(CC) -c $(CFLAGS) src/$@.c -o objs/$@.o
|
||||
$(LD) $(LDFLAGS) -o $(BUILDDIR)/$@ objs/$@.o $(LIBINUM_FLAG) $(XTRA_LIBS)
|
||||
|
||||
clean:
|
||||
@rm -rf $(OBJDIR)
|
||||
@rm -rf $(BUILDDIR)
|
BIN
doc/libinum-examples/build/integral_gauss-legendre
Executable file
BIN
doc/libinum-examples/build/integral_gauss-legendre
Executable file
Binary file not shown.
BIN
doc/libinum-examples/build/root_newton
Executable file
BIN
doc/libinum-examples/build/root_newton
Executable file
Binary file not shown.
BIN
doc/libinum-examples/objs/integral_gauss-legendre.o
Normal file
BIN
doc/libinum-examples/objs/integral_gauss-legendre.o
Normal file
Binary file not shown.
BIN
doc/libinum-examples/objs/root_newton.o
Normal file
BIN
doc/libinum-examples/objs/root_newton.o
Normal file
Binary file not shown.
92
doc/libinum-examples/src/integral_gauss-legendre.c
Normal file
92
doc/libinum-examples/src/integral_gauss-legendre.c
Normal file
@ -0,0 +1,92 @@
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
// define MPFR_USE_VA_LIST to enable the use of mpfr_inits and mpfr_clears
|
||||
#define MPFR_USE_VA_LIST
|
||||
#include <mpfr.h>
|
||||
#include <libinum.h>
|
||||
|
||||
int func(mpfr_t* out, mpfr_t in, void* extra_args);
|
||||
|
||||
int main(int argc, const char* argv[]){
|
||||
int ret;
|
||||
mpfr_t tolerance, val, lower, upper;
|
||||
array_mpfr abcissa, weights;
|
||||
|
||||
// precision of MPFR floats
|
||||
mpfr_set_default_prec(53);
|
||||
|
||||
// tolerance for computing weights
|
||||
mpfr_init(tolerance);
|
||||
mpfr_set_d(tolerance, 1.e-11, MPFR_RNDN);
|
||||
|
||||
// compute weights
|
||||
ret=gauss_legendre_weights_mpfr(10, tolerance, 10000, &abcissa, &weights);
|
||||
// return codes
|
||||
if(ret==LIBINUM_ERROR_MAXITER){
|
||||
printf("error: maximum number of iterations reached when computing the integration abcissa\n");
|
||||
mpfr_clear(tolerance);
|
||||
return(ret);
|
||||
}
|
||||
else if(ret==LIBINUM_ERROR_NAN){
|
||||
printf("error: infinity encountered when computing the integration abcissa\n");
|
||||
mpfr_clear(tolerance);
|
||||
return(ret);
|
||||
}
|
||||
else{
|
||||
printf("abcissa:\n");
|
||||
array_mpfr_print(abcissa);
|
||||
printf("\nweights:\n");
|
||||
array_mpfr_print(weights);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
mpfr_clear(tolerance);
|
||||
|
||||
mpfr_inits(val, lower, upper, NULL);
|
||||
|
||||
mpfr_set_ui(lower, 0, MPFR_RNDN);
|
||||
mpfr_set_ui(upper, 2, MPFR_RNDN);
|
||||
|
||||
ret=integrate_gauss_mpfr(&val, &func, lower, upper, abcissa, weights, NULL);
|
||||
// return codes
|
||||
if(ret==LIBINUM_ERROR_SIZE_MISMATCH){
|
||||
printf("error: the mpfr_arrays 'abcissa' and 'weights' must have the same length\n");
|
||||
mpfr_clears(val, upper, lower, NULL);
|
||||
array_mpfr_free(abcissa);
|
||||
array_mpfr_free(weights);
|
||||
return(ret);
|
||||
}
|
||||
else if(ret==LIBINUM_ERROR_NAN){
|
||||
printf("error: the integrand is singular\n");
|
||||
array_mpfr_free(abcissa);
|
||||
array_mpfr_free(weights);
|
||||
mpfr_clears(val, upper, lower, NULL);
|
||||
return(ret);
|
||||
}
|
||||
else{
|
||||
printf("\\int_0^2 x/sin(x) dx = ");
|
||||
fprint_mpfr(stdout, val);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
mpfr_clears(val, upper, lower, NULL);
|
||||
array_mpfr_free(abcissa);
|
||||
array_mpfr_free(weights);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*
|
||||
// e^x
|
||||
int func(mpfr_t* out, mpfr_t in, void* extra_args){
|
||||
mpfr_exp(*out, in, MPFR_RNDN);
|
||||
return(0);
|
||||
}
|
||||
*/
|
||||
|
||||
// x/sin(x)
|
||||
int func(mpfr_t* out, mpfr_t in, void* extra_args){
|
||||
mpfr_sin(*out, in, MPFR_RNDN);
|
||||
mpfr_div(*out, in, *out, MPFR_RNDN);
|
||||
return(0);
|
||||
}
|
58
doc/libinum-examples/src/root_newton.c
Normal file
58
doc/libinum-examples/src/root_newton.c
Normal file
@ -0,0 +1,58 @@
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
// define MPFR_USE_VA_LIST to enable the use of mpfr_inits and mpfr_clears
|
||||
#define MPFR_USE_VA_LIST
|
||||
#include <mpfr.h>
|
||||
#include <libinum.h>
|
||||
|
||||
int func(mpfr_t* out, mpfr_t in, void* extra_args);
|
||||
int dfunc(mpfr_t* out, mpfr_t in, void* extra_args);
|
||||
|
||||
int main(int argc, const char* argv[]){
|
||||
int ret;
|
||||
mpfr_t init, prec, x;
|
||||
unsigned int maxiter;
|
||||
int extra_arg;
|
||||
|
||||
mpfr_inits(init, prec, x, NULL);
|
||||
|
||||
// start at 2
|
||||
mpfr_set_ui(init, 2, MPFR_RNDN);
|
||||
// precision
|
||||
mpfr_set_d(prec, 1.e-30, MPFR_RNDN);
|
||||
// maximum number of iterations before error
|
||||
maxiter=10000;
|
||||
// extra argument
|
||||
extra_arg=4;
|
||||
|
||||
// compute root
|
||||
ret=root_newton_mpfr(&x, &func, &dfunc, init, prec, maxiter, &extra_arg);
|
||||
|
||||
// return codes
|
||||
if(ret==LIBINUM_ERROR_MAXITER){
|
||||
printf("error: maximum number of iterations reached\n");
|
||||
}
|
||||
else if(ret==LIBINUM_ERROR_NAN){
|
||||
printf("error: infinity encountered\n");
|
||||
}
|
||||
else{
|
||||
mpfr_printf("% 14.7Re\n", x);
|
||||
}
|
||||
|
||||
mpfr_clears(init, prec, x, NULL);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
// x^2-1
|
||||
int func(mpfr_t* out, mpfr_t in, void* extra_args){
|
||||
mpfr_pow_ui(*out, in, 2, MPFR_RNDN);
|
||||
mpfr_add_d(*out, *out, -1./ *((int*)extra_args), MPFR_RNDN);
|
||||
return(0);
|
||||
}
|
||||
|
||||
// 2*x
|
||||
int dfunc(mpfr_t* out, mpfr_t in, void* extra_args){
|
||||
mpfr_mul_ui(*out, in, 2, MPFR_RNDN);
|
||||
return(0);
|
||||
}
|
20
include/libinum.h
Normal file
20
include/libinum.h
Normal file
@ -0,0 +1,20 @@
|
||||
#ifndef LIBINUM_H
|
||||
#define LIBINUM_H
|
||||
|
||||
#define LIBINUM_VERSION "1.0"
|
||||
|
||||
#include <libinum/types.h>
|
||||
|
||||
#include <libinum/errors.h>
|
||||
|
||||
#include <libinum/integral.h>
|
||||
#include <libinum/root.h>
|
||||
|
||||
#include <libinum/utils.h>
|
||||
|
||||
#include <libinum/array.h>
|
||||
#include <libinum/polynomial.h>
|
||||
#include <libinum/polynomialMV.h>
|
||||
|
||||
|
||||
#endif
|
1
include/libinum/array.h
Symbolic link
1
include/libinum/array.h
Symbolic link
@ -0,0 +1 @@
|
||||
../../src/array.h
|
1
include/libinum/array_2_mpfr.h
Symbolic link
1
include/libinum/array_2_mpfr.h
Symbolic link
@ -0,0 +1 @@
|
||||
../../src/array_2_mpfr.h
|
1
include/libinum/array_base.h
Symbolic link
1
include/libinum/array_base.h
Symbolic link
@ -0,0 +1 @@
|
||||
../../src/array_base.h
|
1
include/libinum/array_char.h
Symbolic link
1
include/libinum/array_char.h
Symbolic link
@ -0,0 +1 @@
|
||||
../../src/array_char.h
|
1
include/libinum/array_double.h
Symbolic link
1
include/libinum/array_double.h
Symbolic link
@ -0,0 +1 @@
|
||||
../../src/array_double.h
|
1
include/libinum/array_int.h
Symbolic link
1
include/libinum/array_int.h
Symbolic link
@ -0,0 +1 @@
|
||||
../../src/array_int.h
|
1
include/libinum/array_ldouble.h
Symbolic link
1
include/libinum/array_ldouble.h
Symbolic link
@ -0,0 +1 @@
|
||||
../../src/array_ldouble.h
|
1
include/libinum/array_mpfr.h
Symbolic link
1
include/libinum/array_mpfr.h
Symbolic link
@ -0,0 +1 @@
|
||||
../../src/array_mpfr.h
|
1
include/libinum/array_polynomial_double.h
Symbolic link
1
include/libinum/array_polynomial_double.h
Symbolic link
@ -0,0 +1 @@
|
||||
../../src/array_polynomial_double.h
|
1
include/libinum/array_polynomial_ldouble.h
Symbolic link
1
include/libinum/array_polynomial_ldouble.h
Symbolic link
@ -0,0 +1 @@
|
||||
../../src/array_polynomial_ldouble.h
|
1
include/libinum/array_polynomial_mpfr.h
Symbolic link
1
include/libinum/array_polynomial_mpfr.h
Symbolic link
@ -0,0 +1 @@
|
||||
../../src/array_polynomial_mpfr.h
|
1
include/libinum/array_pthread_t.h
Symbolic link
1
include/libinum/array_pthread_t.h
Symbolic link
@ -0,0 +1 @@
|
||||
../../src/array_pthread_t.h
|
1
include/libinum/array_str.h
Symbolic link
1
include/libinum/array_str.h
Symbolic link
@ -0,0 +1 @@
|
||||
../../src/array_str.h
|
1
include/libinum/array_type.h
Symbolic link
1
include/libinum/array_type.h
Symbolic link
@ -0,0 +1 @@
|
||||
../../src/array_type.h
|
1
include/libinum/array_uint.h
Symbolic link
1
include/libinum/array_uint.h
Symbolic link
@ -0,0 +1 @@
|
||||
../../src/array_uint.h
|
1
include/libinum/errors.h
Symbolic link
1
include/libinum/errors.h
Symbolic link
@ -0,0 +1 @@
|
||||
../../src/errors.h
|
1
include/libinum/integral.h
Symbolic link
1
include/libinum/integral.h
Symbolic link
@ -0,0 +1 @@
|
||||
../../src/integral.h
|
1
include/libinum/integral_base.h
Symbolic link
1
include/libinum/integral_base.h
Symbolic link
@ -0,0 +1 @@
|
||||
../../src/integral_base.h
|
1
include/libinum/integral_double.h
Symbolic link
1
include/libinum/integral_double.h
Symbolic link
@ -0,0 +1 @@
|
||||
../../src/integral_double.h
|
1
include/libinum/integral_ldouble.h
Symbolic link
1
include/libinum/integral_ldouble.h
Symbolic link
@ -0,0 +1 @@
|
||||
../../src/integral_ldouble.h
|
1
include/libinum/integral_mpfr.h
Symbolic link
1
include/libinum/integral_mpfr.h
Symbolic link
@ -0,0 +1 @@
|
||||
../../src/integral_mpfr.h
|
1
include/libinum/polynomial.h
Symbolic link
1
include/libinum/polynomial.h
Symbolic link
@ -0,0 +1 @@
|
||||
../../src/polynomial.h
|
1
include/libinum/polynomialMV.h
Symbolic link
1
include/libinum/polynomialMV.h
Symbolic link
@ -0,0 +1 @@
|
||||
../../src/polynomialMV.h
|
1
include/libinum/polynomialMV_base.h
Symbolic link
1
include/libinum/polynomialMV_base.h
Symbolic link
@ -0,0 +1 @@
|
||||
../../src/polynomialMV_base.h
|
1
include/libinum/polynomialMV_int.h
Symbolic link
1
include/libinum/polynomialMV_int.h
Symbolic link
@ -0,0 +1 @@
|
||||
../../src/polynomialMV_int.h
|
1
include/libinum/polynomialMV_mpz.h
Symbolic link
1
include/libinum/polynomialMV_mpz.h
Symbolic link
@ -0,0 +1 @@
|
||||
../../src/polynomialMV_mpz.h
|
1
include/libinum/polynomialMV_type.h
Symbolic link
1
include/libinum/polynomialMV_type.h
Symbolic link
@ -0,0 +1 @@
|
||||
../../src/polynomialMV_type.h
|
1
include/libinum/polynomial_base.h
Symbolic link
1
include/libinum/polynomial_base.h
Symbolic link
@ -0,0 +1 @@
|
||||
../../src/polynomial_base.h
|
1
include/libinum/polynomial_double.h
Symbolic link
1
include/libinum/polynomial_double.h
Symbolic link
@ -0,0 +1 @@
|
||||
../../src/polynomial_double.h
|
1
include/libinum/polynomial_ldouble.h
Symbolic link
1
include/libinum/polynomial_ldouble.h
Symbolic link
@ -0,0 +1 @@
|
||||
../../src/polynomial_ldouble.h
|
1
include/libinum/polynomial_mpfr.h
Symbolic link
1
include/libinum/polynomial_mpfr.h
Symbolic link
@ -0,0 +1 @@
|
||||
../../src/polynomial_mpfr.h
|
1
include/libinum/polynomial_type.h
Symbolic link
1
include/libinum/polynomial_type.h
Symbolic link
@ -0,0 +1 @@
|
||||
../../src/polynomial_type.h
|
1
include/libinum/root.h
Symbolic link
1
include/libinum/root.h
Symbolic link
@ -0,0 +1 @@
|
||||
../../src/root.h
|
1
include/libinum/root_base.h
Symbolic link
1
include/libinum/root_base.h
Symbolic link
@ -0,0 +1 @@
|
||||
../../src/root_base.h
|
1
include/libinum/root_double.h
Symbolic link
1
include/libinum/root_double.h
Symbolic link
@ -0,0 +1 @@
|
||||
../../src/root_double.h
|
1
include/libinum/root_ldouble.h
Symbolic link
1
include/libinum/root_ldouble.h
Symbolic link
@ -0,0 +1 @@
|
||||
../../src/root_ldouble.h
|
1
include/libinum/root_mpfr.h
Symbolic link
1
include/libinum/root_mpfr.h
Symbolic link
@ -0,0 +1 @@
|
||||
../../src/root_mpfr.h
|
1
include/libinum/types.h
Symbolic link
1
include/libinum/types.h
Symbolic link
@ -0,0 +1 @@
|
||||
../../src/types.h
|
1
include/libinum/utils.h
Symbolic link
1
include/libinum/utils.h
Symbolic link
@ -0,0 +1 @@
|
||||
../../src/utils.h
|
227
src/array.c
Normal file
227
src/array.c
Normal file
@ -0,0 +1,227 @@
|
||||
/*
|
||||
Copyright 2016 Ian Jauslin
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#include "array.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include "errors.h"
|
||||
#include "polynomial.h"
|
||||
#include "utils.h"
|
||||
|
||||
//--------------------------------------------------
|
||||
//
|
||||
// integer array (array_int)
|
||||
//
|
||||
//--------------------------------------------------
|
||||
#include "array_int.h"
|
||||
#include "array_base.c"
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
//
|
||||
// unsigned integer array (array_uint)
|
||||
//
|
||||
//--------------------------------------------------
|
||||
#include "array_uint.h"
|
||||
#include "array_base.c"
|
||||
|
||||
//--------------------------------------------------
|
||||
//
|
||||
// double array (array_double)
|
||||
//
|
||||
//--------------------------------------------------
|
||||
#include "array_double.h"
|
||||
#include "array_base.c"
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
//
|
||||
// long double array (array_ldouble)
|
||||
//
|
||||
//--------------------------------------------------
|
||||
#include "array_ldouble.h"
|
||||
#include "array_base.c"
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
//
|
||||
// MPFR array (array_mpfr)
|
||||
//
|
||||
//--------------------------------------------------
|
||||
#include "array_mpfr.h"
|
||||
#include "array_base.c"
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
//
|
||||
// array of MPFR arrays (array_2_mpfr)
|
||||
//
|
||||
//--------------------------------------------------
|
||||
#include "array_2_mpfr.h"
|
||||
#include "array_base.c"
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
//
|
||||
// character array (array_char)
|
||||
//
|
||||
//--------------------------------------------------
|
||||
#include "array_char.h"
|
||||
#include "array_base.c"
|
||||
|
||||
// append a char*
|
||||
int array_char_append_str(char* str, array_char* output){
|
||||
char* ptr;
|
||||
for (ptr=str;*ptr!='\0';ptr++){
|
||||
array_char_append(*ptr, output);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
// convert to char*
|
||||
int array_char_to_str(array_char input, char** output){
|
||||
unsigned int i;
|
||||
(*output)=calloc(input.length+1,sizeof(char));
|
||||
for(i=0;i<input.length;i++){
|
||||
(*output)[i]=input.values[i];
|
||||
}
|
||||
if((*output)[input.length-1]!='\0'){
|
||||
(*output)[input.length]='\0';
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
// noinit (changes the size of input if needed)
|
||||
char* array_char_to_str_noinit(array_char* input){
|
||||
if(input->values[input->length-1]!='\0'){
|
||||
if(input->length==input->memory){
|
||||
array_char_resize(input,input->length+1);
|
||||
}
|
||||
// add final '\0'
|
||||
input->values[input->length]='\0';
|
||||
}
|
||||
return(input->values);
|
||||
}
|
||||
|
||||
// convert from char*
|
||||
int str_to_array_char(char* str, array_char* output){
|
||||
char* ptr;
|
||||
unsigned int str_len=0;
|
||||
for(ptr=str;*ptr!='\0';ptr++){
|
||||
str_len++;
|
||||
}
|
||||
array_char_init(output, str_len);
|
||||
for(ptr=str;*ptr!='\0';ptr++){
|
||||
array_char_append(*ptr,output);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
// compare an array_char and a char*
|
||||
int array_char_cmp_str(array_char array_char, char* str){
|
||||
unsigned int j;
|
||||
for(j=0;j<array_char.length && str[j]!='\0';j++){
|
||||
if(array_char.values[j]!=str[j]){
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
if(j==array_char.length && str[j]=='\0'){
|
||||
return(1);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
// format strings
|
||||
int array_char_snprintf(array_char* output, char* fmt, ...){
|
||||
size_t size=100;
|
||||
unsigned int extra_size;
|
||||
char* out_str=calloc(size,sizeof(char));
|
||||
char* ptr;
|
||||
va_list vaptr;
|
||||
|
||||
// initialize argument list starting after fmt
|
||||
va_start(vaptr, fmt);
|
||||
// print format
|
||||
extra_size=vsnprintf(out_str, size, fmt, vaptr);
|
||||
va_end(vaptr);
|
||||
|
||||
// if too large
|
||||
if(extra_size>size){
|
||||
// resize
|
||||
free(out_str);
|
||||
// +1 for '\0'
|
||||
size=extra_size+1;
|
||||
out_str=calloc(size,sizeof(char));
|
||||
// read format again
|
||||
va_start(vaptr, fmt);
|
||||
vsnprintf(out_str,size,fmt,vaptr);
|
||||
va_end(vaptr);
|
||||
}
|
||||
|
||||
// write to char array
|
||||
for(ptr=out_str;*ptr!='\0';ptr++){
|
||||
array_char_append(*ptr, output);
|
||||
}
|
||||
|
||||
free(out_str);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
//
|
||||
// string array (array_str)
|
||||
//
|
||||
//--------------------------------------------------
|
||||
#include "array_str.h"
|
||||
#include "array_base.c"
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
//
|
||||
// mpfr polynomial array (array_polynomial_mpfr)
|
||||
//
|
||||
//--------------------------------------------------
|
||||
#include "array_polynomial_mpfr.h"
|
||||
#include "array_base.c"
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
//
|
||||
// double polynomial array (array_polynomial_double)
|
||||
//
|
||||
//--------------------------------------------------
|
||||
#include "array_polynomial_double.h"
|
||||
#include "array_base.c"
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
//
|
||||
// long double polynomial array (array_polynomial_ldouble)
|
||||
//
|
||||
//--------------------------------------------------
|
||||
#include "array_polynomial_ldouble.h"
|
||||
#include "array_base.c"
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
//
|
||||
// pthread_t array (array_pthread_t)
|
||||
//
|
||||
//--------------------------------------------------
|
||||
#include "array_pthread_t.h"
|
||||
#include "array_base.c"
|
150
src/array.h
Normal file
150
src/array.h
Normal file
@ -0,0 +1,150 @@
|
||||
/*
|
||||
Copyright 2016 Ian Jauslin
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Mutable arrays
|
||||
*/
|
||||
|
||||
#ifndef LIBINUM_ARRAY_H
|
||||
#define LIBINUM_ARRAY_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
//--------------------------------------------------
|
||||
//
|
||||
// integer array (array_int)
|
||||
//
|
||||
//--------------------------------------------------
|
||||
#include "array_int.h"
|
||||
#include "array_base.h"
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
//
|
||||
// unsigned integer array (array_uint)
|
||||
//
|
||||
//--------------------------------------------------
|
||||
#include "array_uint.h"
|
||||
#include "array_base.h"
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
//
|
||||
// double array (array_double)
|
||||
//
|
||||
//--------------------------------------------------
|
||||
#include "array_double.h"
|
||||
#include "array_base.h"
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
//
|
||||
// long double array (array_ldouble)
|
||||
//
|
||||
//--------------------------------------------------
|
||||
#include "array_ldouble.h"
|
||||
#include "array_base.h"
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
//
|
||||
// MPFR array (array_mpfr)
|
||||
//
|
||||
//--------------------------------------------------
|
||||
#include "array_mpfr.h"
|
||||
#include "array_base.h"
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
//
|
||||
// array of MPFR arrays (array_2_mpfr)
|
||||
//
|
||||
//--------------------------------------------------
|
||||
#include "array_2_mpfr.h"
|
||||
#include "array_base.h"
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
//
|
||||
// character array (array_char)
|
||||
//
|
||||
//--------------------------------------------------
|
||||
#include "array_char.h"
|
||||
#include "array_base.h"
|
||||
|
||||
// append a char*
|
||||
int array_char_append_str(char* str, array_char* output);
|
||||
|
||||
// convert to char*
|
||||
int array_char_to_str(array_char input, char** output);
|
||||
// noinit (changes the size of input if needed)
|
||||
char* array_char_to_str_noinit(array_char* input);
|
||||
|
||||
// convert from char*
|
||||
int str_to_array_char(char* str, array_char* output);
|
||||
|
||||
// compare an array_char and a char*
|
||||
int array_char_cmp_str(array_char array_char, char* str);
|
||||
|
||||
// format strings
|
||||
int array_char_snprintf(array_char* output, char* fmt, ...);
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
//
|
||||
// string array (array_str)
|
||||
//
|
||||
//--------------------------------------------------
|
||||
#include "array_str.h"
|
||||
#include "array_base.h"
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
//
|
||||
// mpfr polynomial array (array_polynomial_mpfr)
|
||||
//
|
||||
//--------------------------------------------------
|
||||
#include "array_polynomial_mpfr.h"
|
||||
#include "array_base.h"
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
//
|
||||
// double polynomial array (array_polynomial_double)
|
||||
//
|
||||
//--------------------------------------------------
|
||||
#include "array_polynomial_double.h"
|
||||
#include "array_base.h"
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
//
|
||||
// long double polynomial array (array_polynomial_ldouble)
|
||||
//
|
||||
//--------------------------------------------------
|
||||
#include "array_polynomial_ldouble.h"
|
||||
#include "array_base.h"
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
//
|
||||
// pthread_t array (array_pthread_t)
|
||||
//
|
||||
//--------------------------------------------------
|
||||
#include "array_pthread_t.h"
|
||||
#include "array_base.h"
|
||||
|
||||
#endif
|
54
src/array_2_mpfr.h
Normal file
54
src/array_2_mpfr.h
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
Copyright 2016 Ian Jauslin
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Preprocessor macros for arrays of MPFR float arrays
|
||||
*/
|
||||
|
||||
|
||||
// reset CPP macros
|
||||
#undef ARRAY_TYPENAME
|
||||
#undef ARRAY_FUNC
|
||||
#undef ARRAY_VAL_TYPE
|
||||
#undef ARRAY_VAL_FREE
|
||||
#undef ARRAY_VAL_SET
|
||||
#undef ARRAY_VAL_CPY
|
||||
#undef ARRAY_VAL_IFEQ
|
||||
#undef ARRAY_VAL_IFLT
|
||||
#undef ARRAY_VAL_IFGT
|
||||
#undef ARRAY_VAL_PRINT
|
||||
|
||||
|
||||
// name of the polynomial type
|
||||
#define ARRAY_TYPENAME array_2_mpfr
|
||||
// prefix of function names
|
||||
#define ARRAY_FUNC(NAME) array_2_mpfr_ ## NAME
|
||||
|
||||
// type of values
|
||||
#define ARRAY_VAL_TYPE array_mpfr
|
||||
// free
|
||||
#define ARRAY_VAL_FREE(VAL) array_mpfr_free(VAL)
|
||||
// set values
|
||||
#define ARRAY_VAL_SET(VAL, NEWVAL) VAL=NEWVAL
|
||||
// copy values
|
||||
#define ARRAY_VAL_CPY(FROMVAL, TOVAL) array_mpfr_cpy(FROMVAL, &TOVAL);
|
||||
// compare values
|
||||
#define ARRAY_VAL_IFEQ(VAL1, VAL2) array_mpfr_cmp(VAL1, VAL2)==0
|
||||
#define ARRAY_VAL_IFLT(VAL1, VAL2) array_mpfr_cmp(VAL1, VAL2)<0
|
||||
#define ARRAY_VAL_IFGT(VAL1, VAL2) array_mpfr_cmp(VAL1, VAL2)>0
|
||||
// print values
|
||||
#define ARRAY_VAL_PRINT(VAL) array_mpfr_print(VAL)
|
||||
|
249
src/array_base.c
Normal file
249
src/array_base.c
Normal file
@ -0,0 +1,249 @@
|
||||
/*
|
||||
Copyright 2016 Ian Jauslin
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Base functions for arrays
|
||||
|
||||
see polynomial_*.h for the values taken by ARRAY_FUNC, etc...
|
||||
*/
|
||||
|
||||
|
||||
// init
|
||||
int ARRAY_FUNC(init) (ARRAY_TYPENAME* array, unsigned int memory){
|
||||
array->values=calloc(memory,sizeof(ARRAY_VAL_TYPE));
|
||||
array->memory=memory;
|
||||
array->length=0;
|
||||
return(0);
|
||||
}
|
||||
int ARRAY_FUNC(free) (ARRAY_TYPENAME array){
|
||||
#ifdef ARRAY_VAL_FREE
|
||||
unsigned int i;
|
||||
for(i=0;i<array.length;i++){
|
||||
ARRAY_VAL_FREE(array.values[i]);
|
||||
}
|
||||
#endif
|
||||
free(array.values);
|
||||
return(0);
|
||||
}
|
||||
// do not free values, only free calloc'ed memory
|
||||
int ARRAY_FUNC(free_vects) (ARRAY_TYPENAME array){
|
||||
free(array.values);
|
||||
return(0);
|
||||
}
|
||||
|
||||
// resize memory
|
||||
int ARRAY_FUNC(resize) (ARRAY_TYPENAME* array, unsigned int newsize){
|
||||
unsigned int i;
|
||||
ARRAY_TYPENAME new_array;
|
||||
ARRAY_FUNC(init) (&new_array, newsize);
|
||||
for(i=0;i<array->length;i++){
|
||||
ARRAY_VAL_SET(new_array.values[i], array->values[i]);
|
||||
}
|
||||
free(array->values);
|
||||
*array=new_array;
|
||||
return(0);
|
||||
}
|
||||
|
||||
// add a value
|
||||
int ARRAY_FUNC(append) (ARRAY_VAL_TYPE val, ARRAY_TYPENAME* output){
|
||||
if(output->length >= output->memory){
|
||||
ARRAY_FUNC(resize) (output,2*output->memory+1);
|
||||
}
|
||||
ARRAY_VAL_CPY(val, output->values[output->length]);
|
||||
output->length++;
|
||||
return(0);
|
||||
}
|
||||
// do not copy the value, instead let the last element of the array point to 'val'
|
||||
// only if the value requires initializing
|
||||
#ifdef ARRAY_VAL_FREE
|
||||
int ARRAY_FUNC(append_noinit) (ARRAY_VAL_TYPE val, ARRAY_TYPENAME* output){
|
||||
if(output->length >= output->memory){
|
||||
ARRAY_FUNC(resize) (output,2*output->memory+1);
|
||||
}
|
||||
ARRAY_VAL_SET(output->values[output->length], val);
|
||||
output->length++;
|
||||
return(0);
|
||||
}
|
||||
#endif
|
||||
// add a value only if it is not already present
|
||||
#ifdef ARRAY_VAL_IFEQ
|
||||
int ARRAY_FUNC(append_unique) (ARRAY_VAL_TYPE val, ARRAY_TYPENAME* output){
|
||||
if(ARRAY_FUNC(find) (val, *output)<0){
|
||||
ARRAY_FUNC(append) (val, output);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
// copy
|
||||
int ARRAY_FUNC(cpy) (ARRAY_TYPENAME input, ARRAY_TYPENAME* output){
|
||||
ARRAY_FUNC(init) (output, input.length);
|
||||
ARRAY_FUNC(cpy_noinit) (input, output);
|
||||
return(0);
|
||||
}
|
||||
// do not init output array
|
||||
int ARRAY_FUNC(cpy_noinit) (ARRAY_TYPENAME input, ARRAY_TYPENAME* output){
|
||||
unsigned int i;
|
||||
if(output->memory<input.length){
|
||||
return(LIBINUM_ERROR_SIZE_MISMATCH);
|
||||
}
|
||||
for(i=0;i<input.length;i++){
|
||||
ARRAY_VAL_CPY(input.values[i], output->values[i]);
|
||||
}
|
||||
output->length=input.length;
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
// concatenate
|
||||
int ARRAY_FUNC(concat) (ARRAY_TYPENAME input, ARRAY_TYPENAME* output){
|
||||
unsigned int i;
|
||||
for(i=0;i<input.length;i++){
|
||||
ARRAY_FUNC(append) (input.values[i], output);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
// concat but only add values that are not already present in the array
|
||||
#ifdef ARRAY_VAL_IFEQ
|
||||
int ARRAY_FUNC(concat_unique) (ARRAY_TYPENAME input, ARRAY_TYPENAME* output){
|
||||
unsigned int i;
|
||||
for(i=0;i<input.length;i++){
|
||||
ARRAY_FUNC(append_unique) (input.values[i], output);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
// sub-array
|
||||
int ARRAY_FUNC(subarray) (ARRAY_TYPENAME array, unsigned int begin, unsigned int end, ARRAY_TYPENAME* subarray){
|
||||
unsigned int i;
|
||||
if(begin>end || end>=array.length){
|
||||
return(LIBINUM_ERROR_ILLEGAL_MEMORY_ACCESS);
|
||||
}
|
||||
ARRAY_FUNC(init) (subarray,end-begin);
|
||||
for(i=begin;i<=end;i++){
|
||||
ARRAY_FUNC(append) (array.values[i], subarray);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
// find (does not assume the array is sorted)
|
||||
#ifdef ARRAY_VAL_IFEQ
|
||||
int ARRAY_FUNC(find) (ARRAY_VAL_TYPE val, ARRAY_TYPENAME array){
|
||||
unsigned int i;
|
||||
for(i=0;i<array.length;i++){
|
||||
if(ARRAY_VAL_IFEQ(array.values[i], val)){
|
||||
return(i);
|
||||
}
|
||||
}
|
||||
return(-1);
|
||||
}
|
||||
#endif
|
||||
|
||||
// sort (quicksort)
|
||||
#ifdef ARRAY_VAL_IFLT
|
||||
int ARRAY_FUNC(sort) (ARRAY_TYPENAME array){
|
||||
if(array.length>1){
|
||||
ARRAY_FUNC(sort_sub) (array, 0, array.length-1);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
// sort a sub-array
|
||||
int ARRAY_FUNC(sort_sub) (ARRAY_TYPENAME array, unsigned int begin, unsigned int end){
|
||||
unsigned int i;
|
||||
unsigned int index;
|
||||
ARRAY_VAL_TYPE tmp;
|
||||
// the pivot: middle of the array
|
||||
unsigned int pivot=(begin+end)/2;
|
||||
|
||||
// if the array is non trivial
|
||||
if(begin<end){
|
||||
// send pivot to the end
|
||||
ARRAY_VAL_SET(tmp, array.values[pivot]);
|
||||
ARRAY_VAL_SET(array.values[pivot], array.values[end]);
|
||||
ARRAY_VAL_SET(array.values[end], tmp);
|
||||
|
||||
// loop over the others
|
||||
for(i=begin, index=begin;i<end;i++){
|
||||
// compare with pivot
|
||||
if(ARRAY_VAL_IFLT(array.values[i], array.values[end])){
|
||||
// if smaller, exchange with reference index
|
||||
ARRAY_VAL_SET(tmp, array.values[index]);
|
||||
ARRAY_VAL_SET(array.values[index], array.values[i]);
|
||||
ARRAY_VAL_SET(array.values[i], tmp);
|
||||
// move reference index
|
||||
index++;
|
||||
}
|
||||
}
|
||||
// put pivot (which we had sent to the end) in the right place
|
||||
ARRAY_VAL_SET(tmp, array.values[end]);
|
||||
ARRAY_VAL_SET(array.values[end], array.values[index]);
|
||||
ARRAY_VAL_SET(array.values[index], tmp);
|
||||
|
||||
// recurse
|
||||
if(index>0){
|
||||
ARRAY_FUNC(sort_sub) (array, begin, index-1);
|
||||
}
|
||||
ARRAY_FUNC(sort_sub) (array, index+1, end);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
// compare arrays
|
||||
#if defined ARRAY_VAL_IFLT && defined ARRAY_VAL_IFGT
|
||||
int ARRAY_FUNC(cmp) (ARRAY_TYPENAME array1, ARRAY_TYPENAME array2){
|
||||
unsigned int i;
|
||||
|
||||
// compare lengths
|
||||
if(array1.length<array2.length){
|
||||
return(-1);
|
||||
}
|
||||
if(array1.length>array2.length){
|
||||
return(1);
|
||||
}
|
||||
|
||||
// compare terms
|
||||
for(i=0;i<array1.length;i++){
|
||||
if(ARRAY_VAL_IFLT(array1.values[i], array2.values[i])){
|
||||
return(-1);
|
||||
}
|
||||
if(ARRAY_VAL_IFGT(array1.values[i], array2.values[i])){
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
|
||||
// if equal
|
||||
return(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
// print array
|
||||
#ifdef ARRAY_VAL_PRINT
|
||||
int ARRAY_FUNC(print) (ARRAY_TYPENAME array){
|
||||
unsigned int i;
|
||||
printf("(");
|
||||
for(i=0;i<array.length;i++){
|
||||
ARRAY_VAL_PRINT(array.values[i]);
|
||||
if(i<array.length-1){
|
||||
printf(", ");
|
||||
}
|
||||
}
|
||||
printf(")");
|
||||
return(0);
|
||||
}
|
||||
#endif
|
78
src/array_base.h
Normal file
78
src/array_base.h
Normal file
@ -0,0 +1,78 @@
|
||||
/*
|
||||
Copyright 2016 Ian Jauslin
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Base functions for arrays
|
||||
|
||||
see polynomial_*.h for the values taken by ARRAY_FUNC, etc...
|
||||
*/
|
||||
|
||||
// init
|
||||
int ARRAY_FUNC(init) (ARRAY_TYPENAME* array, unsigned int memory);
|
||||
int ARRAY_FUNC(free) (ARRAY_TYPENAME array);
|
||||
// do not free values, only free calloc'ed memory
|
||||
int ARRAY_FUNC(free_vects) (ARRAY_TYPENAME array);
|
||||
|
||||
// resize memory
|
||||
int ARRAY_FUNC(resize) (ARRAY_TYPENAME* array, unsigned int newsize);
|
||||
|
||||
// add a value
|
||||
int ARRAY_FUNC(append) (ARRAY_VAL_TYPE val, ARRAY_TYPENAME* output);
|
||||
#ifdef ARRAY_VAL_FREE
|
||||
// do not copy the value, instead let the last element of the array point to 'val'
|
||||
int ARRAY_FUNC(append_noinit) (ARRAY_VAL_TYPE val, ARRAY_TYPENAME* output);
|
||||
#endif
|
||||
// add a value only if it is not already present
|
||||
#ifdef ARRAY_VAL_IFEQ
|
||||
int ARRAY_FUNC(append_unique) (ARRAY_VAL_TYPE val, ARRAY_TYPENAME* output);
|
||||
#endif
|
||||
|
||||
// copy
|
||||
int ARRAY_FUNC(cpy) (ARRAY_TYPENAME input, ARRAY_TYPENAME* output);
|
||||
int ARRAY_FUNC(cpy_noinit) (ARRAY_TYPENAME input, ARRAY_TYPENAME* output);
|
||||
|
||||
// concatenate
|
||||
int ARRAY_FUNC(concat) (ARRAY_TYPENAME input, ARRAY_TYPENAME* output);
|
||||
// concat but only add values that are not already present in the array
|
||||
#ifdef ARRAY_VAL_IFEQ
|
||||
int ARRAY_FUNC(concat_unique) (ARRAY_TYPENAME input, ARRAY_TYPENAME* output);
|
||||
#endif
|
||||
|
||||
// sub-array
|
||||
int ARRAY_FUNC(subarray) (ARRAY_TYPENAME array, unsigned int begin, unsigned int end, ARRAY_TYPENAME* subarray);
|
||||
|
||||
// find (does not assume the array is sorted)
|
||||
#ifdef ARRAY_VAL_IFEQ
|
||||
int ARRAY_FUNC(find) (ARRAY_VAL_TYPE val, ARRAY_TYPENAME array);
|
||||
#endif
|
||||
|
||||
// sort (quicksort)
|
||||
#ifdef ARRAY_VAL_IFLT
|
||||
int ARRAY_FUNC(sort) (ARRAY_TYPENAME array);
|
||||
// sort a sub-array
|
||||
int ARRAY_FUNC(sort_sub) (ARRAY_TYPENAME array, unsigned int begin, unsigned int end);
|
||||
#endif
|
||||
|
||||
// compare arrays
|
||||
#if defined ARRAY_VAL_IFLT && defined ARRAY_VAL_IFGT
|
||||
int ARRAY_FUNC(cmp) (ARRAY_TYPENAME array1, ARRAY_TYPENAME array2);
|
||||
#endif
|
||||
|
||||
// print array
|
||||
#ifdef ARRAY_VAL_PRINT
|
||||
int ARRAY_FUNC(print) (ARRAY_TYPENAME array);
|
||||
#endif
|
||||
|
52
src/array_char.h
Normal file
52
src/array_char.h
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
Copyright 2016 Ian Jauslin
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Preprocessor macros for char arrays
|
||||
*/
|
||||
|
||||
|
||||
// reset CPP macros
|
||||
#undef ARRAY_TYPENAME
|
||||
#undef ARRAY_FUNC
|
||||
#undef ARRAY_VAL_TYPE
|
||||
#undef ARRAY_VAL_FREE
|
||||
#undef ARRAY_VAL_SET
|
||||
#undef ARRAY_VAL_CPY
|
||||
#undef ARRAY_VAL_IFEQ
|
||||
#undef ARRAY_VAL_IFLT
|
||||
#undef ARRAY_VAL_IFGT
|
||||
#undef ARRAY_VAL_PRINT
|
||||
|
||||
|
||||
// name of the polynomial type
|
||||
#define ARRAY_TYPENAME array_char
|
||||
// prefix of function names
|
||||
#define ARRAY_FUNC(NAME) array_char_ ## NAME
|
||||
|
||||
// type of values
|
||||
#define ARRAY_VAL_TYPE char
|
||||
// set values
|
||||
#define ARRAY_VAL_SET(VAL, NEWVAL) VAL = NEWVAL
|
||||
// copy values
|
||||
#define ARRAY_VAL_CPY(FROMVAL, TOVAL) TOVAL = FROMVAL
|
||||
// compare values
|
||||
#define ARRAY_VAL_IFEQ(VAL1, VAL2) VAL1==VAL2
|
||||
#define ARRAY_VAL_IFLT(VAL1, VAL2) VAL1<VAL2
|
||||
#define ARRAY_VAL_IFGT(VAL1, VAL2) VAL1>VAL2
|
||||
// print values
|
||||
#define ARRAY_VAL_PRINT(VAL) printf("%c",VAL)
|
||||
|
52
src/array_double.h
Normal file
52
src/array_double.h
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
Copyright 2016 Ian Jauslin
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Preprocessor macros for double arrays
|
||||
*/
|
||||
|
||||
|
||||
// reset CPP macros
|
||||
#undef ARRAY_TYPENAME
|
||||
#undef ARRAY_FUNC
|
||||
#undef ARRAY_VAL_TYPE
|
||||
#undef ARRAY_VAL_FREE
|
||||
#undef ARRAY_VAL_SET
|
||||
#undef ARRAY_VAL_CPY
|
||||
#undef ARRAY_VAL_IFEQ
|
||||
#undef ARRAY_VAL_IFLT
|
||||
#undef ARRAY_VAL_IFGT
|
||||
#undef ARRAY_VAL_PRINT
|
||||
|
||||
|
||||
// name of the polynomial type
|
||||
#define ARRAY_TYPENAME array_double
|
||||
// prefix of function names
|
||||
#define ARRAY_FUNC(NAME) array_double_ ## NAME
|
||||
|
||||
// type of values
|
||||
#define ARRAY_VAL_TYPE double
|
||||
// set values
|
||||
#define ARRAY_VAL_SET(VAL, NEWVAL) VAL = NEWVAL
|
||||
// copy values
|
||||
#define ARRAY_VAL_CPY(FROMVAL, TOVAL) TOVAL = FROMVAL
|
||||
// compare values
|
||||
#define ARRAY_VAL_IFEQ(VAL1, VAL2) VAL1==VAL2
|
||||
#define ARRAY_VAL_IFLT(VAL1, VAL2) VAL1<VAL2
|
||||
#define ARRAY_VAL_IFGT(VAL1, VAL2) VAL1>VAL2
|
||||
// print values
|
||||
#define ARRAY_VAL_PRINT(VAL) fprint_double(stdout, VAL)
|
||||
|
52
src/array_int.h
Normal file
52
src/array_int.h
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
Copyright 2016 Ian Jauslin
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Preprocessor macros for integer arrays
|
||||
*/
|
||||
|
||||
|
||||
// reset CPP macros
|
||||
#undef ARRAY_TYPENAME
|
||||
#undef ARRAY_FUNC
|
||||
#undef ARRAY_VAL_TYPE
|
||||
#undef ARRAY_VAL_FREE
|
||||
#undef ARRAY_VAL_SET
|
||||
#undef ARRAY_VAL_CPY
|
||||
#undef ARRAY_VAL_IFEQ
|
||||
#undef ARRAY_VAL_IFLT
|
||||
#undef ARRAY_VAL_IFGT
|
||||
#undef ARRAY_VAL_PRINT
|
||||
|
||||
|
||||
// name of the polynomial type
|
||||
#define ARRAY_TYPENAME array_int
|
||||
// prefix of function names
|
||||
#define ARRAY_FUNC(NAME) array_int_ ## NAME
|
||||
|
||||
// type of values
|
||||
#define ARRAY_VAL_TYPE int
|
||||
// set values
|
||||
#define ARRAY_VAL_SET(VAL, NEWVAL) VAL = NEWVAL
|
||||
// copy values
|
||||
#define ARRAY_VAL_CPY(FROMVAL, TOVAL) TOVAL = FROMVAL
|
||||
// compare values
|
||||
#define ARRAY_VAL_IFEQ(VAL1, VAL2) VAL1==VAL2
|
||||
#define ARRAY_VAL_IFLT(VAL1, VAL2) VAL1<VAL2
|
||||
#define ARRAY_VAL_IFGT(VAL1, VAL2) VAL1>VAL2
|
||||
// print values
|
||||
#define ARRAY_VAL_PRINT(VAL) printf("%d",VAL)
|
||||
|
52
src/array_ldouble.h
Normal file
52
src/array_ldouble.h
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
Copyright 2016 Ian Jauslin
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Preprocessor macros for long double arrays
|
||||
*/
|
||||
|
||||
|
||||
// reset CPP macros
|
||||
#undef ARRAY_TYPENAME
|
||||
#undef ARRAY_FUNC
|
||||
#undef ARRAY_VAL_TYPE
|
||||
#undef ARRAY_VAL_FREE
|
||||
#undef ARRAY_VAL_SET
|
||||
#undef ARRAY_VAL_CPY
|
||||
#undef ARRAY_VAL_IFEQ
|
||||
#undef ARRAY_VAL_IFLT
|
||||
#undef ARRAY_VAL_IFGT
|
||||
#undef ARRAY_VAL_PRINT
|
||||
|
||||
|
||||
// name of the polynomial type
|
||||
#define ARRAY_TYPENAME array_ldouble
|
||||
// prefix of function names
|
||||
#define ARRAY_FUNC(NAME) array_ldouble_ ## NAME
|
||||
|
||||
// type of values
|
||||
#define ARRAY_VAL_TYPE long double
|
||||
// set values
|
||||
#define ARRAY_VAL_SET(VAL, NEWVAL) VAL = NEWVAL
|
||||
// copy values
|
||||
#define ARRAY_VAL_CPY(FROMVAL, TOVAL) TOVAL = FROMVAL
|
||||
// compare values
|
||||
#define ARRAY_VAL_IFEQ(VAL1, VAL2) VAL1==VAL2
|
||||
#define ARRAY_VAL_IFLT(VAL1, VAL2) VAL1<VAL2
|
||||
#define ARRAY_VAL_IFGT(VAL1, VAL2) VAL1>VAL2
|
||||
// print values
|
||||
#define ARRAY_VAL_PRINT(VAL) fprint_ldouble(stdout, VAL)
|
||||
|
54
src/array_mpfr.h
Normal file
54
src/array_mpfr.h
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
Copyright 2016 Ian Jauslin
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Preprocessor macros for MPFR float arrays
|
||||
*/
|
||||
|
||||
|
||||
// reset CPP macros
|
||||
#undef ARRAY_TYPENAME
|
||||
#undef ARRAY_FUNC
|
||||
#undef ARRAY_VAL_TYPE
|
||||
#undef ARRAY_VAL_FREE
|
||||
#undef ARRAY_VAL_SET
|
||||
#undef ARRAY_VAL_CPY
|
||||
#undef ARRAY_VAL_IFEQ
|
||||
#undef ARRAY_VAL_IFLT
|
||||
#undef ARRAY_VAL_IFGT
|
||||
#undef ARRAY_VAL_PRINT
|
||||
|
||||
|
||||
// name of the polynomial type
|
||||
#define ARRAY_TYPENAME array_mpfr
|
||||
// prefix of function names
|
||||
#define ARRAY_FUNC(NAME) array_mpfr_ ## NAME
|
||||
|
||||
// type of values
|
||||
#define ARRAY_VAL_TYPE mpfr_t
|
||||
// free
|
||||
#define ARRAY_VAL_FREE(VAL) mpfr_clear(VAL)
|
||||
// set values
|
||||
#define ARRAY_VAL_SET(VAL, NEWVAL) VAL[0]=NEWVAL[0]
|
||||
// copy values
|
||||
#define ARRAY_VAL_CPY(FROMVAL, TOVAL) mpfr_init(TOVAL); mpfr_set(TOVAL, FROMVAL, MPFR_RNDN)
|
||||
// compare values
|
||||
#define ARRAY_VAL_IFEQ(VAL1, VAL2) mpfr_cmp(VAL1, VAL2)==0
|
||||
#define ARRAY_VAL_IFLT(VAL1, VAL2) mpfr_cmp(VAL1, VAL2)<0
|
||||
#define ARRAY_VAL_IFGT(VAL1, VAL2) mpfr_cmp(VAL1, VAL2)>0
|
||||
// print values
|
||||
#define ARRAY_VAL_PRINT(VAL) fprint_mpfr(stdout, VAL)
|
||||
|
50
src/array_polynomial_double.h
Normal file
50
src/array_polynomial_double.h
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
Copyright 2016 Ian Jauslin
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Preprocessor macros for arrays of polynomials with double coefficients
|
||||
*/
|
||||
|
||||
|
||||
// reset CPP macros
|
||||
#undef ARRAY_TYPENAME
|
||||
#undef ARRAY_FUNC
|
||||
#undef ARRAY_VAL_TYPE
|
||||
#undef ARRAY_VAL_FREE
|
||||
#undef ARRAY_VAL_SET
|
||||
#undef ARRAY_VAL_CPY
|
||||
#undef ARRAY_VAL_IFEQ
|
||||
#undef ARRAY_VAL_IFLT
|
||||
#undef ARRAY_VAL_IFGT
|
||||
#undef ARRAY_VAL_PRINT
|
||||
|
||||
|
||||
// name of the polynomial type
|
||||
#define ARRAY_TYPENAME array_polynomial_double
|
||||
// prefix of function names
|
||||
#define ARRAY_FUNC(NAME) array_polynomial_double_ ## NAME
|
||||
|
||||
// type of values
|
||||
#define ARRAY_VAL_TYPE polynomial_double
|
||||
// free
|
||||
#define ARRAY_VAL_FREE(VAL) polynomial_double_free(VAL)
|
||||
// set values
|
||||
#define ARRAY_VAL_SET(VAL, NEWVAL) VAL = NEWVAL
|
||||
// copy values
|
||||
#define ARRAY_VAL_CPY(FROMVAL, TOVAL) polynomial_double_cpy(FROMVAL, &TOVAL)
|
||||
// print values
|
||||
#define ARRAY_VAL_PRINT(VAL) polynomial_double_print(VAL)
|
||||
|
50
src/array_polynomial_ldouble.h
Normal file
50
src/array_polynomial_ldouble.h
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
Copyright 2016 Ian Jauslin
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Preprocessor macros for arrays of polynomials with long double coefficients
|
||||
*/
|
||||
|
||||
|
||||
// reset CPP macros
|
||||
#undef ARRAY_TYPENAME
|
||||
#undef ARRAY_FUNC
|
||||
#undef ARRAY_VAL_TYPE
|
||||
#undef ARRAY_VAL_FREE
|
||||
#undef ARRAY_VAL_SET
|
||||
#undef ARRAY_VAL_CPY
|
||||
#undef ARRAY_VAL_IFEQ
|
||||
#undef ARRAY_VAL_IFLT
|
||||
#undef ARRAY_VAL_IFGT
|
||||
#undef ARRAY_VAL_PRINT
|
||||
|
||||
|
||||
// name of the polynomial type
|
||||
#define ARRAY_TYPENAME array_polynomial_ldouble
|
||||
// prefix of function names
|
||||
#define ARRAY_FUNC(NAME) array_polynomial_ldouble_ ## NAME
|
||||
|
||||
// type of values
|
||||
#define ARRAY_VAL_TYPE polynomial_ldouble
|
||||
// free
|
||||
#define ARRAY_VAL_FREE(VAL) polynomial_ldouble_free(VAL)
|
||||
// set values
|
||||
#define ARRAY_VAL_SET(VAL, NEWVAL) VAL = NEWVAL
|
||||
// copy values
|
||||
#define ARRAY_VAL_CPY(FROMVAL, TOVAL) polynomial_ldouble_cpy(FROMVAL, &TOVAL)
|
||||
// print values
|
||||
#define ARRAY_VAL_PRINT(VAL) polynomial_ldouble_print(VAL)
|
||||
|
50
src/array_polynomial_mpfr.h
Normal file
50
src/array_polynomial_mpfr.h
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
Copyright 2016 Ian Jauslin
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Preprocessor macros for arrays of polynomials with mpfr coefficients
|
||||
*/
|
||||
|
||||
|
||||
// reset CPP macros
|
||||
#undef ARRAY_TYPENAME
|
||||
#undef ARRAY_FUNC
|
||||
#undef ARRAY_VAL_TYPE
|
||||
#undef ARRAY_VAL_FREE
|
||||
#undef ARRAY_VAL_SET
|
||||
#undef ARRAY_VAL_CPY
|
||||
#undef ARRAY_VAL_IFEQ
|
||||
#undef ARRAY_VAL_IFLT
|
||||
#undef ARRAY_VAL_IFGT
|
||||
#undef ARRAY_VAL_PRINT
|
||||
|
||||
|
||||
// name of the polynomial type
|
||||
#define ARRAY_TYPENAME array_polynomial_mpfr
|
||||
// prefix of function names
|
||||
#define ARRAY_FUNC(NAME) array_polynomial_mpfr_ ## NAME
|
||||
|
||||
// type of values
|
||||
#define ARRAY_VAL_TYPE polynomial_mpfr
|
||||
// free
|
||||
#define ARRAY_VAL_FREE(VAL) polynomial_mpfr_free(VAL)
|
||||
// set values
|
||||
#define ARRAY_VAL_SET(VAL, NEWVAL) VAL = NEWVAL
|
||||
// copy values
|
||||
#define ARRAY_VAL_CPY(FROMVAL, TOVAL) polynomial_mpfr_cpy(FROMVAL, &TOVAL)
|
||||
// print values
|
||||
#define ARRAY_VAL_PRINT(VAL) polynomial_mpfr_print(VAL)
|
||||
|
50
src/array_pthread_t.h
Normal file
50
src/array_pthread_t.h
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
Copyright 2016 Ian Jauslin
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Preprocessor macros for pthread_t arrays
|
||||
*/
|
||||
|
||||
|
||||
// reset CPP macros
|
||||
#undef ARRAY_TYPENAME
|
||||
#undef ARRAY_FUNC
|
||||
#undef ARRAY_VAL_TYPE
|
||||
#undef ARRAY_VAL_FREE
|
||||
#undef ARRAY_VAL_SET
|
||||
#undef ARRAY_VAL_CPY
|
||||
#undef ARRAY_VAL_IFEQ
|
||||
#undef ARRAY_VAL_IFLT
|
||||
#undef ARRAY_VAL_IFGT
|
||||
#undef ARRAY_VAL_PRINT
|
||||
|
||||
|
||||
// name of the polynomial type
|
||||
#define ARRAY_TYPENAME array_pthread_t
|
||||
// prefix of function names
|
||||
#define ARRAY_FUNC(NAME) array_pthread_t_ ## NAME
|
||||
|
||||
// type of values
|
||||
#define ARRAY_VAL_TYPE pthread_t
|
||||
// set values
|
||||
#define ARRAY_VAL_SET(VAL, NEWVAL) VAL = NEWVAL
|
||||
// copy values
|
||||
#define ARRAY_VAL_CPY(FROMVAL, TOVAL) TOVAL = FROMVAL
|
||||
// compare values
|
||||
#define ARRAY_VAL_IFEQ(VAL1, VAL2) VAL1==VAL2
|
||||
#define ARRAY_VAL_IFLT(VAL1, VAL2) VAL1<VAL2
|
||||
#define ARRAY_VAL_IFGT(VAL1, VAL2) VAL1>VAL2
|
||||
|
54
src/array_str.h
Normal file
54
src/array_str.h
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
Copyright 2016 Ian Jauslin
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Preprocessor macros for string arrays
|
||||
*/
|
||||
|
||||
|
||||
// reset CPP macros
|
||||
#undef ARRAY_TYPENAME
|
||||
#undef ARRAY_FUNC
|
||||
#undef ARRAY_VAL_TYPE
|
||||
#undef ARRAY_VAL_FREE
|
||||
#undef ARRAY_VAL_SET
|
||||
#undef ARRAY_VAL_CPY
|
||||
#undef ARRAY_VAL_IFEQ
|
||||
#undef ARRAY_VAL_IFLT
|
||||
#undef ARRAY_VAL_IFGT
|
||||
#undef ARRAY_VAL_PRINT
|
||||
|
||||
|
||||
// name of the polynomial type
|
||||
#define ARRAY_TYPENAME array_str
|
||||
// prefix of function names
|
||||
#define ARRAY_FUNC(NAME) array_str_ ## NAME
|
||||
|
||||
// type of values
|
||||
#define ARRAY_VAL_TYPE array_char
|
||||
// free
|
||||
#define ARRAY_VAL_FREE(VAL) array_char_free(VAL)
|
||||
// set values
|
||||
#define ARRAY_VAL_SET(VAL, NEWVAL) VAL = NEWVAL
|
||||
// copy values
|
||||
#define ARRAY_VAL_CPY(FROMVAL, TOVAL) array_char_cpy(FROMVAL, &TOVAL)
|
||||
// compare values
|
||||
#define ARRAY_VAL_IFEQ(VAL1, VAL2) array_char_cmp(VAL1, VAL2)==0
|
||||
#define ARRAY_VAL_IFLT(VAL1, VAL2) array_char_cmp(VAL1, VAL2)<0
|
||||
#define ARRAY_VAL_IFGT(VAL1, VAL2) array_char_cmp(VAL1, VAL2)>0
|
||||
// print values
|
||||
#define ARRAY_VAL_PRINT(VAL) array_char_print(VAL)
|
||||
|
28
src/array_type.h
Normal file
28
src/array_type.h
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
Copyright 2016 Ian Jauslin
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Structure definition for arrays
|
||||
|
||||
see array_*.h for the values taken by ARRAY_TYPENAME, etc...
|
||||
*/
|
||||
|
||||
typedef struct ARRAY_TYPENAME {
|
||||
ARRAY_VAL_TYPE* values;
|
||||
unsigned int length;
|
||||
unsigned int memory;
|
||||
} ARRAY_TYPENAME;
|
||||
|
52
src/array_uint.h
Normal file
52
src/array_uint.h
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
Copyright 2016 Ian Jauslin
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Preprocessor macros for unsigned int arrays
|
||||
*/
|
||||
|
||||
|
||||
// reset CPP macros
|
||||
#undef ARRAY_TYPENAME
|
||||
#undef ARRAY_FUNC
|
||||
#undef ARRAY_VAL_TYPE
|
||||
#undef ARRAY_VAL_FREE
|
||||
#undef ARRAY_VAL_SET
|
||||
#undef ARRAY_VAL_CPY
|
||||
#undef ARRAY_VAL_IFEQ
|
||||
#undef ARRAY_VAL_IFLT
|
||||
#undef ARRAY_VAL_IFGT
|
||||
#undef ARRAY_VAL_PRINT
|
||||
|
||||
|
||||
// name of the polynomial type
|
||||
#define ARRAY_TYPENAME array_uint
|
||||
// prefix of function names
|
||||
#define ARRAY_FUNC(NAME) array_uint_ ## NAME
|
||||
|
||||
// type of values
|
||||
#define ARRAY_VAL_TYPE unsigned int
|
||||
// set values
|
||||
#define ARRAY_VAL_SET(VAL, NEWVAL) VAL = NEWVAL
|
||||
// copy values
|
||||
#define ARRAY_VAL_CPY(FROMVAL, TOVAL) TOVAL = FROMVAL
|
||||
// compare values
|
||||
#define ARRAY_VAL_IFEQ(VAL1, VAL2) VAL1==VAL2
|
||||
#define ARRAY_VAL_IFLT(VAL1, VAL2) VAL1<VAL2
|
||||
#define ARRAY_VAL_IFGT(VAL1, VAL2) VAL1>VAL2
|
||||
// print values
|
||||
#define ARRAY_VAL_PRINT(VAL) printf("%u",VAL)
|
||||
|
29
src/errors.h
Normal file
29
src/errors.h
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
Copyright 2016 Ian Jauslin
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef LIBINUM_ERRORS_H
|
||||
#define LIBINUM_ERRORS_H
|
||||
|
||||
// maximal number of iterations reached
|
||||
#define LIBINUM_ERROR_MAXITER -1
|
||||
// illegal memoru access
|
||||
#define LIBINUM_ERROR_ILLEGAL_MEMORY_ACCESS -2
|
||||
// size incompatibilities
|
||||
#define LIBINUM_ERROR_SIZE_MISMATCH -3
|
||||
// NaN or Inf
|
||||
#define LIBINUM_ERROR_NAN -4
|
||||
|
||||
#endif
|
52
src/integral.c
Normal file
52
src/integral.c
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
Copyright 2016 Ian Jauslin
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#include "integral.h"
|
||||
|
||||
#include <mpfr.h>
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include "root.h"
|
||||
#include "array.h"
|
||||
#include "polynomial.h"
|
||||
#include "errors.h"
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
//
|
||||
// using doubles
|
||||
//
|
||||
//--------------------------------------------------
|
||||
#include "integral_double.h"
|
||||
#include "integral_base.c"
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
//
|
||||
// using long doubles
|
||||
//
|
||||
//--------------------------------------------------
|
||||
#include "integral_ldouble.h"
|
||||
#include "integral_base.c"
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
//
|
||||
// using mpfr floats
|
||||
//
|
||||
//--------------------------------------------------
|
||||
#include "integral_mpfr.h"
|
||||
#include "integral_base.c"
|
53
src/integral.h
Normal file
53
src/integral.h
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
Copyright 2016 Ian Jauslin
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Integration of real functions
|
||||
*/
|
||||
|
||||
#ifndef LIBINUM_INTEGRAL_H
|
||||
#define LIBINUM_INTEGRAL_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
//
|
||||
// using doubles
|
||||
//
|
||||
//--------------------------------------------------
|
||||
#include "integral_double.h"
|
||||
#include "integral_base.h"
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
//
|
||||
// using long doubles
|
||||
//
|
||||
//--------------------------------------------------
|
||||
#include "integral_ldouble.h"
|
||||
#include "integral_base.h"
|
||||
|
||||
//--------------------------------------------------
|
||||
//
|
||||
// using mpfr floats
|
||||
//
|
||||
//--------------------------------------------------
|
||||
|
||||
#include "integral_mpfr.h"
|
||||
#include "integral_base.h"
|
||||
|
||||
#endif
|
506
src/integral_base.c
Normal file
506
src/integral_base.c
Normal file
@ -0,0 +1,506 @@
|
||||
/*
|
||||
Copyright 2016 Ian Jauslin
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Base functions for integration
|
||||
|
||||
see integral_*.h for the values taken by INTEGRAL_FUNC, etc...
|
||||
*/
|
||||
|
||||
|
||||
// compute the integral of a real function of 1 variable using the Gauss-Legendre scheme
|
||||
int INTEGRAL_FUNC(integrate_gauss) (INTEGRAL_FLOAT_TYPE* out, int (*func)(INTEGRAL_FLOAT_TYPE*, INTEGRAL_FLOAT_TYPE, void*), INTEGRAL_FLOAT_TYPE lower, INTEGRAL_FLOAT_TYPE upper, INTEGRAL_FLOATARRAY_TYPE abcissa, INTEGRAL_FLOATARRAY_TYPE weights, void* extra_args){
|
||||
unsigned int i;
|
||||
INTEGRAL_FLOAT_TYPE valf, delta, avg, x;
|
||||
int ret;
|
||||
|
||||
// check arguments
|
||||
if(abcissa.length != weights.length){
|
||||
return(LIBINUM_ERROR_SIZE_MISMATCH);
|
||||
}
|
||||
|
||||
#ifdef INTEGRAL_FLOAT_INIT
|
||||
INTEGRAL_FLOAT_INIT(valf);
|
||||
INTEGRAL_FLOAT_INIT(delta);
|
||||
INTEGRAL_FLOAT_INIT(avg);
|
||||
INTEGRAL_FLOAT_INIT(x);
|
||||
#endif
|
||||
|
||||
// init to 0
|
||||
INTEGRAL_FLOAT_SET_UI(*out, 0);
|
||||
|
||||
// half length of interval
|
||||
INTEGRAL_FLOAT_SUB(delta, upper, lower);
|
||||
INTEGRAL_FLOAT_DIV_UI(delta, delta, 2);
|
||||
// average of interval
|
||||
INTEGRAL_FLOAT_ADD(avg, upper, lower);
|
||||
INTEGRAL_FLOAT_DIV_UI(avg, avg, 2);
|
||||
|
||||
for(i=0;i<abcissa.length;i++){
|
||||
// evaluate at x
|
||||
INTEGRAL_FLOAT_MUL(x, delta, abcissa.values[i]);
|
||||
INTEGRAL_FLOAT_ADD(x, x, avg);
|
||||
|
||||
ret=(*func)(&valf, x, extra_args);
|
||||
if(ret<0){
|
||||
#ifdef INTEGRAL_FLOAT_FREE
|
||||
INTEGRAL_FLOAT_FREE(valf);
|
||||
INTEGRAL_FLOAT_FREE(delta);
|
||||
INTEGRAL_FLOAT_FREE(avg);
|
||||
INTEGRAL_FLOAT_FREE(x);
|
||||
#endif
|
||||
return(ret);
|
||||
}
|
||||
// check whether valf is a number
|
||||
if(! INTEGRAL_FLOAT_ISNUMBER(valf)){
|
||||
#ifdef INTEGRAL_FLOAT_FREE
|
||||
INTEGRAL_FLOAT_FREE(valf);
|
||||
INTEGRAL_FLOAT_FREE(delta);
|
||||
INTEGRAL_FLOAT_FREE(avg);
|
||||
INTEGRAL_FLOAT_FREE(x);
|
||||
#endif
|
||||
return(LIBINUM_ERROR_NAN);
|
||||
}
|
||||
|
||||
INTEGRAL_FLOAT_MUL(valf, valf, weights.values[i]);
|
||||
INTEGRAL_FLOAT_ADD(*out, *out, valf);
|
||||
}
|
||||
|
||||
INTEGRAL_FLOAT_MUL(*out, *out, delta);
|
||||
|
||||
#ifdef INTEGRAL_FLOAT_FREE
|
||||
INTEGRAL_FLOAT_FREE(valf);
|
||||
INTEGRAL_FLOAT_FREE(delta);
|
||||
INTEGRAL_FLOAT_FREE(avg);
|
||||
INTEGRAL_FLOAT_FREE(x);
|
||||
#endif
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
// multithreaded version
|
||||
// arguments to pass to each thread
|
||||
struct INTEGRAL_FUNC(pthread_integrate_gauss_args) {
|
||||
// partial sum of the values assigned to the thread
|
||||
INTEGRAL_FLOAT_TYPE out;
|
||||
// abcissa
|
||||
INTEGRAL_FLOATARRAY_TYPE x;
|
||||
// weights
|
||||
INTEGRAL_FLOATARRAY_TYPE weights;
|
||||
// pointer to the function to evaluate
|
||||
int (*func)(INTEGRAL_FLOAT_TYPE*, INTEGRAL_FLOAT_TYPE, void*);
|
||||
// extra arguments passed to func
|
||||
void* extra_args;
|
||||
// return value
|
||||
int ret;
|
||||
};
|
||||
int INTEGRAL_FUNC(integrate_gauss_multithread) (INTEGRAL_FLOAT_TYPE* out, int (*func)(INTEGRAL_FLOAT_TYPE*, INTEGRAL_FLOAT_TYPE, void*), INTEGRAL_FLOAT_TYPE lower, INTEGRAL_FLOAT_TYPE upper, INTEGRAL_FLOATARRAY_TYPE abcissa, INTEGRAL_FLOATARRAY_TYPE weights, void* extra_args, unsigned int threads, array_pthread_t* thread_ids){
|
||||
unsigned int i;
|
||||
INTEGRAL_FLOAT_TYPE x, delta, avg;
|
||||
struct INTEGRAL_FUNC(pthread_integrate_gauss_args) args[threads];
|
||||
int ret=0;
|
||||
unsigned int thread_nr;
|
||||
|
||||
array_pthread_t_init(thread_ids, threads);
|
||||
thread_ids->length=threads;
|
||||
|
||||
// check arguments
|
||||
if(abcissa.length != weights.length){
|
||||
return(LIBINUM_ERROR_SIZE_MISMATCH);
|
||||
}
|
||||
|
||||
#ifdef INTEGRAL_FLOAT_INIT
|
||||
INTEGRAL_FLOAT_INIT(delta);
|
||||
INTEGRAL_FLOAT_INIT(avg);
|
||||
INTEGRAL_FLOAT_INIT(x);
|
||||
#endif
|
||||
|
||||
// init to 0
|
||||
INTEGRAL_FLOAT_SET_UI(*out, 0);
|
||||
|
||||
// half length of interval
|
||||
INTEGRAL_FLOAT_SUB(delta, upper, lower);
|
||||
INTEGRAL_FLOAT_DIV_UI(delta, delta, 2);
|
||||
// average of interval
|
||||
INTEGRAL_FLOAT_ADD(avg, upper, lower);
|
||||
INTEGRAL_FLOAT_DIV_UI(avg, avg, 2);
|
||||
|
||||
// inits
|
||||
for(thread_nr=0;thread_nr<threads;thread_nr++){
|
||||
INTEGRAL_FLOATARRAY_FUNC(init) (&(args[thread_nr].x),abcissa.length/threads+1);
|
||||
INTEGRAL_FLOATARRAY_FUNC(init) (&(args[thread_nr].weights),abcissa.length/threads+1);
|
||||
#ifdef INTEGRAL_FLOAT_INIT
|
||||
INTEGRAL_FLOAT_INIT(args[thread_nr].out);
|
||||
#endif
|
||||
}
|
||||
|
||||
// set abcissa and weights
|
||||
for(i=0,thread_nr=0;i<abcissa.length;i++,thread_nr=(thread_nr+1)%threads){
|
||||
INTEGRAL_FLOAT_MUL(x, delta, abcissa.values[i]);
|
||||
INTEGRAL_FLOAT_ADD(x, x, avg);
|
||||
|
||||
INTEGRAL_FLOATARRAY_FUNC(append) (x, &(args[thread_nr].x));
|
||||
INTEGRAL_FLOATARRAY_FUNC(append) (weights.values[i], &(args[thread_nr].weights));
|
||||
}
|
||||
|
||||
for(thread_nr=0;thread_nr<threads;thread_nr++){
|
||||
// set func
|
||||
args[thread_nr].func=func;
|
||||
// set extra_args
|
||||
args[thread_nr].extra_args=extra_args;
|
||||
// init ret
|
||||
args[thread_nr].ret=0;
|
||||
// run threads
|
||||
pthread_create(thread_ids->values+thread_nr, NULL, INTEGRAL_FUNC(integrate_gauss_thread), (void*)(args+thread_nr));
|
||||
}
|
||||
|
||||
// wait for completion and join
|
||||
for(thread_nr=0;thread_nr<threads;thread_nr++){
|
||||
pthread_join(thread_ids->values[thread_nr], NULL);
|
||||
|
||||
if(args[thread_nr].ret<0){
|
||||
ret=args[thread_nr].ret;
|
||||
}
|
||||
else{
|
||||
INTEGRAL_FLOAT_ADD(*out, *out, args[thread_nr].out);
|
||||
}
|
||||
}
|
||||
|
||||
// multiply by size of interval
|
||||
INTEGRAL_FLOAT_MUL(*out, *out, delta);
|
||||
|
||||
for(thread_nr=0;thread_nr<threads;thread_nr++){
|
||||
INTEGRAL_FLOATARRAY_FUNC(free) (args[thread_nr].x);
|
||||
INTEGRAL_FLOATARRAY_FUNC(free) (args[thread_nr].weights);
|
||||
#ifdef INTEGRAL_FLOAT_FREE
|
||||
INTEGRAL_FLOAT_FREE(args[thread_nr].out);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef INTEGRAL_FLOAT_FREE
|
||||
INTEGRAL_FLOAT_FREE(delta);
|
||||
INTEGRAL_FLOAT_FREE(avg);
|
||||
INTEGRAL_FLOAT_FREE(x);
|
||||
#endif
|
||||
|
||||
|
||||
return(ret);
|
||||
}
|
||||
// per-thread function
|
||||
void* INTEGRAL_FUNC(integrate_gauss_thread) (void* args){
|
||||
unsigned int i;
|
||||
INTEGRAL_FLOAT_TYPE valf;
|
||||
int ret;
|
||||
struct INTEGRAL_FUNC(pthread_integrate_gauss_args)* argument=((struct INTEGRAL_FUNC(pthread_integrate_gauss_args)*)args);
|
||||
#ifdef INTEGRAL_FLOAT_INIT
|
||||
INTEGRAL_FLOAT_INIT(valf);
|
||||
#endif
|
||||
|
||||
INTEGRAL_FLOAT_SET_UI(argument->out, 0);
|
||||
|
||||
for(i=0;i<argument->x.length;i++){
|
||||
// evaluate
|
||||
ret=(*(argument->func))(&valf, argument->x.values[i], argument->extra_args);
|
||||
|
||||
if(ret<0){
|
||||
#ifdef INTEGRAL_FLOAT_FREE
|
||||
INTEGRAL_FLOAT_FREE(valf);
|
||||
#endif
|
||||
argument->ret=ret;
|
||||
return(NULL);
|
||||
}
|
||||
// check whether valf is a number
|
||||
if(! INTEGRAL_FLOAT_ISNUMBER(valf)){
|
||||
#ifdef INTEGRAL_FLOAT_FREE
|
||||
INTEGRAL_FLOAT_FREE(valf);
|
||||
#endif
|
||||
argument->ret=LIBINUM_ERROR_NAN;
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
INTEGRAL_FLOAT_MUL(valf, valf, argument->weights.values[i]);
|
||||
INTEGRAL_FLOAT_ADD(argument->out, argument->out, valf);
|
||||
}
|
||||
#ifdef INTEGRAL_FLOAT_FREE
|
||||
INTEGRAL_FLOAT_FREE(valf);
|
||||
#endif
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// smart management of temporary variables: initialize as many as needed but allow them to be re-used instead of freeing them
|
||||
#ifdef INTEGRAL_FLOAT_INIT
|
||||
int INTEGRAL_FUNC(integrate_gauss_smarttmp) (INTEGRAL_FLOAT_TYPE* out, int (*func)(INTEGRAL_FLOAT_TYPE*, INTEGRAL_FLOAT_TYPE, void*), INTEGRAL_FLOAT_TYPE lower, INTEGRAL_FLOAT_TYPE upper, INTEGRAL_FLOATARRAY_TYPE abcissa, INTEGRAL_FLOATARRAY_TYPE weights, INTEGRAL_FLOATARRAY_TYPE* tmps, void* extra_args){
|
||||
unsigned int i;
|
||||
int ret;
|
||||
|
||||
// check arguments
|
||||
if(abcissa.length != weights.length){
|
||||
return(LIBINUM_ERROR_SIZE_MISMATCH);
|
||||
}
|
||||
|
||||
// allocate tmps if needed
|
||||
if(tmps->memory<4){
|
||||
// no need to resize since the values should not be kept
|
||||
INTEGRAL_FLOATARRAY_FUNC(free)(*tmps);
|
||||
INTEGRAL_FLOATARRAY_FUNC(init)(tmps, 4);
|
||||
}
|
||||
for (i=tmps->length;i<4;i++){
|
||||
INTEGRAL_FLOAT_INIT(tmps->values[i]);
|
||||
(tmps->length)++;
|
||||
}
|
||||
|
||||
// init to 0
|
||||
INTEGRAL_FLOAT_SET_UI(*out, 0);
|
||||
|
||||
// half length of interval
|
||||
INTEGRAL_FLOAT_SUB(tmps->values[0], upper, lower);
|
||||
INTEGRAL_FLOAT_DIV_UI(tmps->values[0], tmps->values[0], 2);
|
||||
// average of interval
|
||||
INTEGRAL_FLOAT_ADD(tmps->values[1], upper, lower);
|
||||
INTEGRAL_FLOAT_DIV_UI(tmps->values[1], tmps->values[1], 2);
|
||||
|
||||
for(i=0;i<abcissa.length;i++){
|
||||
// evaluation point
|
||||
INTEGRAL_FLOAT_MUL(tmps->values[2], tmps->values[0], abcissa.values[i]);
|
||||
INTEGRAL_FLOAT_ADD(tmps->values[2], tmps->values[2], tmps->values[1]);
|
||||
|
||||
ret=(*func)(tmps->values+3, tmps->values[2], extra_args);
|
||||
if(ret<0){
|
||||
return(ret);
|
||||
}
|
||||
// check whether tmps->values[3] is a number
|
||||
if(! INTEGRAL_FLOAT_ISNUMBER(tmps->values[3])){
|
||||
return(LIBINUM_ERROR_NAN);
|
||||
}
|
||||
|
||||
INTEGRAL_FLOAT_MUL(tmps->values[3], tmps->values[3], weights.values[i]);
|
||||
INTEGRAL_FLOAT_ADD(*out, *out, tmps->values[3]);
|
||||
}
|
||||
|
||||
INTEGRAL_FLOAT_MUL(*out, *out, tmps->values[0]);
|
||||
|
||||
return(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
// multithreaded version with smart management of temporary variables (only for datatypes that need to be initialized)
|
||||
#ifdef INTEGRAL_FLOAT_INIT
|
||||
// arguments to pass to each thread
|
||||
struct INTEGRAL_FUNC(pthread_integrate_gauss_smarttmp_args) {
|
||||
// partial sum of the values assigned to the thread
|
||||
INTEGRAL_FLOAT_TYPE* out;
|
||||
// abcissa
|
||||
INTEGRAL_FLOATARRAY_TYPE x;
|
||||
// weights
|
||||
INTEGRAL_FLOATARRAY_TYPE weights;
|
||||
// tmp
|
||||
INTEGRAL_FLOAT_TYPE* tmp;
|
||||
// pointer to the function to evaluate
|
||||
int (*func)(INTEGRAL_FLOAT_TYPE*, INTEGRAL_FLOAT_TYPE, void*);
|
||||
// extra arguments passed to func
|
||||
void* extra_args;
|
||||
// return value
|
||||
int ret;
|
||||
};
|
||||
int INTEGRAL_FUNC(integrate_gauss_smarttmp_multithread) (INTEGRAL_FLOAT_TYPE* out, int (*func)(INTEGRAL_FLOAT_TYPE*, INTEGRAL_FLOAT_TYPE, void*), INTEGRAL_FLOAT_TYPE lower, INTEGRAL_FLOAT_TYPE upper, INTEGRAL_FLOATARRAY_TYPE abcissa, INTEGRAL_FLOATARRAY_TYPE weights, INTEGRAL_FLOATARRAY_TYPE* tmps, void* extra_args, unsigned int threads, array_pthread_t* thread_ids){
|
||||
unsigned int i;
|
||||
struct INTEGRAL_FUNC(pthread_integrate_gauss_smarttmp_args) args[threads];
|
||||
int ret=0;
|
||||
unsigned int thread_nr;
|
||||
|
||||
array_pthread_t_init(thread_ids, threads);
|
||||
thread_ids->length=threads;
|
||||
|
||||
// check arguments
|
||||
if(abcissa.length != weights.length){
|
||||
return(LIBINUM_ERROR_SIZE_MISMATCH);
|
||||
}
|
||||
|
||||
// allocate tmps if needed
|
||||
if(tmps->memory<2+2*threads+abcissa.length){
|
||||
// no need to resize since the values should not be kept
|
||||
INTEGRAL_FLOATARRAY_FUNC(free)(*tmps);
|
||||
INTEGRAL_FLOATARRAY_FUNC(init)(tmps, 2+2*threads+abcissa.length);
|
||||
}
|
||||
for (i=tmps->length;i<2+2*threads+abcissa.length;i++){
|
||||
INTEGRAL_FLOAT_INIT(tmps->values[i]);
|
||||
(tmps->length)++;
|
||||
}
|
||||
|
||||
|
||||
// init to 0
|
||||
INTEGRAL_FLOAT_SET_UI(*out, 0);
|
||||
|
||||
// half length of interval
|
||||
INTEGRAL_FLOAT_SUB(tmps->values[0], upper, lower);
|
||||
INTEGRAL_FLOAT_DIV_UI(tmps->values[0], tmps->values[0], 2);
|
||||
// average of interval
|
||||
INTEGRAL_FLOAT_ADD(tmps->values[1], upper, lower);
|
||||
INTEGRAL_FLOAT_DIV_UI(tmps->values[1], tmps->values[1], 2);
|
||||
|
||||
// inits
|
||||
for(thread_nr=0;thread_nr<threads;thread_nr++){
|
||||
INTEGRAL_FLOATARRAY_FUNC(init) (&(args[thread_nr].x),abcissa.length/threads+1);
|
||||
INTEGRAL_FLOATARRAY_FUNC(init) (&(args[thread_nr].weights),abcissa.length/threads+1);
|
||||
args[thread_nr].out=tmps->values+2+thread_nr;
|
||||
args[thread_nr].tmp=tmps->values+2+threads+thread_nr;
|
||||
}
|
||||
|
||||
// set abcissa and weights
|
||||
for(i=0,thread_nr=0;i<abcissa.length;i++,thread_nr=(thread_nr+1)%threads){
|
||||
INTEGRAL_FLOAT_MUL(tmps->values[2+2*threads+i], tmps->values[0], abcissa.values[i]);
|
||||
INTEGRAL_FLOAT_ADD(tmps->values[2+2*threads+i], tmps->values[2+2*threads+i], tmps->values[1]);
|
||||
|
||||
INTEGRAL_FLOATARRAY_FUNC(append_noinit) (tmps->values[2+2*threads+i], &(args[thread_nr].x));
|
||||
INTEGRAL_FLOATARRAY_FUNC(append_noinit) (weights.values[i], &(args[thread_nr].weights));
|
||||
}
|
||||
|
||||
for(thread_nr=0;thread_nr<threads;thread_nr++){
|
||||
// set func
|
||||
args[thread_nr].func=func;
|
||||
// set extra_args
|
||||
args[thread_nr].extra_args=extra_args;
|
||||
// init ret
|
||||
args[thread_nr].ret=0;
|
||||
// run threads
|
||||
pthread_create(thread_ids->values+thread_nr, NULL, INTEGRAL_FUNC(integrate_gauss_smarttmp_thread), (void*)(args+thread_nr));
|
||||
}
|
||||
|
||||
// wait for completion and join
|
||||
for(thread_nr=0;thread_nr<threads;thread_nr++){
|
||||
pthread_join(thread_ids->values[thread_nr], NULL);
|
||||
|
||||
if(args[thread_nr].ret<0){
|
||||
ret=args[thread_nr].ret;
|
||||
}
|
||||
else{
|
||||
INTEGRAL_FLOAT_ADD(*out, *out, *(args[thread_nr].out));
|
||||
}
|
||||
}
|
||||
|
||||
// multiply by size of interval
|
||||
INTEGRAL_FLOAT_MUL(*out, *out, tmps->values[0]);
|
||||
|
||||
// free x and weights
|
||||
for(thread_nr=0;thread_nr<threads;thread_nr++){
|
||||
INTEGRAL_FLOATARRAY_FUNC(free_vects)(args[thread_nr].x);
|
||||
INTEGRAL_FLOATARRAY_FUNC(free_vects)(args[thread_nr].weights);
|
||||
}
|
||||
return(ret);
|
||||
}
|
||||
// per-thread function
|
||||
void* INTEGRAL_FUNC(integrate_gauss_smarttmp_thread) (void* args){
|
||||
unsigned int i;
|
||||
int ret;
|
||||
struct INTEGRAL_FUNC(pthread_integrate_gauss_smarttmp_args)* argument=((struct INTEGRAL_FUNC(pthread_integrate_gauss_smarttmp_args)*)args);
|
||||
|
||||
INTEGRAL_FLOAT_SET_UI(*(argument->out), 0);
|
||||
|
||||
for(i=0;i<argument->x.length;i++){
|
||||
// evaluate
|
||||
ret=(*(argument->func))(argument->tmp, argument->x.values[i], argument->extra_args);
|
||||
|
||||
if(ret<0){
|
||||
argument->ret=ret;
|
||||
return(NULL);
|
||||
}
|
||||
// check whether argument->tmp is a number
|
||||
if(! INTEGRAL_FLOAT_ISNUMBER(*(argument->tmp))){
|
||||
argument->ret=LIBINUM_ERROR_NAN;
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
INTEGRAL_FLOAT_MUL(*(argument->tmp), *(argument->tmp), argument->weights.values[i]);
|
||||
INTEGRAL_FLOAT_ADD(*(argument->out), *(argument->out), *(argument->tmp));
|
||||
}
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// compute the abcissa and weights for the Gauss-Legendre numerical integration scheme
|
||||
int INTEGRAL_FUNC(gauss_legendre_weights) (unsigned int order, INTEGRAL_FLOAT_TYPE tolerance, unsigned int maxiter, INTEGRAL_FLOATARRAY_TYPE* abcissa, INTEGRAL_FLOATARRAY_TYPE* weights){
|
||||
unsigned int i;
|
||||
INTEGRAL_FLOAT_TYPE x, tmp;
|
||||
INTEGRAL_POLYNOMIALARRAY_TYPE legendre;
|
||||
int ret;
|
||||
|
||||
INTEGRAL_FLOATARRAY_FUNC(init) (abcissa, order);
|
||||
INTEGRAL_FLOATARRAY_FUNC(init) (weights, order);
|
||||
|
||||
#ifdef INTEGRAL_FLOAT_INIT
|
||||
INTEGRAL_FLOAT_INIT(x);
|
||||
INTEGRAL_FLOAT_INIT(tmp);
|
||||
#endif
|
||||
|
||||
INTEGRAL_POLYNOMIALARRAY_FUNC(init) (&legendre, 2);
|
||||
// compute the roots of the 'order'-th Legendre polynomial
|
||||
INTEGRAL_POLYNOMIAL_FUNC(legendre) (order, legendre.values);
|
||||
INTEGRAL_POLYNOMIAL_FUNC(derive) (legendre.values[0], legendre.values+1);
|
||||
legendre.length=2;
|
||||
|
||||
for(i=0;i<order;i++){
|
||||
// initial guess
|
||||
INTEGRAL_FLOAT_SET_D(x, cos(3.1415926*(i+0.75)/(order+0.5)));
|
||||
ret=INTEGRAL_FUNC(root_newton_inplace) (&x, &INTEGRAL_FUNC(legendre_wrapper), &INTEGRAL_FUNC(deriv_legendre_wrapper), tolerance, maxiter, &legendre);
|
||||
|
||||
if(ret<0){
|
||||
#ifdef INTEGRAL_FLOAT_FREE
|
||||
INTEGRAL_FLOAT_FREE(x);
|
||||
INTEGRAL_FLOAT_FREE(tmp);
|
||||
#endif
|
||||
INTEGRAL_POLYNOMIALARRAY_FUNC(free) (legendre);
|
||||
INTEGRAL_FLOATARRAY_FUNC(free) (*abcissa);
|
||||
INTEGRAL_FLOATARRAY_FUNC(free) (*weights);
|
||||
return(ret);
|
||||
}
|
||||
|
||||
INTEGRAL_FLOATARRAY_FUNC(append) (x, abcissa);
|
||||
|
||||
// weight: 2/((1-x^2)*(deriv_Legendre(x)))^2
|
||||
INTEGRAL_POLYNOMIAL_FUNC(evaluate) (&tmp, x, legendre.values[1]);
|
||||
INTEGRAL_FLOAT_POW_UI(tmp, tmp, 2);
|
||||
INTEGRAL_FLOAT_POW_UI(x, x, 2);
|
||||
INTEGRAL_FLOAT_UI_SUB(x, 1, x);
|
||||
INTEGRAL_FLOAT_MUL(x, x, tmp);
|
||||
INTEGRAL_FLOAT_SET_UI(tmp, 2);
|
||||
INTEGRAL_FLOAT_DIV(x, tmp, x);
|
||||
|
||||
INTEGRAL_FLOATARRAY_FUNC(append) (x, weights);
|
||||
}
|
||||
|
||||
#ifdef INTEGRAL_FLOAT_FREE
|
||||
INTEGRAL_FLOAT_FREE(x);
|
||||
INTEGRAL_FLOAT_FREE(tmp);
|
||||
#endif
|
||||
INTEGRAL_POLYNOMIALARRAY_FUNC(free) (legendre);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
// wrapper functions to evaluate the legendre polynomial and its derivative
|
||||
int INTEGRAL_FUNC(legendre_wrapper) (INTEGRAL_FLOAT_TYPE* out, INTEGRAL_FLOAT_TYPE in, void* legendre){
|
||||
INTEGRAL_POLYNOMIAL_FUNC(evaluate) (out, in, ((INTEGRAL_POLYNOMIALARRAY_TYPE*)legendre)->values[0]);
|
||||
return(0);
|
||||
}
|
||||
int INTEGRAL_FUNC(deriv_legendre_wrapper) (INTEGRAL_FLOAT_TYPE* out, INTEGRAL_FLOAT_TYPE in, void* legendre){
|
||||
INTEGRAL_POLYNOMIAL_FUNC(evaluate) (out, in, ((INTEGRAL_POLYNOMIALARRAY_TYPE*)legendre)->values[1]);
|
||||
return(0);
|
||||
}
|
48
src/integral_base.h
Normal file
48
src/integral_base.h
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
Copyright 2016 Ian Jauslin
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Base functions for integration
|
||||
|
||||
see integral_*.h for the values taken by INTEGRAL_FUNC, etc...
|
||||
*/
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
// compute the integral of a real function of 1 variable using the Gauss-Legendre scheme
|
||||
int INTEGRAL_FUNC(integrate_gauss) (INTEGRAL_FLOAT_TYPE* out, int (*func)(INTEGRAL_FLOAT_TYPE*, INTEGRAL_FLOAT_TYPE, void*), INTEGRAL_FLOAT_TYPE lower, INTEGRAL_FLOAT_TYPE upper, INTEGRAL_FLOATARRAY_TYPE abcissa, INTEGRAL_FLOATARRAY_TYPE weights, void* extra_args);
|
||||
|
||||
// multithreaded version
|
||||
int INTEGRAL_FUNC(integrate_gauss_multithread) (INTEGRAL_FLOAT_TYPE* out, int (*func)(INTEGRAL_FLOAT_TYPE*, INTEGRAL_FLOAT_TYPE, void*), INTEGRAL_FLOAT_TYPE lower, INTEGRAL_FLOAT_TYPE upper, INTEGRAL_FLOATARRAY_TYPE abcissa, INTEGRAL_FLOATARRAY_TYPE weights, void* extra_args, unsigned int threads, array_pthread_t* thread_ids);
|
||||
// per-thread function
|
||||
void* INTEGRAL_FUNC(integrate_gauss_thread) (void* args);
|
||||
|
||||
// smart management of temporary variables: initialize as many as needed but allow them to be re-used instead of freeing them
|
||||
#ifdef INTEGRAL_FLOAT_INIT
|
||||
int INTEGRAL_FUNC(integrate_gauss_smarttmp) (INTEGRAL_FLOAT_TYPE* out, int (*func)(INTEGRAL_FLOAT_TYPE*, INTEGRAL_FLOAT_TYPE, void*), INTEGRAL_FLOAT_TYPE lower, INTEGRAL_FLOAT_TYPE upper, INTEGRAL_FLOATARRAY_TYPE abcissa, INTEGRAL_FLOATARRAY_TYPE weights, INTEGRAL_FLOATARRAY_TYPE* tmps, void* extra_args);
|
||||
// multithreaded version with smart management of temporary variables (only for datatypes that need to be initialized)
|
||||
int INTEGRAL_FUNC(integrate_gauss_smarttmp_multithread) (INTEGRAL_FLOAT_TYPE* out, int (*func)(INTEGRAL_FLOAT_TYPE*, INTEGRAL_FLOAT_TYPE, void*), INTEGRAL_FLOAT_TYPE lower, INTEGRAL_FLOAT_TYPE upper, INTEGRAL_FLOATARRAY_TYPE abcissa, INTEGRAL_FLOATARRAY_TYPE weights, INTEGRAL_FLOATARRAY_TYPE* tmps, void* extra_args, unsigned int threads, array_pthread_t* thread_ids);
|
||||
// per-thread function
|
||||
void* INTEGRAL_FUNC(integrate_gauss_smarttmp_thread) (void* args);
|
||||
#endif
|
||||
|
||||
// compute the abcissa and weights for the Gauss-Legendre numerical integration scheme
|
||||
int INTEGRAL_FUNC(gauss_legendre_weights) (unsigned int order, INTEGRAL_FLOAT_TYPE tolerance, unsigned int maxiter, INTEGRAL_FLOATARRAY_TYPE* abcissa, INTEGRAL_FLOATARRAY_TYPE* weights);
|
||||
|
||||
// wrapper functions to evaluate the legendre polynomial and its derivative
|
||||
int INTEGRAL_FUNC(legendre_wrapper) (INTEGRAL_FLOAT_TYPE* out, INTEGRAL_FLOAT_TYPE in, void* legendre);
|
||||
int INTEGRAL_FUNC(deriv_legendre_wrapper) (INTEGRAL_FLOAT_TYPE* out, INTEGRAL_FLOAT_TYPE in, void* legendre);
|
||||
|
81
src/integral_double.h
Normal file
81
src/integral_double.h
Normal file
@ -0,0 +1,81 @@
|
||||
/*
|
||||
Copyright 2016 Ian Jauslin
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Preprocessor macros for integration using with doubles
|
||||
*/
|
||||
|
||||
|
||||
// reset CPP macros
|
||||
#undef INTEGRAL_FUNC
|
||||
#undef INTEGRAL_FLOAT_TYPE
|
||||
#undef INTEGRAL_FLOAT_INIT
|
||||
#undef INTEGRAL_FLOAT_FREE
|
||||
#undef INTEGRAL_FLOAT_SET_D
|
||||
#undef INTEGRAL_FLOAT_SET_UI
|
||||
#undef INTEGRAL_FLOAT_ADD
|
||||
#undef INTEGRAL_FLOAT_SUB
|
||||
#undef INTEGRAL_FLOAT_UI_SUB
|
||||
#undef INTEGRAL_FLOAT_MUL
|
||||
#undef INTEGRAL_FLOAT_POW_UI
|
||||
#undef INTEGRAL_FLOAT_DIV
|
||||
#undef INTEGRAL_FLOAT_DIV_UI
|
||||
#undef INTEGRAL_FLOAT_ISNUMBER
|
||||
#undef INTEGRAL_FLOATARRAY_TYPE
|
||||
#undef INTEGRAL_FLOATARRAY_FUNC
|
||||
#undef INTEGRAL_POLYNOMIAL_FUNC
|
||||
#undef INTEGRAL_POLYNOMIALARRAY_TYPE
|
||||
#undef INTEGRAL_POLYNOMIALARRAY_FUNC
|
||||
|
||||
// suffix of function names
|
||||
#define INTEGRAL_FUNC(NAME) NAME ## _double
|
||||
|
||||
// type of floats
|
||||
#define INTEGRAL_FLOAT_TYPE double
|
||||
// set float from double
|
||||
#define INTEGRAL_FLOAT_SET_D(FLOAT, VAL) FLOAT=VAL
|
||||
// set float from unsigned int
|
||||
#define INTEGRAL_FLOAT_SET_UI(FLOAT, VAL) FLOAT=(double)VAL
|
||||
// add floats
|
||||
#define INTEGRAL_FLOAT_ADD(FLOAT, VAL1, VAL2) FLOAT=VAL1+VAL2
|
||||
// subtract floats
|
||||
#define INTEGRAL_FLOAT_SUB(FLOAT, VAL1, VAL2) FLOAT=VAL1-VAL2
|
||||
// subtract floats in which the first is specified as an unsigned int
|
||||
#define INTEGRAL_FLOAT_UI_SUB(FLOAT, VAL1, VAL2) FLOAT=(double)VAL1-VAL2
|
||||
// multiply floats
|
||||
#define INTEGRAL_FLOAT_MUL(FLOAT, VAL1, VAL2) FLOAT=VAL1*VAL2
|
||||
// power of a float, specified as an unsigned int
|
||||
#define INTEGRAL_FLOAT_POW_UI(FLOAT, VAL1, VAL2) FLOAT=pow(VAL1, (double)VAL2)
|
||||
// divide floats
|
||||
#define INTEGRAL_FLOAT_DIV(FLOAT, VAL1, VAL2) FLOAT=VAL1/VAL2
|
||||
// divide floats, one of which is specified as an unsigned int
|
||||
#define INTEGRAL_FLOAT_DIV_UI(FLOAT, VAL1, VAL2) FLOAT=VAL1/(double)VAL2
|
||||
// check whether a float is a regular number
|
||||
#define INTEGRAL_FLOAT_ISNUMBER(FLOAT) (fpclassify(FLOAT)>=FP_ZERO)
|
||||
|
||||
// type of float arrays
|
||||
#define INTEGRAL_FLOATARRAY_TYPE array_double
|
||||
// prefix of float array function names
|
||||
#define INTEGRAL_FLOATARRAY_FUNC(NAME) array_double_ ## NAME
|
||||
|
||||
// prefix of polynomial function names
|
||||
#define INTEGRAL_POLYNOMIAL_FUNC(NAME) polynomial_double_ ## NAME
|
||||
|
||||
// type of polynomial arrays
|
||||
#define INTEGRAL_POLYNOMIALARRAY_TYPE array_polynomial_double
|
||||
// prefix of polynomial array function names
|
||||
#define INTEGRAL_POLYNOMIALARRAY_FUNC(NAME) array_polynomial_double_ ## NAME
|
||||
|
81
src/integral_ldouble.h
Normal file
81
src/integral_ldouble.h
Normal file
@ -0,0 +1,81 @@
|
||||
/*
|
||||
Copyright 2016 Ian Jauslin
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Preprocessor macros for integration using with long doubles
|
||||
*/
|
||||
|
||||
|
||||
// reset CPP macros
|
||||
#undef INTEGRAL_FUNC
|
||||
#undef INTEGRAL_FLOAT_TYPE
|
||||
#undef INTEGRAL_FLOAT_INIT
|
||||
#undef INTEGRAL_FLOAT_FREE
|
||||
#undef INTEGRAL_FLOAT_SET_D
|
||||
#undef INTEGRAL_FLOAT_SET_UI
|
||||
#undef INTEGRAL_FLOAT_ADD
|
||||
#undef INTEGRAL_FLOAT_SUB
|
||||
#undef INTEGRAL_FLOAT_UI_SUB
|
||||
#undef INTEGRAL_FLOAT_MUL
|
||||
#undef INTEGRAL_FLOAT_POW_UI
|
||||
#undef INTEGRAL_FLOAT_DIV
|
||||
#undef INTEGRAL_FLOAT_DIV_UI
|
||||
#undef INTEGRAL_FLOAT_ISNUMBER
|
||||
#undef INTEGRAL_FLOATARRAY_TYPE
|
||||
#undef INTEGRAL_FLOATARRAY_FUNC
|
||||
#undef INTEGRAL_POLYNOMIAL_FUNC
|
||||
#undef INTEGRAL_POLYNOMIALARRAY_TYPE
|
||||
#undef INTEGRAL_POLYNOMIALARRAY_FUNC
|
||||
|
||||
// suffix of function names
|
||||
#define INTEGRAL_FUNC(NAME) NAME ## _ldouble
|
||||
|
||||
// type of floats
|
||||
#define INTEGRAL_FLOAT_TYPE long double
|
||||
// set float from double
|
||||
#define INTEGRAL_FLOAT_SET_D(FLOAT, VAL) FLOAT=(long double)VAL
|
||||
// set float from unsigned int
|
||||
#define INTEGRAL_FLOAT_SET_UI(FLOAT, VAL) FLOAT=(long double)VAL
|
||||
// add floats
|
||||
#define INTEGRAL_FLOAT_ADD(FLOAT, VAL1, VAL2) FLOAT=VAL1+VAL2
|
||||
// subtract floats
|
||||
#define INTEGRAL_FLOAT_SUB(FLOAT, VAL1, VAL2) FLOAT=VAL1-VAL2
|
||||
// subtract floats in which the first is specified as an unsigned int
|
||||
#define INTEGRAL_FLOAT_UI_SUB(FLOAT, VAL1, VAL2) FLOAT=(long double)VAL1-VAL2
|
||||
// multiply floats
|
||||
#define INTEGRAL_FLOAT_MUL(FLOAT, VAL1, VAL2) FLOAT=VAL1*VAL2
|
||||
// power of a float, specified as an unsigned int
|
||||
#define INTEGRAL_FLOAT_POW_UI(FLOAT, VAL1, VAL2) FLOAT=powl(VAL1, (long double)VAL2)
|
||||
// divide floats
|
||||
#define INTEGRAL_FLOAT_DIV(FLOAT, VAL1, VAL2) FLOAT=VAL1/VAL2
|
||||
// divide floats, one of which is specified as an unsigned int
|
||||
#define INTEGRAL_FLOAT_DIV_UI(FLOAT, VAL1, VAL2) FLOAT=VAL1/(long double)VAL2
|
||||
// check whether a float is a regular number
|
||||
#define INTEGRAL_FLOAT_ISNUMBER(FLOAT) (fpclassify(FLOAT)>=FP_ZERO)
|
||||
|
||||
// type of float arrays
|
||||
#define INTEGRAL_FLOATARRAY_TYPE array_ldouble
|
||||
// prefix of float array function names
|
||||
#define INTEGRAL_FLOATARRAY_FUNC(NAME) array_ldouble_ ## NAME
|
||||
|
||||
// prefix of polynomial function names
|
||||
#define INTEGRAL_POLYNOMIAL_FUNC(NAME) polynomial_ldouble_ ## NAME
|
||||
|
||||
// type of polynomial arrays
|
||||
#define INTEGRAL_POLYNOMIALARRAY_TYPE array_polynomial_ldouble
|
||||
// prefix of polynomial array function names
|
||||
#define INTEGRAL_POLYNOMIALARRAY_FUNC(NAME) array_polynomial_ldouble_ ## NAME
|
||||
|
84
src/integral_mpfr.h
Normal file
84
src/integral_mpfr.h
Normal file
@ -0,0 +1,84 @@
|
||||
/*
|
||||
Copyright 2016 Ian Jauslin
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Preprocessor macros for integration using with multi-precision floats (mpfr)
|
||||
*/
|
||||
|
||||
|
||||
// reset CPP macros
|
||||
#undef INTEGRAL_FUNC
|
||||
#undef INTEGRAL_FLOAT_TYPE
|
||||
#undef INTEGRAL_FLOAT_INIT
|
||||
#undef INTEGRAL_FLOAT_FREE
|
||||
#undef INTEGRAL_FLOAT_SET_D
|
||||
#undef INTEGRAL_FLOAT_SET_UI
|
||||
#undef INTEGRAL_FLOAT_ADD
|
||||
#undef INTEGRAL_FLOAT_SUB
|
||||
#undef INTEGRAL_FLOAT_UI_SUB
|
||||
#undef INTEGRAL_FLOAT_MUL
|
||||
#undef INTEGRAL_FLOAT_POW_UI
|
||||
#undef INTEGRAL_FLOAT_DIV
|
||||
#undef INTEGRAL_FLOAT_DIV_UI
|
||||
#undef INTEGRAL_FLOAT_ISNUMBER
|
||||
#undef INTEGRAL_FLOATARRAY_TYPE
|
||||
#undef INTEGRAL_FLOATARRAY_FUNC
|
||||
#undef INTEGRAL_POLYNOMIAL_FUNC
|
||||
#undef INTEGRAL_POLYNOMIALARRAY_TYPE
|
||||
#undef INTEGRAL_POLYNOMIALARRAY_FUNC
|
||||
|
||||
// suffix of function names
|
||||
#define INTEGRAL_FUNC(NAME) NAME ## _mpfr
|
||||
|
||||
// type of floats
|
||||
#define INTEGRAL_FLOAT_TYPE mpfr_t
|
||||
// init float
|
||||
#define INTEGRAL_FLOAT_INIT(VAR) mpfr_init(VAR)
|
||||
// free float
|
||||
#define INTEGRAL_FLOAT_FREE(VAR) mpfr_clear(VAR)
|
||||
// set float from double
|
||||
#define INTEGRAL_FLOAT_SET_D(FLOAT, VAL) mpfr_set_d(FLOAT, VAL, MPFR_RNDN)
|
||||
// set float from unsigned int
|
||||
#define INTEGRAL_FLOAT_SET_UI(FLOAT, VAL) mpfr_set_ui(FLOAT, VAL, MPFR_RNDN)
|
||||
// add floats
|
||||
#define INTEGRAL_FLOAT_ADD(FLOAT, VAL1, VAL2) mpfr_add(FLOAT, VAL1, VAL2, MPFR_RNDN)
|
||||
// subtract floats
|
||||
#define INTEGRAL_FLOAT_SUB(FLOAT, VAL1, VAL2) mpfr_sub(FLOAT, VAL1, VAL2, MPFR_RNDN)
|
||||
// subtract floats in which the first is specified as an unsigned int
|
||||
#define INTEGRAL_FLOAT_UI_SUB(FLOAT, VAL1, VAL2) mpfr_ui_sub(FLOAT, VAL1, VAL2, MPFR_RNDN)
|
||||
// multiply floats
|
||||
#define INTEGRAL_FLOAT_MUL(FLOAT, VAL1, VAL2) mpfr_mul(FLOAT, VAL1, VAL2, MPFR_RNDN)
|
||||
// power of a float, specified as an unsigned int
|
||||
#define INTEGRAL_FLOAT_POW_UI(FLOAT, VAL1, VAL2) mpfr_pow_ui(FLOAT, VAL1, VAL2, MPFR_RNDN)
|
||||
// divide floats
|
||||
#define INTEGRAL_FLOAT_DIV(FLOAT, VAL1, VAL2) mpfr_div(FLOAT, VAL1, VAL2, MPFR_RNDN)
|
||||
// divide floats, one of which is specified as an unsigned int
|
||||
#define INTEGRAL_FLOAT_DIV_UI(FLOAT, VAL1, VAL2) mpfr_div_ui(FLOAT, VAL1, VAL2, MPFR_RNDN)
|
||||
// check whether a float is a regular number
|
||||
#define INTEGRAL_FLOAT_ISNUMBER(FLOAT) mpfr_number_p(FLOAT)!=0
|
||||
|
||||
// type of float arrays
|
||||
#define INTEGRAL_FLOATARRAY_TYPE array_mpfr
|
||||
// prefix of float array function names
|
||||
#define INTEGRAL_FLOATARRAY_FUNC(NAME) array_mpfr_ ## NAME
|
||||
|
||||
// prefix of polynomial function names
|
||||
#define INTEGRAL_POLYNOMIAL_FUNC(NAME) polynomial_mpfr_ ## NAME
|
||||
|
||||
// type of polynomial arrays
|
||||
#define INTEGRAL_POLYNOMIALARRAY_TYPE array_polynomial_mpfr
|
||||
// prefix of polynomial array function names
|
||||
#define INTEGRAL_POLYNOMIALARRAY_FUNC(NAME) array_polynomial_mpfr_ ## NAME
|
55
src/polynomial.c
Normal file
55
src/polynomial.c
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
Copyright 2016 Ian Jauslin
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#include "polynomial.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <mpfr.h>
|
||||
#include <math.h>
|
||||
#include "array.h"
|
||||
#include "utils.h"
|
||||
#include "errors.h"
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
//
|
||||
// mpfr coefficients, unsigned int order (polynomial_mpfr)
|
||||
//
|
||||
//--------------------------------------------------
|
||||
|
||||
#include "polynomial_mpfr.h"
|
||||
#include "polynomial_base.c"
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
//
|
||||
// double coefficients, unsigned int order (polynomial_mpfr)
|
||||
//
|
||||
//--------------------------------------------------
|
||||
|
||||
#include "polynomial_double.h"
|
||||
#include "polynomial_base.c"
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
//
|
||||
// long double coefficients, unsigned int order (polynomial_mpfr)
|
||||
//
|
||||
//--------------------------------------------------
|
||||
|
||||
#include "polynomial_ldouble.h"
|
||||
#include "polynomial_base.c"
|
55
src/polynomial.h
Normal file
55
src/polynomial.h
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
Copyright 2016 Ian Jauslin
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Real polynomial
|
||||
*/
|
||||
|
||||
|
||||
#ifndef LIBINUM_POLYNOMIAL_H
|
||||
#define LIBINUM_POLYNOMIAL_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
//--------------------------------------------------
|
||||
//
|
||||
// mpfr coefficients, unsigned int order (polynomial_mpfr)
|
||||
//
|
||||
//--------------------------------------------------
|
||||
#include "polynomial_mpfr.h"
|
||||
#include "polynomial_base.h"
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
//
|
||||
// double coefficients, unsigned int order (polynomial_mpfr)
|
||||
//
|
||||
//--------------------------------------------------
|
||||
|
||||
#include "polynomial_double.h"
|
||||
#include "polynomial_base.h"
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
//
|
||||
// long double coefficients, unsigned int order (polynomial_mpfr)
|
||||
//
|
||||
//--------------------------------------------------
|
||||
|
||||
#include "polynomial_ldouble.h"
|
||||
#include "polynomial_base.h"
|
||||
|
||||
#endif
|
30
src/polynomialMV.c
Normal file
30
src/polynomialMV.c
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
Copyright 2016 Ian Jauslin
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
#include "polynomialMV.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "array.h"
|
||||
#include "errors.h"
|
||||
|
||||
// multi-precision integer coefficients
|
||||
#include "polynomialMV_mpz.h"
|
||||
#include "polynomialMV_base.c"
|
||||
|
||||
// integer coefficients
|
||||
#include "polynomialMV_int.h"
|
||||
#include "polynomialMV_base.c"
|
34
src/polynomialMV.h
Normal file
34
src/polynomialMV.h
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
Copyright 2016 Ian Jauslin
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Multi-variable polynomials
|
||||
*/
|
||||
|
||||
#ifndef LIBINUM_POLYNOMIAL_MV_H
|
||||
#define LIBINUM_POLYNOMIAL_MV_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
// multi-precision integer coefficients
|
||||
#include "polynomialMV_mpz.h"
|
||||
#include "polynomialMV_base.h"
|
||||
|
||||
// integer coefficients
|
||||
#include "polynomialMV_int.h"
|
||||
#include "polynomialMV_base.h"
|
||||
|
||||
#endif
|
293
src/polynomialMV_base.c
Normal file
293
src/polynomialMV_base.c
Normal file
@ -0,0 +1,293 @@
|
||||
/*
|
||||
Copyright 2016 Ian Jauslin
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Base functions for multivariable polynomials
|
||||
|
||||
see polynomialMV_*.h for the values taken by POLYNOMIALMV_FUNC, etc...
|
||||
*/
|
||||
|
||||
// init
|
||||
int POLYNOMIALMV_FUNC(init) (POLYNOMIALMV_TYPENAME* polynomial, int size){
|
||||
polynomial->factors=calloc(size, sizeof(POLYNOMIALMV_FACTOR_TYPE));
|
||||
polynomial->coefficients=calloc(size, sizeof(POLYNOMIALMV_COEF_TYPE));
|
||||
polynomial->length=0;
|
||||
polynomial->memory=size;
|
||||
return(0);
|
||||
}
|
||||
|
||||
// free memory
|
||||
int POLYNOMIALMV_FUNC(free) (POLYNOMIALMV_TYPENAME polynomial){
|
||||
unsigned int i;
|
||||
for(i=0;i<polynomial.length;i++){
|
||||
POLYNOMIALMV_FACTOR_FUNC(free) (polynomial.factors[i]);
|
||||
#ifdef POLYNOMIALMV_COEF_FREE
|
||||
POLYNOMIALMV_COEF_FREE(polynomial.coefficients[i]);
|
||||
#endif
|
||||
}
|
||||
free(polynomial.factors);
|
||||
free(polynomial.coefficients);
|
||||
return(0);
|
||||
}
|
||||
|
||||
// resize the memory allocated to a polynomial
|
||||
int POLYNOMIALMV_FUNC(resize) (POLYNOMIALMV_TYPENAME* polynomial, int new_size){
|
||||
POLYNOMIALMV_TYPENAME new_poly;
|
||||
unsigned int i;
|
||||
|
||||
POLYNOMIALMV_FUNC(init) (&new_poly, new_size);
|
||||
for(i=0;i<polynomial->length;i++){
|
||||
new_poly.factors[i]=polynomial->factors[i];
|
||||
POLYNOMIALMV_COEF_SET(new_poly.coefficients[i], polynomial->coefficients[i]);
|
||||
}
|
||||
new_poly.length=polynomial->length;
|
||||
|
||||
free(polynomial->factors);
|
||||
free(polynomial->coefficients);
|
||||
|
||||
*polynomial=new_poly;
|
||||
return(0);
|
||||
}
|
||||
|
||||
// copy a polynomial
|
||||
int POLYNOMIALMV_FUNC(cpy) (POLYNOMIALMV_TYPENAME input, POLYNOMIALMV_TYPENAME* output){
|
||||
POLYNOMIALMV_FUNC(init) (output, input.length);
|
||||
POLYNOMIALMV_FUNC(cpy_noinit) (input, output);
|
||||
return(0);
|
||||
}
|
||||
int POLYNOMIALMV_FUNC(cpy_noinit) (POLYNOMIALMV_TYPENAME input, POLYNOMIALMV_TYPENAME* output){
|
||||
unsigned int i;
|
||||
if(output->memory<input.length){
|
||||
return(LIBINUM_ERROR_ILLEGAL_MEMORY_ACCESS);
|
||||
}
|
||||
for(i=0;i<input.length;i++){
|
||||
POLYNOMIALMV_FACTOR_FUNC(cpy) (input.factors[i],output->factors+i);
|
||||
POLYNOMIALMV_COEF_CPY(output->coefficients[i], input.coefficients[i]);
|
||||
}
|
||||
output->length=input.length;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
// append an element to a polynomial
|
||||
int POLYNOMIALMV_FUNC(append) (POLYNOMIALMV_FACTOR_TYPE factor, POLYNOMIALMV_COEF_TYPE coef, POLYNOMIALMV_TYPENAME* output){
|
||||
unsigned int offset=output->length;
|
||||
|
||||
if(output->length>=output->memory){
|
||||
POLYNOMIALMV_FUNC(resize) (output,2*output->memory+1);
|
||||
}
|
||||
|
||||
// copy and allocate
|
||||
POLYNOMIALMV_FACTOR_FUNC(cpy) (factor, output->factors+offset);
|
||||
POLYNOMIALMV_COEF_CPY(output->coefficients[offset], coef);
|
||||
//increment length
|
||||
output->length++;
|
||||
|
||||
return(0);
|
||||
}
|
||||
// if there already exists an element with the same factor, then just add coefficients
|
||||
// requires the factors to be ordered
|
||||
int POLYNOMIALMV_FUNC(append_inplace) (POLYNOMIALMV_FACTOR_TYPE factor, POLYNOMIALMV_COEF_TYPE coef, POLYNOMIALMV_TYPENAME* output){
|
||||
unsigned int i;
|
||||
unsigned short int foundit=0;
|
||||
for(i=0;i<output->length;i++){
|
||||
if(POLYNOMIALMV_FACTOR_FUNC(cmp) (factor, output->factors[i])==0){
|
||||
POLYNOMIALMV_COEF_ADD(output->coefficients[i], output->coefficients[i], coef);
|
||||
foundit=1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(foundit==0){
|
||||
POLYNOMIALMV_FUNC(append) (factor, coef, output);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
// do not allocate memory for the factor or the coefficient
|
||||
int POLYNOMIALMV_FUNC(append_noinit) (POLYNOMIALMV_FACTOR_TYPE factor, POLYNOMIALMV_COEF_TYPE coef, POLYNOMIALMV_TYPENAME* output){
|
||||
int offset=output->length;
|
||||
|
||||
if(output->length>=output->memory){
|
||||
POLYNOMIALMV_FUNC(resize) (output,2*output->memory+1);
|
||||
}
|
||||
|
||||
// copy without allocating
|
||||
output->factors[offset]=factor;
|
||||
POLYNOMIALMV_COEF_SET(output->coefficients[offset], coef);
|
||||
// increment length
|
||||
output->length++;
|
||||
return(0);
|
||||
}
|
||||
// noinit factor but init coefficient
|
||||
int POLYNOMIALMV_FUNC(append_noinitfactor) (POLYNOMIALMV_FACTOR_TYPE factor, POLYNOMIALMV_COEF_TYPE coef, POLYNOMIALMV_TYPENAME* output){
|
||||
int offset=output->length;
|
||||
|
||||
if(output->length>=output->memory){
|
||||
POLYNOMIALMV_FUNC(resize) (output,2*output->memory+1);
|
||||
}
|
||||
|
||||
// copy without allocating
|
||||
output->factors[offset]=factor;
|
||||
POLYNOMIALMV_COEF_CPY(output->coefficients[offset], coef);
|
||||
// increment length
|
||||
output->length++;
|
||||
return(0);
|
||||
}
|
||||
// noinit
|
||||
// if there already exists an element with the same factor, then just add coefficients
|
||||
// requires the factors to be ordered
|
||||
int POLYNOMIALMV_FUNC(append_noinit_inplace) (POLYNOMIALMV_FACTOR_TYPE factor, POLYNOMIALMV_COEF_TYPE coef, POLYNOMIALMV_TYPENAME* output){
|
||||
unsigned int i;
|
||||
unsigned short int foundit=0;
|
||||
for(i=0;i<output->length;i++){
|
||||
if(POLYNOMIALMV_FACTOR_FUNC(cmp) (factor, output->factors[i])==0){
|
||||
POLYNOMIALMV_COEF_ADD(output->coefficients[i], output->coefficients[i], coef);
|
||||
foundit=1;
|
||||
// free
|
||||
POLYNOMIALMV_FACTOR_FUNC(free) (factor);
|
||||
#ifdef POLYNOMIALMV_COEF_FREE
|
||||
POLYNOMIALMV_COEF_FREE(coef);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(foundit==0){
|
||||
POLYNOMIALMV_FUNC(append_noinit) (factor, coef, output);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
// noinit factor but init coefficient
|
||||
// if there already exists an element with the same factor, then just add coefficients
|
||||
// requires the factors to be ordered
|
||||
int POLYNOMIALMV_FUNC(append_noinitfactor_inplace) (POLYNOMIALMV_FACTOR_TYPE factor, POLYNOMIALMV_COEF_TYPE coef, POLYNOMIALMV_TYPENAME* output){
|
||||
unsigned int i;
|
||||
unsigned short int foundit=0;
|
||||
for(i=0;i<output->length;i++){
|
||||
if(POLYNOMIALMV_FACTOR_FUNC(cmp) (factor, output->factors[i])==0){
|
||||
POLYNOMIALMV_COEF_ADD(output->coefficients[i], output->coefficients[i], coef);
|
||||
foundit=1;
|
||||
// free factor
|
||||
POLYNOMIALMV_FACTOR_FUNC(free) (factor);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(foundit==0){
|
||||
POLYNOMIALMV_FUNC(append_noinitfactor) (factor, coef, output);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
// add polynomials (inplace)
|
||||
int POLYNOMIALMV_FUNC(add_inplace) (POLYNOMIALMV_TYPENAME input, POLYNOMIALMV_TYPENAME* inout){
|
||||
unsigned int i;
|
||||
for(i=0;i<input.length;i++){
|
||||
POLYNOMIALMV_FUNC(append_inplace) (input.factors[i], input.coefficients[i], inout);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
// not inplace
|
||||
int POLYNOMIALMV_FUNC(add) (POLYNOMIALMV_TYPENAME input1, POLYNOMIALMV_TYPENAME input2, POLYNOMIALMV_TYPENAME* output){
|
||||
POLYNOMIALMV_FUNC(cpy) (input1, output);
|
||||
POLYNOMIALMV_FUNC(add_inplace) (input2, output);
|
||||
return(0);
|
||||
}
|
||||
|
||||
// multiply a polynomial by a scalar
|
||||
int POLYNOMIALMV_FUNC(multiply_scalar) (POLYNOMIALMV_TYPENAME polynomial, POLYNOMIALMV_COEF_TYPE num){
|
||||
unsigned int i;
|
||||
for(i=0;i<polynomial.length;i++){
|
||||
POLYNOMIALMV_COEF_MUL(polynomial.coefficients[i], polynomial.coefficients[i], num);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
// multiply polynomials
|
||||
int POLYNOMIALMV_FUNC(prod) (POLYNOMIALMV_TYPENAME input1, POLYNOMIALMV_TYPENAME input2, POLYNOMIALMV_TYPENAME* output){
|
||||
// position in polys
|
||||
unsigned int pos1, pos2;
|
||||
POLYNOMIALMV_FACTOR_TYPE out_factor;
|
||||
POLYNOMIALMV_COEF_TYPE out_num;
|
||||
|
||||
POLYNOMIALMV_FUNC(init) (output, input1.length);
|
||||
#ifdef POLYNOMIALMV_COEF_INIT
|
||||
POLYNOMIALMV_COEF_INIT(out_num);
|
||||
#endif
|
||||
|
||||
// loop over terms
|
||||
for(pos1=0;pos1<input1.length;pos1++){
|
||||
for(pos2=0;pos2<input2.length;pos2++){
|
||||
// allocate
|
||||
POLYNOMIALMV_FACTOR_FUNC(init) (&out_factor, input1.factors[pos1].length + input2.factors[pos2].length);
|
||||
|
||||
// concatenate factor
|
||||
POLYNOMIALMV_FACTOR_FUNC(concat) (input1.factors[pos1],&out_factor);
|
||||
POLYNOMIALMV_FACTOR_FUNC(concat) (input2.factors[pos2],&out_factor);
|
||||
// sort factor
|
||||
POLYNOMIALMV_FACTOR_FUNC(sort) (out_factor);
|
||||
// multiply coefficient
|
||||
POLYNOMIALMV_COEF_MUL(out_num, input1.coefficients[pos1], input2.coefficients[pos2]);
|
||||
|
||||
// write factor and coef
|
||||
POLYNOMIALMV_FUNC(append_noinit_inplace) (out_factor, out_num, output);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef POLYNOMIALMV_COEF_FREE
|
||||
POLYNOMIALMV_COEF_FREE(out_num);
|
||||
#endif
|
||||
return(0);
|
||||
}
|
||||
|
||||
// order factors
|
||||
int POLYNOMIALMV_FUNC(order) (POLYNOMIALMV_TYPENAME polynomial){
|
||||
unsigned int i,j;
|
||||
for(i=0;i<polynomial.length;i++){
|
||||
for(j=0;j<polynomial.factors[i].length-1;j++){
|
||||
if(polynomial.factors[i].values[j] > polynomial.factors[i].values[j+1]){
|
||||
POLYNOMIALMV_FACTOR_FUNC(sort) (polynomial.factors[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
// print
|
||||
int POLYNOMIALMV_FUNC(print) (POLYNOMIALMV_TYPENAME polynomial){
|
||||
unsigned int i,j;
|
||||
|
||||
// for each monomial
|
||||
for(i=0;i<polynomial.length;i++){
|
||||
if(i==0){
|
||||
printf(" ");
|
||||
}
|
||||
else{
|
||||
printf("+ ");
|
||||
}
|
||||
|
||||
// print num
|
||||
POLYNOMIALMV_COEF_PRINT(polynomial.coefficients[i]);
|
||||
|
||||
// print factors
|
||||
for(j=0;j<polynomial.factors[i].length;j++){
|
||||
POLYNOMIALMV_FACTOR_ELT_PRINT(polynomial.factors[i].values[j]);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
67
src/polynomialMV_base.h
Normal file
67
src/polynomialMV_base.h
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
Copyright 2016 Ian Jauslin
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Base functions for multivariable polynomials
|
||||
|
||||
polynomialMV_*.h for the values taken by POLYNOMIALMV_FUNC, etc...
|
||||
*/
|
||||
|
||||
// init
|
||||
int POLYNOMIALMV_FUNC(init) (POLYNOMIALMV_TYPENAME* polynomial, int size);
|
||||
int POLYNOMIALMV_FUNC(free) (POLYNOMIALMV_TYPENAME polynomial);
|
||||
|
||||
// resize the memory allocated to a polynomial
|
||||
int POLYNOMIALMV_FUNC(resize) (POLYNOMIALMV_TYPENAME* polynomial, int new_size);
|
||||
|
||||
// copy a polynomial
|
||||
int POLYNOMIALMV_FUNC(cpy) (POLYNOMIALMV_TYPENAME input, POLYNOMIALMV_TYPENAME* output);
|
||||
int POLYNOMIALMV_FUNC(cpy_noinit) (POLYNOMIALMV_TYPENAME input, POLYNOMIALMV_TYPENAME* output);
|
||||
|
||||
// append an element to a polynomial
|
||||
int POLYNOMIALMV_FUNC(append) (POLYNOMIALMV_FACTOR_TYPE factor, POLYNOMIALMV_COEF_TYPE coef, POLYNOMIALMV_TYPENAME* output);
|
||||
// if there already exists an element with the same factor, then just add coefficients
|
||||
// requires the factors to be ordered
|
||||
int POLYNOMIALMV_FUNC(append_inplace) (POLYNOMIALMV_FACTOR_TYPE factor, POLYNOMIALMV_COEF_TYPE coef, POLYNOMIALMV_TYPENAME* output);
|
||||
// do not allocate memory for factor or coefficient
|
||||
int POLYNOMIALMV_FUNC(append_noinit) (POLYNOMIALMV_FACTOR_TYPE factor, POLYNOMIALMV_COEF_TYPE coef, POLYNOMIALMV_TYPENAME* output);
|
||||
// noinit factor but init coefficient
|
||||
int POLYNOMIALMV_FUNC(append_noinitfactor) (POLYNOMIALMV_FACTOR_TYPE factor, POLYNOMIALMV_COEF_TYPE coef, POLYNOMIALMV_TYPENAME* output);
|
||||
// noinit
|
||||
// if there already exists an element with the same factor, then just add coefficients
|
||||
// requires the factors to be ordered
|
||||
int POLYNOMIALMV_FUNC(append_noinit_inplace) (POLYNOMIALMV_FACTOR_TYPE factor, POLYNOMIALMV_COEF_TYPE coef, POLYNOMIALMV_TYPENAME* output);
|
||||
// noinit factors but init coefficient
|
||||
// if there already exists an element with the same factor, then just add coefficients
|
||||
// requires the factors to be ordered
|
||||
int POLYNOMIALMV_FUNC(append_noinitfactor_inplace) (POLYNOMIALMV_FACTOR_TYPE factor, POLYNOMIALMV_COEF_TYPE coef, POLYNOMIALMV_TYPENAME* output);
|
||||
|
||||
// add polynomials (inplace)
|
||||
int POLYNOMIALMV_FUNC(add_inplace) (POLYNOMIALMV_TYPENAME input, POLYNOMIALMV_TYPENAME* inout);
|
||||
// not inplace
|
||||
int POLYNOMIALMV_FUNC(add) (POLYNOMIALMV_TYPENAME input1, POLYNOMIALMV_TYPENAME input2, POLYNOMIALMV_TYPENAME* output);
|
||||
|
||||
// multiply a polynomial by a scalar
|
||||
int POLYNOMIALMV_FUNC(multiply_scalar) (POLYNOMIALMV_TYPENAME polynomial, POLYNOMIALMV_COEF_TYPE num);
|
||||
|
||||
// multiply polynomials
|
||||
int POLYNOMIALMV_FUNC(prod) (POLYNOMIALMV_TYPENAME input1, POLYNOMIALMV_TYPENAME input2, POLYNOMIALMV_TYPENAME* output);
|
||||
|
||||
// order factors
|
||||
int POLYNOMIALMV_FUNC(order) (POLYNOMIALMV_TYPENAME polynomial);
|
||||
|
||||
// print
|
||||
int POLYNOMIALMV_FUNC(print) (POLYNOMIALMV_TYPENAME polynomial);
|
62
src/polynomialMV_int.h
Normal file
62
src/polynomialMV_int.h
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
Copyright 2016 Ian Jauslin
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Preprocessor macros for multivariable polynomials with integer coefficients and integer-indexed variables
|
||||
*/
|
||||
|
||||
|
||||
// reset CPP macros
|
||||
#undef POLYNOMIALMV_TYPENAME
|
||||
#undef POLYNOMIALMV_FUNC
|
||||
#undef POLYNOMIALMV_COEF_TYPE
|
||||
#undef POLYNOMIALMV_COEF_INIT
|
||||
#undef POLYNOMIALMV_COEF_FREE
|
||||
#undef POLYNOMIALMV_COEF_SET
|
||||
#undef POLYNOMIALMV_COEF_CPY
|
||||
#undef POLYNOMIALMV_COEF_ADD
|
||||
#undef POLYNOMIALMV_COEF_MUL
|
||||
#undef POLYNOMIALMV_COEF_PRINT
|
||||
#undef POLYNOMIALMV_FACTOR_TYPE
|
||||
#undef POLYNOMIALMV_FACTOR_FUNC
|
||||
#undef POLYNOMIALMV_FACTOR_ELT_PRINT
|
||||
|
||||
|
||||
// name of the polynomial type
|
||||
#define POLYNOMIALMV_TYPENAME polynomialMV_int
|
||||
// prefix of function names
|
||||
#define POLYNOMIALMV_FUNC(NAME) polynomialMV_int_ ## NAME
|
||||
|
||||
// type of the coefficient
|
||||
#define POLYNOMIALMV_COEF_TYPE int
|
||||
// set coefficient
|
||||
#define POLYNOMIALMV_COEF_SET(COEF, VAL) COEF = VAL
|
||||
// copy coefficient
|
||||
#define POLYNOMIALMV_COEF_CPY(COEF, VAL) COEF = VAL
|
||||
// add coefficients
|
||||
#define POLYNOMIALMV_COEF_ADD(COEF, VAL1, VAL2) COEF = VAL1 + VAL2
|
||||
// multiply coefficients
|
||||
#define POLYNOMIALMV_COEF_MUL(COEF, VAL1, VAL2) COEF = VAL1 * VAL2
|
||||
// print a coefficient
|
||||
#define POLYNOMIALMV_COEF_PRINT(COEF) printf("%d", COEF)
|
||||
|
||||
// type of the factor (must be an array)
|
||||
#define POLYNOMIALMV_FACTOR_TYPE array_int
|
||||
// prefix of factor function names
|
||||
#define POLYNOMIALMV_FACTOR_FUNC(NAME) array_int_ ## NAME
|
||||
// print an element of a factor
|
||||
#define POLYNOMIALMV_FACTOR_ELT_PRINT(ELT) printf("[x%d]", ELT)
|
||||
|
66
src/polynomialMV_mpz.h
Normal file
66
src/polynomialMV_mpz.h
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
Copyright 2016 Ian Jauslin
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Preprocessor macros for multivariable polynomials with multi-precision integer (mpz) coefficients and integer-indexed variables
|
||||
*/
|
||||
|
||||
|
||||
// reset CPP macros
|
||||
#undef POLYNOMIALMV_TYPENAME
|
||||
#undef POLYNOMIALMV_FUNC
|
||||
#undef POLYNOMIALMV_COEF_TYPE
|
||||
#undef POLYNOMIALMV_COEF_INIT
|
||||
#undef POLYNOMIALMV_COEF_FREE
|
||||
#undef POLYNOMIALMV_COEF_SET
|
||||
#undef POLYNOMIALMV_COEF_CPY
|
||||
#undef POLYNOMIALMV_COEF_ADD
|
||||
#undef POLYNOMIALMV_COEF_MUL
|
||||
#undef POLYNOMIALMV_COEF_PRINT
|
||||
#undef POLYNOMIALMV_FACTOR_TYPE
|
||||
#undef POLYNOMIALMV_FACTOR_FUNC
|
||||
#undef POLYNOMIALMV_FACTOR_ELT_PRINT
|
||||
|
||||
|
||||
// name of the polynomial type
|
||||
#define POLYNOMIALMV_TYPENAME polynomialMV_mpz
|
||||
// prefix of function names
|
||||
#define POLYNOMIALMV_FUNC(NAME) polynomialMV_mpz_ ## NAME
|
||||
|
||||
// type of the coefficient
|
||||
#define POLYNOMIALMV_COEF_TYPE mpz_t
|
||||
// init coefficient
|
||||
#define POLYNOMIALMV_COEF_INIT(VAR) mpz_init(VAR)
|
||||
// free coefficient
|
||||
#define POLYNOMIALMV_COEF_FREE(VAR) mpz_clear(VAR)
|
||||
// set coefficient
|
||||
#define POLYNOMIALMV_COEF_SET(COEF, VAL) COEF[0]=VAL[0]
|
||||
// copy coefficient
|
||||
#define POLYNOMIALMV_COEF_CPY(COEF, VAL) mpz_init(COEF); mpz_set(COEF, VAL)
|
||||
// add coefficients
|
||||
#define POLYNOMIALMV_COEF_ADD(COEF, VAL1, VAL2) mpz_add(COEF, VAL1, VAL2)
|
||||
// multiply coefficients
|
||||
#define POLYNOMIALMV_COEF_MUL(COEF, VAL1, VAL2) mpz_mul(COEF, VAL1, VAL2)
|
||||
// print a coefficient
|
||||
#define POLYNOMIALMV_COEF_PRINT(COEF) gmp_printf("%Zd", COEF)
|
||||
|
||||
// type of the factor (must be an array)
|
||||
#define POLYNOMIALMV_FACTOR_TYPE array_int
|
||||
// prefix of factor function names
|
||||
#define POLYNOMIALMV_FACTOR_FUNC(NAME) array_int_ ## NAME
|
||||
// print an element of a factor
|
||||
#define POLYNOMIALMV_FACTOR_ELT_PRINT(ELT) printf("[x%d]", ELT)
|
||||
|
29
src/polynomialMV_type.h
Normal file
29
src/polynomialMV_type.h
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
Copyright 2016 Ian Jauslin
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Structure definition for multivariable polynomials
|
||||
|
||||
see polynomialMV_*.h for the values taken by POLYNOMIALMV_TYPENAME, etc...
|
||||
*/
|
||||
|
||||
typedef struct POLYNOMIALMV_TYPENAME {
|
||||
POLYNOMIALMV_COEF_TYPE* coefficients;
|
||||
POLYNOMIALMV_FACTOR_TYPE* factors;
|
||||
unsigned int length;
|
||||
unsigned int memory;
|
||||
} POLYNOMIALMV_TYPENAME;
|
||||
|
337
src/polynomial_base.c
Normal file
337
src/polynomial_base.c
Normal file
@ -0,0 +1,337 @@
|
||||
/*
|
||||
Copyright 2016 Ian Jauslin
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Base functions for real polynomials
|
||||
|
||||
see polynomial_*.h for the values taken by POLYNOMIAL_FUNC, etc...
|
||||
*/
|
||||
|
||||
|
||||
// init
|
||||
int POLYNOMIAL_FUNC(init) (POLYNOMIAL_TYPENAME* poly, unsigned int memory){
|
||||
POLYNOMIAL_COEFSARRAY_FUNC(init) (&(poly->coefficients), memory);
|
||||
POLYNOMIAL_ORDERSARRAY_FUNC(init) (&(poly->orders), memory);
|
||||
return(0);
|
||||
}
|
||||
int POLYNOMIAL_FUNC(free) (POLYNOMIAL_TYPENAME poly){
|
||||
POLYNOMIAL_COEFSARRAY_FUNC(free) (poly.coefficients);
|
||||
POLYNOMIAL_ORDERSARRAY_FUNC(free) (poly.orders);
|
||||
return(0);
|
||||
}
|
||||
|
||||
// resize memory
|
||||
int POLYNOMIAL_FUNC(resize) (POLYNOMIAL_TYPENAME* poly, unsigned int newsize){
|
||||
POLYNOMIAL_COEFSARRAY_FUNC(resize) (&(poly->coefficients), newsize);
|
||||
POLYNOMIAL_ORDERSARRAY_FUNC(resize) (&(poly->orders), newsize);
|
||||
return(0);
|
||||
}
|
||||
|
||||
// add a monomial
|
||||
int POLYNOMIAL_FUNC(add_monomial) (POLYNOMIAL_COEF_TYPE val, POLYNOMIAL_ORDER_TYPE order, POLYNOMIAL_TYPENAME* output){
|
||||
unsigned int i;
|
||||
if((output->coefficients.length != output->orders.length) || (output->coefficients.memory != output->orders.memory)){
|
||||
return(LIBINUM_ERROR_SIZE_MISMATCH);
|
||||
}
|
||||
// check whether the order already exists in the polynomial
|
||||
for(i=0;i< output->coefficients.length;i++){
|
||||
if(POLYNOMIAL_ORDER_CMP(order, output->orders.values[i])==0){
|
||||
POLYNOMIAL_COEF_ADD(output->coefficients.values[i], output->coefficients.values[i], val);
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
// if the order does not already exist
|
||||
if(output->coefficients.length >= output->coefficients.memory){
|
||||
POLYNOMIAL_FUNC(resize) (output,2*output->coefficients.memory+1);
|
||||
}
|
||||
POLYNOMIAL_COEF_CPY(val, output->coefficients.values[output->coefficients.length]);
|
||||
POLYNOMIAL_ORDER_CPY(order, output->orders.values[output->coefficients.length]);
|
||||
output->coefficients.length++;
|
||||
output->orders.length++;
|
||||
return(0);
|
||||
}
|
||||
// from a double-valued coefficient and an unsigned int order
|
||||
int POLYNOMIAL_FUNC(add_monomial_dui) (double val, unsigned int order, POLYNOMIAL_TYPENAME* output){
|
||||
unsigned int i;
|
||||
if((output->coefficients.length != output->orders.length) || (output->coefficients.memory != output->orders.memory)){
|
||||
return(LIBINUM_ERROR_SIZE_MISMATCH);
|
||||
}
|
||||
// check whether the order already exists in the polynomial
|
||||
for(i=0;i< output->coefficients.length;i++){
|
||||
if(POLYNOMIAL_ORDER_CMP_UI(output->orders.values[i], order)==0){
|
||||
POLYNOMIAL_COEF_ADD_D(output->coefficients.values[i], output->coefficients.values[i], val);
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
// if the order does not already exist
|
||||
if(output->coefficients.length >= output->coefficients.memory){
|
||||
POLYNOMIAL_FUNC(resize) (output,2*output->coefficients.memory+1);
|
||||
}
|
||||
POLYNOMIAL_COEF_CPY_D(val, output->coefficients.values[output->coefficients.length]);
|
||||
POLYNOMIAL_ORDER_CPY_UI(order, output->orders.values[output->coefficients.length]);
|
||||
output->coefficients.length++;
|
||||
output->orders.length++;
|
||||
return(0);
|
||||
}
|
||||
|
||||
// copy
|
||||
int POLYNOMIAL_FUNC(cpy) (POLYNOMIAL_TYPENAME input, POLYNOMIAL_TYPENAME* output){
|
||||
POLYNOMIAL_COEFSARRAY_FUNC(cpy) (input.coefficients, &(output->coefficients));
|
||||
POLYNOMIAL_ORDERSARRAY_FUNC(cpy) (input.orders, &(output->orders));
|
||||
return(0);
|
||||
}
|
||||
int POLYNOMIAL_FUNC(cpy_noinit) (POLYNOMIAL_TYPENAME input, POLYNOMIAL_TYPENAME* output){
|
||||
int ret;
|
||||
ret=POLYNOMIAL_COEFSARRAY_FUNC(cpy_noinit) (input.coefficients, &(output->coefficients));
|
||||
if(ret<0){
|
||||
return(ret);
|
||||
}
|
||||
POLYNOMIAL_ORDERSARRAY_FUNC(cpy_noinit) (input.orders, &(output->orders));
|
||||
return(ret);
|
||||
}
|
||||
|
||||
// add
|
||||
int POLYNOMIAL_FUNC(add_inplace) (POLYNOMIAL_TYPENAME poly1, POLYNOMIAL_TYPENAME* poly2){
|
||||
unsigned int i;
|
||||
if(poly1.coefficients.length != poly1.orders.length){
|
||||
return(LIBINUM_ERROR_SIZE_MISMATCH);
|
||||
}
|
||||
for(i=0;i<poly1.coefficients.length;i++){
|
||||
POLYNOMIAL_FUNC(add_monomial) (poly1.coefficients.values[i], poly1.orders.values[i], poly2);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
int POLYNOMIAL_FUNC(add) (POLYNOMIAL_TYPENAME poly1, POLYNOMIAL_TYPENAME poly2, POLYNOMIAL_TYPENAME* output){
|
||||
int ret;
|
||||
POLYNOMIAL_FUNC(cpy) (poly2, output);
|
||||
ret=POLYNOMIAL_FUNC(add_inplace) (poly1, output);
|
||||
return(ret);
|
||||
}
|
||||
|
||||
// multiply by a scalar
|
||||
int POLYNOMIAL_FUNC(mul_scalar_inplace) (POLYNOMIAL_COEF_TYPE x, POLYNOMIAL_TYPENAME* poly){
|
||||
unsigned int i;
|
||||
if(poly->coefficients.length != poly->orders.length){
|
||||
return(LIBINUM_ERROR_SIZE_MISMATCH);
|
||||
}
|
||||
for(i=0;i<poly->coefficients.length;i++){
|
||||
POLYNOMIAL_COEF_MUL(poly->coefficients.values[i], poly->coefficients.values[i], x);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
int POLYNOMIAL_FUNC(mul_scalar) (POLYNOMIAL_COEF_TYPE x, POLYNOMIAL_TYPENAME poly, POLYNOMIAL_TYPENAME* output){
|
||||
int ret;
|
||||
POLYNOMIAL_FUNC(cpy) (poly, output);
|
||||
ret=POLYNOMIAL_FUNC(mul_scalar_inplace) (x, output);
|
||||
return(ret);
|
||||
}
|
||||
|
||||
// multiply by a monomial
|
||||
int POLYNOMIAL_FUNC(mul_monomial_inplace) (POLYNOMIAL_COEF_TYPE x, POLYNOMIAL_ORDER_TYPE order, POLYNOMIAL_TYPENAME* poly){
|
||||
unsigned int i;
|
||||
if(poly->coefficients.length != poly->orders.length){
|
||||
return(LIBINUM_ERROR_SIZE_MISMATCH);
|
||||
}
|
||||
for(i=0;i<poly->coefficients.length;i++){
|
||||
POLYNOMIAL_COEF_MUL(poly->coefficients.values[i], poly->coefficients.values[i], x);
|
||||
POLYNOMIAL_ORDER_ADD(poly->orders.values[i], poly->orders.values[i], order);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
int POLYNOMIAL_FUNC(mul_monomial) (POLYNOMIAL_COEF_TYPE x, POLYNOMIAL_ORDER_TYPE order, POLYNOMIAL_TYPENAME poly, POLYNOMIAL_TYPENAME* output){
|
||||
int ret;
|
||||
POLYNOMIAL_FUNC(cpy) (poly,output);
|
||||
ret=POLYNOMIAL_FUNC(mul_monomial_inplace) (x, order, output);
|
||||
return(ret);
|
||||
}
|
||||
|
||||
// multiply two polynomials
|
||||
int POLYNOMIAL_FUNC(mul_inplace) (POLYNOMIAL_TYPENAME poly1, POLYNOMIAL_TYPENAME* poly2){
|
||||
unsigned int i;
|
||||
int ret;
|
||||
if(poly1.coefficients.length != poly1.orders.length){
|
||||
return(LIBINUM_ERROR_SIZE_MISMATCH);
|
||||
}
|
||||
for(i=0;i<poly1.coefficients.length;i++){
|
||||
ret=POLYNOMIAL_FUNC(mul_monomial_inplace) (poly1.coefficients.values[i], poly1.orders.values[i], poly2);
|
||||
if(ret<0){
|
||||
return(ret);
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
int POLYNOMIAL_FUNC(mul) (POLYNOMIAL_TYPENAME poly1, POLYNOMIAL_TYPENAME poly2, POLYNOMIAL_TYPENAME* output){
|
||||
int ret;
|
||||
POLYNOMIAL_FUNC(cpy) (poly2, output);
|
||||
ret=POLYNOMIAL_FUNC(mul_inplace) (poly1, output);
|
||||
return(ret);
|
||||
}
|
||||
|
||||
// derive
|
||||
int POLYNOMIAL_FUNC(derive_inplace) (POLYNOMIAL_TYPENAME* poly){
|
||||
unsigned int i;
|
||||
if(poly->coefficients.length != poly->orders.length){
|
||||
return(LIBINUM_ERROR_SIZE_MISMATCH);
|
||||
}
|
||||
for(i=0;i<poly->coefficients.length;i++){
|
||||
if(POLYNOMIAL_ORDER_CMP_UI(poly->orders.values[i], 0)>0){
|
||||
POLYNOMIAL_COEF_MUL_ORDER(poly->coefficients.values[i], poly->coefficients.values[i], poly->orders.values[i]);
|
||||
POLYNOMIAL_ORDER_SUB_UI(poly->orders.values[i], poly->orders.values[i], 1);
|
||||
}
|
||||
else{
|
||||
// remove the term by setting it to the last term and reducing the length
|
||||
#ifdef POLYNOMIAL_COEF_FREE
|
||||
POLYNOMIAL_COEF_FREE(poly->coefficients.values[i]);
|
||||
#endif
|
||||
#ifdef POLYNOMIAL_ORDER_FREE
|
||||
POLYNOMIAL_ORDER_FREE(poly->orders.values[i]);
|
||||
#endif
|
||||
if(i<poly->coefficients.length-1){
|
||||
POLYNOMIAL_COEF_SET(poly->coefficients.values[i], poly->coefficients.values[poly->coefficients.length-1]);
|
||||
POLYNOMIAL_ORDER_SET(poly->orders.values[i], poly->orders.values[poly->coefficients.length-1]);
|
||||
i--;
|
||||
}
|
||||
poly->coefficients.length--;
|
||||
poly->orders.length--;
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
int POLYNOMIAL_FUNC(derive) (POLYNOMIAL_TYPENAME poly, POLYNOMIAL_TYPENAME* output){
|
||||
int ret;
|
||||
POLYNOMIAL_FUNC(cpy) (poly, output);
|
||||
ret=POLYNOMIAL_FUNC(derive_inplace) (output);
|
||||
return(ret);
|
||||
}
|
||||
|
||||
// evaluate
|
||||
int POLYNOMIAL_FUNC(evaluate) (POLYNOMIAL_COEF_TYPE* out, POLYNOMIAL_COEF_TYPE x, POLYNOMIAL_TYPENAME poly){
|
||||
unsigned int i;
|
||||
POLYNOMIAL_COEF_TYPE tmp;
|
||||
|
||||
#ifdef POLYNOMIAL_COEF_INIT
|
||||
POLYNOMIAL_COEF_INIT(tmp);
|
||||
#endif
|
||||
|
||||
if(poly.coefficients.length != poly.orders.length){
|
||||
return(LIBINUM_ERROR_SIZE_MISMATCH);
|
||||
}
|
||||
|
||||
POLYNOMIAL_COEF_SET_UI(*out, 0);
|
||||
for(i=0;i<poly.coefficients.length;i++){
|
||||
POLYNOMIAL_COEF_POW_UI(tmp, x, poly.orders.values[i]);
|
||||
POLYNOMIAL_COEF_MUL(tmp, tmp, poly.coefficients.values[i]);
|
||||
POLYNOMIAL_COEF_ADD(*out, *out, tmp);
|
||||
}
|
||||
#ifdef POLYNOMIAL_COEF_FREE
|
||||
POLYNOMIAL_COEF_FREE(tmp);
|
||||
#endif
|
||||
return(0);
|
||||
}
|
||||
|
||||
// print
|
||||
int POLYNOMIAL_FUNC(print) (POLYNOMIAL_TYPENAME poly){
|
||||
unsigned int j;
|
||||
|
||||
if(poly.coefficients.length != poly.orders.length){
|
||||
return(LIBINUM_ERROR_SIZE_MISMATCH);
|
||||
}
|
||||
|
||||
printf(" ");
|
||||
for(j=0;j<poly.coefficients.length;j++){
|
||||
if(j>0){
|
||||
printf("+ ");
|
||||
}
|
||||
POLYNOMIAL_COEF_PRINT(poly.coefficients.values[j]);
|
||||
printf(" x^");
|
||||
POLYNOMIAL_ORDER_PRINT(poly.orders.values[j]);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
// n-th Legendre polynomial
|
||||
int POLYNOMIAL_FUNC(legendre) (unsigned int n, POLYNOMIAL_TYPENAME* output){
|
||||
POLYNOMIAL_TYPENAME prevpoly, tmppoly;
|
||||
unsigned int i;
|
||||
int j;
|
||||
POLYNOMIAL_COEF_TYPE tmp;
|
||||
POLYNOMIAL_ORDER_TYPE tmp_o;
|
||||
|
||||
if(n==0){
|
||||
POLYNOMIAL_FUNC(init) (output, 1);
|
||||
POLYNOMIAL_FUNC(add_monomial_dui) (1., 0, output);
|
||||
return(0);
|
||||
}
|
||||
else if(n==1){
|
||||
POLYNOMIAL_FUNC(init) (output, n);
|
||||
POLYNOMIAL_FUNC(add_monomial_dui) (1., 1, output);
|
||||
return(0);
|
||||
}
|
||||
|
||||
#ifdef POLYNOMIAL_COEF_INIT
|
||||
POLYNOMIAL_COEF_INIT(tmp);
|
||||
#endif
|
||||
#ifdef POLYNOMIAL_ORDER_INIT
|
||||
POLYNOMIAL_ORDER_INIT(tmp_o);
|
||||
#endif
|
||||
|
||||
// init: prevpoly=1
|
||||
POLYNOMIAL_FUNC(init) (&prevpoly, n-1);
|
||||
POLYNOMIAL_FUNC(add_monomial_dui) (1., 0, &prevpoly);
|
||||
// init: output=x
|
||||
POLYNOMIAL_FUNC(init) (output, n);
|
||||
POLYNOMIAL_FUNC(add_monomial_dui) (1., 1, output);
|
||||
|
||||
// implement i*p_i=(2*i-1)*p_{i-1}-(i-1)*p_{i-2}
|
||||
for(i=2;i<=n;i++){
|
||||
// save current poly to copy it to prevpoly at the end of the loop
|
||||
POLYNOMIAL_FUNC(cpy) (*output, &tmppoly);
|
||||
|
||||
// (2*i-1)/i*p_{i-1}
|
||||
POLYNOMIAL_COEF_SET_UI(tmp, 2*i-1);
|
||||
POLYNOMIAL_COEF_DIV_UI(tmp, tmp, i);
|
||||
POLYNOMIAL_ORDER_SET_UI(tmp_o, 1);
|
||||
POLYNOMIAL_FUNC(mul_monomial_inplace) (tmp, tmp_o, output);
|
||||
|
||||
// -(i-1)/i*p_{i-2}
|
||||
// copy i to a signed int
|
||||
j=i;
|
||||
POLYNOMIAL_COEF_SET_SI(tmp, -j+1);
|
||||
POLYNOMIAL_COEF_DIV_UI(tmp, tmp, i);
|
||||
POLYNOMIAL_FUNC(mul_scalar_inplace) (tmp, &prevpoly);
|
||||
|
||||
// add it to p_n
|
||||
POLYNOMIAL_FUNC(add_inplace) (prevpoly, output);
|
||||
|
||||
// replace prevpoly
|
||||
POLYNOMIAL_FUNC(free) (prevpoly);
|
||||
prevpoly=tmppoly;
|
||||
}
|
||||
|
||||
POLYNOMIAL_FUNC(free) (prevpoly);
|
||||
#ifdef POLYNOMIAL_COEF_FREE
|
||||
POLYNOMIAL_COEF_FREE(tmp);
|
||||
#endif
|
||||
#ifdef POLYNOMIAL_ORDER_FREE
|
||||
POLYNOMIAL_ORDER_FREE(tmp_o);
|
||||
#endif
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
67
src/polynomial_base.h
Normal file
67
src/polynomial_base.h
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
Copyright 2016 Ian Jauslin
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Base functions for real polynomials
|
||||
|
||||
see polynomial_*.h for the values taken by POLYNOMIAL_FUNC, etc...
|
||||
*/
|
||||
|
||||
// init
|
||||
int POLYNOMIAL_FUNC(init) (POLYNOMIAL_TYPENAME* poly, unsigned int memory);
|
||||
int POLYNOMIAL_FUNC(free) (POLYNOMIAL_TYPENAME poly);
|
||||
|
||||
// resize memory
|
||||
int POLYNOMIAL_FUNC(resize) (POLYNOMIAL_TYPENAME* poly, unsigned int newsize);
|
||||
|
||||
// add a monomial
|
||||
int POLYNOMIAL_FUNC(add_monomial) (POLYNOMIAL_COEF_TYPE val, POLYNOMIAL_ORDER_TYPE order, POLYNOMIAL_TYPENAME* output);
|
||||
// from a double-valued coefficient and an unsigned int order
|
||||
int POLYNOMIAL_FUNC(add_monomial_dui) (double val, unsigned int order, POLYNOMIAL_TYPENAME* output);
|
||||
|
||||
// copy
|
||||
int POLYNOMIAL_FUNC(cpy) (POLYNOMIAL_TYPENAME input, POLYNOMIAL_TYPENAME* output);
|
||||
int POLYNOMIAL_FUNC(cpy_noinit) (POLYNOMIAL_TYPENAME input, POLYNOMIAL_TYPENAME* output);
|
||||
|
||||
// add
|
||||
int POLYNOMIAL_FUNC(add_inplace) (POLYNOMIAL_TYPENAME poly1, POLYNOMIAL_TYPENAME* poly2);
|
||||
int POLYNOMIAL_FUNC(add) (POLYNOMIAL_TYPENAME poly1, POLYNOMIAL_TYPENAME poly2, POLYNOMIAL_TYPENAME* output);
|
||||
|
||||
// multiply by a scalar
|
||||
int POLYNOMIAL_FUNC(mul_scalar_inplace) (POLYNOMIAL_COEF_TYPE x, POLYNOMIAL_TYPENAME* poly);
|
||||
int POLYNOMIAL_FUNC(mul_scalar) (POLYNOMIAL_COEF_TYPE x, POLYNOMIAL_TYPENAME poly, POLYNOMIAL_TYPENAME* output);
|
||||
|
||||
// multiply by a monomial
|
||||
int POLYNOMIAL_FUNC(mul_monomial_inplace) (POLYNOMIAL_COEF_TYPE x, POLYNOMIAL_ORDER_TYPE order, POLYNOMIAL_TYPENAME* poly);
|
||||
int POLYNOMIAL_FUNC(mul_monomial) (POLYNOMIAL_COEF_TYPE x, POLYNOMIAL_ORDER_TYPE order, POLYNOMIAL_TYPENAME poly, POLYNOMIAL_TYPENAME* output);
|
||||
|
||||
// multiply two polynomials
|
||||
int POLYNOMIAL_FUNC(mul_inplace) (POLYNOMIAL_TYPENAME poly1, POLYNOMIAL_TYPENAME* poly2);
|
||||
int POLYNOMIAL_FUNC(mul) (POLYNOMIAL_TYPENAME poly1, POLYNOMIAL_TYPENAME poly2, POLYNOMIAL_TYPENAME* output);
|
||||
|
||||
// derive
|
||||
int POLYNOMIAL_FUNC(derive_inplace) (POLYNOMIAL_TYPENAME* poly);
|
||||
int POLYNOMIAL_FUNC(derive) (POLYNOMIAL_TYPENAME poly, POLYNOMIAL_TYPENAME* output);
|
||||
|
||||
// evaluate
|
||||
int POLYNOMIAL_FUNC(evaluate) (POLYNOMIAL_COEF_TYPE* out, POLYNOMIAL_COEF_TYPE x, POLYNOMIAL_TYPENAME poly);
|
||||
|
||||
// print
|
||||
int POLYNOMIAL_FUNC(print) (POLYNOMIAL_TYPENAME poly);
|
||||
|
||||
|
||||
// n-th Legendre polynomial
|
||||
int POLYNOMIAL_FUNC(legendre) (unsigned int n, POLYNOMIAL_TYPENAME* output);
|
117
src/polynomial_double.h
Normal file
117
src/polynomial_double.h
Normal file
@ -0,0 +1,117 @@
|
||||
/*
|
||||
Copyright 2016 Ian Jauslin
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Preprocessor macros for real polynomials with double coefficients and unsigned integer powers
|
||||
*/
|
||||
|
||||
|
||||
// reset CPP macros
|
||||
#undef POLYNOMIAL_TYPENAME
|
||||
#undef POLYNOMIAL_FUNC
|
||||
#undef POLYNOMIAL_COEF_TYPE
|
||||
#undef POLYNOMIAL_COEFSARRAY_TYPE
|
||||
#undef POLYNOMIAL_COEFSARRAY_FUNC
|
||||
#undef POLYNOMIAL_COEF_INIT
|
||||
#undef POLYNOMIAL_COEF_FREE
|
||||
#undef POLYNOMIAL_COEF_SET
|
||||
#undef POLYNOMIAL_COEF_SET_SI
|
||||
#undef POLYNOMIAL_COEF_SET_UI
|
||||
#undef POLYNOMIAL_COEF_CPY
|
||||
#undef POLYNOMIAL_COEF_CPY_D
|
||||
#undef POLYNOMIAL_COEF_ADD
|
||||
#undef POLYNOMIAL_COEF_ADD_D
|
||||
#undef POLYNOMIAL_COEF_MUL
|
||||
#undef POLYNOMIAL_COEF_MUL_ORDER
|
||||
#undef POLYNOMIAL_COEF_DIV_UI
|
||||
#undef POLYNOMIAL_COEF_POW_UI
|
||||
#undef POLYNOMIAL_COEF_PRINT
|
||||
#undef POLYNOMIAL_ORDER_TYPE
|
||||
#undef POLYNOMIAL_ORDERSARRAY_TYPE
|
||||
#undef POLYNOMIAL_ORDERSARRAY_FUNC
|
||||
#undef POLYNOMIAL_ORDER_INIT
|
||||
#undef POLYNOMIAL_ORDER_FREE
|
||||
#undef POLYNOMIAL_ORDER_SET
|
||||
#undef POLYNOMIAL_ORDER_SET_UI
|
||||
#undef POLYNOMIAL_ORDER_CPY
|
||||
#undef POLYNOMIAL_ORDER_CPY_UI
|
||||
#undef POLYNOMIAL_ORDER_ADD
|
||||
#undef POLYNOMIAL_ORDER_SUB_UI
|
||||
#undef POLYNOMIAL_ORDER_CMP
|
||||
#undef POLYNOMIAL_ORDER_CMP_UI
|
||||
#undef POLYNOMIAL_ORDER_PRINT
|
||||
|
||||
// name of the polynomial type
|
||||
#define POLYNOMIAL_TYPENAME polynomial_double
|
||||
// prefix of function names
|
||||
#define POLYNOMIAL_FUNC(NAME) polynomial_double_ ## NAME
|
||||
|
||||
// type of the coefficient
|
||||
#define POLYNOMIAL_COEF_TYPE double
|
||||
// type of coefficient arrays
|
||||
#define POLYNOMIAL_COEFSARRAY_TYPE array_double
|
||||
// prefix of coefficient array function names
|
||||
#define POLYNOMIAL_COEFSARRAY_FUNC(NAME) array_double_ ## NAME
|
||||
// set coefficient
|
||||
#define POLYNOMIAL_COEF_SET(COEF, VAL) COEF=VAL
|
||||
// set coefficient from signed int
|
||||
#define POLYNOMIAL_COEF_SET_SI(COEF, VAL) COEF=(double)VAL
|
||||
// set coefficient from unsigned int
|
||||
#define POLYNOMIAL_COEF_SET_UI(COEF, VAL) COEF=(double)VAL
|
||||
// copy coefficient
|
||||
#define POLYNOMIAL_COEF_CPY(VAL, COEF) COEF=VAL
|
||||
// copy coefficient from double
|
||||
#define POLYNOMIAL_COEF_CPY_D(VAL, COEF) COEF=VAL
|
||||
// add coefficients
|
||||
#define POLYNOMIAL_COEF_ADD(COEF, VAL1, VAL2) COEF=VAL1+VAL2
|
||||
// add coefficients, one of which is specified as a double
|
||||
#define POLYNOMIAL_COEF_ADD_D(COEF, VAL1, VAL2) COEF=VAL1+VAL2
|
||||
// multiply coefficients
|
||||
#define POLYNOMIAL_COEF_MUL(COEF, VAL1, VAL2) COEF=VAL1*VAL2
|
||||
// multiply coefficients, one of which is specified as a POLYNOMIAL_ORDER_TYPE
|
||||
#define POLYNOMIAL_COEF_MUL_ORDER(COEF, VAL1, VAL2) COEF=VAL1*(double)VAL2
|
||||
// divide coefficients, one of which is specified as an unsigned int
|
||||
#define POLYNOMIAL_COEF_DIV_UI(COEF, VAL1, VAL2) COEF=VAL1/(double)VAL2
|
||||
// power of a coefficient, specified as an unsigned int
|
||||
#define POLYNOMIAL_COEF_POW_UI(COEF, VAL1, VAL2) COEF=pow(VAL1, (double)VAL2)
|
||||
// print a coefficient
|
||||
#define POLYNOMIAL_COEF_PRINT(COEF) fprint_double(stdout, COEF)
|
||||
|
||||
// type of the order
|
||||
#define POLYNOMIAL_ORDER_TYPE unsigned int
|
||||
// type of order arrays
|
||||
#define POLYNOMIAL_ORDERSARRAY_TYPE array_uint
|
||||
// prefix of order array function names
|
||||
#define POLYNOMIAL_ORDERSARRAY_FUNC(NAME) array_uint_ ## NAME
|
||||
// set order
|
||||
#define POLYNOMIAL_ORDER_SET(ORDER, VAL) ORDER=VAL
|
||||
// set order from unsigned int
|
||||
#define POLYNOMIAL_ORDER_SET_UI(ORDER, VAL) ORDER=VAL
|
||||
// copy order
|
||||
#define POLYNOMIAL_ORDER_CPY(VAL, ORDER) ORDER=VAL
|
||||
// copy order from unsigned int
|
||||
#define POLYNOMIAL_ORDER_CPY_UI(VAL, ORDER) ORDER=VAL
|
||||
// add orders
|
||||
#define POLYNOMIAL_ORDER_ADD(ORDER, VAL1, VAL2) ORDER=VAL1+VAL2
|
||||
// subtract an order and an unsigned integer
|
||||
#define POLYNOMIAL_ORDER_SUB_UI(ORDER, VAL1, VAL2) ORDER=VAL1-VAL2
|
||||
// compare orders (0 if equal, -1 if <, +1 if >)
|
||||
#define POLYNOMIAL_ORDER_CMP(VAL1, VAL2) (int)VAL1-(int)VAL2
|
||||
// compare orders, one of which is specified as an unsigned int (0 if equal, -1 if <, +1 if >)
|
||||
#define POLYNOMIAL_ORDER_CMP_UI(VAL1, VAL2) (int)VAL1-(int)VAL2
|
||||
// print orders
|
||||
#define POLYNOMIAL_ORDER_PRINT(ORDER) printf("%u",ORDER)
|
||||
|
117
src/polynomial_ldouble.h
Normal file
117
src/polynomial_ldouble.h
Normal file
@ -0,0 +1,117 @@
|
||||
/*
|
||||
Copyright 2016 Ian Jauslin
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Preprocessor macros for real polynomials with long double coefficients and unsigned integer powers
|
||||
*/
|
||||
|
||||
|
||||
// reset CPP macros
|
||||
#undef POLYNOMIAL_TYPENAME
|
||||
#undef POLYNOMIAL_FUNC
|
||||
#undef POLYNOMIAL_COEF_TYPE
|
||||
#undef POLYNOMIAL_COEFSARRAY_TYPE
|
||||
#undef POLYNOMIAL_COEFSARRAY_FUNC
|
||||
#undef POLYNOMIAL_COEF_INIT
|
||||
#undef POLYNOMIAL_COEF_FREE
|
||||
#undef POLYNOMIAL_COEF_SET
|
||||
#undef POLYNOMIAL_COEF_SET_SI
|
||||
#undef POLYNOMIAL_COEF_SET_UI
|
||||
#undef POLYNOMIAL_COEF_CPY
|
||||
#undef POLYNOMIAL_COEF_CPY_D
|
||||
#undef POLYNOMIAL_COEF_ADD
|
||||
#undef POLYNOMIAL_COEF_ADD_D
|
||||
#undef POLYNOMIAL_COEF_MUL
|
||||
#undef POLYNOMIAL_COEF_MUL_ORDER
|
||||
#undef POLYNOMIAL_COEF_DIV_UI
|
||||
#undef POLYNOMIAL_COEF_POW_UI
|
||||
#undef POLYNOMIAL_COEF_PRINT
|
||||
#undef POLYNOMIAL_ORDER_TYPE
|
||||
#undef POLYNOMIAL_ORDERSARRAY_TYPE
|
||||
#undef POLYNOMIAL_ORDERSARRAY_FUNC
|
||||
#undef POLYNOMIAL_ORDER_INIT
|
||||
#undef POLYNOMIAL_ORDER_FREE
|
||||
#undef POLYNOMIAL_ORDER_SET
|
||||
#undef POLYNOMIAL_ORDER_SET_UI
|
||||
#undef POLYNOMIAL_ORDER_CPY
|
||||
#undef POLYNOMIAL_ORDER_CPY_UI
|
||||
#undef POLYNOMIAL_ORDER_ADD
|
||||
#undef POLYNOMIAL_ORDER_SUB_UI
|
||||
#undef POLYNOMIAL_ORDER_CMP
|
||||
#undef POLYNOMIAL_ORDER_CMP_UI
|
||||
#undef POLYNOMIAL_ORDER_PRINT
|
||||
|
||||
// name of the polynomial type
|
||||
#define POLYNOMIAL_TYPENAME polynomial_ldouble
|
||||
// prefix of function names
|
||||
#define POLYNOMIAL_FUNC(NAME) polynomial_ldouble_ ## NAME
|
||||
|
||||
// type of the coefficient
|
||||
#define POLYNOMIAL_COEF_TYPE long double
|
||||
// type of coefficient arrays
|
||||
#define POLYNOMIAL_COEFSARRAY_TYPE array_ldouble
|
||||
// prefix of coefficient array function names
|
||||
#define POLYNOMIAL_COEFSARRAY_FUNC(NAME) array_ldouble_ ## NAME
|
||||
// set coefficient
|
||||
#define POLYNOMIAL_COEF_SET(COEF, VAL) COEF=VAL
|
||||
// set coefficient from signed int
|
||||
#define POLYNOMIAL_COEF_SET_SI(COEF, VAL) COEF=(long double)VAL
|
||||
// set coefficient from unsigned int
|
||||
#define POLYNOMIAL_COEF_SET_UI(COEF, VAL) COEF=(long double)VAL
|
||||
// copy coefficient
|
||||
#define POLYNOMIAL_COEF_CPY(VAL, COEF) COEF=VAL
|
||||
// copy coefficient from double
|
||||
#define POLYNOMIAL_COEF_CPY_D(VAL, COEF) COEF=(long double)VAL
|
||||
// add coefficients
|
||||
#define POLYNOMIAL_COEF_ADD(COEF, VAL1, VAL2) COEF=VAL1+VAL2
|
||||
// add coefficients, one of which is specified as a double
|
||||
#define POLYNOMIAL_COEF_ADD_D(COEF, VAL1, VAL2) COEF=VAL1+(long double)VAL2
|
||||
// multiply coefficients
|
||||
#define POLYNOMIAL_COEF_MUL(COEF, VAL1, VAL2) COEF=VAL1*VAL2
|
||||
// multiply coefficients, one of which is specified as a POLYNOMIAL_ORDER_TYPE
|
||||
#define POLYNOMIAL_COEF_MUL_ORDER(COEF, VAL1, VAL2) COEF=VAL1*(long double)VAL2
|
||||
// divide coefficients, one of which is specified as an unsigned int
|
||||
#define POLYNOMIAL_COEF_DIV_UI(COEF, VAL1, VAL2) COEF=VAL1/(long double)VAL2
|
||||
// power of a coefficient, specified as an unsigned int
|
||||
#define POLYNOMIAL_COEF_POW_UI(COEF, VAL1, VAL2) COEF=powl(VAL1, (long double)VAL2)
|
||||
// print a coefficient
|
||||
#define POLYNOMIAL_COEF_PRINT(COEF) fprint_ldouble(stdout, COEF)
|
||||
|
||||
// type of the order
|
||||
#define POLYNOMIAL_ORDER_TYPE unsigned int
|
||||
// type of order arrays
|
||||
#define POLYNOMIAL_ORDERSARRAY_TYPE array_uint
|
||||
// prefix of order array function names
|
||||
#define POLYNOMIAL_ORDERSARRAY_FUNC(NAME) array_uint_ ## NAME
|
||||
// set order
|
||||
#define POLYNOMIAL_ORDER_SET(ORDER, VAL) ORDER=VAL
|
||||
// set order from unsigned int
|
||||
#define POLYNOMIAL_ORDER_SET_UI(ORDER, VAL) ORDER=VAL
|
||||
// copy order
|
||||
#define POLYNOMIAL_ORDER_CPY(VAL, ORDER) ORDER=VAL
|
||||
// copy order from unsigned int
|
||||
#define POLYNOMIAL_ORDER_CPY_UI(VAL, ORDER) ORDER=VAL
|
||||
// add orders
|
||||
#define POLYNOMIAL_ORDER_ADD(ORDER, VAL1, VAL2) ORDER=VAL1+VAL2
|
||||
// subtract an order and an unsigned integer
|
||||
#define POLYNOMIAL_ORDER_SUB_UI(ORDER, VAL1, VAL2) ORDER=VAL1-VAL2
|
||||
// compare orders (0 if equal, -1 if <, +1 if >)
|
||||
#define POLYNOMIAL_ORDER_CMP(VAL1, VAL2) (int)VAL1-(int)VAL2
|
||||
// compare orders, one of which is specified as an unsigned int (0 if equal, -1 if <, +1 if >)
|
||||
#define POLYNOMIAL_ORDER_CMP_UI(VAL1, VAL2) (int)VAL1-(int)VAL2
|
||||
// print orders
|
||||
#define POLYNOMIAL_ORDER_PRINT(ORDER) printf("%u",ORDER)
|
||||
|
121
src/polynomial_mpfr.h
Normal file
121
src/polynomial_mpfr.h
Normal file
@ -0,0 +1,121 @@
|
||||
/*
|
||||
Copyright 2016 Ian Jauslin
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Preprocessor macros for real polynomials with multi-precision float (mpfr) coefficients and unsigned integer powers
|
||||
*/
|
||||
|
||||
|
||||
// reset CPP macros
|
||||
#undef POLYNOMIAL_TYPENAME
|
||||
#undef POLYNOMIAL_FUNC
|
||||
#undef POLYNOMIAL_COEF_TYPE
|
||||
#undef POLYNOMIAL_COEFSARRAY_TYPE
|
||||
#undef POLYNOMIAL_COEFSARRAY_FUNC
|
||||
#undef POLYNOMIAL_COEF_INIT
|
||||
#undef POLYNOMIAL_COEF_FREE
|
||||
#undef POLYNOMIAL_COEF_SET
|
||||
#undef POLYNOMIAL_COEF_SET_SI
|
||||
#undef POLYNOMIAL_COEF_SET_UI
|
||||
#undef POLYNOMIAL_COEF_CPY
|
||||
#undef POLYNOMIAL_COEF_CPY_D
|
||||
#undef POLYNOMIAL_COEF_ADD
|
||||
#undef POLYNOMIAL_COEF_ADD_D
|
||||
#undef POLYNOMIAL_COEF_MUL
|
||||
#undef POLYNOMIAL_COEF_MUL_ORDER
|
||||
#undef POLYNOMIAL_COEF_DIV_UI
|
||||
#undef POLYNOMIAL_COEF_POW_UI
|
||||
#undef POLYNOMIAL_COEF_PRINT
|
||||
#undef POLYNOMIAL_ORDER_TYPE
|
||||
#undef POLYNOMIAL_ORDERSARRAY_TYPE
|
||||
#undef POLYNOMIAL_ORDERSARRAY_FUNC
|
||||
#undef POLYNOMIAL_ORDER_INIT
|
||||
#undef POLYNOMIAL_ORDER_FREE
|
||||
#undef POLYNOMIAL_ORDER_SET
|
||||
#undef POLYNOMIAL_ORDER_SET_UI
|
||||
#undef POLYNOMIAL_ORDER_CPY
|
||||
#undef POLYNOMIAL_ORDER_CPY_UI
|
||||
#undef POLYNOMIAL_ORDER_ADD
|
||||
#undef POLYNOMIAL_ORDER_SUB_UI
|
||||
#undef POLYNOMIAL_ORDER_CMP
|
||||
#undef POLYNOMIAL_ORDER_CMP_UI
|
||||
#undef POLYNOMIAL_ORDER_PRINT
|
||||
|
||||
// name of the polynomial type
|
||||
#define POLYNOMIAL_TYPENAME polynomial_mpfr
|
||||
// prefix of function names
|
||||
#define POLYNOMIAL_FUNC(NAME) polynomial_mpfr_ ## NAME
|
||||
|
||||
// type of the coefficient
|
||||
#define POLYNOMIAL_COEF_TYPE mpfr_t
|
||||
// type of coefficient arrays
|
||||
#define POLYNOMIAL_COEFSARRAY_TYPE array_mpfr
|
||||
// prefix of coefficient array function names
|
||||
#define POLYNOMIAL_COEFSARRAY_FUNC(NAME) array_mpfr_ ## NAME
|
||||
// init coefficient
|
||||
#define POLYNOMIAL_COEF_INIT(VAR) mpfr_init(VAR)
|
||||
// free coefficient
|
||||
#define POLYNOMIAL_COEF_FREE(VAR) mpfr_clear(VAR)
|
||||
// set coefficient
|
||||
#define POLYNOMIAL_COEF_SET(COEF, VAL) COEF[0]=VAL[0]
|
||||
// set coefficient from signed int
|
||||
#define POLYNOMIAL_COEF_SET_SI(COEF, VAL) mpfr_set_si(COEF, VAL, MPFR_RNDN)
|
||||
// set coefficient from unsigned int
|
||||
#define POLYNOMIAL_COEF_SET_UI(COEF, VAL) mpfr_set_ui(COEF, VAL, MPFR_RNDN)
|
||||
// copy coefficient
|
||||
#define POLYNOMIAL_COEF_CPY(VAL, COEF) mpfr_init(COEF); mpfr_set(COEF, VAL, MPFR_RNDN)
|
||||
// copy coefficient from double
|
||||
#define POLYNOMIAL_COEF_CPY_D(VAL, COEF) mpfr_init(COEF); mpfr_set_d(COEF, VAL, MPFR_RNDN)
|
||||
// add coefficients
|
||||
#define POLYNOMIAL_COEF_ADD(COEF, VAL1, VAL2) mpfr_add(COEF, VAL1, VAL2, MPFR_RNDN)
|
||||
// add coefficients, one of which is specified as a double
|
||||
#define POLYNOMIAL_COEF_ADD_D(COEF, VAL1, VAL2) mpfr_add_d(COEF, VAL1, VAL2, MPFR_RNDN)
|
||||
// multiply coefficients
|
||||
#define POLYNOMIAL_COEF_MUL(COEF, VAL1, VAL2) mpfr_mul(COEF, VAL1, VAL2, MPFR_RNDN)
|
||||
// multiply coefficients, one of which is specified as a POLYNOMIAL_ORDER_TYPE
|
||||
#define POLYNOMIAL_COEF_MUL_ORDER(COEF, VAL1, VAL2) mpfr_mul_ui(COEF, VAL1, VAL2, MPFR_RNDN)
|
||||
// divide coefficients, one of which is specified as an unsigned int
|
||||
#define POLYNOMIAL_COEF_DIV_UI(COEF, VAL1, VAL2) mpfr_div_ui(COEF, VAL1, VAL2, MPFR_RNDN)
|
||||
// power of a coefficient, specified as an unsigned int
|
||||
#define POLYNOMIAL_COEF_POW_UI(COEF, VAL1, VAL2) mpfr_pow_ui(COEF, VAL1, VAL2, MPFR_RNDN)
|
||||
// print a coefficient
|
||||
#define POLYNOMIAL_COEF_PRINT(COEF) fprint_mpfr(stdout, COEF)
|
||||
|
||||
// type of the order
|
||||
#define POLYNOMIAL_ORDER_TYPE unsigned int
|
||||
// type of order arrays
|
||||
#define POLYNOMIAL_ORDERSARRAY_TYPE array_uint
|
||||
// prefix of order array function names
|
||||
#define POLYNOMIAL_ORDERSARRAY_FUNC(NAME) array_uint_ ## NAME
|
||||
// set order
|
||||
#define POLYNOMIAL_ORDER_SET(ORDER, VAL) ORDER=VAL
|
||||
// set order from unsigned int
|
||||
#define POLYNOMIAL_ORDER_SET_UI(ORDER, VAL) ORDER=VAL
|
||||
// copy order
|
||||
#define POLYNOMIAL_ORDER_CPY(VAL, ORDER) ORDER=VAL
|
||||
// copy order from unsigned int
|
||||
#define POLYNOMIAL_ORDER_CPY_UI(VAL, ORDER) ORDER=VAL
|
||||
// add orders
|
||||
#define POLYNOMIAL_ORDER_ADD(ORDER, VAL1, VAL2) ORDER=VAL1+VAL2
|
||||
// subtract an order and an unsigned integer
|
||||
#define POLYNOMIAL_ORDER_SUB_UI(ORDER, VAL1, VAL2) ORDER=VAL1-VAL2
|
||||
// compare orders (0 if equal, -1 if <, +1 if >)
|
||||
#define POLYNOMIAL_ORDER_CMP(VAL1, VAL2) (int)VAL1-(int)VAL2
|
||||
// compare orders, one of which is specified as an unsigned int (0 if equal, -1 if <, +1 if >)
|
||||
#define POLYNOMIAL_ORDER_CMP_UI(VAL1, VAL2) (int)VAL1-(int)VAL2
|
||||
// print orders
|
||||
#define POLYNOMIAL_ORDER_PRINT(ORDER) printf("%u",ORDER)
|
||||
|
27
src/polynomial_type.h
Normal file
27
src/polynomial_type.h
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
Copyright 2016 Ian Jauslin
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Structure definition for real polynomials
|
||||
|
||||
see polynomial_*.h for the values taken by POLYNOMIAL_TYPENAME, etc...
|
||||
*/
|
||||
|
||||
typedef struct POLYNOMIAL_TYPENAME {
|
||||
POLYNOMIAL_COEFSARRAY_TYPE coefficients;
|
||||
POLYNOMIAL_ORDERSARRAY_TYPE orders;
|
||||
} POLYNOMIAL_TYPENAME;
|
||||
|
51
src/root.c
Normal file
51
src/root.c
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
Copyright 2016 Ian Jauslin
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#include "root.h"
|
||||
|
||||
#include <mpfr.h>
|
||||
#include <math.h>
|
||||
#include "errors.h"
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
//
|
||||
// using doubles
|
||||
//
|
||||
//--------------------------------------------------
|
||||
|
||||
#include "root_double.h"
|
||||
#include "root_base.c"
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
//
|
||||
// using long doubles
|
||||
//
|
||||
//--------------------------------------------------
|
||||
|
||||
#include "root_ldouble.h"
|
||||
#include "root_base.c"
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
//
|
||||
// using mpfr floats
|
||||
//
|
||||
//--------------------------------------------------
|
||||
|
||||
#include "root_mpfr.h"
|
||||
#include "root_base.c"
|
57
src/root.h
Normal file
57
src/root.h
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
Copyright 2016 Ian Jauslin
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Root finding
|
||||
*/
|
||||
|
||||
#ifndef LIBINUM_ROOT_H
|
||||
#define LIBINUM_ROOT_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
//
|
||||
// using doubles
|
||||
//
|
||||
//--------------------------------------------------
|
||||
|
||||
#include "root_double.h"
|
||||
#include "root_base.h"
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
//
|
||||
// using long doubles
|
||||
//
|
||||
//--------------------------------------------------
|
||||
|
||||
#include "root_ldouble.h"
|
||||
#include "root_base.h"
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
//
|
||||
// using mpfr floats
|
||||
//
|
||||
//--------------------------------------------------
|
||||
|
||||
#include "root_mpfr.h"
|
||||
#include "root_base.h"
|
||||
|
||||
#endif
|
||||
|
134
src/root_base.c
Normal file
134
src/root_base.c
Normal file
@ -0,0 +1,134 @@
|
||||
/*
|
||||
Copyright 2016 Ian Jauslin
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Base functions for root finding
|
||||
|
||||
see integral_*.h for the values taken by ROOT_FUNC, etc...
|
||||
*/
|
||||
|
||||
|
||||
// compute the root of a real function of 1 variable using the Newton method
|
||||
int ROOT_FUNC(root_newton_inplace) (ROOT_FLOAT_TYPE* out, int (*func)(ROOT_FLOAT_TYPE*, ROOT_FLOAT_TYPE, void*), int (*deriv_func)(ROOT_FLOAT_TYPE*, ROOT_FLOAT_TYPE, void*), ROOT_FLOAT_TYPE tolerance, unsigned int maxiter, void* extra_args){
|
||||
unsigned int count=0;
|
||||
ROOT_FLOAT_TYPE valf, valdf, delta, tmp;
|
||||
int ret;
|
||||
|
||||
#ifdef ROOT_FLOAT_INIT
|
||||
ROOT_FLOAT_INIT(valf);
|
||||
ROOT_FLOAT_INIT(valdf);
|
||||
ROOT_FLOAT_INIT(delta);
|
||||
ROOT_FLOAT_INIT(tmp);
|
||||
#endif
|
||||
|
||||
// evaluate at guess
|
||||
ret=(*func)(&valf, *out, extra_args);
|
||||
if(ret<0){
|
||||
#ifdef ROOT_FLOAT_FREE
|
||||
ROOT_FLOAT_FREE(valf);
|
||||
ROOT_FLOAT_FREE(valdf);
|
||||
ROOT_FLOAT_FREE(delta);
|
||||
ROOT_FLOAT_FREE(tmp);
|
||||
#endif
|
||||
return(ret);
|
||||
}
|
||||
// check that valf is a number
|
||||
if(! ROOT_FLOAT_ISNUMBER(valf)){
|
||||
#ifdef ROOT_FLOAT_FREE
|
||||
ROOT_FLOAT_FREE(valf);
|
||||
ROOT_FLOAT_FREE(valdf);
|
||||
ROOT_FLOAT_FREE(delta);
|
||||
ROOT_FLOAT_FREE(tmp);
|
||||
#endif
|
||||
return(LIBINUM_ERROR_NAN);
|
||||
}
|
||||
|
||||
ROOT_FLOAT_ABS(delta, valf);
|
||||
|
||||
// loop until tolerance is reached
|
||||
while(ROOT_FLOAT_CMP(delta, tolerance) > 0 && count < maxiter){
|
||||
// new guess
|
||||
(*deriv_func)(&valdf, *out, extra_args);
|
||||
if(ret<0){
|
||||
#ifdef ROOT_FLOAT_FREE
|
||||
ROOT_FLOAT_FREE(valf);
|
||||
ROOT_FLOAT_FREE(valdf);
|
||||
ROOT_FLOAT_FREE(delta);
|
||||
ROOT_FLOAT_FREE(tmp);
|
||||
#endif
|
||||
return(ret);
|
||||
}
|
||||
// check that valdf is a number that is not 0
|
||||
if(! ROOT_FLOAT_ISNUMBER(valdf) || ROOT_FLOAT_ISZERO(valdf)){
|
||||
#ifdef ROOT_FLOAT_FREE
|
||||
ROOT_FLOAT_FREE(valf);
|
||||
ROOT_FLOAT_FREE(valdf);
|
||||
ROOT_FLOAT_FREE(delta);
|
||||
ROOT_FLOAT_FREE(tmp);
|
||||
#endif
|
||||
return(LIBINUM_ERROR_NAN);
|
||||
}
|
||||
|
||||
ROOT_FLOAT_DIV(tmp, valf, valdf);
|
||||
ROOT_FLOAT_SUB(*out, *out, tmp);
|
||||
|
||||
// evaluate at new guess
|
||||
(*func)(&valf, *out, extra_args);
|
||||
if(ret<0){
|
||||
#ifdef ROOT_FLOAT_FREE
|
||||
ROOT_FLOAT_FREE(valf);
|
||||
ROOT_FLOAT_FREE(valdf);
|
||||
ROOT_FLOAT_FREE(delta);
|
||||
ROOT_FLOAT_FREE(tmp);
|
||||
#endif
|
||||
return(ret);
|
||||
}
|
||||
// check that valf is a number
|
||||
if(! ROOT_FLOAT_ISNUMBER(valf)){
|
||||
#ifdef ROOT_FLOAT_FREE
|
||||
ROOT_FLOAT_FREE(valf);
|
||||
ROOT_FLOAT_FREE(valdf);
|
||||
ROOT_FLOAT_FREE(delta);
|
||||
ROOT_FLOAT_FREE(tmp);
|
||||
#endif
|
||||
return(LIBINUM_ERROR_NAN);
|
||||
}
|
||||
|
||||
ROOT_FLOAT_ABS(delta, valf);
|
||||
|
||||
// increase counter
|
||||
count++;
|
||||
}
|
||||
|
||||
// free variables
|
||||
#ifdef ROOT_FLOAT_FREE
|
||||
ROOT_FLOAT_FREE(valf);
|
||||
ROOT_FLOAT_FREE(valdf);
|
||||
ROOT_FLOAT_FREE(delta);
|
||||
ROOT_FLOAT_FREE(tmp);
|
||||
#endif
|
||||
|
||||
// fail if maxiter was reached
|
||||
if(count==maxiter){
|
||||
return(LIBINUM_ERROR_MAXITER);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
int ROOT_FUNC(root_newton) (ROOT_FLOAT_TYPE* out, int (*func)(ROOT_FLOAT_TYPE*, ROOT_FLOAT_TYPE, void*), int (*deriv_func)(ROOT_FLOAT_TYPE*, ROOT_FLOAT_TYPE, void*), ROOT_FLOAT_TYPE init, ROOT_FLOAT_TYPE tolerance, unsigned int maxiter, void* extra_args){
|
||||
ROOT_FLOAT_SET(*out, init);
|
||||
ROOT_FUNC(root_newton_inplace) (out, func, deriv_func, tolerance, maxiter, extra_args);
|
||||
return(0);
|
||||
}
|
27
src/root_base.h
Normal file
27
src/root_base.h
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
Copyright 2016 Ian Jauslin
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Base functions for root finding
|
||||
|
||||
see integral_*.h for the values taken by ROOT_FUNC, etc...
|
||||
*/
|
||||
|
||||
|
||||
// compute the root of a real function of 1 variable using the Newton method
|
||||
int ROOT_FUNC(root_newton_inplace) (ROOT_FLOAT_TYPE* out, int (*func)(ROOT_FLOAT_TYPE*, ROOT_FLOAT_TYPE, void*), int (*deriv_func)(ROOT_FLOAT_TYPE*, ROOT_FLOAT_TYPE, void*), ROOT_FLOAT_TYPE tolerance, unsigned int maxiter, void* extra_args);
|
||||
int ROOT_FUNC(root_newton) (ROOT_FLOAT_TYPE* out, int (*func)(ROOT_FLOAT_TYPE*, ROOT_FLOAT_TYPE, void*), int (*deriv_func)(ROOT_FLOAT_TYPE*, ROOT_FLOAT_TYPE, void*), ROOT_FLOAT_TYPE init, ROOT_FLOAT_TYPE tolerance, unsigned int maxiter, void* extra_args);
|
||||
|
55
src/root_double.h
Normal file
55
src/root_double.h
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
Copyright 2016 Ian Jauslin
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Preprocessor macros for root finding using doubles
|
||||
*/
|
||||
|
||||
|
||||
// reset CPP macros
|
||||
#undef ROOT_FUNC
|
||||
#undef ROOT_FLOAT_TYPE
|
||||
#undef ROOT_FLOAT_INIT
|
||||
#undef ROOT_FLOAT_FREE
|
||||
#undef ROOT_FLOAT_SET
|
||||
#undef ROOT_FLOAT_SUB
|
||||
#undef ROOT_FLOAT_DIV
|
||||
#undef ROOT_FLOAT_CMP
|
||||
#undef ROOT_FLOAT_ABS
|
||||
#undef ROOT_FLOAT_ISNUMBER
|
||||
#undef ROOT_FLOAT_ISZERO
|
||||
|
||||
|
||||
// suffix of function names
|
||||
#define ROOT_FUNC(NAME) NAME ## _double
|
||||
|
||||
// type of floats
|
||||
#define ROOT_FLOAT_TYPE double
|
||||
// set float
|
||||
#define ROOT_FLOAT_SET(FLOAT, VAL) FLOAT=VAL
|
||||
// subtract floats
|
||||
#define ROOT_FLOAT_SUB(FLOAT, VAL1, VAL2) FLOAT=VAL1-VAL2
|
||||
// divide floats
|
||||
#define ROOT_FLOAT_DIV(FLOAT, VAL1, VAL2) FLOAT=VAL1/VAL2
|
||||
// compare floats (0 if equal, -1 if <, +1 if >)
|
||||
#define ROOT_FLOAT_CMP(VAL1, VAL2) VAL1-VAL2
|
||||
// abs of float
|
||||
#define ROOT_FLOAT_ABS(FLOAT, VAL) FLOAT=fabs(VAL)
|
||||
// check whether a float is a regular number
|
||||
#define ROOT_FLOAT_ISNUMBER(FLOAT) (fpclassify(FLOAT)>=FP_ZERO)
|
||||
// whether float is 0
|
||||
#define ROOT_FLOAT_ISZERO(VAL) (VAL==0.)
|
||||
|
55
src/root_ldouble.h
Normal file
55
src/root_ldouble.h
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
Copyright 2016 Ian Jauslin
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Preprocessor macros for root finding using long doubles
|
||||
*/
|
||||
|
||||
|
||||
// reset CPP macros
|
||||
#undef ROOT_FUNC
|
||||
#undef ROOT_FLOAT_TYPE
|
||||
#undef ROOT_FLOAT_INIT
|
||||
#undef ROOT_FLOAT_FREE
|
||||
#undef ROOT_FLOAT_SET
|
||||
#undef ROOT_FLOAT_SUB
|
||||
#undef ROOT_FLOAT_DIV
|
||||
#undef ROOT_FLOAT_CMP
|
||||
#undef ROOT_FLOAT_ABS
|
||||
#undef ROOT_FLOAT_ISNUMBER
|
||||
#undef ROOT_FLOAT_ISZERO
|
||||
|
||||
|
||||
// suffix of function names
|
||||
#define ROOT_FUNC(NAME) NAME ## _ldouble
|
||||
|
||||
// type of floats
|
||||
#define ROOT_FLOAT_TYPE long double
|
||||
// set float
|
||||
#define ROOT_FLOAT_SET(FLOAT, VAL) FLOAT=VAL
|
||||
// subtract floats
|
||||
#define ROOT_FLOAT_SUB(FLOAT, VAL1, VAL2) FLOAT=VAL1-VAL2
|
||||
// divide floats
|
||||
#define ROOT_FLOAT_DIV(FLOAT, VAL1, VAL2) FLOAT=VAL1/VAL2
|
||||
// compare floats (0 if equal, -1 if <, +1 if >)
|
||||
#define ROOT_FLOAT_CMP(VAL1, VAL2) VAL1-VAL2
|
||||
// abs of float
|
||||
#define ROOT_FLOAT_ABS(FLOAT, VAL) FLOAT=fabsl(VAL)
|
||||
// check whether a float is a regular number
|
||||
#define ROOT_FLOAT_ISNUMBER(FLOAT) (fpclassify(FLOAT)>=FP_ZERO)
|
||||
// whether float is 0
|
||||
#define ROOT_FLOAT_ISZERO(VAL) (VAL==0.)
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user