diff options
Diffstat (limited to 'tests/galaxy/cumulativedistributor.cpp')
-rw-r--r-- | tests/galaxy/cumulativedistributor.cpp | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/tests/galaxy/cumulativedistributor.cpp b/tests/galaxy/cumulativedistributor.cpp new file mode 100644 index 00000000..0171b4d4 --- /dev/null +++ b/tests/galaxy/cumulativedistributor.cpp @@ -0,0 +1,143 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.io +** +** This file is part of the Qt Data Visualization module. +** +** Licensees holding valid commercial license for Qt may use this file in +** accordance with the Qt License Agreement provided with the Software +** or, alternatively, in accordance with the terms contained in a written +** agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.io +** +****************************************************************************/ + +/* + * Galaxy creation code obtained from http://beltoforion.de/galaxy/galaxy_en.html + * Thanks to Ingo Berg, great work. + * Licensed under a Creative Commons Attribution 3.0 License + * http://creativecommons.org/licenses/by/3.0/ + */ + +#include "cumulativedistributor.h" + +#include <QDebug> + +CumulativeDistributor::CumulativeDistributor() + : m_pDistFun(NULL), + m_vM1(), + m_vY1(), + m_vX1(), + m_vM2(), + m_vY2(), + m_vX2() +{ +} + +CumulativeDistributor::~CumulativeDistributor() +{ +} + +void CumulativeDistributor::setupRealistic(qreal I0, qreal k, qreal a, + qreal RBulge, qreal min, qreal max, + int nSteps) +{ + m_fMin = min; + m_fMax = max; + m_nSteps = nSteps; + + m_I0 = I0; + m_k = k; + m_a = a; + m_RBulge = RBulge; + + m_pDistFun = &CumulativeDistributor::Intensity; + + // build the distribution function + buildCDF(m_nSteps); +} + +void CumulativeDistributor::buildCDF(int nSteps) +{ + qreal h = (m_fMax - m_fMin) / nSteps; + qreal x = 0, y = 0; + + m_vX1.clear(); + m_vY1.clear(); + m_vX2.clear(); + m_vM1.clear(); + m_vM1.clear(); + + // Simpson rule for integration of the distribution function + m_vY1.push_back(0.0); + m_vX1.push_back(0.0); + for (int i = 0; i < nSteps; i += 2) { + x = (i + 2) * h; + y += h/3 * ((this->*m_pDistFun)(m_fMin + i*h) + 4*(this->*m_pDistFun)(m_fMin + (i+1)*h) + (this->*m_pDistFun)(m_fMin + (i+2)*h) ); + + m_vM1.push_back((y - m_vY1.back()) / (2*h)); + m_vX1.push_back(x); + m_vY1.push_back(y); + } + + // normieren + for (int i = 0; i < m_vM1.size(); i++) { + m_vY1[i] /= m_vY1.back(); + m_vM1[i] /= m_vY1.back(); + } + + m_vY2.clear(); + m_vM2.clear(); + m_vY2.push_back(0.0); + + qreal p = 0; + h = 1.0 / nSteps; + for (int i = 1, k = 0; i < nSteps; ++i) { + p = (qreal)i * h; + + for (; m_vY1[k+1] <= p; ++k) { + } + + y = m_vX1[k] + (p - m_vY1[k]) / m_vM1[k]; + + m_vM2.push_back( (y - m_vY2.back()) / h); + m_vX2.push_back(p); + m_vY2.push_back(y); + } +} + +qreal CumulativeDistributor::valFromProp(qreal fVal) +{ + if (fVal < 0.0 || fVal > 1.0) + throw std::runtime_error("out of range"); + + qreal h = 1.0 / m_vY2.size(); + + int i = int(fVal / h); + qreal remainder = fVal - i*h; + + int min = qMin(m_vY2.size(), m_vM2.size()); + if (i >= min) + i = min - 1; + + return (m_vY2[i] + m_vM2[i] * remainder); +} + +qreal CumulativeDistributor::IntensityBulge(qreal R, qreal I0, qreal k) +{ + return I0 * exp(-k * pow(R, 0.25)); +} + +qreal CumulativeDistributor::IntensityDisc(qreal R, qreal I0, qreal a) +{ + return I0 * exp(-R/a); +} + +qreal CumulativeDistributor::Intensity(qreal x) +{ + return (x < m_RBulge) ? IntensityBulge(x, m_I0, m_k) : IntensityDisc(x - m_RBulge, IntensityBulge(m_RBulge, m_I0, m_k), m_a); +} |