//TODO complex values as matrix entries too //TODO support endomorphisms over Rn too Expression EigenvectorsCommand::operator()(const QList< Analitza::Expression >& args) { Expression ret; QStringList errors; const Eigen::MatrixXcd eigeninfo = executeEigenSolver(args, true, errors); if (!errors.isEmpty()) { ret.addError(errors.first()); return ret; } const int neigenvectors = eigeninfo.rows(); QScopedPointer<Analitza::List> list(new Analitza::List); for (int j = 0; j < neigenvectors; ++j) { const Eigen::VectorXcd col = eigeninfo.col(j); QScopedPointer<Analitza::Vector> eigenvector(new Analitza::Vector(neigenvectors)); for (int i = 0; i < neigenvectors; ++i) { const std::complex<double> eigenvalue = col(i); const double realpart = eigenvalue.real(); const double imagpart = eigenvalue.imag(); if (std::isnan(realpart) || std::isnan(imagpart)) { ret.addError(QCoreApplication::tr("Returned eigenvalue is NaN", "NaN means Not a Number, is an invalid float number")); return ret; } else if (std::isinf(realpart) || std::isinf(imagpart)) { ret.addError(QCoreApplication::tr("Returned eigenvalue is too big")); return ret; } else { bool isonlyreal = true; if (std::isnormal(imagpart)) { isonlyreal = false; } Analitza::Cn * eigenvalueobj = 0; if (isonlyreal) { eigenvalueobj = new Analitza::Cn(realpart); } else { eigenvalueobj = new Analitza::Cn(realpart, imagpart); } eigenvector->appendBranch(eigenvalueobj); } } list->appendBranch(eigenvector.take()); } ret.setTree(list.take()); return ret; }
Expression VectorCommand::operator()(const QList< Analitza::Expression >& args) { Expression ret; const int nargs = args.size(); switch(nargs) { case 0: { ret.addError(QCoreApplication::tr("Invalid parameter count for '%1'").arg(VectorCommand::id)); } break; case 1: { const Analitza::Object *arg = args.first().tree(); //TODO vector(5) := vector{0,0,0,0,0} if (arg->type() == Analitza::Object::list) { const Analitza::List *list = static_cast<const Analitza::List*>(arg); const int n = list->size(); Analitza::Vector *vector = new Analitza::Vector(n); for (int i = 0; i < n; ++i) vector->appendBranch(list->at(i)->copy()); ret.setTree(vector); } else { ret.addError(QCoreApplication::tr("Invalid parameter type for '%1', was expected a list").arg(VectorCommand::id)); } } break; case 2: { const Analitza::Object *arg = args.first().tree(); if (arg->type() == Analitza::Object::value) { const Analitza::Cn *lengthobj = static_cast<const Analitza::Cn*>(args.first().tree()); if (lengthobj->isInteger() && lengthobj->value() > 0) { ret.setTree(new Analitza::Vector(lengthobj->intValue(), static_cast<const Analitza::Cn*>(args.last().tree()))); } else { ret.addError(QCoreApplication::tr("Vector size must be some integer value greater to zero")); } } else { ret.addError(QCoreApplication::tr("Vector size must be some integer value greater to zero")); } } break; default: ret.addError(QCoreApplication::tr("Invalid parameter count for '%1'").arg(VectorCommand::id)); break; } return ret; }
Expression RangeCommand::operator()(const QList< Analitza::Expression >& args) { Expression ret; const int nargs = args.size(); double a = 1; double b = 0; double h = 1; switch(nargs) { case 0: { ret.addError(QCoreApplication::tr("Invalid parameter count for '%1'").arg(RangeCommand::id)); return ret; } break; case 1: { b = static_cast<const Analitza::Cn*>(args.first().tree())->value(); } break; case 2: { a = static_cast<const Analitza::Cn*>(args.first().tree())->value(); b = static_cast<const Analitza::Cn*>(args.last().tree())->value(); } break; case 3: { a = static_cast<const Analitza::Cn*>(args.at(0).tree())->value(); b = static_cast<const Analitza::Cn*>(args.at(1).tree())->value(); h = static_cast<const Analitza::Cn*>(args.at(2).tree())->value(); } break; default: ret.addError(QCoreApplication::tr("Invalid parameter count for '%1'").arg(RangeCommand::id)); return ret; break; } Analitza::List *seq = new Analitza::List; for (double x = a; x <= b; x += h) seq->appendBranch(new Analitza::Cn(x)); ret.setTree(seq); return ret; }