1 // @(#)root/minuit2:$Id$
2 // Authors: M. Winkler, F. James, L. Moneta, A. Zsenei   2003-2005
3 
4 /**********************************************************************
5  *                                                                    *
6  * Copyright (c) 2005 LCG ROOT Math team,  CERN/PH-SFT                *
7  *                                                                    *
8  **********************************************************************/
9 
10 #include <cmath>
11 
12 namespace ROOT {
13 
14 namespace Minuit2 {
15 
mnbins(double a1,double a2,int naa,double & bl,double & bh,int & nb,double & bwid)16 void mnbins(double a1, double a2, int naa, double &bl, double &bh, int &nb, double &bwid)
17 {
18 
19    //*-*-*-*-*-*-*-*-*-*-*Compute reasonable histogram intervals*-*-*-*-*-*-*-*-*
20    //*-*                  ======================================
21    //*-*        Function TO DETERMINE REASONABLE HISTOGRAM INTERVALS
22    //*-*        GIVEN ABSOLUTE UPPER AND LOWER BOUNDS  A1 AND A2
23    //*-*        AND DESIRED MAXIMUM NUMBER OF BINS NAA
24    //*-*        PROGRAM MAKES REASONABLE BINNING FROM BL TO BH OF WIDTH BWID
25    //*-*        F. JAMES,   AUGUST, 1974 , stolen for Minuit, 1988
26    //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
27 
28    /* Local variables */
29    double awid, ah, al, sigfig, sigrnd, alb;
30    int kwid, lwid, na = 0, log_;
31 
32    al = a1 < a2 ? a1 : a2;
33    //     al = std::min(a1,a2);
34    //     ah = std::max(a1,a2);
35    ah = a1 > a2 ? a1 : a2;
36    if (al == ah)
37       ah = al + 1;
38 
39    //*-*-       IF NAA .EQ. -1 , PROGRAM USES BWID INPUT FROM CALLING ROUTINE
40    if (naa == -1)
41       goto L150;
42 L10:
43    na = naa - 1;
44    if (na < 1)
45       na = 1;
46 
47    //*-*-        GET NOMINAL BIN WIDTH IN EXPON FORM
48 L20:
49    awid = (ah - al) / double(na);
50    log_ = int(log10(awid));
51    if (awid <= 1)
52       --log_;
53    sigfig = awid * pow(10.0, -log_);
54    //*-*-       ROUND MANTISSA UP TO 2, 2.5, 5, OR 10
55    if (sigfig > 2)
56       goto L40;
57    sigrnd = 2;
58    goto L100;
59 L40:
60    if (sigfig > 2.5)
61       goto L50;
62    sigrnd = 2.5;
63    goto L100;
64 L50:
65    if (sigfig > 5)
66       goto L60;
67    sigrnd = 5;
68    goto L100;
69 L60:
70    sigrnd = 1;
71    ++log_;
72 L100:
73    bwid = sigrnd * pow(10.0, log_);
74    goto L200;
75    //*-*-       GET NEW BOUNDS FROM NEW WIDTH BWID
76 L150:
77    if (bwid <= 0)
78       goto L10;
79 L200:
80    alb = al / bwid;
81    lwid = int(alb);
82    if (alb < 0)
83       --lwid;
84    bl = bwid * double(lwid);
85    alb = ah / bwid + 1;
86    kwid = int(alb);
87    if (alb < 0)
88       --kwid;
89    bh = bwid * double(kwid);
90    nb = kwid - lwid;
91    if (naa > 5)
92       goto L240;
93    if (naa == -1)
94       return;
95    //*-*-        REQUEST FOR ONE BIN IS DIFFICULT CASE
96    if (naa > 1 || nb == 1)
97       return;
98    bwid *= 2;
99    nb = 1;
100    return;
101 L240:
102    if (nb << 1 != naa)
103       return;
104    ++na;
105    goto L20;
106 } /* mnbins_ */
107 
108 } // namespace Minuit2
109 
110 } // namespace ROOT
111