robol / MPSolve

Multiprecision Polynomial Solver
GNU General Public License v3.0
42 stars 16 forks source link

Under octave-5.2.0 mps_roots([1 0 0],'s') and mps_roots([1 0 0 0 0 0 0],'u') fail #24

Open robertgj opened 4 years ago

robertgj commented 4 years ago

Firstly, thank you for the mpsolve package.

Building the mpsolve-3.1.7 zipfile downloaded from github.com:

wget -c https://github.com/robol/MPSolve/archive/master.zip
unzip master.zip
cd MPSolve-master
sh ./autogen.sh
./configure --prefix=$OCTAVE_DIR
make -j 6 && make install

Testing:

octave:1> version
ans = 5.2.0-robj
octave:2> pkg load mpsolve
octave:3> pkg list mpsolve
Package Name  | Version | Installation directory
--------------+---------+-----------------------
     mpsolve *|   3.1.7 | .../octave-5.2.0/share/octave/packages/mpsolve-3.1.7
octave:4> mps_roots([1 0 0],'u')
ans =

   6.9093e-310 + 8.6590e-317i
   1.3809e-319 + 1.7319e-306i

octave:5> mps_roots([1 0 0],'s')
ans =

   6.9952e-317 +  0.0000e+00i
   2.5736e+151 + 3.8537e+255i

octave:6> roots([1 0 0])
ans =

   0
   0

octave:7> mps_roots([1 0 0 0 0 0 0],'u')
ans =

   7.0663e-317 +  0.0000e+00i
    2.1322e-81 + 2.8664e+161i
   1.9253e+161 + 7.3681e+228i
    3.4546e-86 +  3.5641e-57i
   4.5663e+257 + 2.1335e+233i
   3.6247e+233 +  6.2591e-85i

octave:9> roots([1 0 0 0 0 0 0])
ans =

   0
   0
   0
   0
   0
   0

Unfortunately, the version of MPSolve available at https://numpi.dm.unipi.it/_media/software/mpsolve/mpsolve-3.2.1.tar.gz fails to compile under octave-5.2.0 because octave_support.h, mps_polyeig.m and DESCRIPTION are missing from examples/octave. However, at the command line:

$ src/mpsolve/mpsolve -v
MPSolve 3.2.1
[robj@morgawr mpsolve-3.2.1]$ src/mpsolve/mpsolve test.pol
(0, 0)
(0, 0)
(0, 0)
(0, 0)
(0, 0)
(0, 0)
[robj@morgawr mpsolve-3.2.1]$ cat test.pol
  ! File: test.pol 
    Degree=6;
    Monomial;
    Real;
    Integer;

     0
     0
     0
     0
     0
     0
     1

    ! EOF

Compiling with debugging symbols:

[mpsolve-3.2.1]$ CFLAGS="-ggdb3 -O0" LDFLAGS="-g" ./configure --prefix=$OCTAVE_DIR
make V=1

and running valgrind:

$ valgrind octave-cli
==67796== Memcheck, a memory error detector
==67796== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==67796== Using Valgrind-3.16.0 and LibVEX; rerun with -h for copyright info
==67796== Command: octave-cli
==67796== 
GNU Octave, version 5.2.0-robj
Copyright (C) 2020 John W. Eaton and others.
This is free software; see the source code for copying conditions.
There is ABSOLUTELY NO WARRANTY; not even for MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  For details, type 'warranty'.

Octave was configured for "x86_64-pc-linux-gnu".

Additional information about Octave is available at https://www.octave.org.

Please contribute if you find this software useful.
For more information, visit https://www.octave.org/get-involved.html

Read https://www.octave.org/bugs.html to learn how to submit bug reports.
For information about changes from previous versions, type 'news'.

octave:1> pkg load mpsolve
octave:2> pkg list mpsolve
Package Name  | Version | Installation directory
--------------+---------+-----------------------
     mpsolve *|   3.1.7 | .../octave-5.2.0/share/octave/packages/mpsolve-3.1.7
octave:3> mps_roots([1 0 0 0 0 0 0],'u')
==67796== Invalid read of size 8
==67796==    at 0xBB80731: mps_raise_data (data.c:123)
==67796==    by 0xBB80CFE: mps_prepare_data (data.c:189)
==67796==    by 0xBB85F6E: mps_standard_mpsolve (main.c:153)
==67796==    by 0xBB356F5: mps_mpsolve (interface.c:74)
==67796==    by 0x5DA82E5: Fmps_roots(octave_value_list const&, int) (in /usr/local/octave-5.2.0/lib/octave/packages/mpsolve-3.1.7/x86_64-pc-linux-gnu-api-v53/mps_roots.oct)
==67796==    by 0x4EF1173: octave_builtin::call(octave::tree_evaluator&, int, octave_value_list const&) (in /usr/local/octave-5.2.0/lib/octave/5.2.0-robj/liboctinterp.so.7.0.1)
==67796==    by 0x4EDBE74: octave::tree_evaluator::visit_index_expression(octave::tree_index_expression&) (in /usr/local/octave-5.2.0/lib/octave/5.2.0-robj/liboctinterp.so.7.0.1)
==67796==    by 0x4ED5C64: octave::tree_evaluator::evaluate(octave::tree_expression*, int) (in /usr/local/octave-5.2.0/lib/octave/5.2.0-robj/liboctinterp.so.7.0.1)
==67796==    by 0x4ECF2B3: octave::tree_evaluator::visit_statement(octave::tree_statement&) (in /usr/local/octave-5.2.0/lib/octave/5.2.0-robj/liboctinterp.so.7.0.1)
==67796==    by 0x4ECF161: octave::tree_evaluator::visit_statement_list(octave::tree_statement_list&) (in /usr/local/octave-5.2.0/lib/octave/5.2.0-robj/liboctinterp.so.7.0.1)
==67796==    by 0x4DF0A6A: octave::tree_evaluator::repl(bool) (in /usr/local/octave-5.2.0/lib/octave/5.2.0-robj/liboctinterp.so.7.0.1)
==67796==    by 0x4AEA0C9: octave::interpreter::execute() [clone .cold] (in /usr/local/octave-5.2.0/lib/octave/5.2.0-robj/liboctinterp.so.7.0.1)
==67796==  Address 0x94550c0 is 0 bytes after a block of size 0 alloc'd
==67796==    at 0x483A809: malloc (vg_replace_malloc.c:307)
==67796==    by 0xBB35817: mps_malloc (interface.c:117)
==67796==    by 0xBB802A3: mps_allocate_data (data.c:51)
==67796==    by 0xBB85AEE: mps_standard_mpsolve (main.c:51)
==67796==    by 0xBB356F5: mps_mpsolve (interface.c:74)
==67796==    by 0x5DA82E5: Fmps_roots(octave_value_list const&, int) (in /usr/local/octave-5.2.0/lib/octave/packages/mpsolve-3.1.7/x86_64-pc-linux-gnu-api-v53/mps_roots.oct)
==67796==    by 0x4EF1173: octave_builtin::call(octave::tree_evaluator&, int, octave_value_list const&) (in /usr/local/octave-5.2.0/lib/octave/5.2.0-robj/liboctinterp.so.7.0.1)
==67796==    by 0x4EDBE74: octave::tree_evaluator::visit_index_expression(octave::tree_index_expression&) (in /usr/local/octave-5.2.0/lib/octave/5.2.0-robj/liboctinterp.so.7.0.1)
==67796==    by 0x4ED5C64: octave::tree_evaluator::evaluate(octave::tree_expression*, int) (in /usr/local/octave-5.2.0/lib/octave/5.2.0-robj/liboctinterp.so.7.0.1)
==67796==    by 0x4ECF2B3: octave::tree_evaluator::visit_statement(octave::tree_statement&) (in /usr/local/octave-5.2.0/lib/octave/5.2.0-robj/liboctinterp.so.7.0.1)
==67796==    by 0x4ECF161: octave::tree_evaluator::visit_statement_list(octave::tree_statement_list&) (in /usr/local/octave-5.2.0/lib/octave/5.2.0-robj/liboctinterp.so.7.0.1)
==67796==    by 0x4DF0A6A: octave::tree_evaluator::repl(bool) (in /usr/local/octave-5.2.0/lib/octave/5.2.0-robj/liboctinterp.so.7.0.1)
==67796== 
==67796== Invalid read of size 4
==67796==    at 0xBBFB364: __gmpf_get_prec (in /usr/lib64/libgmp.so.10.3.2)
==67796==    by 0xBB4C43B: mpc_get_prec (mpc.c:149)
==67796==    by 0xBB8073F: mps_raise_data (data.c:123)
==67796==    by 0xBB80CFE: mps_prepare_data (data.c:189)
==67796==    by 0xBB85F6E: mps_standard_mpsolve (main.c:153)
==67796==    by 0xBB356F5: mps_mpsolve (interface.c:74)
==67796==    by 0x5DA82E5: Fmps_roots(octave_value_list const&, int) (in /usr/local/octave-5.2.0/lib/octave/packages/mpsolve-3.1.7/x86_64-pc-linux-gnu-api-v53/mps_roots.oct)
==67796==    by 0x4EF1173: octave_builtin::call(octave::tree_evaluator&, int, octave_value_list const&) (in /usr/local/octave-5.2.0/lib/octave/5.2.0-robj/liboctinterp.so.7.0.1)
==67796==    by 0x4EDBE74: octave::tree_evaluator::visit_index_expression(octave::tree_index_expression&) (in /usr/local/octave-5.2.0/lib/octave/5.2.0-robj/liboctinterp.so.7.0.1)
==67796==    by 0x4ED5C64: octave::tree_evaluator::evaluate(octave::tree_expression*, int) (in /usr/local/octave-5.2.0/lib/octave/5.2.0-robj/liboctinterp.so.7.0.1)
==67796==    by 0x4ECF2B3: octave::tree_evaluator::visit_statement(octave::tree_statement&) (in /usr/local/octave-5.2.0/lib/octave/5.2.0-robj/liboctinterp.so.7.0.1)
==67796==    by 0x4ECF161: octave::tree_evaluator::visit_statement_list(octave::tree_statement_list&) (in /usr/local/octave-5.2.0/lib/octave/5.2.0-robj/liboctinterp.so.7.0.1)
==67796==  Address 0x30 is not stack'd, malloc'd or (recently) free'd
==67796== 
fatal: caught signal Segmentation fault -- stopping myself...
==67796== 
==67796== Process terminating with default action of signal 11 (SIGSEGV): dumping core
==67796==    at 0x75528F3: raise (in /usr/lib64/libpthread-2.31.so)
==67796==    by 0x7552A8F: ??? (in /usr/lib64/libpthread-2.31.so)
==67796==    by 0xBBFB363: __gmpf_get_prec (in /usr/lib64/libgmp.so.10.3.2)
==67796==    by 0xBB4C43B: mpc_get_prec (mpc.c:149)
==67796==    by 0xBB8073F: mps_raise_data (data.c:123)
==67796==    by 0xBB80CFE: mps_prepare_data (data.c:189)
==67796==    by 0xBB85F6E: mps_standard_mpsolve (main.c:153)
==67796==    by 0xBB356F5: mps_mpsolve (interface.c:74)
==67796==    by 0x5DA82E5: Fmps_roots(octave_value_list const&, int) (in /usr/local/octave-5.2.0/lib/octave/packages/mpsolve-3.1.7/x86_64-pc-linux-gnu-api-v53/mps_roots.oct)
==67796==    by 0x4EF1173: octave_builtin::call(octave::tree_evaluator&, int, octave_value_list const&) (in /usr/local/octave-5.2.0/lib/octave/5.2.0-robj/liboctinterp.so.7.0.1)
==67796==    by 0x4EDBE74: octave::tree_evaluator::visit_index_expression(octave::tree_index_expression&) (in /usr/local/octave-5.2.0/lib/octave/5.2.0-robj/liboctinterp.so.7.0.1)
==67796==    by 0x4ED5C64: octave::tree_evaluator::evaluate(octave::tree_expression*, int) (in /usr/local/octave-5.2.0/lib/octave/5.2.0-robj/liboctinterp.so.7.0.1)
==67796== 
==67796== HEAP SUMMARY:
==67796==     in use at exit: 7,112,158 bytes in 73,163 blocks
==67796==   total heap usage: 421,721 allocs, 348,558 frees, 52,582,073 bytes allocated
==67796== 
==67796== LEAK SUMMARY:
==67796==    definitely lost: 671 bytes in 83 blocks
==67796==    indirectly lost: 0 bytes in 0 blocks
==67796==      possibly lost: 105,448 bytes in 3,188 blocks
==67796==    still reachable: 7,006,039 bytes in 69,892 blocks
==67796==                       of which reachable via heuristic:
==67796==                         newarray           : 224,728 bytes in 1,697 blocks
==67796==         suppressed: 0 bytes in 0 blocks
==67796== Rerun with --leak-check=full to see details of leaked memory
==67796== 
==67796== For lists of detected and suppressed errors, rerun with: -s
==67796== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
Segmentation fault (core dumped)
robol commented 4 years ago

Indeed, I have to admit that the Octave interface is practically not maintained anymore; however, the MATLAB interface should work under Octave, it is sufficient to call the configure script with:

   ./configure MEX="mkoctfile --mex"

I am inclined to remove the Octave files in future releases, and use the mex file only (to avoid duplicating the effort). Could you try if that works for you?

robertgj commented 4 years ago

On Wed, 02 Sep 2020 03:54:30 -0700 Leonardo Robol notifications@github.com wrote:

Indeed, I have to admit that the Octave interface is practically not maintained anymore; however, the MATLAB interface should work under Octave, it is sufficient to call the configure script with: ./configure MEX=mkoctfile --mex I am inclined to remove the Octave files in future releases, and use the mex file only (to avoid duplicating the effort). Could you try if that works for you?

Hi,

There seems to be a conflict between mps_boolean and the standard library boolean type:

make[3]: Entering directory '/home/robj/TMP/MPSolve-master/examples/matlab'

Best regards,

Rob Jenssen

robol commented 4 years ago

There is a compile time option to avoid these defines, since they are in the mex headers as well. For MATLAB it works, and for Octave it used to work; apparently it doesn't anymore. I'll investigate this as soon as I find some time.