/* * surf - visualizing algebraic curves and algebraic surfaces * Copyright (C) 1996-1997 Friedrich-Alexander-Universitaet * Erlangen-Nuernberg * 1997-2000 Johannes Gutenberg-Universitaet Mainz * Authors: Stephan Endrass, Hans Huelf, Ruediger Oertel, * Kai Schneider, Ralf Schmitt, Johannes Beigel * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ // =========================================================================== // File roots.cc // Author: Stephan Endrass // Address: endrass@mi.uni-erlangen.de // Date: 3.2.95 // =========================================================================== #include #include #include #include "degree.h" #include "def.h" #include "monomarith.h" #include "polyarith.h" #include "polyroot.h" #include "bezierarith.h" #include "hornerarith.h" #include "polylexyacc.h" #include "gui_config.h" #include "NewClip.h" // using namespace globals; int numeric_multi_root = 0; // ---------------------------------------------------------------------------- // compute roots of f in [zmin,zmax] where g is positive // f: polynomial // [zmin,zmax]: interval // *root: roots of f // *root_old: values near the roots // old_n: # of values in *root_old // depends on: // numeric_multi_root: TRUE => compute all roots // FALSE => compute biggest root // numeric_root_finder_data: chooses method // ---------------------------------------------------------------------------- int zero_of_polyx( polyx *f, double zmax,double zmin, double *root, double *root_old,int old_n, NewClip *clipper ) { // ------------ // get degree // ------------ int n = f->n; int num = 0; while( n >= 0 && f->a[n] == 0.0 ) { n--; } switch( n ) { // --------------------------- // zero polynomial: one root // --------------------------- case -1 : root[0] = zmax; return TRUE; // ------------------------------ // constant polynomial: no root // ------------------------------ case 0 : return 0; // ------------------------------------- // linear polynomial: at most one root // ------------------------------------ case 1 : root[0] = -f->a[0]/f->a[1]; return ( zmin < root[0] && root[0] < zmax && clipper->clip_user_xyz( root[0] ) ? 1 : 0 ); // ------------------------------------------------------- // polynomial of degree two or higher: several methods // ------------------------------------------------------- default : if( numeric_root_finder_data == NUMERIC_ROOT_BEZIER ) { // ------------------------------- // Rockwoods all roots algorithm // ------------------------------- if( numeric_multi_root ) { if( old_n == 0 ) { num = zero_of_bezier_multi_root_no_help( f,zmin,zmax, root ); } else { num = zero_of_bezier_multi_root_no_help( f,zmin,zmax, root ); } } else { if( old_n == 0 ) { if( zero_of_bezier_single_root_no_help( f,zmin,zmax,root ) > 0 ) { while( !clipper->clip_user_xyz( root[0] ) && zmin 0 ) { while( !clipper->clip_user_xyz( root[0] ) && root[0]>zmin ) { if( zero_of_bezier_single_root_help_open( f,zmin,root[0],root,root_old[0] )==0 ) { return 0; } } return 1; } } } } else { // ------------------- // D-chain algorithm // ------------------- int mults[MAX_DEGREE]; num = polyx_all_roots( f,zmin,zmax,root,mults ); if( !numeric_multi_root ) { for( int j=0; jclip_user_xyz( root[j] ) ) { root[0] = root[j]; return 1; } } return 0; } } } int num_new = num; for( int j=0, k=0; jclip_user_xyz( root[j] ) ) { if( k