| Metadata | Details |
|---|---|
| Date | 2026-09-04 |
| Version (package) | 3.3.0-1 |
| Version (asset) | 3.3.0 |
| Author | Matteo P. |
| URL | https://github.com/pmatteo68/bifpack-java |
A complete Java 8 reimplementation of BIFPACK 3.3, the FORTRAN 77 numerical library by Rudiger Seydel for continuation, bifurcation, and stability analysis of nonlinear algebraic and differential equations. All original algorithms are faithfully reproduced -- pseudo-arclength continuation, damped Newton iteration, Householder QR factorization, RKF7 integration, multiple shooting for BVPs, Hopf detection, branch switching, and Floquet/monodromy stability analysis. The result is a self-contained Maven project that requires no FORTRAN toolchain at runtime.
BIFPACK was written by Rudiger Seydel [7][8], mathematician and author of the reference text "Practical Bifurcation and Stability Analysis" [1]. The library accompanied the third edition of that book (Springer, 2010) and provided working FORTRAN 77 implementations of the numerical methods described therein. Version 3.3 (1999) is the version ported here.
The original package covers a broad range of computational tasks in nonlinear analysis:
- Continuation and path-following for algebraic systems (CONTA), BVPs (CONTB), and periodic orbits (CONTD), all using pseudo-arclength parameterisation.
- A damped Newton solver with lambda-strategy (NOLE) backed by Businger-Golub QR factorization with column pivoting (BGDECO/BGSOLV).
- A 7th-order Runge-Kutta-Fehlberg ODE integrator (RKF7, 13-stage Fehlberg 7(6) tableau).
- A multiple-shooting BVP solver (ODEBC1) with rank-1 corrections and monotonicity tests.
- Bifurcation test functions (TESTA, TESTB), branch switching (SWITA, SWITB), and automated bifurcation location via sign-change tracking and bisection (LOCATE).
- Hopf bifurcation detection by the augmented 3N+2 steady-state system (HOPFA) and the dynamic BVP method (HOPF/FABZ).
- Stability of stationary solutions via Jacobian eigenvalues (STASTA) and stability of periodic orbits via monodromy/Floquet multipliers (STAPER, MONOD, MONOD2).
- Period-doubling detection (DOUBLING) and primary BVP bifurcation scan (PBP).
The Java port replaces EISPACK (BALANC, ELMHES, HQR) with Apache Commons Math 3 EigenDecomposition [2], eliminates FORTRAN COMMON blocks in favour of a single ContinuationContext object, and exposes EXTERNAL subroutine arguments as Java 8 functional interfaces.
- Java 8 or later
- Maven 3.6 or later
- Internet access for the first build (Maven downloads dependencies automatically)
No FORTRAN compiler, native library, JNI, or JNA is required at runtime.
org.de.seydel.bifpack
.api -- public functional interfaces and value types (VectorFunction, etc.)
.core -- ContinuationContext (replaces all FORTRAN COMMON blocks)
.linalg -- HouseholderQr (BGDECO/BGSOLV), Eigenvalues wrapper
.nonlinear -- NewtonSolver (NOLE)
.ode -- Rkf7, MultipleShootingSolver (ODEBC1), BvpSolver (SOLVER/DATEN)
.continuation -- ContinuationAlgebraic (CONTA), ContinuationBvp (CONTB),
ContinuationPeriodic (CONTD)
.bifurcation -- TestFunctionAlgebraic (TESTA), TestFunctionBvp (TESTB),
BranchSwitcherAlgebraic (SWITA), BranchSwitcherBvp (SWITB),
BifurcationLocator (LOCATE), HopfPoint (HOPFA),
PrimaryBifurcationPoints (PBP)
.periodic -- HopfBifurcation (HOPF/FABZ), PeriodDoubling (DOUBLING),
PhaseChecker (CHECKPHASE)
.stability -- StabilityStationary (STASTA), StabilityPeriodic (STAPER),
MonodromyMatrix (MONOD/MONOD2)
.io -- BifpackOutput (formatted solution output)
.examples.* -- all ported example programs (see table below)
The packages form a strict layered dependency. Lower layers have no knowledge of
higher layers; api and core are the shared foundation used by everything above them.
examples.*
+-- continuation (CONTA / CONTB / CONTD)
| +-- bifurcation
| +-- ode
| +-- nonlinear
| +-- core
+-- bifurcation (TESTA / TESTB / SWITA / SWITB / LOCATE / PBP)
| +-- ode
| +-- linalg
| +-- core
+-- periodic (HOPF / FABZ / DOUBLING)
| +-- bifurcation
| +-- ode
| +-- core
+-- stability (STASTA / STAPER / MONOD)
| +-- ode
| +-- linalg
| +-- core
+-- io
| +-- core
+-- ode (Rkf7 / ODEBC1 / BvpSolver)
| +-- nonlinear
| +-- linalg
| +-- core
| +-- api
+-- nonlinear (NOLE)
| +-- linalg
| +-- api
+-- linalg (BGDECO / BGSOLV)
+-- core (ContinuationContext)
| +-- api
+-- api (VectorFunction, BoundaryCondition, ...)
graph TD
subgraph L5["Layer 5 - examples"]
EX["examples.*"]
end
subgraph L4["Layer 4 - analysis"]
CO["continuation (CONTA/CONTB/CONTD)"]
BI["bifurcation (TESTA/TESTB/SWITA/SWITB/LOCATE/PBP)"]
PE["periodic (HOPF/FABZ/DOUBLING)"]
ST["stability (STASTA/STAPER/MONOD)"]
IO["io"]
end
subgraph L3["Layer 3 - ODE and BVP"]
OD["ode (Rkf7/ODEBC1/BvpSolver)"]
end
subgraph L2["Layer 2 - numerics"]
NL["nonlinear (NOLE)"]
LA["linalg (BGDECO/BGSOLV)"]
end
subgraph L1["Layer 1 - state"]
CX["core (ContinuationContext)"]
end
subgraph L0["Layer 0 - API"]
AP["api (VectorFunction, BoundaryCondition)"]
end
EX --> CO
EX --> BI
EX --> PE
EX --> ST
EX --> IO
EX --> OD
CO --> BI
CO --> OD
CO --> NL
CO --> CX
BI --> OD
BI --> LA
BI --> CX
PE --> BI
PE --> OD
PE --> CX
ST --> OD
ST --> LA
ST --> CX
IO --> CX
OD --> NL
OD --> LA
OD --> CX
OD --> AP
NL --> LA
NL --> AP
CX --> AP
The three diagrams below trace the control flow through the most important computational pipelines in the library.
The outer loop that drives all continuation. A tangent predictor advances along the solution branch; a Newton corrector projects back onto it. The test function monitors for bifurcations at every accepted step.
[initial point x0, lambda0]
|
v
[compute tangent: null vector of augmented Jacobian]
|
v
[predict: x_pred = x + ds * tangent]
|
v
[Newton corrector: solve augmented system]
|
converged? --no--> halve step ds, go back to predict
|
yes
|
v
[evaluate test function psi (TESTA or TESTB)]
|
sign change in psi? --no---------------------------+
| |
yes |
| |
v |
[LOCATE: bisect to bifurcation point lambda*] |
| |
branch switch? --no--> record point |
| | |
yes | |
| v v
v [continue on [step accepted]
[SWITA / SWITB: original branch] |
new branch start] v
[adapt step size ds]
|
end condition? --no--> go to tangent
|
yes
|
v
[Done]
flowchart TD
A([Start]) --> B["Initial point x0, lambda0"]
B --> C["Compute tangent: null vector of augmented Jacobian"]
C --> D["Predict: x_pred = x + ds * tangent"]
D --> E{"Newton corrector\nconverged?"}
E -- no --> F["Halve step ds\nretry predictor"]
F --> C
E -- yes --> G["Evaluate test function psi\nTESTA or TESTB"]
G --> H{"Sign change\nin psi?"}
H -- yes --> I["LOCATE: bisect to lambda*"]
I --> J{"Branch switch?"}
J -- yes --> K["SWITA / SWITB\nnew branch start"]
J -- no --> L["Record bifurcation\ncontinue on original branch"]
H -- no --> M["Step accepted"]
L --> M
M --> N["Adapt step size ds"]
N --> O{"End condition\nmet?"}
O -- no --> C
O -- yes --> P([Done])
K --> P
Each Newton iteration integrates the ODE over every shooting interval, assembles a block-structured residual from the shooting gaps and the boundary conditions, then solves the resulting linear system by Householder QR with column pivoting.
INPUT: shooting nodes s[0..M-1], ODE f, BCs g, tolerance eps
|
v
[for each interval j = 0..M-2:]
[ integrate: Rkf7(t_j, t_{j+1}, s[j]) --> s_end_j, G_j (sensitivity matrix)]
|
v
[assemble residual F:]
[ shooting gaps: F_j = s[j+1] - G_j * s[j] for j = 0..M-2]
[ boundary conds: F_bc = g(s[0], s[M-1])]
|
v
[build block Jacobian from {G_j}, bcJac, bcJacYb]
|
v
[HouseholderQr decompose (BGDECO): column-pivoting QR]
|
v
[solve for Newton step dx (BGSOLV)]
|
monotonicity: ||F(x+dx)|| < ||F(x)|| ? --no--> damp dx = dx/2, retry solve
|
yes
|
v
[accept: x = x + dx, update shooting nodes]
|
converged: ||F|| < eps ? --no--> go back to integrate
|
yes
|
v
OUTPUT: updated nodes + propagator matrices G_j
(consumed by TestFunctionBvp and BranchSwitcherBvp)
flowchart TD
A([BvpSolver.solve]) --> B["Integrate each interval j with Rkf7\ns_end_j, G_j = Rkf7(t_j, t_{j+1}, s_j)"]
B --> C["Assemble residual F:\nshooting gaps F_j = s_{j+1} - G_j*s_j\nboundary conds F_bc = g(s_0, s_{M-1})"]
C --> D["Build block Jacobian\nfrom G_j, bcJac, bcJacYb"]
D --> E["HouseholderQr decompose (BGDECO)\ncolumn-pivoting QR"]
E --> F["Solve for Newton step dx (BGSOLV)"]
F --> G{"Monotonicity test\n||F(x+dx)|| < ||F(x)||?"}
G -- no --> H["Damp: dx = dx / 2\nretry"]
H --> G
G -- yes --> I["Accept: x = x + dx\nupdate shooting nodes"]
I --> J{"Converged?\n||F|| < eps"}
J -- no --> B
J -- yes --> K(["Return nodes + G matrices\nused by TESTB and SWITB"])
The bordered-system approach evaluates the test function psi without ever computing det(E) directly. PBP drives a lambda scan; a sign change triggers bisection and then a branch switch using the null vector propagated to all shooting nodes.
INPUT: MultipleShootingSolver.Result (nodes, G_j, bcJac, bcJacYb)
|
v
[compute G_product = G_{M-2} * ... * G_0 (total state propagator)]
|
v
[form E = B_yb * G_product + A_bc (boundary-shooting matrix)]
|
v
[auto-detect indk: first component NOT fixed by Dirichlet BC]
[ scan bcJac rows for unit vectors (tolerance 1e-6)]
|
v
[save em = E[indl]; replace row indl with unit vector e_{indk}]
|
v
[solve bordered system: E_bordered * ha = e_{indl} (HouseholderQr)]
|
v
[compute psi = em^T * ha -- bifurcation test value]
|
v
[propagate null vector: vGrid_j = G_{j-1} * vGrid_{j-1}]
|
v --- TestFunctionBvp returns (psi, vGrid) ---
|
PBP scan: lambda from lambdaMin to lambdaMax
|
sign change: psi_prev * psi_curr < 0 ? --no--> advance lambda, save state
|
yes
|
v
[bisect to lambda*: quadratic interpolation + re-solve BVP]
|
v
[perturb all nodes: s_new_j = s_j + alpha * vGrid_j]
|
v
[re-solve BVP on perturbed guess (BranchSwitcherBvp / SWITB)]
|
converged? --no--> switch failed
|
yes
|
v
OUTPUT: new branch confirmed at lambda*
flowchart TD
A([TestFunctionBvp.evaluate]) --> B["G_product = G_{M-2} * ... * G_0\ntotal state propagator"]
B --> C["E = B_yb * G_product + A_bc\nboundary-shooting matrix"]
C --> D["Auto-detect indk:\nfirst component not fixed by Dirichlet BC\nscan bcJac rows for unit vectors"]
D --> E["Save em = E[indl]\nreplace row indl with e_{indk}"]
E --> F["Solve bordered system:\nE_bordered * ha = e_{indl} (HouseholderQr)"]
F --> G["Compute psi = em^T * ha\nbifurcation test value"]
G --> H["Propagate null vector:\nvGrid_j = G_{j-1} * vGrid_{j-1}"]
H --> I([Return psi and vGrid])
I --> J{"PBP scan:\nsign change psi_prev * psi_curr < 0?"}
J -- no --> K["Advance lambda, save state"]
K --> J
J -- yes --> L["Bisect to lambda*\nquadratic interpolation + re-solve"]
L --> M["Perturb nodes:\ns_j = s_j + alpha * vGrid_j"]
M --> N["Re-solve BVP\nBranchSwitcherBvp / SWITB"]
N --> O{"Converged?"}
O -- yes --> P([New branch at lambda*])
O -- no --> Q([Switch failed])
mvn package
This compiles all sources and runs the full test suite (39 tests). To skip tests:
mvn package -DskipTests
mvn test
All 39 unit and integration tests should pass. Tests cover HouseholderQr, Eigenvalues, NewtonSolver, Rkf7, MultipleShootingSolver/BvpSolver, StabilityStationary/Periodic, ContinuationAlgebraic, HopfPoint, and integration tests reproducing results from the original FORTRAN example programs.
Each example has a standard main entry point. Use the exec:java goal from the
org.codehaus.mojo exec plugin (no additional pom configuration required):
mvn compile exec:java -Dexec.mainClass=<fully-qualified-class-name>
| Id | Name | Fully-qualified class name | Description | Expected Result |
|---|---|---|---|---|
| 1 | exa1 | org.de.seydel.bifpack.examples.exa1.Example1Algebraic |
Brusselator 3-cell - algebraic continuation (CONTA) | Solution branch from lambda=1.435; 3 unstable eigenvalues reported |
| 2 | exa1m2 | org.de.seydel.bifpack.examples.exa1m2.Example1m2BranchSwitch |
Brusselator 3-cell - branch switching via LOCATE and SWITA | 5 genuine bifurcations detected; all 5 branch switches produce new solution branches |
| 3 | exa3 | org.de.seydel.bifpack.examples.exa3.Example3LorenzHopf |
Lorenz system - Hopf bifurcation location (HOPFA) | Hopf at lambda*=33.4545; analytic error < 1e-7 |
| 4 | exd1 | org.de.seydel.bifpack.examples.exd1.Example1Periodic |
Brusselator 2-cell - periodic orbit continuation (CONTD) | Hopf at lambda=5; Floquet multipliers mu_3,4 ~= 1 (trivial + Hopf modes confirmed) |
| 5 | exd2 | org.de.seydel.bifpack.examples.exd2.Example2Cstr |
CSTR - periodic orbit continuation (CONTD) | CSTR Hopf at lambda |
| 6 | exb1f | org.de.seydel.bifpack.examples.exb1f.Example1fCatalyst |
Catalyst BVP - automatic continuation loop (CONTB) | 2 branch points located at lambda |
| 7 | exb1m | org.de.seydel.bifpack.examples.exb1m.Example1mCatalyst |
Catalyst BVP - manual continuation loop | 35-step eta-continuation from eta=0.834 to eta=0.154; BC residual < 1e-19 |
| 8 | exb2f | org.de.seydel.bifpack.examples.exb2f.Example2fSuperconductivity |
Superconductivity BVP - automatic loop (CONTB) | 3 branch switches succeed (SWITB LEVEL=1) at eta~0.583, ~0.517, ~0.516 |
| 9 | exb2m | org.de.seydel.bifpack.examples.exb2m.Example2mSuperconductivity |
Superconductivity BVP - manual loop with SWITB | Branch switch succeeds: lambda=0.9124, y1(0)=0.5875 |
| 10 | exb2am | org.de.seydel.bifpack.examples.exb2am.Example2amSuperconductivityShooting |
Superconductivity BVP - multiple shooting (ODEBC1 direct) | Fold branch tracked 15 steps to turning point near lambda~0.921 |
| 11 | exb4 | org.de.seydel.bifpack.examples.exb4.Example4Brusselator |
Brusselator BVP - primary bifurcation scan (PBP) | 1 primary bifurcation at lambda=0.079834 (psi~0) |
| 12 | exb13 | org.de.seydel.bifpack.examples.exb13.Example13Olmstead |
Olmstead BVP - continuation and bifurcation scan | 4 primary bifurcations at lambda=(k*pi/2)^2: 2.467, 9.870, 22.21, 39.48 (k=1..4) |
Each printed solution point carries a label field (or an equivalent trailing column
in tabular output). The three possible values are:
| label | meaning |
|---|---|
| (blank) | Ordinary continuation step; nothing notable at this point. |
initial |
The starting point of the branch, before continuation began. |
T |
Turning point (fold): the parameter lambda reversed direction along the branch at this step. |
Turning points mark folds of the solution curve. In practice they indicate where the branch doubles back on itself in parameter space -- for example, the two folds of an S-shaped steady-state curve, or the tip of a fold branch in a BVP continuation.
The project targets Java 8. All source code (lambdas, functional interfaces, streams)
is valid Java 21+ without modification. Only pom.xml requires changes.
Java 25 dropped support for --release 8. Building on a Java 25+ JDK with the
current source=8 / target=8 settings produces a compiler error.
Replace the two properties with a single release property:
<!-- remove these two lines -->
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<!-- add this one line in their place -->
<maven.compiler.release>21</maven.compiler.release>maven.compiler.release is the preferred modern form: it sets source level, target
level, and bootstrap classpath in one value, preventing cross-version API leakage.
Use 21 (current LTS) or 25 (latest LTS as of 2025).
JUnit 4 with surefire 3.x on Java 17+ requires reflective access to test internals.
Surefire 3.x adds the necessary --add-opens flags automatically in most cases, so
tests usually pass without changes. If mvn test fails with
InaccessibleObjectException, either:
- add explicit
--add-opensto the surefire plugin configuration inpom.xml, or - migrate tests to JUnit 5 (
junit-jupiter 5.x).
Migrating to JUnit 5 requires updating the dependency and changing @Test imports;
the test logic itself does not change.
commons-math3 has no module-info.java and runs as an automatic module on the
classpath. The EigenDecomposition API used here is fully public. No changes needed
for Java 25+.
All Java 8 constructs in this codebase compile and run identically on Java 21+. No API was removed between Java 8 and Java 25 that this project relies on.
| Artifact | Version | Purpose |
|---|---|---|
org.apache.commons:commons-math3 |
3.6.1 | Eigenvalue decomposition (replaces EISPACK) |
junit:junit |
4.13.2 | Test framework (test scope only) |
All floating-point arithmetic uses Java double (64-bit IEEE 754), matching the
FORTRAN DOUBLE PRECISION type used throughout the original BIFPACK sources.
This section documents every significant piece of the original BIFPACK 3.3 source tree and records what happened to it in the Java port. The goal is to let anyone familiar with Seydel's FORTRAN navigate directly to the corresponding Java code, and to make every intentional omission explicit.
All routines in the table below are algorithmically complete: the Java implementation reproduces the same numerical steps, convergence criteria, and output as the FORTRAN original. Results match to floating-point precision in all 39 regression tests.
| FORTRAN source | FORTRAN routine(s) | Java class | Fidelity notes |
|---|---|---|---|
packa1.f |
CONTA |
continuation.ContinuationAlgebraic |
Exact: LEVEL 0/1/2, adaptive KCO/K2, curvature control, secant extrapolation, turning-point detection, WINDOW, STEPMP, IFINAL |
packa1.f |
STASTA |
stability.StabilityStationary |
Exact: Jacobian eigenvalues, unstable-mode count |
packa2.f |
TESTA |
bifurcation.TestFunctionAlgebraic |
Exact: bordered-system test function for algebraic systems |
packa2.f |
SWITA |
bifurcation.BranchSwitcherAlgebraic |
Exact: all three switching methods (1 = null-vector perturbation, 2 = fold, 3 = manual) |
packa2.f |
LOCATE |
bifurcation.BifurcationLocator |
Exact: bisection with test-function sign tracking |
packa3.f |
HOPFA |
bifurcation.HopfPoint |
Exact: augmented 3N+2 steady-state system for Hopf locus |
packb1.f |
CONTB |
continuation.ContinuationBvp |
Exact: same pseudo-arclength algorithm as CONTA, applied to the BVP shooting grid |
packb2.f |
TESTB |
bifurcation.TestFunctionBvp |
Exact: bordered system with auto-detected indk (first state component not fixed by Dirichlet BC; tolerance 1e-6 accounts for finite-difference bcJac errors); null vector propagated to all shooting nodes |
packb2.f |
SWITB |
bifurcation.BranchSwitcherBvp |
Exact: LEVEL=1 interpolation to branch point, propagated null-vector perturbation, augmented re-solve |
packb3.f |
PBP |
bifurcation.PrimaryBifurcationPoints |
Exact: lambda scan, sign-change detection, quadratic bisection |
packd.f |
CONTD |
continuation.ContinuationPeriodic |
Exact: periodic-orbit continuation via shooting + monodromy |
packd.f |
HOPF / FABZ |
periodic.HopfBifurcation |
Exact: dynamic BVP method for Hopf detection |
packd.f |
DOUBLING |
periodic.PeriodDoubling |
Exact: period-doubling detection via Floquet multiplier -1 |
packd.f |
STAPER |
stability.StabilityPeriodic |
Exact: Floquet multiplier stability for periodic orbits |
packd.f |
MONOD / MONOD2 |
stability.MonodromyMatrix |
Exact: monodromy matrix integration by variational equations |
packd.f |
CHECKPHASE |
periodic.PhaseChecker |
Exact: phase condition enforcement for periodic solutions |
nole.f |
NOLE |
nonlinear.NewtonSolver |
Exact: damped Newton with lambda-strategy, monotonicity test |
linear.f |
BGDECO / BGSOLV |
linalg.HouseholderQr |
Exact: Businger-Golub QR with column pivoting [3]; row-major storage adapted for Java |
shoot.f |
ODEBC1 |
ode.MultipleShootingSolver |
Exact: multiple-shooting Newton loop with rank-1 corrections and monotonicity damping |
ode1.f |
RKF7 |
ode.Rkf7 |
Exact: 13-stage Fehlberg 7(6) tableau [4] with adaptive step control; sensitivity (variational) equations integrated simultaneously |
These are deliberate design changes that affect structure but not numerical behaviour.
| FORTRAN mechanism | Java equivalent | Rationale |
|---|---|---|
COMMON blocks (/ALLG/, /BVPC/, /PERC/, ...) |
core.ContinuationContext |
Single mutable object eliminates implicit global aliasing; passed explicitly |
EXTERNAL subroutine arguments (f, bc, g) |
api.VectorFunction, api.BoundaryCondition, api.PeriodCondition functional interfaces |
Idiomatic Java 8 lambdas replace FORTRAN callback convention |
| Column-major matrix storage (FORTRAN default) | Row-major double[][] |
All index arithmetic transposed consistently; no numerical difference |
EISPACK routines (BALANC, ELMHES, HQR) |
linalg.EigenvalueSolver wrapping Apache Commons Math 3 EigenDecomposition |
EISPACK is obsolete; Commons Math 3 is a well-tested drop-in; results agree on all test cases |
DOUBLE PRECISION throughout |
double throughout |
Identical 64-bit IEEE 754 representation; no mixed-precision code |
| 1-indexed arrays and loop bounds | 0-indexed Java arrays | All index offsets translated (e.g. FORTRAN INDL=1 -> Java indl=0) |
The following FORTRAN components were not ported. Each omission is deliberate and documented here so that nothing appears to be silently missing.
| FORTRAN source / routine | Reason for omission |
|---|---|
INTERA (interactive front-end) |
Terminal-menu driver with no useful Java analogue; replaced by the example programs and the public API |
CHECKDATA (input validator) |
Tightly coupled to INTERA's terminal I/O; its validation logic is subsumed by constructor preconditions and Javadoc contracts in the Java API |
BIFLAB (interactive front-end variant) |
Same rationale as INTERA |
dataman.f (post-processing file tool) |
Binary file management utility for the FORTRAN output format; Java users read results from the return values of the solver methods directly |
bifpoint.f (post-processing file tool) |
Same rationale as dataman.f |
No algorithmic routine from the BIFPACK source tree has been silently dropped or materially simplified. Every numerical method described in Seydel [1] and implemented in BIFPACK 3.3 [5] has a corresponding Java class.
This Java port is a derivative work of BIFPACK 3.3.
The original BIFPACK FORTRAN source code is:
BIFPACK -- a package for Bifurcation, Continuation, and Stability Analysis. Copyright (C) 1983, 1999 R. Seydel. Licensed under the GNU General Public License, version 2 or any later version.
Because this port is derived from that GPL-licensed work, it is distributed under the same terms: GNU General Public License v2 or later (GPL-2.0-or-later).
See LICENSE.md for the full copyright notice and links to the license text.
This project is an independent Java reimplementation created for study and research purposes. It is not affiliated with, endorsed by, or produced in collaboration with Prof. Rudiger Seydel [7][8] or Springer-Verlag.
The numerical algorithms, mathematical formulations, and example problems are derived from Seydel's work [1][5]. Full credit for the original design belongs to him.
Any errors, numerical discrepancies, or misbehaviour in this Java port are solely the responsibility of the porting author and have nothing to do with the correctness or quality of the original BIFPACK FORTRAN package.
This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
If you use this software in academic work, please cite the original reference [1] and acknowledge that the implementation is a Java port of BIFPACK 3.3 [5].
[1]: Rudiger Seydel, "Practical Bifurcation and Stability Analysis", 3rd ed., Springer, 2010. ISBN 978-1-4419-1739-3. https://link.springer.com/book/10.1007/978-1-4419-1740-9
[2]: Apache Commons Math 3 -- EigenDecomposition. https://commons.apache.org/proper/commons-math/javadocs/api-3.6.1/org/apache/commons/math3/linear/EigenDecomposition.html
[3]: P. A. Businger and G. H. Golub, "Linear least squares solutions by Householder transformations", Numerische Mathematik 7 (1965), pp. 269-276.
[4]: E. Fehlberg, "Klassische Runge-Kutta-Formeln siebenter und achter Ordnung mit Schrittweiten-Kontrolle", Computing 4 (1969), pp. 93-106.
[5]: R. Seydel, BIFPACK 3.3 FORTRAN source distribution (1999). Accompanying software for reference [1].
[6]: R. Seydel, bifurcation.de -- original BIFPACK FORTRAN software download. http://www.bifurcation.de/software.html
[7]: R. Seydel, academic page at the University of Cologne. http://www.mi.uni-koeln.de/~seydel/
[8]: R. Seydel, LinkedIn profile. https://www.linkedin.com/in/r%C3%BCdiger-seydel-26b5572a/