diff options
Diffstat (limited to 'graphics/epix/data_bins.cc')
-rw-r--r-- | graphics/epix/data_bins.cc | 411 |
1 files changed, 0 insertions, 411 deletions
diff --git a/graphics/epix/data_bins.cc b/graphics/epix/data_bins.cc deleted file mode 100644 index 9474c1de25..0000000000 --- a/graphics/epix/data_bins.cc +++ /dev/null @@ -1,411 +0,0 @@ -/* - * data_bins.cc -- ePiX::data_bins class for histogram data - * - * This file is part of ePiX, a C++ library for creating high-quality - * figures in LaTeX - * - * Version 1.2.0-2 - * Last Change: September 26, 2007 - */ - -/* - * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 - * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> - * Department of Mathematics and Computer Science - * College of the Holy Cross - * Worcester, MA, 01610-2395, USA - */ - -/* - * ePiX 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. - * - * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#include <cmath> -#include <string> -#include <sstream> -#include <list> -#include <vector> - -#include "errors.h" - -#include "constants.h" -#include "functions.h" -#include "triples.h" - -#include "path.h" -#include "spline.h" - -#include "curves.h" - -#include "data_bins.h" - -namespace ePiX { - - // print summary statistics - static void __epix_out_of_range(const std::string& fcn, - unsigned int lo, unsigned int hi, - unsigned int hits) - { - if (0 == lo + hi && 0 == hits) - return; - - // else - if (0 < lo + hi) - { - std::stringstream buf; - buf << fcn << " has " << lo + hi << " point(s) out of range: "; - - bool need_comma(false); - - if (0 < lo) - { - buf << lo << " below"; - need_comma = true; - } - - if (0 < hi) - { - if (need_comma) - buf << ", "; - - buf << hi << " above"; - } - epix_warning(buf.str()); - } - - if (0 < hits) - { - std::stringstream buf; - buf << fcn << " has " << hits/2 << " point(s) on cuts"; - epix_warning(buf.str()); - } - } - - - //// histogram data bin //// - class d_bin { - public: - d_bin(double low, double high) - : m_lo(low), m_hi(high), m_dbl_count(0) { } - - double add_datum(double x) - { - if (x < m_lo || m_hi < x) - return 0.0; - - else if (m_lo < x && x < m_hi) - { - m_dbl_count += 2; - return 1.0; - } - - else // x == m_lo || x == m_hi - { - ++m_dbl_count; - return 0.5; - } - } - - // draw rectangle; height = scale*population - void draw_ht(double scale) const - { - rect(P(m_lo,0), P(m_hi, 0.5*scale*m_dbl_count)); - } - - // area = scale*population - void draw_area(double scale) const - { - if (EPIX_EPSILON < m_hi - m_lo) - rect(P(m_lo,0), P(m_hi, 0.5*scale*m_dbl_count/(m_hi - m_lo))); - } - - double lo() const - { - return m_lo; - } - - double hi() const - { - return m_hi; - } - - double ht(double scale) const - { - return 0.5*scale*m_dbl_count; - } - - P loc(double scale) const - { - return P(0.5*(m_lo + m_hi), 0.5*scale*m_dbl_count); - } - - d_bin* clone() const - { - return new d_bin(*this); - } - - private: - double m_lo, m_hi; // end values - - // twice the number of elements; endpoint hits count as 1 - unsigned int m_dbl_count; - }; // end of class d_bin - - - //// data_bins functions //// - data_bins::data_bins(double lo, double hi, unsigned int n) - : m_lo_val(min(lo, hi)), m_hi_val(max(lo, hi)), - m_lo_ct(0), m_hi_ct(0), m_pop(0), m_cut_hits(0), - m_cuts_locked(false) - { - // divide [lo, hi] into n pieces (n>0), or into unit pieces (n=0) - unsigned int ct(n>0 ? n : (unsigned int)(m_hi_val - m_lo_val)); - const double dx((m_hi_val - m_lo_val)/ct); - - for (unsigned int i=0; i<=ct; ++i) - m_cuts.push_back(m_lo_val + i*dx); - } - - data_bins::data_bins(const data_bins& db) - : m_lo_val(db.m_lo_val), m_hi_val(db.m_hi_val), - m_lo_ct(db.m_lo_ct), m_hi_ct(db.m_hi_ct), - m_pop(db.m_pop), m_cut_hits(db.m_cut_hits), - m_cuts_locked(db.m_cuts_locked), m_cuts(db.m_cuts) - { - for (std::list<d_bin*>::const_iterator p=db.m_bins.begin(); - p != db.m_bins.end(); ++p) - m_bins.push_back((*p)->clone()); - } - - data_bins& data_bins::operator= (const data_bins& db) - { - if (this != &db) - { - std::list<d_bin*> tmp; - for (std::list<d_bin*>::const_iterator p=db.m_bins.begin(); - p!=db.m_bins.end(); ++p) - tmp.push_back((*p)->clone()); - - // assign data - m_lo_val = db.m_lo_val; - m_hi_val = db.m_hi_val; - - m_lo_ct = db.m_lo_ct; - m_hi_ct = db.m_hi_ct; - m_pop = db.m_pop; - m_cut_hits = db.m_cut_hits; - m_cuts_locked = db.m_cuts_locked; - - // deallocate memory - for (std::list<d_bin*>::iterator p=m_bins.begin(); - p!=m_bins.end(); ++p) - delete *p; - - m_cuts = db.m_cuts; - swap(m_bins, tmp); - } - - return *this; - } - - data_bins::~data_bins() - { - for (std::list<d_bin*>::iterator p=m_bins.begin(); p!=m_bins.end(); ++p) - delete *p; - } - - - data_bins& data_bins::cut(double x) - { - if (m_cuts_locked) - epix_warning("cut() called on locked data_bins, no action"); - - else if (x < m_lo_val || m_hi_val < x) - epix_warning("cut() out of range, no action"); - - else - m_cuts.push_back(x); - - return *this; - } - - data_bins& data_bins::read(const std::vector<double>& data) - { - if (0 < data.size()) - { - if (!m_cuts_locked) - initialize(); - - for (std::vector<double>::const_iterator p=data.begin(); - p != data.end(); ++p) - insert(*p); - } - return *this; - } - - unsigned int data_bins::pop() const - { - return m_pop; - } - - // rectangles - void data_bins::histogram(double scale) const - { - if (m_pop == 0) - return; - - // else - __epix_out_of_range("histogram", m_lo_ct, m_hi_ct, m_cut_hits); - - // const double denom((m_hi_val - m_lo_val)/m_pop); - const double adj(scale/m_pop); - - for (std::list<d_bin*>::const_iterator p=m_bins.begin(); - p != m_bins.end(); ++p) - (*p)->draw_area(adj); - } - - void data_bins::bar_chart(double scale) const - { - if (m_pop == 0) - return; - - // else - __epix_out_of_range("bar_chart", m_lo_ct, m_hi_ct, m_cut_hits); - - const double adj(scale/m_pop); // scale=1 -> ht=frac of pop in bin - - for (std::list<d_bin*>::const_iterator p=m_bins.begin(); - p != m_bins.end(); ++p) - (*p)->draw_ht(adj); - } - - // piecewise-cubic interpolation of bar_chart - void data_bins::plot(double scale) const - { - if (m_pop == 0) - return; - - // else - __epix_out_of_range("data_bins::plot", m_lo_ct, m_hi_ct, m_cut_hits); - - // get rectangle corners - std::vector<P> vertices; - - std::list<d_bin*>::const_iterator bn(m_bins.begin()); - vertices.push_back(P((*bn)->lo(),0)); - - for (bn = m_bins.begin(); bn != m_bins.end(); ++bn) - { - vertices.push_back(P((*bn)->lo(), (*bn)->ht(scale/m_pop))); - vertices.push_back(P((*bn)->hi(), (*bn)->ht(scale/m_pop))); - } - - --bn; // last bin - vertices.push_back(P((*bn)->hi(),0)); - - const unsigned int N(vertices.size()); - - // draw piecewise cubic interpolation - line(vertices.at(0), 0.5*(vertices.at(0) + vertices.at(1))); - - // Magic number 20 to reduce file size - for (unsigned int i=1; i< N-1; ++i) - spline(0.5*(vertices.at(i-1) + vertices.at(i)), - vertices.at(i), - vertices.at(i), - 0.5*(vertices.at(i) + vertices.at(i+1)), 20); - - line(0.5*(vertices.at(N-2) + vertices.at(N-1)), vertices.at(N-1)); - } // end of plot(scale) - - - // private bookkeeping functions - void data_bins::initialize() - { - if (!m_cuts_locked) // defensive redundancy - { - // sort list of cuts, remove duplicates, and lock - m_cuts.sort(); - m_cuts.unique(); - - m_cuts_locked=true; - - // allocate d_bins - for (std::list<double>::const_iterator curr = m_cuts.begin(); - curr != m_cuts.end(); ++curr) - { - std::list<double>::const_iterator next(curr); - ++next; - - if (next != m_cuts.end() && *curr != *next) - m_bins.push_back(new d_bin(*curr, *next)); - - else if (*curr != m_hi_val) - m_bins.push_back(new d_bin(*curr, m_hi_val)); - } - } - } - - // Ideally no data lies on a cut, but we'll cope as well as possible - // otherwise. Data on an end cut is "out of range". Data on an interior - // cut contributes 1/2 to the population of each adjacent bin. - void data_bins::insert(double x) - { - ++m_pop; - - std::list<d_bin*>::iterator p(m_bins.begin()); - - // check end bins first - if (x <= m_lo_val) - { - ++m_lo_ct; - if (fabs(x - m_lo_val) < EPIX_EPSILON) - { - (*p)->add_datum(x); - m_cut_hits += 2; - } - return; - } - - if (m_hi_val <= x) - { - ++m_hi_ct; - if (fabs(x - m_hi_val) < EPIX_EPSILON) - { - p = m_bins.end(); - --p; - (*p)->add_datum(x); - m_cut_hits += 2; - } - return; - } - - // else - double success(0.0); - p = m_bins.begin(); - - // try "normal" bins serially - while (success < 0.75 && p!=m_bins.end()) // success is a half-integer - { - double ct((*p++)->add_datum(x)); // 1 for yes, 0.5 for endpt, 0 for no - success += ct; - if (fabs(ct - 0.5) < EPIX_EPSILON) - ++m_cut_hits; - } - - if (success < 0.75) // still not added! - epix_warning("data_bin::insert() internal error"); - } -} // end of namespace |