File indexing completed on 2024-04-28 03:40:47

0001 /*************************************************************************************
0002  *  Copyright (C) 2009 by Aleix Pol <aleixpol@kde.org>                               *
0003  *                                                                                   *
0004  *  This program is free software; you can redistribute it and/or                    *
0005  *  modify it under the terms of the GNU General Public License                      *
0006  *  as published by the Free Software Foundation; either version 2                   *
0007  *  of the License, or (at your option) any later version.                           *
0008  *                                                                                   *
0009  *  This program is distributed in the hope that it will be useful,                  *
0010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of                   *
0011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                    *
0012  *  GNU General Public License for more details.                                     *
0013  *                                                                                   *
0014  *  You should have received a copy of the GNU General Public License                *
0015  *  along with this program; if not, write to the Free Software                      *
0016  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA   *
0017  *************************************************************************************/
0018 
0019 #include "vector.h"
0020 #include "expression.h"
0021 #include "abstractexpressionvisitor.h"
0022 #include "analitzautils.h"
0023 #include "value.h"
0024 
0025 using namespace Analitza;
0026 
0027 Vector::Vector(const Vector& v)
0028     : Object(Object::vector)//, m_elements(v.m_elements.size())
0029     , m_hasOnlyNumbers(true)
0030     , m_nonZeroTaken(false) , m_isDiagonalRowVector(true) , m_nonZeros(0)
0031 {
0032     m_elements.reserve(v.m_elements.size());
0033     foreach(const Object* o, v.m_elements) {
0034         m_elements.append(o->copy());
0035     }
0036 }
0037 
0038 Vector::Vector(int size)
0039     : Object(Object::vector)//, m_elements(size)
0040     , m_hasOnlyNumbers(true)
0041     , m_nonZeroTaken(false)
0042     , m_isDiagonalRowVector(true)
0043     , m_nonZeros(0)
0044 {
0045     m_elements.reserve(size);
0046 }
0047 
0048 Vector::Vector(Object::ObjectType t, int size)
0049     : Object(t)
0050     , m_hasOnlyNumbers(true)
0051     , m_nonZeroTaken(false)
0052     , m_isDiagonalRowVector(true)
0053     , m_nonZeros(0)
0054 {
0055     m_elements.reserve(size);
0056 }
0057 
0058 Vector::Vector(int size, const Cn* value)
0059     : Object(Object::vector)//, m_elements(size)
0060     , m_hasOnlyNumbers(true)
0061     , m_nonZeroTaken(false)
0062     , m_isDiagonalRowVector(true)
0063     , m_nonZeros(0)
0064 {
0065     Q_ASSERT(size > 0);
0066     Q_ASSERT(value);
0067     
0068     for (int i = 0; i < size; ++i)
0069         appendBranch(value->copy());
0070 }
0071 
0072 Vector::~Vector()
0073 {
0074     qDeleteAll(m_elements);
0075 }
0076 
0077 Vector* Vector::copy() const
0078 {
0079     Vector *v=new Vector(m_type, size());
0080     foreach(const Object* o, m_elements) {
0081         v->m_elements.append(o->copy());
0082     }
0083     return v;
0084 }
0085 
0086 void Vector::appendBranch(Object* o)
0087 {
0088     Q_ASSERT(o);
0089     
0090     if (o->type() != Object::value && m_hasOnlyNumbers)
0091         m_hasOnlyNumbers = false;
0092     
0093     const bool isobjzero = o->isZero();
0094     
0095     if (!isobjzero) {
0096         if (!m_nonZeroTaken)
0097             ++m_nonZeros;
0098     }
0099     
0100     if (o->type() == Object::value) {
0101         //puse && !m_nonZeroTaken sin testing
0102         if (m_nonZeros > 1 && !m_nonZeroTaken) {
0103             m_isDiagonalRowVector = false;
0104             m_nonZeroTaken = true;
0105         }
0106     }
0107     
0108     m_elements.append(o);
0109 }
0110 
0111 QVariant Vector::accept(AbstractExpressionVisitor* e) const
0112 {
0113     return e->visit(this);
0114 }
0115 
0116 bool Vector::matches(const Object* exp, QMap< QString, const Object* >* found) const
0117 {
0118     if(Object::vector!=exp->type())
0119         return false;
0120     const Vector* c=(const Vector*) exp;
0121     if(m_elements.count()!=c->m_elements.count())
0122         return false;
0123     
0124     bool matching=true;
0125     Vector::const_iterator it, it2, itEnd=m_elements.constEnd();
0126     for(it=m_elements.constBegin(), it2=c->m_elements.constBegin(); matching && it!=itEnd; ++it, ++it2) {
0127         matching &= (*it)->matches(*it2, found);
0128     }
0129     return matching;
0130 }
0131 
0132 bool Vector::operator==(const Vector& v) const
0133 {
0134     bool eq=v.size()==size();
0135     
0136     for(int i=0; eq && i<m_elements.count(); ++i) {
0137         eq = eq && AnalitzaUtils::equalTree(m_elements[i], v.m_elements[i]);
0138     }
0139     return eq;
0140 }
0141 
0142 bool Vector::isZero() const
0143 {
0144     bool zero = false;
0145     foreach(const Object* o, m_elements) {
0146         zero |= o->isZero();
0147     }
0148     return zero;
0149 }
0150 
0151 bool Vector::isStandardBasisVector() const
0152 {
0153     bool hasOne = false;
0154     foreach(const Object* o, m_elements) {
0155         Q_ASSERT(o->type() == Object::value);
0156         Cn* v = (Cn*) o;
0157         switch (v->intValue()) {
0158             case 0:
0159                 continue;
0160             case 1:
0161                 hasOne = true;
0162                 break;
0163             default:
0164                 return false;
0165         }
0166     }
0167     return hasOne;
0168 }