• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1.. _chapter-version-history:
2
3===============
4Version History
5===============
6
71.7.0
8=====
9
10Backward Incompatible API Changes
11---------------------------------
12
13#. ``Solver::Options::sparse_linear_algebra_library`` has been renamed
14   to ``Solver::Options::sparse_linear_algebra_library_type``.
15
16New Features
17------------
18
19#. Sparse and dense covariance estimation.
20#. A new Wolfe line search. (Alex Stewart)
21#. ``BFGS`` line search direction. (Alex Stewart)
22#. C API
23#. Speeded up the use of loss functions > 17x.
24#. Faster ``DENSE_QR``, ``DENSE_NORMAL_CHOLESKY`` and ``DENSE_SCHUR``
25   solvers.
26#. Support for multiple dense linear algebra backends. In particular
27   optimized ``BLAS`` and ``LAPACK`` implementations (e.g., Intel MKL,
28   ACML, OpenBLAS etc) can now be used to do the dense linear
29   algebra for ``DENSE_QR``, ``DENSE_NORMAL_CHOLESKY`` and
30   ``DENSE_SCHUR``
31#. Use of Inner iterations can now be adaptively stopped. Iteration
32   and runtime statistics for inner iterations are not reported in
33   ``Solver::Summary`` and ``Solver::Summary::FullReport``.
34#. Improved inner iteration step acceptance criterion.
35#. Add BlockRandomAccessCRSMatrix.
36#. Speeded up automatic differentiation by 7\%.
37#. Bundle adjustment example from libmv/Blender (Sergey Sharybin)
38#. Add the ability to turn shared library compilation on and off
39#. No more dependence on Protocol Buffers.
40#. Incomplete LQ factorization.
41#. Ability to write trust region problems to disk.
42#. Add sinh, cosh, tanh and tan functions to automatic differentiation
43   (Johannes Schönberger)
44#. Simplifications to the cmake build file.
45#. ``miniglog`` can now be used as a replacement for ``google-glog``
46   on non Android platforms. (This is NOT recommended).
47
48Bug Fixes
49---------
50
51#. Fix ``ITERATIVE_SCHUR`` solver to work correctly when the schur
52   complement is of size zero. (Soohyun Bae)
53#. Fix the ``spec`` file for generating ``RPM`` packages (Brian Pitts
54   and Taylor Braun-Jones).
55#. Fix how ceres calls CAMD (Manas Jagadev)
56#. Fix breakage on old versions of SuiteSparse. (Fisher Yu)
57#. Fix warning C4373 in Visual Studio (Petter Strandmark)
58#. Fix compilation error caused by missing suitesparse headers and
59   reorganize them to be more robust. (Sergey Sharybin)
60#. Check GCC Version before adding -fast compiler option on
61   OSX. (Steven Lovegrove)
62#. Add documentation for minimizer progress output.
63#. Lint and other cleanups (William Rucklidge and James Roseborough)
64#. Collections port fix for MSC 2008 (Sergey Sharybin)
65#. Various corrections and cleanups in the documentation.
66#. Change the path where CeresConfig.cmake is installed (Pablo
67   Speciale)
68#. Minor errors in documentation (Pablo Speciale)
69#. Updated depend.cmake to follow CMake IF convention. (Joydeep
70   Biswas)
71#. Stablize the schur ordering algorithm.
72#. Update license header in split.h.
73#. Enabling -O4 (link-time optimization) only if compiler/linker
74   support it. (Alex Stewart)
75#. Consistent glog path across files.
76#. ceres-solver.spec: Use cleaner, more conventional Release string
77   (Taylor Braun-Jones)
78#. Fix compile bug on RHEL6 due to missing header (Taylor Braun-Jones)
79#. CMake file is less verbose.
80#. Use the latest upstream version of google-test and gmock.
81#. Rationalize some of the variable names in ``Solver::Options``.
82#. Improve Summary::FullReport when line search is used.
83#. Expose line search parameters in ``Solver::Options``.
84#. Fix update of L-BFGS history buffers after they become full. (Alex
85   Stewart)
86#. Fix configuration error on systems without SuiteSparse installed
87   (Sergey Sharybin)
88#. Enforce the read call returns correct value in ``curve_fitting_c.c``
89   (Arnaud Gelas)
90#. Fix DynamicAutoDiffCostFunction (Richard Stebbing)
91#. Fix Problem::RemoveParameterBlock documentation (Johannes
92   Schönberger)
93#. Fix a logging bug in parameter_block.h
94#. Refactor the preconditioner class structure.
95#. Fix an uninitialized variable warning when building with ``GCC``.
96#. Fix a reallocation bug in
97   ``CreateJacobianBlockSparsityTranspose``. (Yuliy Schwartzburg)
98#. Add a define for O_BINARY.
99
100
1011.6.0
102=====
103
104New Features
105------------
106
107#. Major Performance improvements.
108
109   a. Schur type solvers (``SPARSE_SCHUR``, ``DENSE_SCHUR``,
110      ``ITERATIVE_SCHUR``) are significantly faster due to custom BLAS
111      routines and fewer heap allocations.
112
113   b. ``SPARSE_SCHUR`` when used with ``CX_SPARSE`` now uses a block
114      AMD for much improved factorization performance.
115
116   c. The jacobian matrix is pre-ordered so that
117      ``SPARSE_NORMAL_CHOLESKY`` and ``SPARSE_SCHUR`` do not have to
118      make copies inside ``CHOLMOD``.
119
120   d. Faster autodiff by replacing division by multplication by inverse.
121
122   e. When compiled without threads, the schur eliminator does not pay
123      the penalty for locking and unlocking mutexes.
124
125#. Users can now use ``linear_solver_ordering`` to affect the
126   fill-reducing ordering used by ``SUITE_SPARSE`` for
127   ``SPARSE_NORMAL_CHOLESKY``.
128#. ``Problem`` can now report the set of parameter blocks it knows about.
129#. ``TrustRegionMinimizer`` uses the evaluator to compute the gradient
130   instead of a matrix vector multiply.
131#. On ``Mac OS``, whole program optimization is enabled.
132#. Users can now use automatic differentiation to define new
133   ``LocalParameterization`` objects. (Sergey Sharybin)
134#. Enable larger tuple sizes for Visual Studio 2012. (Petter Strandmark)
135
136
137Bug Fixes
138---------
139
140#. Update the documentation for ``CostFunction``.
141#. Fixed a typo in the documentation. (Pablo Speciale)
142#. Fix a typo in suitesparse.cc.
143#. Bugfix in ``NumericDiffCostFunction``. (Nicolas Brodu)
144#. Death to BlockSparseMatrixBase.
145#. Change Minimizer::Options::min_trust_region_radius to double.
146#. Update to compile with stricter gcc checks. (Joydeep Biswas)
147#. Do not modify cached CMAKE_CXX_FLAGS_RELEASE. (Sergey Sharybin)
148#. ``<iterator>`` needed for back_insert_iterator. (Petter Strandmark)
149#. Lint cleanup. (William Rucklidge)
150#. Documentation corrections. (Pablo Speciale)
151
152
1531.5.0
154=====
155
156Backward Incompatible API Changes
157---------------------------------
158
159#. Added ``Problem::Evaluate``. Now you can evaluate a problem or any
160   part of it without calling the solver.
161
162   In light of this the following settings have been deprecated and
163   removed from the API.
164
165   - ``Solver::Options::return_initial_residuals``
166   - ``Solver::Options::return_initial_gradient``
167   - ``Solver::Options::return_initial_jacobian``
168   - ``Solver::Options::return_final_residuals``
169   - ``Solver::Options::return_final_gradient``
170   - ``Solver::Options::return_final_jacobian``
171
172   Instead we recommend using something like this.
173
174   .. code-block:: c++
175
176     Problem problem;
177     // Build problem
178
179     vector<double> initial_residuals;
180     problem.Evaluate(Problem::EvaluateOptions(),
181                      NULL, /* No cost */
182                      &initial_residuals,
183                      NULL, /* No gradient */
184                      NULL  /* No jacobian */ );
185
186     Solver::Options options;
187     Solver::Summary summary;
188     Solver::Solve(options, &problem, &summary);
189
190     vector<double> final_residuals;
191     problem.Evaluate(Problem::EvaluateOptions(),
192                      NULL, /* No cost */
193                      &final_residuals,
194                      NULL, /* No gradient */
195                      NULL  /* No jacobian */ );
196
197
198New Features
199------------
200#. Problem now supports removal of ParameterBlocks and
201   ResidualBlocks. There is a space/time tradeoff in doing this which
202   is controlled by
203   ``Problem::Options::enable_fast_parameter_block_removal``.
204
205#. Ceres now supports Line search based optimization algorithms in
206   addition to trust region algorithms. Currently there is support for
207   gradient descent, non-linear conjugate gradient and LBFGS search
208   directions.
209#. Added ``Problem::Evaluate``. Now you can evaluate a problem or any
210   part of it without calling the solver. In light of this the
211   following settings have been deprecated and removed from the API.
212
213   - ``Solver::Options::return_initial_residuals``
214   - ``Solver::Options::return_initial_gradient``
215   - ``Solver::Options::return_initial_jacobian``
216   - ``Solver::Options::return_final_residuals``
217   - ``Solver::Options::return_final_gradient``
218   - ``Solver::Options::return_final_jacobian``
219
220#. New, much improved HTML documentation using Sphinx.
221#. Changed ``NumericDiffCostFunction`` to take functors like
222   ``AutoDiffCostFunction``.
223#. Added support for mixing automatic, analytic and numeric
224   differentiation. This is done by adding ``CostFunctionToFunctor``
225   and ``NumericDiffFunctor`` objects to the API.
226#. Sped up the robust loss function correction logic when residual is
227   one dimensional.
228#. Sped up ``DenseQRSolver`` by changing the way dense jacobians are
229   stored. This is a 200-500% improvement in linear solver performance
230   depending on the size of the problem.
231#. ``DENSE_SCHUR`` now supports multi-threading.
232#. Greatly expanded ``Summary::FullReport``:
233
234   - Report the ordering used by the ``LinearSolver``.
235   - Report the ordering used by the inner iterations.
236   - Execution timing breakdown into evaluations and linear solves.
237   - Effective size of the problem solved by the solver, which now
238     accounts for the size of the tangent space when using a
239     ``LocalParameterization``.
240#. Ceres when run at the ``VLOG`` level 3 or higher will report
241   detailed timing information about its internals.
242#. Remove extraneous initial and final residual evaluations. This
243   speeds up the solver a bit.
244#. Automatic differenatiation with a dynamic number of parameter
245   blocks. (Based on an idea by Thad Hughes).
246#. Sped up problem construction and destruction.
247#. Added matrix adapters to ``rotation.h`` so that the rotation matrix
248   routines can work with row and column major matrices. (Markus Moll)
249#. ``SCHUR_JACOBI`` can now be used without ``SuiteSparse``.
250#. A ``.spec`` file for producing RPMs. (Taylor Braun-Jones)
251#. ``CMake`` can now build the sphinx documentation (Pablo Speciale)
252#. Add support for creating a CMake config file during build to make
253   embedding Ceres in other CMake-using projects easier. (Pablo
254   Speciale).
255#. Better error reporting in ``Problem`` for missing parameter blocks.
256#. A more flexible ``Android.mk`` and a more modular build. If binary
257   size and/or compile time is a concern, larger parts of the solver
258   can be disabled at compile time.
259
260Bug Fixes
261---------
262#. Compilation fixes for MSVC2010 (Sergey Sharybin)
263#. Fixed "deprecated conversion from string constant to char*"
264   warnings. (Pablo Speciale)
265#. Correctly propagate ifdefs when building without Schur eliminator
266   template specializations.
267#. Correct handling of ``LIB_SUFFIX`` on Linux. (Yuliy Schwartzburg).
268#. Code and signature cleanup in ``rotation.h``.
269#. Make examples independent of internal code.
270#. Disable unused member in ``gtest`` which results in build error on
271   OS X with latest Xcode. (Taylor Braun-Jones)
272#. Pass the correct flags to the linker when using
273   ``pthreads``. (Taylor Braun-Jones)
274#. Only use ``cmake28`` macro when building on RHEL6. (Taylor
275   Braun-Jones)
276#. Remove ``-Wno-return-type-c-linkage`` when compiling with
277   GCC. (Taylor Braun-Jones)
278#. Fix ``No previous prototype`` warnings. (Sergey Sharybin)
279#. MinGW build fixes. (Sergey Sharybin)
280#. Lots of minor code and lint fixes. (William Rucklidge)
281#. Fixed a bug in ``solver_impl.cc`` residual evaluation. (Markus
282   Moll)
283#. Fixed varidic evaluation bug in ``AutoDiff``.
284#. Fixed ``SolverImpl`` tests.
285#. Fixed a bug in ``DenseSparseMatrix::ToDenseMatrix()``.
286#. Fixed an initialization bug in ``ProgramEvaluator``.
287#. Fixes to Android.mk paths (Carlos Hernandez)
288#. Modify ``nist.cc`` to compute accuracy based on ground truth
289   solution rather than the ground truth function value.
290#. Fixed a memory leak in ``cxsparse.cc``. (Alexander Mordvintsev).
291#. Fixed the install directory for libraries by correctly handling
292   ``LIB_SUFFIX``. (Taylor Braun-Jones)
293
2941.4.0
295=====
296
297Backward Incompatible API Changes
298---------------------------------
299
300The new ordering API breaks existing code. Here the common case fixes.
301
302**Before**
303
304.. code-block:: c++
305
306 options.linear_solver_type = ceres::DENSE_SCHUR
307 options.ordering_type = ceres::SCHUR
308
309**After**
310
311
312.. code-block:: c++
313
314  options.linear_solver_type = ceres::DENSE_SCHUR
315
316
317**Before**
318
319.. code-block:: c++
320
321 options.linear_solver_type = ceres::DENSE_SCHUR;
322 options.ordering_type = ceres::USER;
323 for (int i = 0; i < num_points; ++i) {
324   options.ordering.push_back(my_points[i])
325 }
326 for (int i = 0; i < num_cameras; ++i) {
327   options.ordering.push_back(my_cameras[i])
328 }
329 options.num_eliminate_blocks = num_points;
330
331
332**After**
333
334.. code-block:: c++
335
336 options.linear_solver_type = ceres::DENSE_SCHUR;
337 options.ordering = new ceres::ParameterBlockOrdering;
338 for (int i = 0; i < num_points; ++i) {
339   options.linear_solver_ordering->AddElementToGroup(my_points[i], 0);
340 }
341 for (int i = 0; i < num_cameras; ++i) {
342   options.linear_solver_ordering->AddElementToGroup(my_cameras[i], 1);
343 }
344
345
346New Features
347------------
348
349#. A new richer, more expressive and consistent API for ordering
350   parameter blocks.
351#. A non-linear generalization of Ruhe & Wedin's Algorithm II. This
352   allows the user to use variable projection on separable and
353   non-separable non-linear least squares problems. With
354   multithreading, this results in significant improvements to the
355   convergence behavior of the solver at a small increase in run time.
356#. An image denoising example using fields of experts. (Petter
357   Strandmark)
358#. Defines for Ceres version and ABI version.
359#. Higher precision timer code where available. (Petter Strandmark)
360#. Example Makefile for users of Ceres.
361#. IterationSummary now informs the user when the step is a
362   non-monotonic step.
363#. Fewer memory allocations when using ``DenseQRSolver``.
364#. GradientChecker for testing CostFunctions (William Rucklidge)
365#. Add support for cost functions with 10 parameter blocks in
366   ``Problem``. (Fisher)
367#. Add support for 10 parameter blocks in ``AutoDiffCostFunction``.
368
369
370Bug Fixes
371---------
372
373#. static cast to force Eigen::Index to long conversion
374#. Change LOG(ERROR) to LOG(WARNING) in ``schur_complement_solver.cc``.
375#. Remove verbose logging from ``DenseQRSolve``.
376#. Fix the Android NDK build.
377#. Better handling of empty and constant Problems.
378#. Remove an internal header that was leaking into the public API.
379#. Memory leak in ``trust_region_minimizer.cc``
380#. Schur ordering was operating on the wrong object (Ricardo Martin)
381#. MSVC fixes (Petter Strandmark)
382#. Various fixes to ``nist.cc`` (Markus Moll)
383#. Fixed a jacobian scaling bug.
384#. Numerically robust computation of ``model_cost_change``.
385#. Signed comparison compiler warning fixes (Ricardo Martin)
386#. Various compiler warning fixes all over.
387#. Inclusion guard fixes (Petter Strandmark)
388#. Segfault in test code (Sergey Popov)
389#. Replaced ``EXPECT/ASSERT_DEATH`` with the more portable
390   ``EXPECT_DEATH_IF_SUPPORTED`` macros.
391#. Fixed the camera projection model in Ceres' implementation of
392   Snavely's camera model. (Ricardo Martin)
393
394
3951.3.0
396=====
397
398New Features
399------------
400
401#. Android Port (Scott Ettinger also contributed to the port)
402#. Windows port. (Changchang Wu and Pierre Moulon also contributed to the port)
403#. New subspace Dogleg Solver. (Markus Moll)
404#. Trust region algorithm now supports the option of non-monotonic steps.
405#. New loss functions ``ArcTanLossFunction``, ``TolerantLossFunction``
406   and ``ComposedLossFunction``. (James Roseborough).
407#. New ``DENSE_NORMAL_CHOLESKY`` linear solver, which uses Eigen's
408   LDLT factorization on the normal equations.
409#. Cached symbolic factorization when using ``CXSparse``.
410   (Petter Strandark)
411#. New example ``nist.cc`` and data from the NIST non-linear
412   regression test suite. (Thanks to Douglas Bates for suggesting this.)
413#. The traditional Dogleg solver now uses an elliptical trust
414   region (Markus Moll)
415#. Support for returning initial and final gradients & Jacobians.
416#. Gradient computation support in the evaluators, with an eye
417   towards developing first order/gradient based solvers.
418#. A better way to compute ``Solver::Summary::fixed_cost``. (Markus Moll)
419#. ``CMake`` support for building documentation, separate examples,
420   installing and uninstalling the library and Gerrit hooks (Arnaud
421   Gelas)
422#. ``SuiteSparse4`` support (Markus Moll)
423#. Support for building Ceres without ``TR1`` (This leads to
424   slightly slower ``DENSE_SCHUR`` and ``SPARSE_SCHUR`` solvers).
425#. ``BALProblem`` can now write a problem back to disk.
426#. ``bundle_adjuster`` now allows the user to normalize and perturb the
427   problem before solving.
428#. Solver progress logging to file.
429#. Added ``Program::ToString`` and ``ParameterBlock::ToString`` to
430   help with debugging.
431#. Ability to build Ceres as a shared library (MacOS and Linux only),
432   associated versioning and build release script changes.
433#. Portable floating point classification API.
434
435
436Bug Fixes
437---------
438
439#. Fix how invalid step evaluations are handled.
440#. Change the slop handling around zero for model cost changes to use
441   relative tolerances rather than absolute tolerances.
442#. Fix an inadvertant integer to bool conversion. (Petter Strandmark)
443#. Do not link to ``libgomp`` when building on
444   windows. (Petter Strandmark)
445#. Include ``gflags.h`` in ``test_utils.cc``. (Petter
446   Strandmark)
447#. Use standard random number generation routines. (Petter Strandmark)
448#. ``TrustRegionMinimizer`` does not implicitly negate the
449   steps that it takes. (Markus Moll)
450#. Diagonal scaling allows for equal upper and lower bounds. (Markus Moll)
451#. TrustRegionStrategy does not misuse LinearSolver:Summary anymore.
452#. Fix Eigen3 Row/Column Major storage issue. (Lena Gieseke)
453#. QuaternionToAngleAxis now guarantees an angle in $[-\pi, \pi]$. (Guoxuan Zhang)
454#. Added a workaround for a compiler bug in the Android NDK to the
455   Schur eliminator.
456#. The sparse linear algebra library is only logged in
457   Summary::FullReport if it is used.
458#. Rename the macro ``CERES_DONT_HAVE_PROTOCOL_BUFFERS``
459   to ``CERES_NO_PROTOCOL_BUFFERS`` for consistency.
460#. Fix how static structure detection for the Schur eliminator logs
461   its results.
462#. Correct example code in the documentation. (Petter Strandmark)
463#. Fix ``fpclassify.h`` to work with the Android NDK and STLport.
464#. Fix a memory leak in the ``levenber_marquardt_strategy_test.cc``
465#. Fix an early return bug in the Dogleg solver. (Markus Moll)
466#. Zero initialize Jets.
467#. Moved ``internal/ceres/mock_log.h`` to ``internal/ceres/gmock/mock-log.h``
468#. Unified file path handling in tests.
469#. ``data_fitting.cc`` includes ``gflags``
470#. Renamed Ceres' Mutex class and associated macros to avoid
471   namespace conflicts.
472#. Close the BAL problem file after reading it (Markus Moll)
473#. Fix IsInfinite on Jets.
474#. Drop alignment requirements for Jets.
475#. Fixed Jet to integer comparison. (Keith Leung)
476#. Fix use of uninitialized arrays. (Sebastian Koch & Markus Moll)
477#. Conditionally compile gflag dependencies.(Casey Goodlett)
478#. Add ``data_fitting.cc`` to the examples ``CMake`` file.
479
480
4811.2.3
482=====
483
484Bug Fixes
485---------
486
487#. ``suitesparse_test`` is enabled even when ``-DSUITESPARSE=OFF``.
488#. ``FixedArray`` internal struct did not respect ``Eigen``
489   alignment requirements (Koichi Akabe & Stephan Kassemeyer).
490#. Fixed ``quadratic.cc`` documentation and code mismatch
491   (Nick Lewycky).
492
4931.2.2
494=====
495
496Bug Fixes
497---------
498
499#. Fix constant parameter blocks, and other minor fixes (Markus Moll)
500#. Fix alignment issues when combining ``Jet`` and
501   ``FixedArray`` in automatic differeniation.
502#. Remove obsolete ``build_defs`` file.
503
5041.2.1
505=====
506
507New Features
508------------
509
510#. Powell's Dogleg solver
511#. Documentation now has a brief overview of Trust Region methods and
512   how the Levenberg-Marquardt and Dogleg methods work.
513
514Bug Fixes
515---------
516
517#. Destructor for ``TrustRegionStrategy`` was not virtual (Markus Moll)
518#. Invalid ``DCHECK`` in ``suitesparse.cc`` (Markus Moll)
519#. Iteration callbacks were not properly invoked (Luis Alberto Zarrabeiti)
520#. Logging level changes in ConjugateGradientsSolver
521#. VisibilityBasedPreconditioner setup does not account for skipped camera pairs. This was debugging code.
522#. Enable SSE support on MacOS
523#. ``system_test`` was taking too long and too much memory (Koichi Akabe)
524
5251.2.0
526=====
527
528New Features
529------------
530
531#. ``CXSparse`` support.
532#. Block oriented fill reducing orderings. This reduces the
533   factorization time for sparse ``CHOLMOD`` significantly.
534#. New Trust region loop with support for multiple trust region step
535   strategies. Currently only Levenberg-Marquardt is supported, but
536   this refactoring opens the door for Dog-leg, Stiehaug and others.
537#. ``CMake`` file restructuring.  Builds in ``Release`` mode by   default, and now has platform specific tuning flags.
538#. Re-organized documentation. No new content, but better
539   organization.
540
541
542Bug Fixes
543---------
544
545#. Fixed integer overflow bug in ``block_random_access_sparse_matrix.cc``.
546#. Renamed some macros to prevent name conflicts.
547#. Fixed incorrent input to ``StateUpdatingCallback``.
548#. Fixes to AutoDiff tests.
549#. Various internal cleanups.
550
551
5521.1.1
553=====
554
555Bug Fixes
556---------
557
558#. Fix a bug in the handling of constant blocks. (Louis Simard)
559#. Add an optional lower bound to the Levenberg-Marquardt regularizer
560   to prevent oscillating between well and ill posed linear problems.
561#. Some internal refactoring and test fixes.
562
5631.1.0
564=====
565
566New Features
567------------
568
569#. New iterative linear solver for general sparse problems - ``CGNR``
570   and a block Jacobi preconditioner for it.
571#. Changed the semantics of how ``SuiteSparse`` dependencies are
572   checked and used. Now ``SuiteSparse`` is built by default, only if
573   all of its dependencies are present.
574#. Automatic differentiation now supports dynamic number of residuals.
575#. Support for writing the linear least squares problems to disk in
576   text format so that they can loaded into ``MATLAB``.
577#. Linear solver results are now checked for nan and infinities.
578#. Added ``.gitignore`` file.
579#. A better more robust build system.
580
581
582Bug Fixes
583---------
584
585#. Fixed a strict weak ordering bug in the schur ordering.
586#. Grammar and typos in the documents and code comments.
587#. Fixed tests which depended on exact equality between floating point values.
588
5891.0.0
590=====
591
592Initial Release. Nathan Wiegand contributed to the Mac OSX port.
593