001/*
002*   BracketRoot1D  -- A bracket around a root in a 1D function.
003*
004*   Copyright (C) 2010-2012 by Joseph A. Huwaldt.
005*   All rights reserved.
006*   
007*   This library is free software; you can redistribute it and/or
008*   modify it under the terms of the GNU Lesser General Public
009*   License as published by the Free Software Foundation; either
010*   version 2.1 of the License, or (at your option) any later version.
011*   
012*   This library is distributed in the hope that it will be useful,
013*   but WITHOUT ANY WARRANTY; without even the implied warranty of
014*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
015*   Lesser General Public License for more details.
016*
017*   You should have received a copy of the GNU Lesser General Public License
018*   along with this program; if not, write to the Free Software
019*   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
020*   Or visit:  http://www.gnu.org/licenses/lgpl.html
021**/
022package jahuwaldt.tools.math;
023
024import java.util.List;
025import java.util.ArrayList;
026
027
028/**
029*  Represents the bracket around a root in a 1D function.
030*
031*  <p>  Modified by:  Joseph A. Huwaldt  </p>
032*
033*  @author   Joseph A. Huwaldt   Date:  October 8, 1997
034*  @version  September 16, 2012
035**/
036public class BracketRoot1D implements Comparable<BracketRoot1D> {
037        
038        /**
039        *  The lower bound of the bracket.
040        **/
041        public double x1 = 0;
042        
043        /**
044        *  The upper bound of the bracket.
045        **/
046        public double x2 = 0;
047        
048        
049        //-----------------------------------------------------------------------------------
050        /**
051        *  Construct a bracket around a root in a 1D function.
052        *
053        *  @param x1    The lower bound of the bracket.
054        *  @param x2    The upper bound of the bracket.
055        **/
056        public BracketRoot1D(double x1, double x2) {
057                if (x1 < x2) {
058                        this.x1 = x1;
059                        this.x2 = x2;
060                } else {
061                        this.x2 = x1;
062                        this.x1 = x2;
063                }
064        }
065        
066        /**
067        *  Given a function, <code>func</code>, defined on the interval <code>x1</code> to <code>x2</code>,
068        *  this routine subdivides the interval into <code>n</code> equally spaced segments,
069        *  and searches for zero crossings of the function.  Brackets around any zero crossings found
070        *  are returned.
071        *
072        *  @param func  The function that is being search for zero crossings.
073        *  @param x1    The start of the interval to be searched.
074        *  @param x2    The end of the interval to be searched.
075        *  @param n     The number segments to divide the interval into.
076        *  @return A list containing the brackets that were found.  Could be an empty list if no brackets are found.
077        *  @throws RootException if the Evaluatable1D throws a exception.
078        **/
079        public static List<BracketRoot1D> findBrackets(Evaluatable1D func, double x1, double x2, int n)  throws RootException {
080                List<BracketRoot1D> list = new ArrayList();
081                
082                //      Make sure that x2 is > x1.
083                if (x1 > x2) {
084                        double temp = x1;
085                        x1 = x2;
086                        x2 = temp;
087                }
088                
089                double dx = (x2 - x1)/n;
090                if (dx == 0)    return list;
091                
092                double x = x1;
093                double fp = func.function(x);
094                for (int i=0; i < n; ++i) {
095                        x += dx;
096                        if (x > x2)     x = x2;
097                        double fc = func.function(x);
098                        if (fc*fp <= 0.0) {
099                                list.add(new BracketRoot1D(x - dx, x));
100                        }
101                        fp = fc;
102                }
103                
104                return list;
105        }
106        
107        
108        /**
109        *  Compares this object with the specified object for order.
110        *  Returns a negative integer, zero, or a positive integer as
111        *  this object is less than, equal to, or greater than the specified object.
112        *  This implementation compares the start of the bracket (x1) only.
113        **/
114    @Override
115        public int compareTo(BracketRoot1D o) {
116                return (this.x1 < o.x1 ? -1 : (this.x1 > o.x1 ? 1 : 0));
117        }
118        
119        /**
120        *  Return a String representation of this object.
121        **/
122    @Override
123        public String toString() {
124                StringBuilder buffer = new StringBuilder();
125                buffer.append('{');
126                buffer.append(x1);
127                buffer.append(",");
128                buffer.append(x2);
129                buffer.append('}');
130                return buffer.toString();
131        }
132        
133}