From kde-commits Sat May 31 17:54:47 2014 From: =?utf-8?q?Percy_Camilo_Trive=C3=B1o_Aucahuasi?= Date: Sat, 31 May 2014 17:54:47 +0000 To: kde-commits Subject: [analitza/aucahuasi/matrixctrs] analitza: Clean code and fix error messages. Message-Id: X-MARC-Message: https://marc.info/?l=kde-commits&m=140155890001413 Git commit ba5556016ec008c11ab12f21e16e7ff77d611df6 by Percy Camilo Trive= =C3=B1o Aucahuasi. Committed on 31/05/2014 at 17:53. Pushed by aucahuasi into branch 'aucahuasi/matrixctrs'. Clean code and fix error messages. M +140 -201 analitza/commands/blockmatrixcommands.cpp M +0 -2 analitza/commands/blockmatrixcommands.h M +1 -1 analitza/commands/listcommands.cpp M +33 -132 analitza/commands/matrixcommands.cpp M +44 -0 analitza/commands/matrixcommands.h M +2 -1 analitza/expressiontype.h M +10 -10 analitza/tests/commandstest.cpp M +3 -3 analitza/tests/commandstest.h http://commits.kde.org/analitza/ba5556016ec008c11ab12f21e16e7ff77d611df6 diff --git a/analitza/commands/blockmatrixcommands.cpp b/analitza/commands/= blockmatrixcommands.cpp index b6e001d..6ff20ef 100644 --- a/analitza/commands/blockmatrixcommands.cpp +++ b/analitza/commands/blockmatrixcommands.cpp @@ -24,79 +24,28 @@ #include "expression.h" #include "value.h" #include "matrix.h" -#include "list.h" -#include "container.h" -#include "operations.h" = using Analitza::Expression; using Analitza::ExpressionType; = -//BEGIN type utils - -typedef QList ExpressionTypeList; - -static const ExpressionType ValueType =3D ExpressionType(ExpressionType::V= alue); -static const ExpressionType VectorType =3D ExpressionType(ExpressionType::= Vector, ExpressionType(ExpressionType::Value), -1); -static const ExpressionType MatrixType =3D ExpressionType(ExpressionType::= Matrix, ExpressionType(ExpressionType::Vector, ExpressionType(ExpressionTyp= e::Value), -2), -1); -static const ExpressionTypeList VectorAndMatrixTypes =3D ExpressionTypeLis= t() << VectorType << MatrixType; -static const ExpressionType VectorAndMatrixAlternatives =3D ExpressionType= (ExpressionType::Many, VectorAndMatrixTypes); -static const ExpressionType IndefiniteArityType =3D ExpressionType(Express= ionType::Any); - -static const ExpressionType functionType(const ExpressionTypeList &from, c= onst ExpressionType &to) -{ - ExpressionType ret(ExpressionType::Lambda); - = - foreach (const ExpressionType &type, from) - ret.addParameter(type); - = - ret.addParameter(to); - = - return ret; -} - -static const ExpressionType functionType(const ExpressionType &from, const= ExpressionType &to) -{ - return functionType(ExpressionTypeList() << from, to); -} - -static const ExpressionType variadicFunctionType(const ExpressionType &to) -{ - return functionType(IndefiniteArityType, to); -} - -//END type utils - -static const QString MATRIX_SIZE_ERROR_MESSAGE =3D QCoreApplication::tr("M= atrix dimensions must be greater than zero"); - -// const QString VectorCommand::id =3D QString("range"); -// // const ExpressionType VectorCommand::type =3D functionType(Expression= TypeList() << ValueType << ValueType, VectorType); -// = -// Expression RangeCommand::operator()(const QList< Analitza::Expression >= & args) -// { -// = -// } - - - -//BEGIN FillMatrixConstructor - const QString BlockMatrixCommand::id =3D QString("blockmatrix"); -const ExpressionType BlockMatrixCommand::type =3D variadicFunctionType(Mat= rixType); -//TODO better error messages +const ExpressionType BlockMatrixCommand::type =3D ExpressionType(Expressio= nType::Lambda) +.addParameter(ExpressionType(ExpressionType::Any, ExpressionType(Expressio= nType::Vector, = + ExpressionType(ExpressionType::Matrix, ExpressionType(Exp= ressionType::Vector, ExpressionType(ExpressionType::Value), -2), -1), -1))) +.addParameter(ExpressionType(ExpressionType::Matrix, ExpressionType(Expres= sionType::Vector, ExpressionType(ExpressionType::Value), -2), -1)); + Expression BlockMatrixCommand::operator()(const QList< Analitza::Expressio= n >& args) { Expression ret; = const int nargs =3D args.size(); = - switch(nargs) { - case 0: { - ret.addError(QCoreApplication::tr("Invalid parameter count for '%1'").a= rg(BlockMatrixCommand::id)); + if (nargs =3D=3D 0) { + ret.addError(QCoreApplication::tr("Invalid parameter count for '%1'").ar= g(BlockMatrixCommand::id)); = - return ret; - } break; - } - //BEGIN commom + return ret; + } + = const Analitza::Object::ObjectType firstArgType =3D args.first().tree()->= type(); = if (firstArgType =3D=3D Analitza::Object::vector || firstArgType =3D=3D A= nalitza::Object::matrixrow) { @@ -107,174 +56,172 @@ Expression BlockMatrixCommand::operator()(const QLis= t< Analitza::Expression >& a const int firstVectorSize =3D firstVector->size(); const Analitza::Object::ObjectType firstVectorElementType =3D firstVect= or->at(0)->type(); = - switch(firstVectorElementType) { - case Analitza::Object::matrix: { // try to build a block matrix - const Analitza::Matrix *firstBlock =3D static_cast(firstVector->at(0)); - = - bool isCorrect =3D true; // this flag tells if is ok to build the blo= ck matrix - int nrows =3D 0; - int ncols =3D 0; - int blockpattern[firstVectorSize]; // if vectors(matrixrow) this tell= s the row(column) pattern - = - const int blocklength =3D isVector? firstBlock->columnCount() : first= Block->rowCount(); - = - // we need to know the pattern first, this run only on first arg (fir= st vector) = - for (int blockIndex =3D 0; blockIndex < firstVectorSize && isCorrect;= ++blockIndex) { - if (firstVector->at(blockIndex)->type() =3D=3D Analitza::Object::mat= rix) { - const Analitza::Matrix* block =3D static_cast(firstVector->at(blockIndex)); + if (firstVectorElementType =3D=3D Analitza::Object::matrix) { + const Analitza::Matrix *firstBlock =3D static_cast(firstVector->at(0)); + = + bool isCorrect =3D true; // this flag tells if is ok to build the bloc= k matrix + int nrows =3D 0; + int ncols =3D 0; + int blockpattern[firstVectorSize]; // if vectors(matrixrow) this tells= the row(column) pattern + = + const int blocklength =3D isVector? firstBlock->columnCount() : firstB= lock->rowCount(); + = + // we need to know the pattern first, this run only on first arg (firs= t vector) = + for (int blockIndex =3D 0; blockIndex < firstVectorSize && isCorrect; = ++blockIndex) { + if (firstVector->at(blockIndex)->type() =3D=3D Analitza::Object::matr= ix) { + const Analitza::Matrix* block =3D static_cast(firstVector->at(blockIndex)); + = + if (block->rowCount() > 0 && block->columnCount() > 0) { + const int currentlength =3D isVector? block->columnCount() : block-= >rowCount(); = - if (block->rowCount() > 0 && block->columnCount() > 0) { - const int currentlength =3D isVector? block->columnCount() : block= ->rowCount(); - const int currentpattern =3D isVector? block->rowCount() : block->= columnCount(); + if (currentlength =3D=3D blocklength) { + blockpattern[blockIndex] =3D isVector? block->rowCount() : block->= columnCount(); = - if (currentlength =3D=3D blocklength) { - blockpattern[blockIndex] =3D isVector? block->rowCount() : block-= >columnCount(); - = - if (isVector) - nrows +=3D blockpattern[blockIndex]; - else - ncols +=3D blockpattern[blockIndex]; - } else { - isCorrect =3D false; - ret.addError(QCoreApplication::tr("bloques rows .. altura o numro= ws debe ser same")); - } + if (isVector) + nrows +=3D blockpattern[blockIndex]; + else + ncols +=3D blockpattern[blockIndex]; } else { isCorrect =3D false; - ret.addError(QCoreApplication::tr("no se aceptan bloques/matrices = vacias")); + ret.addError(QCoreApplication::tr("Blocks must have consistent siz= e between each and other")); } } else { - ret.addError(QCoreApplication::tr("not all are matrix i cant build = a block matrix")); isCorrect =3D false; + ret.addError(QCoreApplication::tr("Do not want empty blocks")); } + } else { + ret.addError(QCoreApplication::tr("Blocks must be matrices")); + isCorrect =3D false; } + } + = + // check if all args are ok to build a block matrix + for (int argIndex =3D 0; argIndex < nargs && isCorrect; ++argIndex) { + const Analitza::Object::ObjectType currentArgType =3D args.at(argInde= x).tree()->type(); + const Analitza::Vector *vector =3D static_cast(args.at(argIndex).tree()); = - // check if all args are ok to build a block matrix - for (int argIndex =3D 0; argIndex < nargs && isCorrect; ++argIndex) { - const Analitza::Object::ObjectType currentArgType =3D args.at(argInd= ex).tree()->type(); - const Analitza::Vector *vector =3D static_cast(args.at(argIndex).tree()); - = - if (currentArgType =3D=3D firstArgType) { - if (vector->size() > 0) { - if (vector->size() =3D=3D firstVectorSize) { - const Analitza::Matrix *currentFirstBlock =3D static_cast(vector->at(0)); - const int blocklength =3D isVector? currentFirstBlock->columnCoun= t() : currentFirstBlock->rowCount(); - = - for (int blockIndex =3D 0; blockIndex < firstVectorSize && isCorr= ect; ++blockIndex) { - if (vector->at(blockIndex)->type() =3D=3D Analitza::Object::matr= ix) { - const Analitza::Matrix* block =3D static_cast(vector->at(blockIndex)); + if (currentArgType =3D=3D firstArgType) { + if (vector->size() > 0) { + if (vector->size() =3D=3D firstVectorSize) { + const Analitza::Matrix *currentFirstBlock =3D static_cast(vector->at(0)); + const int blocklength =3D isVector? currentFirstBlock->columnCount= () : currentFirstBlock->rowCount(); + = + for (int blockIndex =3D 0; blockIndex < firstVectorSize && isCorre= ct; ++blockIndex) { + if (vector->at(blockIndex)->type() =3D=3D Analitza::Object::matri= x) { + const Analitza::Matrix* block =3D static_cast(vector->at(blockIndex)); + = + if (block->rowCount() > 0 && block->columnCount() > 0) { + const int currentlength =3D isVector? block->columnCount() : bl= ock->rowCount(); + const int currentpattern =3D isVector? block->rowCount() : bloc= k->columnCount(); = - if (block->rowCount() > 0 && block->columnCount() > 0) { - const int currentlength =3D isVector? block->columnCount() : b= lock->rowCount(); - const int currentpattern =3D isVector? block->rowCount() : blo= ck->columnCount(); - = - if (currentlength !=3D blocklength) { - isCorrect =3D false; - ret.addError(QCoreApplication::tr("cols cada block de row deb= e ser igual de row a row")); - } else if (blockpattern[blockIndex] !=3D currentpattern) { - isCorrect =3D false; - ret.addError(QCoreApplication::tr("bloques rows .. altura o n= umrows debe ser same")); - } - } else { + if (currentlength !=3D blocklength) { + isCorrect =3D false; + ret.addError(QCoreApplication::tr("Blocks must have consistent= size between each and other")); + } else if (blockpattern[blockIndex] !=3D currentpattern) { isCorrect =3D false; - ret.addError(QCoreApplication::tr("no se aceptan bloques/matri= ces vacias")); + ret.addError(QCoreApplication::tr("Blocks must have consistent= size between each and other")); } } else { isCorrect =3D false; - ret.addError(QCoreApplication::tr("no se aceptan bloques/matric= es vacias")); + ret.addError(QCoreApplication::tr("Do not want empty blocks")); } + } else { + isCorrect =3D false; + ret.addError(QCoreApplication::tr("Blocks must be matrices")); } - = - if (isCorrect) - if (isVector) - ncols +=3D blocklength; - else - nrows +=3D blocklength; - } else { - isCorrect =3D false; - ret.addError(QCoreApplication::tr("all argument (vec or row) must= have the same size")); + } + = + if (isCorrect) { + if (isVector) + ncols +=3D blocklength; + else + nrows +=3D blocklength; } } else { - ret.addError("we dont allow empty vector or rows"); // TODO better= message isCorrect =3D false; + ret.addError(QCoreApplication::tr("Number of blocks must be consis= tent")); } } else { + ret.addError(QCoreApplication::tr("Do not want empty vectors/matrix= row elements")); isCorrect =3D false; - ret.addError(QCoreApplication::tr("all argument must be of the same= type: all rows or all vectors")); } + } else { + isCorrect =3D false; + ret.addError(QCoreApplication::tr("Matrix constructor needs vectors = or matrixrow elements")); } + } + = + if (isCorrect) { + Analitza::Matrix *matrix =3D new Analitza::Matrix(); + = + QVector< QVector< const Analitza::Object* > > objmatrix(nrows, QVecto= r< const Analitza::Object* >(ncols, 0)); + = + int nrowsoffset =3D isVector? nrows : 0; + int ncolsoffset =3D isVector? 0 : ncols; = - if (isCorrect) { - Analitza::Matrix *matrix =3D new Analitza::Matrix(); + for (int argIndex =3D 0; argIndex < nargs && isCorrect; ++argIndex) { + const Analitza::Vector *vector =3D static_cast(args.at(argIndex).tree()); = - QVector< QVector< const Analitza::Object* > > objmatrix(nrows, QVect= or< const Analitza::Object* >(ncols, 0)); + int blockpattern =3D 0; = - int nrowsoffset =3D isVector? nrows : 0; - int ncolsoffset =3D isVector? 0 : ncols; + if (isVector) + nrowsoffset =3D 0; + else + ncolsoffset =3D 0; = - for (int argIndex =3D 0; argIndex < nargs && isCorrect; ++argIndex) { - const Analitza::Vector *vector =3D static_cast(args.at(argIndex).tree()); - = - int blockpattern =3D 0; - = - if (isVector) - nrowsoffset =3D 0; - else - ncolsoffset =3D 0; - = - for (int blockIndex =3D 0; blockIndex < firstVectorSize && isCorrec= t; ++blockIndex) { - const Analitza::Matrix* block =3D static_cast(vector->at(blockIndex)); - const int m =3D block->rowCount(); - const int n =3D block->columnCount(); - = - blockpattern =3D isVector? n : m; - = - for (int i =3D 0; i < m; ++i) - for (int j =3D 0; j < n; ++j) - objmatrix[i+nrowsoffset][j+ncolsoffset] =3D block->at(i,j); - = - if (isVector) - nrowsoffset +=3D m; - else if (blockIndex =3D=3D 0) // el patron de cols se define en el= primer matrixrow - ncolsoffset +=3D n; - } + for (int blockIndex =3D 0; blockIndex < firstVectorSize && isCorrect= ; ++blockIndex) { + const Analitza::Matrix* block =3D static_cast(vector->at(blockIndex)); + const int m =3D block->rowCount(); + const int n =3D block->columnCount(); = - if (!isVector) - nrowsoffset +=3D blockpattern; - else if (argIndex =3D=3D 0) - ncolsoffset +=3D blockpattern; - } - = - for (int i =3D 0; i < nrows; ++i) { - Analitza::MatrixRow *row =3D new Analitza::MatrixRow(ncols); + blockpattern =3D isVector? n : m; = - for (int j =3D 0; j < ncols; ++j) - row->appendBranch(objmatrix[i][j]->copy()); + for (int i =3D 0; i < m; ++i) + for (int j =3D 0; j < n; ++j) + objmatrix[i+nrowsoffset][j+ncolsoffset] =3D block->at(i,j); = - matrix->appendBranch(row); + if (isVector) + nrowsoffset +=3D m; + else if (blockIndex =3D=3D 0) // el patron de cols se define en el = primer matrixrow + ncolsoffset +=3D n; } = - ret.setTree(matrix); + if (!isVector) + nrowsoffset +=3D blockpattern; + else if (argIndex =3D=3D 0) + ncolsoffset +=3D blockpattern; + } = - return ret; + for (int i =3D 0; i < nrows; ++i) { + Analitza::MatrixRow *row =3D new Analitza::MatrixRow(ncols); + = + for (int j =3D 0; j < ncols; ++j) + row->appendBranch(objmatrix[i][j]->copy()); + = + matrix->appendBranch(row); } - } break; + = + ret.setTree(matrix); = - } + return ret; + } + } else + ret.addError(QCoreApplication::tr("Blocks must be matrices")); } else - ret.addError("we dont allow empty vector or rows"); // TODO better mess= age + ret.addError(QCoreApplication::tr("Do not want empty vectors/matrixrow = elements")); } else - ret.addError("to build a matrix use vector or rows as args"); // TODO be= tter message - //END commom + ret.addError(QCoreApplication::tr("Matrix constructor needs vectors or m= atrixrow elements")); = return ret; } = -//END FillMatrixConstructor - -//BEGIN DiagonalMatrixConstructor = const QString BlockDiagonalMatrixCommand::id =3D QString("blockdiag"); -const ExpressionType BlockDiagonalMatrixCommand::type =3D variadicFunctio= nType(VectorAndMatrixAlternatives); +// const ExpressionType BlockDiagonalMatrixCommand::type =3D variadicFunc= tionType(VectorAndMatrixAlternatives); +const ExpressionType BlockDiagonalMatrixCommand::type =3D ExpressionType(= ExpressionType::Lambda) +.addParameter(ExpressionType(ExpressionType::Any, = + ExpressionType(ExpressionType::Matrix, ExpressionType(ExpressionTy= pe::Vector, ExpressionType(ExpressionType::Value), -2), -1))) +.addParameter(ExpressionType(ExpressionType::Matrix, ExpressionType(Expres= sionType::Vector, ExpressionType(ExpressionType::Value), -2), -1)); = Expression BlockDiagonalMatrixCommand::operator()(const QList< Analitza::E= xpression >& args) { @@ -283,26 +230,22 @@ Expression BlockDiagonalMatrixCommand::operator()(con= st QList< Analitza::Express int nargs =3D args.size(); bool byvector =3D false; = - switch(nargs) { - case 0: { - ret.addError(QCoreApplication::tr("Invalid parameter count for '%1'").a= rg(BlockDiagonalMatrixCommand::id)); - = - return ret; - } break; - } + if (nargs =3D=3D 0) { + ret.addError(QCoreApplication::tr("Invalid parameter count for '%1'").ar= g(BlockDiagonalMatrixCommand::id)); + return ret; + } + = const Analitza::Vector *v =3D byvector? static_cast(args.first().tree()) : 0; = if (byvector) nargs =3D v->size(); = - for (int k =3D 0; k < nargs; ++k) + for (int k =3D 0; k < nargs; ++k) { if ((byvector? v->at(k)->type() : args.at(k).tree()->type()) =3D=3D Anal= itza::Object::none) { ret.addError(QCoreApplication::tr("the arg %1 is invalid or is error").= arg(k+1)); return ret; } + } = - = - //BEGIN block diag matrix - // first try to build block diag matrix if (args.first().tree()->type() =3D=3D Analitza::Object::matrix) { bool failbyblockdiag =3D false; int nrows =3D 0; @@ -317,11 +260,11 @@ Expression BlockDiagonalMatrixCommand::operator()(con= st QList< Analitza::Express nrows +=3D m; ncols +=3D n; } else { - ret.addError("not se quiere empty matrix/blocks"); //TODO better mess= ages + ret.addError(QCoreApplication::tr("Do not want empty blocks")); failbyblockdiag =3D true; } } else { - ret.addError("not all are matrices/blocks can't build bok diag matrix"= ); //TODO better messages + ret.addError(QCoreApplication::tr("Blocks must be matrices")); failbyblockdiag =3D true; } = @@ -365,10 +308,6 @@ Expression BlockDiagonalMatrixCommand::operator()(cons= t QList< Analitza::Express = return ret; } - //END block diag matrix = - return ret; } - -//END DiagonalMatrixConstructor diff --git a/analitza/commands/blockmatrixcommands.h b/analitza/commands/bl= ockmatrixcommands.h index 2bdb06f..ad9a8e5 100644 --- a/analitza/commands/blockmatrixcommands.h +++ b/analitza/commands/blockmatrixcommands.h @@ -25,7 +25,6 @@ namespace Analitza { class Expression; }; = -//TODO split this class in matrix and blockmatrix ... class BlockMatrixCommand: public Analitza::FunctionDefinition { public: @@ -35,7 +34,6 @@ public: static const Analitza::ExpressionType type; }; = -//TODO split this class in diag and blockdiag ... class BlockDiagonalMatrixCommand: public Analitza::FunctionDefinition { public: diff --git a/analitza/commands/listcommands.cpp b/analitza/commands/listcom= mands.cpp index dd55674..b806722 100644 --- a/analitza/commands/listcommands.cpp +++ b/analitza/commands/listcommands.cpp @@ -29,7 +29,7 @@ using Analitza::ExpressionType; = const QString RangeCommand::id =3D QString("range"); const ExpressionType RangeCommand::type =3D ExpressionType(ExpressionType= ::Lambda) -.addParameter(ExpressionType(ExpressionType::Any, ExpressionType(Expressio= nType(ExpressionType::Value)))) +.addParameter(ExpressionType(ExpressionType::Any, ExpressionType(Expressio= nType::Value))) .addParameter(ExpressionType(ExpressionType::List, ExpressionType(Expressi= onType::Value))); = Expression RangeCommand::operator()(const QList< Analitza::Expression >& a= rgs) diff --git a/analitza/commands/matrixcommands.cpp b/analitza/commands/matri= xcommands.cpp index b352a86..f8c61e5 100644 --- a/analitza/commands/matrixcommands.cpp +++ b/analitza/commands/matrixcommands.cpp @@ -24,55 +24,20 @@ #include "expression.h" #include "value.h" #include "matrix.h" -#include "list.h" -#include "container.h" #include "operations.h" = using Analitza::Expression; using Analitza::ExpressionType; = -//BEGIN type utils - -typedef QList ExpressionTypeList; - -static const ExpressionType ValueType =3D ExpressionType(ExpressionType::V= alue); -static const ExpressionType VectorType =3D ExpressionType(ExpressionType::= Vector, ExpressionType(ExpressionType::Value), -1); -static const ExpressionType MatrixType =3D ExpressionType(ExpressionType::= Matrix, ExpressionType(ExpressionType::Vector, ExpressionType(ExpressionTyp= e::Value), -2), -1); -static const ExpressionTypeList VectorAndMatrixTypes =3D ExpressionTypeLis= t() << VectorType << MatrixType; -static const ExpressionType VectorAndMatrixAlternatives =3D ExpressionType= (ExpressionType::Many, VectorAndMatrixTypes); -static const ExpressionType IndefiniteArityType =3D ExpressionType(Express= ionType::Any, 1); -//ExpressionType(ExpressionType::List, ExpressionType(ExpressionType::Any,= 1)), -static const ExpressionType functionType(const ExpressionTypeList &from, c= onst ExpressionType &to) -{ - ExpressionType ret(ExpressionType::Lambda); - = - foreach (const ExpressionType &type, from) - ret.addParameter(type); - = - ret.addParameter(to); - = - return ret; -} - -static const ExpressionType functionType(const ExpressionType &from, const= ExpressionType &to) -{ - return functionType(ExpressionTypeList() << from, to); -} - -static const ExpressionType variadicFunctionType(const ExpressionType &to) -{ - return functionType(IndefiniteArityType, to); -} - -//END type utils - static const QString MATRIX_SIZE_ERROR_MESSAGE =3D QCoreApplication::tr("M= atrix dimensions must be greater than zero"); = //BEGIN FillMatrixConstructor = const QString MatrixCommand::id =3D QString("matrix"); -const ExpressionType MatrixCommand::type =3D variadicFunctionType(MatrixTy= pe); -//TODO better error messages +const ExpressionType MatrixCommand::type =3D ExpressionType(ExpressionType= ::Lambda) +.addParameter(ExpressionType(ExpressionType::Any)) +.addParameter(ExpressionType(ExpressionType::Matrix, ExpressionType(Expres= sionType::Vector, ExpressionType(ExpressionType::Value), -2), -1)); + Expression MatrixCommand::operator()(const QList< Analitza::Expression >& = args) { Expression ret; @@ -85,6 +50,7 @@ Expression MatrixCommand::operator()(const QList< Analitz= a::Expression >& args) = return ret; } break; + //BEGIN matrix(m,n,v) case 1: { // build square matrix filled with zeros if (args.at(0).tree()->type() =3D=3D Analitza::Object::value) { const Analitza::Cn *nobj =3D static_cast(args.at(= 0).tree()); @@ -132,12 +98,14 @@ Expression MatrixCommand::operator()(const QList< Anal= itza::Expression >& args) return ret; } } break; + //END matrix(m,n,v) } = Q_ASSERT(nargs > 0); Q_ASSERT(ret.toString().isEmpty()); Q_ASSERT(ret.isCorrect()); = + //BEGIN matrix(vector{...}, ...) and matrix(matrixrow{...}, ...) const Analitza::Object::ObjectType firstArgType =3D args.first().tree()->= type(); = if (firstArgType =3D=3D Analitza::Object::vector || firstArgType =3D=3D A= nalitza::Object::matrixrow) { @@ -181,13 +149,14 @@ Expression MatrixCommand::operator()(const QList< Ana= litza::Expression >& args) } else ret.setTree(matrix); } else { - ret.addError("Every argument must be a matrixrow element"); + ret.addError(QCoreApplication::tr("Every argument must be a matrixrow = element")); delete matrix; } } else - ret.addError("we dont allow empty vector or rows"); // TODO better mess= age + ret.addError(QCoreApplication::tr("Do not want empty vectors/matrixrow = elements")); } else - ret.addError("to build a matrix use vector or rows as args"); // TODO be= tter message + ret.addError(QCoreApplication::tr("Matrix constructor needs vectors or m= atrixrow elements")); + //END matrix(vector{...}, ...) and matrix(matrixrow{...}, ...) = return ret; } @@ -198,18 +167,14 @@ Expression MatrixCommand::operator()(const QList< Ana= litza::Expression >& args) //BEGIN IdentityMatrixConstructor = const QString IdentityMatrixCommand::id =3D QString("identitymatrix"); -const ExpressionType IdentityMatrixCommand::type =3D variadicFunctionType(= MatrixType); +const ExpressionType IdentityMatrixCommand::type =3D ExpressionType(Expres= sionType::Lambda) +.addParameter(ExpressionType(ExpressionType::Value)) +.addParameter(ExpressionType(ExpressionType::Matrix, ExpressionType(Expres= sionType::Vector, ExpressionType(ExpressionType::Value), -2), -1)); = Expression IdentityMatrixCommand::operator()(const QList< Analitza::Expres= sion >& args) { Expression ret; = - if (args.size() !=3D 1) { - ret.addError(QCoreApplication::tr("Invalid parameter count for '%2'. Sho= uld have %1 parameters.").arg(1).arg(IdentityMatrixCommand::id)); - = - return ret; - } - = const Analitza::Cn *nobj =3D static_cast(args.first(= ).tree()); const int n =3D nobj->value(); = @@ -241,7 +206,11 @@ Expression IdentityMatrixCommand::operator()(const QLi= st< Analitza::Expression > //BEGIN DiagonalMatrixConstructor = const QString DiagonalMatrixCommand::id =3D QString("diag"); -const ExpressionType DiagonalMatrixCommand::type =3D variadicFunctionType= (VectorAndMatrixAlternatives); +const ExpressionType DiagonalMatrixCommand::type =3D ExpressionType(Expre= ssionType::Lambda) +.addParameter(ExpressionType(ExpressionType::Any)) +.addParameter(ExpressionType(ExpressionType::Many, QList() = +<< ExpressionType(ExpressionType::Vector, ExpressionType(ExpressionType::V= alue), -1) = +<< ExpressionType(ExpressionType::Matrix, ExpressionType(ExpressionType::V= ector, ExpressionType(ExpressionType::Value), -2), -1))); = Expression DiagonalMatrixCommand::operator()(const QList< Analitza::Expres= sion >& args) { @@ -256,6 +225,7 @@ Expression DiagonalMatrixCommand::operator()(const QLis= t< Analitza::Expression > = return ret; } break; + //BEGIN diag(matrix{...}, diagindex) case 1: { if (args.first().tree()->type() =3D=3D Analitza::Object::matrix) { const Analitza::Matrix *matrix =3D static_cast(args.first().tree()); @@ -291,7 +261,7 @@ Expression DiagonalMatrixCommand::operator()(const QLis= t< Analitza::Expression > = if (isneg) { if (absnpos1 > nrows) { - ret.addError("The nth diagonal index must be less than the row coun= t"); + ret.addError(QCoreApplication::tr("The nth diagonal index must be l= ess than the row count")); return ret; } = @@ -299,7 +269,7 @@ Expression DiagonalMatrixCommand::operator()(const QLis= t< Analitza::Expression > rowoffset =3D absnpos; } else { // square matrix case too if (absnpos1 > ncols) { - ret.addError("The nth diagonal index must be less than the column c= ount"); + ret.addError(QCoreApplication::tr("The nth diagonal index must be l= ess than the column count")); return ret; } = @@ -319,17 +289,19 @@ Expression DiagonalMatrixCommand::operator()(const QL= ist< Analitza::Expression > = return ret; } else if (args.last().tree()->type() !=3D Analitza::Object::value && a= rgs.last().tree()->type() !=3D Analitza::Object::matrix) { - ret.addError(QCoreApplication::tr("to specifi the diag index you must = use positve integer value")); //TODO better messages + ret.addError(QCoreApplication::tr("nth diagonal index must be a positi= ve integer number")); = return ret; } } break; + //END diag(matrix{...}, diagindex) } = Q_ASSERT(nargs > 0); Q_ASSERT(ret.toString().isEmpty()); Q_ASSERT(ret.isCorrect()); = + //BEGIN diag(a,b, ...) or diag(vector{a,b, ...}) const Analitza::Vector *v =3D byvector? static_cast(args.first().tree()) : 0; = if (byvector) nargs =3D v->size(); @@ -340,76 +312,6 @@ Expression DiagonalMatrixCommand::operator()(const QLi= st< Analitza::Expression > return ret; } = - = - //BEGIN block diag matrix - // first try to build block diag matrix - if (args.first().tree()->type() =3D=3D Analitza::Object::matrix) { - bool failbyblockdiag =3D false; - int nrows =3D 0; - int ncols =3D 0; - - for (int k =3D 0; k < nargs && !failbyblockdiag; ++k) - if (args.at(k).tree()->type() =3D=3D Analitza::Object::matrix) { - const Analitza::Matrix *block =3D static_cast= (args.at(k).tree()); - const int m =3D block->rowCount(); - const int n =3D block->columnCount(); - if (m > 0 && n > 0) { - nrows +=3D m; - ncols +=3D n; - } else { - ret.addError("not se quiere empty matrix/blocks"); //TODO better mess= ages - failbyblockdiag =3D true; - } - } else { - ret.addError("not all are matrices/blocks can't build bok diag matrix"= ); //TODO better messages - failbyblockdiag =3D true; - } - = - if (!failbyblockdiag) { - Analitza::Matrix *matrix =3D new Analitza::Matrix(); - QVector< QVector< const Analitza::Object* > > objmatrix(nrows, QVector<= const Analitza::Object* >(ncols, 0)); - = - nrows =3D 0; - ncols =3D 0; - = - for (int k =3D 0; k < nargs; ++k) { - const Analitza::Matrix *block =3D static_cast= (args.at(k).tree()); - const int m =3D block->rowCount(); - const int n =3D block->columnCount(); - = - for (int i =3D 0; i < m; ++i) - for (int j =3D 0; j < n; ++j) - objmatrix[i+nrows][j+ncols] =3D block->at(i,j); - = - nrows +=3D m; - ncols +=3D n; - } - = - for (int i =3D 0; i < nrows; ++i) { - Analitza::MatrixRow *row =3D new Analitza::MatrixRow(ncols); - = - for (int j =3D 0; j < ncols; ++j) { - const Analitza::Object *obj =3D objmatrix[i][j]; - = - if (obj) - row->appendBranch(obj->copy()); - else - row->appendBranch(new Analitza::Cn(0)); - } - = - matrix->appendBranch(row); - } - = - ret.setTree(matrix); - } - = - return ret; - } - //END block diag matrix - = - Q_ASSERT(ret.toString().isEmpty()); - Q_ASSERT(ret.isCorrect()); - = Analitza::Matrix *matrix =3D new Analitza::Matrix(); = for (int i =3D 0; i < nargs; ++i) { @@ -425,7 +327,8 @@ Expression DiagonalMatrixCommand::operator()(const QLis= t< Analitza::Expression > } = ret.setTree(matrix); - + //END diag(a,b, ...) or diag(vector{a,b, ...}) + = return ret; } = @@ -435,18 +338,17 @@ Expression DiagonalMatrixCommand::operator()(const QL= ist< Analitza::Expression > //BEGIN TridiagonalMatrixConstructor = const QString TridiagonalMatrixCommand::id =3D QString("tridiag"); -const ExpressionType TridiagonalMatrixCommand::type =3D variadicFunctionTy= pe(MatrixType); +const ExpressionType TridiagonalMatrixCommand::type =3D ExpressionType(Exp= ressionType::Lambda) +.addParameter(ExpressionType(ExpressionType::Value)) +.addParameter(ExpressionType(ExpressionType::Value)) +.addParameter(ExpressionType(ExpressionType::Value)) +.addParameter(ExpressionType(ExpressionType::Value)) +.addParameter(ExpressionType(ExpressionType::Matrix, ExpressionType(Expres= sionType::Vector, ExpressionType(ExpressionType::Value), -2), -1)); = Expression TridiagonalMatrixCommand::operator()(const QList< Analitza::Exp= ression >& args) { Expression ret; = - if (args.size() !=3D 4) { - ret.addError(QCoreApplication::tr("Invalid parameter count for '%2'. Sho= uld have %1 parameters.").arg(4).arg(TridiagonalMatrixCommand::id)); - = - return ret; - } - = const Analitza::Cn *nobj =3D static_cast(args.last()= .tree()); const int n =3D nobj->value(); = @@ -479,4 +381,3 @@ Expression TridiagonalMatrixCommand::operator()(const Q= List< Analitza::Expressio } = //END TridiagonalMatrixConstructor - diff --git a/analitza/commands/matrixcommands.h b/analitza/commands/matrixc= ommands.h index 18f3612..c0f1e21 100644 --- a/analitza/commands/matrixcommands.h +++ b/analitza/commands/matrixcommands.h @@ -25,6 +25,38 @@ namespace Analitza { class Expression; }; = +/** + * \class MatrixCommand + * = + * \brief Implements the \"matrix\" command. + * = + * MatrixCommand constructs a matrix by 2 ways: + * = + * The first way creates a matrix filled with a fixed value. = + * For example: + * \code matrix(3) \endcode = + * constructs a square 3x3 matrix filled with zeros. + * = + * \code matrix(4,5) \endcode = + * constructs a 4x5 matrix filled with zeros. + * = + * \code matrix(6,7, 0.5) \endcode = + * constructs a 6x7 matrix filled with the value 0.5. + * = + * The second way creates a matrix by given vectors or matrixrow elements. + * For example: + * \code matrix(vector{1,3}, vector{4,5}) \endcode = + * constructs a matrix with two column vectors: + * [1 4] + * [3 5] + * = + * \code matrix(matrixrow{1,3}, matrixrow{4,5}) \endcode = + * constructs a matrix with two matrixrow elements: + * [1 3] + * [4 5] + * + */ + class MatrixCommand: public Analitza::FunctionDefinition { public: @@ -34,6 +66,18 @@ public: static const Analitza::ExpressionType type; }; = +/** + * \class IdentityMatrixCommand + * = + * \brief Implements the \"identitymatrix\" command. + * = + * IdentityMatrixCommand constructs a identitymatrix. + * For example: + * \code matrix(2) \endcode + * \code matrix { matrixrow { 1, 0 }, matrixrow { 1, 0 } } \endcode + * = + */ + class IdentityMatrixCommand: public Analitza::FunctionDefinition { public: diff --git a/analitza/expressiontype.h b/analitza/expressiontype.h index 6c6381b..921875d 100644 --- a/analitza/expressiontype.h +++ b/analitza/expressiontype.h @@ -30,7 +30,8 @@ namespace Analitza class ANALITZA_EXPORT ExpressionType { public: - ///Just use undefined type when returning from a recursion + ///Just use undefined type when returning from a recursion. + ///Vector and MatrixRow are the same type. enum Type { Error=3D0, Value, Vector, List, Lambda, Any, Many, Object, C= har, Bool, Matrix }; QString toString() const; = diff --git a/analitza/tests/commandstest.cpp b/analitza/tests/commandstest.= cpp index f162c72..78cf3c1 100644 --- a/analitza/tests/commandstest.cpp +++ b/analitza/tests/commandstest.cpp @@ -27,26 +27,26 @@ = using Analitza::Expression; = -QTEST_MAIN( MatrixTest ) +QTEST_MAIN( CommandsTest ) = -MatrixTest::MatrixTest(QObject *parent) +CommandsTest::CommandsTest(QObject *parent) : QObject(parent) {} = -MatrixTest::~MatrixTest() +CommandsTest::~CommandsTest() {} = -void MatrixTest::initTestCase() +void CommandsTest::initTestCase() { a=3Dnew Analitza::Analyzer; } = -void MatrixTest::cleanupTestCase() +void CommandsTest::cleanupTestCase() { delete a; } = -void MatrixTest::testCorrect_data() +void CommandsTest::testCorrect_data() { QTest::addColumn("expression"); QTest::addColumn("result"); @@ -375,7 +375,7 @@ void MatrixTest::testCorrect_data() QTest::newRow("Id is identity matrix") << script << "true"; = script.clear(); - script << "isidentitymatrix(diag(identitymatrix(3), matrix{matrixrow{1}},= identitymatrix(2)))"; + script << "isidentitymatrix(blockdiag(identitymatrix(3), matrix{matrixrow= {1}}, identitymatrix(2)))"; QTest::newRow("block of Id is Id matrix") << script << "true"; = script.clear(); @@ -383,7 +383,7 @@ void MatrixTest::testCorrect_data() QTest::newRow("Id is diag matrix") << script << "true"; } = -void MatrixTest::testCorrect() +void CommandsTest::testCorrect() { QFETCH(QStringList, expression); QFETCH(QString, result); @@ -412,7 +412,7 @@ void MatrixTest::testCorrect() QVERIFY(a->isCorrect()); } = -void MatrixTest::testIncorrect_data() +void CommandsTest::testIncorrect_data() { QTest::addColumn("expression"); = @@ -465,7 +465,7 @@ void MatrixTest::testIncorrect_data() // QTest::newRow("zero bad") << "iszeromatrix(matrix(-8,5))"; //TODO last= test } = -void MatrixTest::testIncorrect() +void CommandsTest::testIncorrect() { QFETCH(QString, expression); = diff --git a/analitza/tests/commandstest.h b/analitza/tests/commandstest.h index b99cb7a..7b4bf25 100644 --- a/analitza/tests/commandstest.h +++ b/analitza/tests/commandstest.h @@ -26,12 +26,12 @@ namespace Analitza { class Analyzer; } /** @author Percy Camilo T. Aucahuasi */ -class MatrixTest : public QObject +class CommandsTest : public QObject { Q_OBJECT public: - MatrixTest(QObject *parent =3D 0); - ~MatrixTest(); + CommandsTest(QObject *parent =3D 0); + ~CommandsTest(); = private Q_SLOTS: void initTestCase();