File indexing completed on 2024-04-14 03:39:20

0001 
0002 /*************************************************************************************
0003  *  Copyright (C) 2007-2011 by Aleix Pol <aleixpol@kde.org>                          *
0004  *  Copyright (C) 2010-2012 by Percy Camilo T. Aucahuasi <percy.camilo.ta@gmail.com> *
0005  *                                                                                   *
0006  *  This program is free software; you can redistribute it and/or                    *
0007  *  modify it under the terms of the GNU General Public License                      *
0008  *  as published by the Free Software Foundation; either version 2                   *
0009  *  of the License, or (at your option) any later version.                           *
0010  *                                                                                   *
0011  *  This program is distributed in the hope that it will be useful,                  *
0012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of                   *
0013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                    *
0014  *  GNU General Public License for more details.                                     *
0015  *                                                                                   *
0016  *  You should have received a copy of the GNU General Public License                *
0017  *  along with this program; if not, write to the Free Software                      *
0018  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA   *
0019  *************************************************************************************/
0020 
0021 #include "abstractfunctiongraph.h"
0022 #include "functiongraphfactory.h"
0023 
0024 #include "analitza/variable.h"
0025 #include <analitza/variables.h>
0026 
0027 using namespace Analitza;
0028 
0029 // combobox For 3 or fewer options, use a set of radio buttons. 
0030 // no combo para dict For more than 10 options, use a list. 
0031 // get new plots 
0032 // 
0033 // Make the list control large enough that it can show at least four items at a time without scrolling. 
0034 // For lists of ten or more items, increase this minimum size as appropriate. 
0035 
0036 AbstractFunctionGraph::AbstractFunctionGraph(const Analitza::Expression& e, const QSharedPointer<Analitza::Variables>& v)
0037     : AbstractMappingGraph()
0038     , m_resolution(200)
0039     , m_e(e)
0040     , m_varsmod(v ? new Variables(*v) : new Variables)
0041 {
0042     analyzer = new Analitza::Analyzer(m_varsmod);
0043 
0044     Q_ASSERT(!m_e.isEquation());
0045     
0046     analyzer->setExpression(m_e);
0047     analyzer->simplify();
0048 
0049     QStack<Analitza::Object*> stack;
0050     foreach(const QString& var, analyzer->expression().bvarList()) {
0051         Analitza::Cn* val = new Analitza::Cn;
0052         stack.push(val);
0053         m_argumentValues.insert(var, val);
0054     }
0055     analyzer->setStack(stack);
0056 }
0057 
0058 AbstractFunctionGraph::~AbstractFunctionGraph()
0059 {
0060     qDeleteAll(m_argumentValues);
0061     delete analyzer;
0062     delete m_varsmod;
0063 }
0064 
0065 Dimension AbstractFunctionGraph::spaceDimension() const
0066 {
0067     return FunctionGraphFactory::self()->spaceDimension(m_internalId);
0068 }
0069 
0070 Analitza::Variables *AbstractFunctionGraph::variables() const 
0071 { 
0072     return m_varsmod;
0073 }
0074 
0075 void AbstractFunctionGraph::setVariables(Analitza::Variables* variables)
0076 {
0077     Q_ASSERT(variables);
0078     
0079     Analitza::Expression exp = analyzer->expression();
0080     QVector<Analitza::Object*> prevStack = analyzer->runStack();
0081     delete analyzer;
0082     delete m_varsmod;
0083     
0084     analyzer = new Analitza::Analyzer(variables);
0085     analyzer->setExpression(exp);
0086     analyzer->setStack(prevStack);
0087     
0088     m_varsmod = variables;
0089 }
0090 
0091 const Analitza::Expression& AbstractFunctionGraph::expression() const
0092 {
0093     return m_e;
0094 }
0095 
0096 QPair<Analitza::Expression, Analitza::Expression> AbstractFunctionGraph::interval(const QString &argname, bool evaluate) const
0097 {
0098     Q_ASSERT(analyzer->expression().bvarList().contains(argname));
0099     
0100     QPair<Analitza::Expression, Analitza::Expression> ret;
0101     
0102     if (evaluate) {
0103         Analitza::Analyzer *intervalsAnalizer = new Analitza::Analyzer(analyzer->variables());
0104 
0105         ret.first = m_argumentIntervals[argname].lowEndPoint().value(intervalsAnalizer);
0106         ret.second = m_argumentIntervals[argname].highEndPoint().value(intervalsAnalizer);
0107         
0108         delete intervalsAnalizer; 
0109         
0110     } else {
0111         ret.first = m_argumentIntervals[argname].lowEndPoint().value();
0112         ret.second = m_argumentIntervals[argname].highEndPoint().value();
0113     }
0114     
0115     return ret;
0116 }
0117 
0118 bool AbstractFunctionGraph::setInterval(const QString &argname, const Analitza::Expression &min, const Analitza::Expression &max)
0119 {
0120     Q_ASSERT(analyzer->expression().bvarList().contains(argname));
0121     
0122     if (min == Expression(Analitza::Cn("-inf")) && 
0123         max == Expression(Analitza::Cn("inf")))
0124     {
0125         m_argumentIntervals[argname] = RealInterval(EndPoint(min), EndPoint(max));        
0126     }
0127     
0128     Analitza::Analyzer *intervalsAnalizer = new Analitza::Analyzer(analyzer->variables());
0129     intervalsAnalizer->setExpression(min);
0130     double min_val = intervalsAnalizer->calculate().toReal().value();
0131     intervalsAnalizer->setExpression(max);
0132     double max_val = intervalsAnalizer->calculate().toReal().value();
0133     
0134     delete intervalsAnalizer;
0135     
0136     if (max_val < min_val)
0137         return false;
0138     
0139     m_argumentIntervals[argname] = RealInterval(EndPoint(min), EndPoint(max));
0140     
0141     return true;
0142 }
0143 
0144 QPair<double, double> AbstractFunctionGraph::interval(const QString &argname) const
0145 {
0146     Q_ASSERT(analyzer->expression().bvarList().contains(argname));
0147     
0148     QPair<double, double> ret;
0149     
0150     Analitza::Analyzer *intervalsAnalizer = new Analitza::Analyzer(analyzer->variables());
0151     ret.first = m_argumentIntervals[argname].lowEndPoint().value(intervalsAnalizer).toReal().value();
0152     ret.second = m_argumentIntervals[argname].highEndPoint().value(intervalsAnalizer).toReal().value();
0153     
0154     delete intervalsAnalizer;
0155 
0156     return ret;
0157 }
0158 
0159 void AbstractFunctionGraph::clearIntervals()
0160 {
0161     m_argumentIntervals.clear();
0162 }
0163 
0164 bool AbstractFunctionGraph::setInterval(const QString &argname, double min, double max)
0165 {
0166     Q_ASSERT(analyzer->expression().bvarList().contains(argname));
0167     
0168     if (max < min)
0169         return false;
0170 
0171     m_argumentIntervals[argname] = RealInterval(EndPoint(min), EndPoint(max));
0172 
0173     return true;
0174 }
0175 
0176 Analitza::Cn* AbstractFunctionGraph::arg(const QString& argname)
0177 {
0178     return m_argumentValues[argname];
0179 }
0180 
0181 bool AbstractFunctionGraph::hasIntervals() const
0182 {
0183     return !m_argumentIntervals.isEmpty();
0184 }
0185 
0186 bool AbstractFunctionGraph::isCorrect() const
0187 {
0188     return m_errors.isEmpty() && analyzer->isCorrect();
0189 }
0190 
0191 QStringList AbstractFunctionGraph::errors() const
0192 {
0193     QStringList ret = m_errors+analyzer->errors();
0194     ret.removeDuplicates();
0195     return ret;
0196 }