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 }