Mercurial > octave
changeset 33207:a92e59904393 bytecode-interpreter
maint: Merge default to bytecode-interpreter
author | Arun Giridhar <arungiridhar@gmail.com> |
---|---|
date | Thu, 14 Mar 2024 17:28:46 -0400 |
parents | 1e2b93a4840d (current diff) 1ac1aeab7027 (diff) |
children | 70d44ca38603 |
files | |
diffstat | 14 files changed, 272 insertions(+), 292 deletions(-) [+] |
line wrap: on
line diff
--- a/doc/interpreter/testfun.txi Tue Mar 12 15:06:31 2024 -0400 +++ b/doc/interpreter/testfun.txi Thu Mar 14 17:28:46 2024 -0400 @@ -186,6 +186,12 @@ %!shared @var{a}, @var{b} @end example +Modifications to shared variables persist from one test to the next +@strong{only} if the test succeeds. Thus, if one test modifies a shared +variable, later tests cannot know which value of the shared variable to expect +because the pass/fail status of earlier tests is unknown. For this reason, it +is not recommended to modify shared variables in tests. + You can also share test functions: @example
--- a/etc/NEWS.10.md Tue Mar 12 15:06:31 2024 -0400 +++ b/etc/NEWS.10.md Thu Mar 14 17:28:46 2024 -0400 @@ -17,6 +17,14 @@ - `nchoosek` algorithm is now ~2x faster and provides greater precision. +- `nextpow2` algorithm is now more accurate for inputs very close to a power +of 2. The output class now matches the input class for Matlab compatibility. +The function no longer accepts complex inputs and will emit an error for these +inputs. + +- `jsonencode` now outputs integers and floating point integers without ".0" + suffix. + ### Graphical User Interface ### Graphics backend
--- a/libinterp/corefcn/jsonencode.cc Tue Mar 12 15:06:31 2024 -0400 +++ b/libinterp/corefcn/jsonencode.cc Thu Mar 14 17:28:46 2024 -0400 @@ -65,13 +65,13 @@ { double value = obj.scalar_value (); - // Any numeric input from the interpreter will be in double type so in - // order to detect ints, we will check if the floor of the input and the - // input are equal using fabs (A - B) < epsilon method as it is more - // accurate. If value > 999999, MATLAB will encode it in scientific - // notation (double). - if (fabs (floor (value) - value) < std::numeric_limits<double>::epsilon () - && fabs (value) <= 999999) + // Detect floating point numbers which are actually integers by checking + // whether the number and the integer portion of the number are the same + // to within eps. + // FIXME: If value > 999999, MATLAB will encode it in scientific + // notation, but rapidJSON will output all digits. + if (fabs (trunc (value) - value) < std::numeric_limits<double>::epsilon ()) + writer.Int64 (value); // Possibly write NULL for non-finite values (-Inf, Inf, NaN, NA) else if (ConvertInfAndNaN && ! octave::math::isfinite (value)) @@ -79,6 +79,21 @@ else writer.Double (value); } + else if (obj.isinteger ()) + { + if (obj.is_uint64_type ()) + { + uint64_t value = obj.uint64_value (); + writer.Uint64 (value); + } + else + { + // Write all other integers as 64-bit values and let RapidJSON + // determine number of digits to keep. + int64_t value = obj.int64_value (); + writer.Int64 (value); + } + } else if (obj.is_bool_scalar ()) writer.Bool (obj.bool_value ()); else @@ -404,9 +419,10 @@ encode (T& writer, const octave_value& obj, const bool& ConvertInfAndNaN) { if (obj.is_real_scalar ()) + // Numeric scalars. encode_numeric (writer, obj, ConvertInfAndNaN); - // As I checked for scalars, this will detect numeric & logical arrays else if (obj.isnumeric () || obj.islogical ()) + // Numeric and logical arrays. encode_array (writer, obj, ConvertInfAndNaN, obj.dims ()); else if (obj.is_string ()) encode_string (writer, obj, obj.dims ());
--- a/liboctave/array/CMatrix.cc Tue Mar 12 15:06:31 2024 -0400 +++ b/liboctave/array/CMatrix.cc Thu Mar 14 17:28:46 2024 -0400 @@ -28,6 +28,7 @@ #endif #include <algorithm> +#include <cmath> #include <complex> #include <istream> #include <limits> @@ -733,6 +734,14 @@ return anorm; } +// Local function to check if matrix is singular based on rcond. +static inline +bool +is_singular (const double rcond) +{ + return (std::abs (rcond) <= std::numeric_limits<double>::epsilon ()); +} + ComplexMatrix ComplexMatrix::inverse () const { @@ -1603,10 +1612,7 @@ if (info != 0) info = -2; - // Prevent use of extra precision. - double rcond_plus_one = rcon + 1.0; - - if (rcond_plus_one == 1.0 || octave::math::isnan (rcon)) + if (is_singular (rcon) || octave::math::isnan (rcon)) { info = -2; @@ -1702,10 +1708,7 @@ if (info != 0) info = -2; - // Prevent use of extra precision. - double rcond_plus_one = rcon + 1.0; - - if (rcond_plus_one == 1.0 || octave::math::isnan (rcon)) + if (is_singular (rcon) || octave::math::isnan (rcon)) { info = -2; @@ -1795,10 +1798,7 @@ if (info != 0) info = -2; - // Prevent use of extra precision. - double rcond_plus_one = rcon + 1.0; - - if (rcond_plus_one == 1.0 || octave::math::isnan (rcon)) + if (is_singular (rcon) || octave::math::isnan (rcon)) { info = -2; @@ -1891,10 +1891,7 @@ if (info != 0) info = -2; - // Prevent use of extra precision. - double rcond_plus_one = rcon + 1.0; - - if (rcond_plus_one == 1.0 || octave::math::isnan (rcon)) + if (is_singular (rcon) || octave::math::isnan (rcon)) { if (sing_handler) sing_handler (rcon);
--- a/liboctave/array/CSparse.cc Tue Mar 12 15:06:31 2024 -0400 +++ b/liboctave/array/CSparse.cc Thu Mar 14 17:28:46 2024 -0400 @@ -27,8 +27,10 @@ # include "config.h" #endif +#include <cmath> #include <complex> #include <istream> +#include <limits> #include <ostream> #include "quit.h" @@ -651,6 +653,14 @@ return retval; } +// Local function to check if matrix is singular based on rcond. +static inline +bool +is_singular (const double rcond) +{ + return (std::abs (rcond) <= std::numeric_limits<double>::epsilon ()); +} + SparseComplexMatrix SparseComplexMatrix::inverse () const { @@ -1723,10 +1733,7 @@ octave::warn_singular_matrix (rcond); } - // Prevent use of extra precision. - double rcond_plus_one = rcond + 1.0; - - if (rcond_plus_one == 1.0 || octave::math::isnan (rcond)) + if (is_singular (rcond) || octave::math::isnan (rcond)) { err = -2; @@ -2006,10 +2013,7 @@ octave::warn_singular_matrix (rcond); } - // Prevent use of extra precision. - double rcond_plus_one = rcond + 1.0; - - if (rcond_plus_one == 1.0 || octave::math::isnan (rcond)) + if (is_singular (rcond) || octave::math::isnan (rcond)) { err = -2; @@ -2236,10 +2240,7 @@ octave::warn_singular_matrix (rcond); } - // Prevent use of extra precision. - double rcond_plus_one = rcond + 1.0; - - if (rcond_plus_one == 1.0 || octave::math::isnan (rcond)) + if (is_singular (rcond) || octave::math::isnan (rcond)) { err = -2; @@ -2519,10 +2520,7 @@ octave::warn_singular_matrix (rcond); } - // Prevent use of extra precision. - double rcond_plus_one = rcond + 1.0; - - if (rcond_plus_one == 1.0 || octave::math::isnan (rcond)) + if (is_singular (rcond) || octave::math::isnan (rcond)) { err = -2; @@ -2769,10 +2767,7 @@ octave::warn_singular_matrix (rcond); } - // Prevent use of extra precision. - double rcond_plus_one = rcond + 1.0; - - if (rcond_plus_one == 1.0 || octave::math::isnan (rcond)) + if (is_singular (rcond) || octave::math::isnan (rcond)) { err = -2; @@ -3071,10 +3066,7 @@ octave::warn_singular_matrix (rcond); } - // Prevent use of extra precision. - double rcond_plus_one = rcond + 1.0; - - if (rcond_plus_one == 1.0 || octave::math::isnan (rcond)) + if (is_singular (rcond) || octave::math::isnan (rcond)) { err = -2; @@ -3324,10 +3316,7 @@ octave::warn_singular_matrix (rcond); } - // Prevent use of extra precision. - double rcond_plus_one = rcond + 1.0; - - if (rcond_plus_one == 1.0 || octave::math::isnan (rcond)) + if (is_singular (rcond) || octave::math::isnan (rcond)) { err = -2; @@ -3625,10 +3614,7 @@ octave::warn_singular_matrix (rcond); } - // Prevent use of extra precision. - double rcond_plus_one = rcond + 1.0; - - if (rcond_plus_one == 1.0 || octave::math::isnan (rcond)) + if (is_singular (rcond) || octave::math::isnan (rcond)) { err = -2; @@ -4413,10 +4399,7 @@ if (err != 0) err = -2; - // Prevent use of extra precision. - double rcond_plus_one = rcond + 1.0; - - if (rcond_plus_one == 1.0 || octave::math::isnan (rcond)) + if (is_singular (rcond) || octave::math::isnan (rcond)) { err = -2; @@ -4547,10 +4530,7 @@ if (err != 0) err = -2; - // Prevent use of extra precision. - double rcond_plus_one = rcond + 1.0; - - if (rcond_plus_one == 1.0 || octave::math::isnan (rcond)) + if (is_singular (rcond) || octave::math::isnan (rcond)) { err = -2; @@ -4684,10 +4664,7 @@ if (err != 0) err = -2; - // Prevent use of extra precision. - double rcond_plus_one = rcond + 1.0; - - if (rcond_plus_one == 1.0 || octave::math::isnan (rcond)) + if (is_singular (rcond) || octave::math::isnan (rcond)) { err = -2; @@ -4851,10 +4828,7 @@ if (err != 0) err = -2; - // Prevent use of extra precision. - double rcond_plus_one = rcond + 1.0; - - if (rcond_plus_one == 1.0 || octave::math::isnan (rcond)) + if (is_singular (rcond) || octave::math::isnan (rcond)) { err = -2; @@ -5027,10 +5001,7 @@ if (err != 0) err = -2; - // Prevent use of extra precision. - double rcond_plus_one = rcond + 1.0; - - if (rcond_plus_one == 1.0 || octave::math::isnan (rcond)) + if (is_singular (rcond) || octave::math::isnan (rcond)) { err = -2; @@ -5158,10 +5129,7 @@ if (err != 0) err = -2; - // Prevent use of extra precision. - double rcond_plus_one = rcond + 1.0; - - if (rcond_plus_one == 1.0 || octave::math::isnan (rcond)) + if (is_singular (rcond) || octave::math::isnan (rcond)) { err = -2; @@ -5297,10 +5265,7 @@ if (err != 0) err = -2; - // Prevent use of extra precision. - double rcond_plus_one = rcond + 1.0; - - if (rcond_plus_one == 1.0 || octave::math::isnan (rcond)) + if (is_singular (rcond) || octave::math::isnan (rcond)) { err = -2; @@ -5468,10 +5433,7 @@ if (err != 0) err = -2; - // Prevent use of extra precision. - double rcond_plus_one = rcond + 1.0; - - if (rcond_plus_one == 1.0 || octave::math::isnan (rcond)) + if (is_singular (rcond) || octave::math::isnan (rcond)) { err = -2; @@ -5633,11 +5595,8 @@ else rcond = 1.; - // Prevent use of extra precision. - double rcond_plus_one = rcond + 1.0; - if (status == UMFPACK_WARNING_singular_matrix - || rcond_plus_one == 1.0 || octave::math::isnan (rcond)) + || is_singular (rcond) || octave::math::isnan (rcond)) { UMFPACK_ZNAME (report_numeric) (Numeric, control); @@ -5784,10 +5743,7 @@ } else { - // Prevent use of extra precision. - double rcond_plus_one = rcond + 1.0; - - if (rcond_plus_one == 1.0 || octave::math::isnan (rcond)) + if (is_singular (rcond) || octave::math::isnan (rcond)) { err = -2; @@ -6034,10 +5990,7 @@ } else { - // Prevent use of extra precision. - double rcond_plus_one = rcond + 1.0; - - if (rcond_plus_one == 1.0 || octave::math::isnan (rcond)) + if (is_singular (rcond) || octave::math::isnan (rcond)) { err = -2; @@ -6317,10 +6270,7 @@ } else { - // Prevent use of extra precision. - double rcond_plus_one = rcond + 1.0; - - if (rcond_plus_one == 1.0 || octave::math::isnan (rcond)) + if (is_singular (rcond) || octave::math::isnan (rcond)) { err = -2; @@ -6546,10 +6496,7 @@ } else { - // Prevent use of extra precision. - double rcond_plus_one = rcond + 1.0; - - if (rcond_plus_one == 1.0 || octave::math::isnan (rcond)) + if (is_singular (rcond) || octave::math::isnan (rcond)) { err = -2; @@ -6682,11 +6629,8 @@ retval.maybe_compress (); rcond = Info (UMFPACK_RCOND); - // Prevent use of extra precision. - double rcond_plus_one = rcond + 1.0; - if (status == UMFPACK_WARNING_singular_matrix - || rcond_plus_one == 1.0 || octave::math::isnan (rcond)) + || is_singular (rcond) || octave::math::isnan (rcond)) { err = -2;
--- a/liboctave/array/dMatrix.cc Tue Mar 12 15:06:31 2024 -0400 +++ b/liboctave/array/dMatrix.cc Thu Mar 14 17:28:46 2024 -0400 @@ -28,6 +28,7 @@ #endif #include <algorithm> +#include <cmath> #include <istream> #include <limits> #include <ostream> @@ -447,6 +448,14 @@ return anorm; } +// Local function to check if matrix is singular based on rcond. +static inline +bool +is_singular (const double rcond) +{ + return (std::abs (rcond) <= std::numeric_limits<double>::epsilon ()); +} + Matrix Matrix::inverse () const { @@ -1274,10 +1283,7 @@ if (info != 0) info = -2; - // Prevent use of extra precision. - double rcond_plus_one = rcon + 1.0; - - if (rcond_plus_one == 1.0 || octave::math::isnan (rcon)) + if (is_singular (rcon) || octave::math::isnan (rcon)) { info = -2; @@ -1372,10 +1378,7 @@ if (info != 0) info = -2; - // Prevent use of extra precision. - double rcond_plus_one = rcon + 1.0; - - if (rcond_plus_one == 1.0 || octave::math::isnan (rcon)) + if (is_singular (rcon) || octave::math::isnan (rcon)) { info = -2; @@ -1461,10 +1464,7 @@ if (info != 0) info = -2; - // Prevent use of extra precision. - double rcond_plus_one = rcon + 1.0; - - if (rcond_plus_one == 1.0 || octave::math::isnan (rcon)) + if (is_singular (rcon) || octave::math::isnan (rcon)) { info = -2; @@ -1551,10 +1551,7 @@ if (info != 0) info = -2; - // Prevent use of extra precision. - double rcond_plus_one = rcon + 1.0; - - if (rcond_plus_one == 1.0 || octave::math::isnan (rcon)) + if (is_singular (rcon) || octave::math::isnan (rcon)) { if (sing_handler) sing_handler (rcon);
--- a/liboctave/array/dSparse.cc Tue Mar 12 15:06:31 2024 -0400 +++ b/liboctave/array/dSparse.cc Thu Mar 14 17:28:46 2024 -0400 @@ -27,7 +27,9 @@ # include "config.h" #endif +#include <cmath> #include <istream> +#include <limits> #include <ostream> #include "quit.h" @@ -594,6 +596,14 @@ */ +// Local function to check if matrix is singular based on rcond. +static inline +bool +is_singular (const double rcond) +{ + return (std::abs (rcond) <= std::numeric_limits<double>::epsilon ()); +} + SparseMatrix SparseMatrix::inverse () const { @@ -1657,10 +1667,7 @@ octave::warn_singular_matrix (rcond); } - // Prevent use of extra precision. - double rcond_plus_one = rcond + 1.0; - - if (rcond_plus_one == 1.0 || octave::math::isnan (rcond)) + if (is_singular (rcond) || octave::math::isnan (rcond)) { err = -2; @@ -1940,10 +1947,7 @@ octave::warn_singular_matrix (rcond); } - // Prevent use of extra precision. - double rcond_plus_one = rcond + 1.0; - - if (rcond_plus_one == 1.0 || octave::math::isnan (rcond)) + if (is_singular (rcond) || octave::math::isnan (rcond)) { err = -2; @@ -2172,10 +2176,7 @@ octave::warn_singular_matrix (rcond); } - // Prevent use of extra precision. - double rcond_plus_one = rcond + 1.0; - - if (rcond_plus_one == 1.0 || octave::math::isnan (rcond)) + if (is_singular (rcond) || octave::math::isnan (rcond)) { err = -2; @@ -2457,10 +2458,7 @@ octave::warn_singular_matrix (rcond); } - // Prevent use of extra precision. - double rcond_plus_one = rcond + 1.0; - - if (rcond_plus_one == 1.0 || octave::math::isnan (rcond)) + if (is_singular (rcond) || octave::math::isnan (rcond)) { err = -2; @@ -2711,10 +2709,7 @@ octave::warn_singular_matrix (rcond); } - // Prevent use of extra precision. - double rcond_plus_one = rcond + 1.0; - - if (rcond_plus_one == 1.0 || octave::math::isnan (rcond)) + if (is_singular (rcond) || octave::math::isnan (rcond)) { err = -2; @@ -3012,10 +3007,7 @@ octave::warn_singular_matrix (rcond); } - // Prevent use of extra precision. - double rcond_plus_one = rcond + 1.0; - - if (rcond_plus_one == 1.0 || octave::math::isnan (rcond)) + if (is_singular (rcond) || octave::math::isnan (rcond)) { err = -2; @@ -3267,10 +3259,7 @@ octave::warn_singular_matrix (rcond); } - // Prevent use of extra precision. - double rcond_plus_one = rcond + 1.0; - - if (rcond_plus_one == 1.0 || octave::math::isnan (rcond)) + if (is_singular (rcond) || octave::math::isnan (rcond)) { err = -2; @@ -3570,10 +3559,7 @@ octave::warn_singular_matrix (rcond); } - // Prevent use of extra precision. - double rcond_plus_one = rcond + 1.0; - - if (rcond_plus_one == 1.0 || octave::math::isnan (rcond)) + if (is_singular (rcond) || octave::math::isnan (rcond)) { err = -2; @@ -4363,10 +4349,7 @@ if (err != 0) err = -2; - // Prevent use of extra precision. - double rcond_plus_one = rcond + 1.0; - - if (rcond_plus_one == 1.0 || octave::math::isnan (rcond)) + if (is_singular (rcond) || octave::math::isnan (rcond)) { err = -2; @@ -4496,10 +4479,7 @@ if (err != 0) err = -2; - // Prevent use of extra precision. - double rcond_plus_one = rcond + 1.0; - - if (rcond_plus_one == 1.0 || octave::math::isnan (rcond)) + if (is_singular (rcond) || octave::math::isnan (rcond)) { err = -2; @@ -4633,10 +4613,7 @@ if (err != 0) err = -2; - // Prevent use of extra precision. - double rcond_plus_one = rcond + 1.0; - - if (rcond_plus_one == 1.0 || octave::math::isnan (rcond)) + if (is_singular (rcond) || octave::math::isnan (rcond)) { err = -2; @@ -4800,10 +4777,7 @@ if (err != 0) err = -2; - // Prevent use of extra precision. - double rcond_plus_one = rcond + 1.0; - - if (rcond_plus_one == 1.0 || octave::math::isnan (rcond)) + if (is_singular (rcond) || octave::math::isnan (rcond)) { err = -2; @@ -4977,10 +4951,7 @@ if (err != 0) err = -2; - // Prevent use of extra precision. - double rcond_plus_one = rcond + 1.0; - - if (rcond_plus_one == 1.0 || octave::math::isnan (rcond)) + if (is_singular (rcond) || octave::math::isnan (rcond)) { err = -2; @@ -5142,10 +5113,7 @@ if (err != 0) err = -2; - // Prevent use of extra precision. - double rcond_plus_one = rcond + 1.0; - - if (rcond_plus_one == 1.0 || octave::math::isnan (rcond)) + if (is_singular (rcond) || octave::math::isnan (rcond)) { err = -2; @@ -5304,10 +5272,7 @@ if (err != 0) err = -2; - // Prevent use of extra precision. - double rcond_plus_one = rcond + 1.0; - - if (rcond_plus_one == 1.0 || octave::math::isnan (rcond)) + if (is_singular (rcond) || octave::math::isnan (rcond)) { err = -2; @@ -5498,10 +5463,7 @@ if (err != 0) err = -2; - // Prevent use of extra precision. - double rcond_plus_one = rcond + 1.0; - - if (rcond_plus_one == 1.0 || octave::math::isnan (rcond)) + if (is_singular (rcond) || octave::math::isnan (rcond)) { err = -2; @@ -5674,11 +5636,8 @@ else rcond = 1.; - // Prevent use of extra precision. - double rcond_plus_one = rcond + 1.0; - if (status == UMFPACK_WARNING_singular_matrix - || rcond_plus_one == 1.0 || octave::math::isnan (rcond)) + || is_singular (rcond) || octave::math::isnan (rcond)) { UMFPACK_DNAME (report_numeric) (Numeric, control); @@ -5826,10 +5785,7 @@ } else { - // Prevent use of extra precision. - double rcond_plus_one = rcond + 1.0; - - if (rcond_plus_one == 1.0 || octave::math::isnan (rcond)) + if (is_singular (rcond) || octave::math::isnan (rcond)) { err = -2; @@ -6048,10 +6004,7 @@ } else { - // Prevent use of extra precision. - double rcond_plus_one = rcond + 1.0; - - if (rcond_plus_one == 1.0 || octave::math::isnan (rcond)) + if (is_singular (rcond) || octave::math::isnan (rcond)) { err = -2; @@ -6302,10 +6255,7 @@ } else { - // Prevent use of extra precision. - double rcond_plus_one = rcond + 1.0; - - if (rcond_plus_one == 1.0 || octave::math::isnan (rcond)) + if (is_singular (rcond) || octave::math::isnan (rcond)) { err = -2; @@ -6545,10 +6495,7 @@ } else { - // Prevent use of extra precision. - double rcond_plus_one = rcond + 1.0; - - if (rcond_plus_one == 1.0 || octave::math::isnan (rcond)) + if (is_singular (rcond) || octave::math::isnan (rcond)) { err = -2;
--- a/liboctave/array/fCMatrix.cc Tue Mar 12 15:06:31 2024 -0400 +++ b/liboctave/array/fCMatrix.cc Thu Mar 14 17:28:46 2024 -0400 @@ -28,6 +28,7 @@ #endif #include <algorithm> +#include <cmath> #include <complex> #include <istream> #include <limits> @@ -736,6 +737,14 @@ return anorm; } +// Local function to check if matrix is singular based on rcond. +static inline +bool +is_singular (const float rcond) +{ + return (std::abs (rcond) <= std::numeric_limits<float>::epsilon ()); +} + FloatComplexMatrix FloatComplexMatrix::inverse () const { @@ -1605,10 +1614,7 @@ if (info != 0) info = -2; - // Prevent use of extra precision. - float rcond_plus_one = rcon + 1.0; - - if (rcond_plus_one == 1.0 || octave::math::isnan (rcon)) + if (is_singular (rcon) || octave::math::isnan (rcon)) { info = -2; @@ -1708,10 +1714,7 @@ if (info != 0) info = -2; - // Prevent use of extra precision. - float rcond_plus_one = rcon + 1.0; - - if (rcond_plus_one == 1.0 || octave::math::isnan (rcon)) + if (is_singular (rcon) || octave::math::isnan (rcon)) { info = -2; @@ -1805,10 +1808,7 @@ if (info != 0) info = -2; - // Prevent use of extra precision. - float rcond_plus_one = rcon + 1.0; - - if (rcond_plus_one == 1.0 || octave::math::isnan (rcon)) + if (is_singular (rcon) || octave::math::isnan (rcon)) { info = -2; @@ -1901,10 +1901,7 @@ if (info != 0) info = -2; - // Prevent use of extra precision. - float rcond_plus_one = rcon + 1.0; - - if (rcond_plus_one == 1.0 || octave::math::isnan (rcon)) + if (is_singular (rcon) || octave::math::isnan (rcon)) { if (sing_handler) sing_handler (rcon);
--- a/liboctave/array/fMatrix.cc Tue Mar 12 15:06:31 2024 -0400 +++ b/liboctave/array/fMatrix.cc Thu Mar 14 17:28:46 2024 -0400 @@ -28,6 +28,7 @@ #endif #include <algorithm> +#include <cmath> #include <istream> #include <limits> #include <ostream> @@ -453,6 +454,14 @@ return anorm; } +// Local function to check if matrix is singular based on rcond. +static inline +bool +is_singular (const float rcond) +{ + return (std::abs (rcond) <= std::numeric_limits<float>::epsilon ()); +} + FloatMatrix FloatMatrix::inverse () const { @@ -1284,10 +1293,7 @@ if (info != 0) info = -2; - // Prevent use of extra precision. - float rcond_plus_one = rcon + 1.0; - - if (rcond_plus_one == 1.0 || octave::math::isnan (rcon)) + if (is_singular (rcon) || octave::math::isnan (rcon)) { info = -2; @@ -1388,10 +1394,7 @@ if (info != 0) info = -2; - // Prevent use of extra precision. - float rcond_plus_one = rcon + 1.0; - - if (rcond_plus_one == 1.0 || octave::math::isnan (rcon)) + if (is_singular (rcon) || octave::math::isnan (rcon)) { info = -2; @@ -1485,10 +1488,7 @@ if (info != 0) info = -2; - // Prevent use of extra precision. - float rcond_plus_one = rcon + 1.0; - - if (rcond_plus_one == 1.0 || octave::math::isnan (rcon)) + if (is_singular (rcon) || octave::math::isnan (rcon)) { info = -2; @@ -1572,10 +1572,7 @@ if (info != 0) info = -2; - // Prevent use of extra precision. - float rcond_plus_one = rcon + 1.0; - - if (rcond_plus_one == 1.0 || octave::math::isnan (rcon)) + if (is_singular (rcon) || octave::math::isnan (rcon)) { if (sing_handler) sing_handler (rcon);
--- a/scripts/general/nextpow2.m Tue Mar 12 15:06:31 2024 -0400 +++ b/scripts/general/nextpow2.m Thu Mar 14 17:28:46 2024 -0400 @@ -25,16 +25,17 @@ ## -*- texinfo -*- ## @deftypefn {} {@var{n} =} nextpow2 (@var{x}) -## Compute the exponent for the smallest power of two larger than the input. +## Compute the exponent of the next power of two not smaller than the input. ## -## For each element in the input array @var{x}, return the first integer +## For each element in the input array @var{x}, return the smallest integer ## @var{n} such that ## @tex ## $2^n \ge |x|$. ## @end tex ## @ifnottex -## 2^n @geq{} abs (x). +## @code{2^@var{n} @geq{} abs (@var{x})}. ## @end ifnottex +## For input elements equal to zero, return zero. ## ## @seealso{pow2, log2} ## @end deftypefn @@ -47,10 +48,23 @@ if (! isnumeric (x)) error ("nextpow2: X must be numeric"); + elseif (! isreal (x)) + error ("nextpow2: X must be real"); endif - n = ceil (log2 (abs (x))); - n(x == 0) = 0; # special case + [f, n] = log2 (abs (x)); + n(f == 0.5)--; + + if (isfloat (x)) + idx_nan = isnan (x); + n(idx_nan) = x(idx_nan); + n(isinf (x)) = Inf; + else + n = cast (n, class (x)); + if (intmax (x) > flintmax ()) + n((2 .^ n) < abs (x))++; + endif + endif endfunction @@ -70,8 +84,75 @@ %!assert (nextpow2 (Inf), Inf) %!assert (nextpow2 (-Inf), Inf) %!assert (nextpow2 (NaN), NaN) -%!assert (nextpow2 ([1, Inf, 3, -Inf, 9, NaN]), [0, Inf, 2, Inf, 4, NaN]) +%!assert (nextpow2 (NA), NA) +%!assert (nextpow2 ([1, Inf, 3, -Inf, 9, NaN, NA]), ... +%! [0, Inf, 2, Inf, 4, NaN, NA]) + +%!test +%! p = (-1074:1023).'; +%! x = 2 .^ p; +%! x = [x, x + eps(x)]; +%! x = [x, -x]; +%! n = nextpow2 (x); +%! assert (n(:, 1), p); +%! assert (n(:, 3), p); +%! assert (n(:, 2), p + 1); +%! assert (n(:, 4), p + 1); + +%!assert (nextpow2 (realmax ()), 1024) +%!assert (nextpow2 (-realmax ()), 1024) + +%!test +%! p = single (-149:127).'; +%! x = 2 .^ p; +%! x = [x, x + eps(x)]; +%! x = [x, -x]; +%! n = nextpow2 (x); +%! assert (n(:, 1), p); +%! assert (n(:, 3), p); +%! assert (n(:, 2), p + 1); +%! assert (n(:, 4), p + 1); + +%!assert (nextpow2 (realmax ('single')), single (128)) +%!assert (nextpow2 (-realmax ('single')), single (128)) + +%!test +%! p = int32 (0:30).'; +%! x = 2 .^ p; +%! x = [x, x + 1]; +%! x = [x, -x]; +%! n = nextpow2 (x); +%! assert (n(:, 1), p); +%! assert (n(:, 3), p); +%! assert (n(:, 2), p + 1); +%! assert (n(:, 4), p + 1); + +%!assert (nextpow2 (int32 (0)), int32 (0)) +%!assert (nextpow2 (intmin ('int32')), int32 (31)) +%!assert (nextpow2 (intmax ('int32')), int32 (31)) + +%!assert (nextpow2 (uint32 (0)), uint32 (0)) +%!assert (nextpow2 (intmax ('uint32')), uint32 (32)) + +%!test +%! p = int64 (0:62).'; +%! x = 2 .^ p; +%! x = [x, x + 1]; +%! x = [x, -x]; +%! n = nextpow2 (x); +%! assert (n(:, 1), p); +%! assert (n(:, 3), p); +%! assert (n(:, 2), p + 1); +%! assert (n(:, 4), p + 1); + +%!assert (nextpow2 (int64 (0)), int64 (0)) +%!assert (nextpow2 (intmin ('int64')), int64 (63)) +%!assert (nextpow2 (intmax ('int64')), int64 (63)) + +%!assert (nextpow2 (uint64 (0)), uint64 (0)) +%!assert (nextpow2 (intmax ('uint64')), uint64 (64)) ## Test input validation %!error <Invalid call> nextpow2 () %!error <X must be numeric> nextpow2 ("t") +%!error <X must be real> nextpow2 (1 + 2i)
--- a/scripts/plot/draw/patch.m Tue Mar 12 15:06:31 2024 -0400 +++ b/scripts/plot/draw/patch.m Thu Mar 14 17:28:46 2024 -0400 @@ -314,24 +314,6 @@ %! close (hf); %! end_unwind_protect -%!test <*65421> -%! hf = figure ("visible", "off"); -%! unwind_protect -%! h1 = patch ("Vertices",[0, 0; 0, 1; 1, 0;1, 1], ... -%! "Faces", [1, 2, 3; 2, 3, 4], "CData", 1); -%! h2 = patch ("Vertices",[0, 0; 0, 1; 1, 0;1, 1], "CData", 1, ... -%! "Faces", [1, 2, 3; 2, 3, 4]); -%! h1_data = get (h1); -%! h2_data = get (h2); -%! assert ({h1_data.xdata, h1_data.ydata}, ... -%! {[0, 0; 0, 1; 1, 1], [0, 1; 1, 0; 0, 1]}); -%! assert ({h1_data.xdata, h1_data.ydata}, {h2_data.xdata, h2_data.ydata}); -%! assert (h1_data.faces, [1, 2, 3; 4, 5, 6]); -%! assert (h1_data.faces, h2_data.faces); -%! unwind_protect_cleanup -%! close (hf); -%! end_unwind_protect - ## Test input validation %!error <invalid color specification C> patch (1, 1, 'x') %!error <invalid TrueColor data C> patch (1, 1, rand (1,2,3))
--- a/scripts/plot/draw/private/__patch__.m Tue Mar 12 15:06:31 2024 -0400 +++ b/scripts/plot/draw/private/__patch__.m Thu Mar 14 17:28:46 2024 -0400 @@ -176,16 +176,6 @@ args = varargin; endif - ## All args now Property/Value pairs. - ## Ensure geometry properties come before other properties (see bug #65421). - geom_props = {"xdata", "ydata", "zdata", "faces", "vertices"}; - geom_args = or (cellfun (@strcmpi, {args(1:2:end)}, geom_props, ... - "UniformOutput", false){:}); - neworder = zeros (size (args)); - neworder(1:2:end) = [find(geom_args), find(! geom_args)] * 2 - 1; - neworder(2:2:end) = neworder(1:2:end) + 1; - args = args(neworder); - if (isempty (p)) p = gca (); endif
--- a/scripts/startup/site-rcfile Tue Mar 12 15:06:31 2024 -0400 +++ b/scripts/startup/site-rcfile Thu Mar 14 17:28:46 2024 -0400 @@ -6,19 +6,33 @@ ## This file contains commands that should be executed each time Octave starts ## for every user at this site. -if ispc () && isguirunning () ... - && ~strcmp (winqueryreg ("HKEY_CURRENT_USER", 'Console\%%Startup', "DelegationConsole"), ... - "{B23D10C0-E52E-411E-9D5B-C09FDF709C7D}") - warn_str = ["WARNING: You are using an incompatible Windows configuration!\n", ... - "Microsoft's new Terminal App is not compatible with Octave.\n", ... - "Please follow the instructions on the following page and set the ", ... - "default terminal to \"Windows Console Host\":\n", ... - "https://octave.discourse.group/t/4981/"]; - warning ("octave:terminal-app", warn_str); - answer = questdlg ([warn_str, "\n\nWould you like to open that page in your browser?"], ... - "Incompatible Configuration", "Yes", "No", "Yes"); - if strcmp (answer, "Yes") - system ("start https://octave.discourse.group/t/4981/"); +if (ispc () && isguirunning ()) + try + is_windows_console_host = ... + strcmp (winqueryreg ("HKEY_CURRENT_USER", 'Console\%%Startup', "DelegationConsole"), ... + "{B23D10C0-E52E-411E-9D5B-C09FDF709C7D}"); + catch + ## The above might fail for old versions of Windows 10 where that + ## registry key didn't exist. Assume that the Windows Console Host + ## is being used in this case. + is_windows_console_host = true; + end_try_catch + + if (! is_windows_console_host) + warn_str = ["WARNING: You are using an incompatible Windows configuration!\n", ... + "Microsoft's new Terminal App is not compatible with Octave.\n", ... + "Please follow the instructions on the following page and set the ", ... + "default terminal to \"Windows Console Host\":\n", ... + "https://octave.discourse.group/t/4981/"]; + warning ("octave:terminal-app", warn_str); + answer = questdlg ([warn_str, "\n\nWould you like to open that page in your browser?"], ... + "Incompatible Configuration", "Yes", "No", "Yes"); + if (strcmp (answer, "Yes")) + system ("start https://octave.discourse.group/t/4981/"); + endif + clear warn_str answer endif - clear warn_str answer + + clear is_windows_console_host + endif
--- a/test/json/jsonencode_BIST.tst Tue Mar 12 15:06:31 2024 -0400 +++ b/test/json/jsonencode_BIST.tst Thu Mar 14 17:28:46 2024 -0400 @@ -17,6 +17,8 @@ %! assert (isequal (jsonencode (50.025), '50.025')); %! %% FIXME: Uncomment when bug #64960 is fixed %! %% assert (isequal (jsonencode (single (50.025)), '50.025')); +%! assert (isequal (jsonencode (uint64 (1e6)), '1000000')); +%! assert (isequal (jsonencode (int64 (-1e6)), '-1000000')); %! assert (isequal (jsonencode (NaN), 'null')); %! assert (isequal (jsonencode (NA), 'null')); % Octave-only test %! assert (isequal (jsonencode (Inf), 'null')); @@ -112,6 +114,8 @@ %!testif HAVE_RAPIDJSON %! assert (isequal (jsonencode ([]), '[]')); %! assert (isequal (jsonencode ([1, 2, 3, 4]), '[1,2,3,4]')); +%! % Matlab encodes flints with values above 1e6-1 in scientific notation. Octave writes integers. +%! assert (isequal (jsonencode ([1.23e6, 2]), '[1230000,2]')); %! assert (isequal (jsonencode ([true; false; true]), '[true,false,true]')); %% Test arrays