You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
656 lines
24 KiB
656 lines
24 KiB
13 years ago
|
/***************************************************************************
|
||
|
mpsymbols.cpp
|
||
|
-------------------
|
||
|
begin : Sun Nov 25 2001
|
||
|
copyright : (C) 2001 by Kamil
|
||
|
email : kamil@localhost.localdomain
|
||
|
***************************************************************************/
|
||
|
|
||
|
/***************************************************************************
|
||
|
* *
|
||
|
* This program is free software; you can redistribute it and/or modify *
|
||
|
* it under the terms of the GNU General Public License as published by *
|
||
|
* the Free Software Foundation; either version 2 of the License, or *
|
||
|
* (at your option) any later version. *
|
||
|
* *
|
||
|
***************************************************************************/
|
||
|
|
||
|
#include"mpsymbols.h"
|
||
|
#include"mpdelunay.h"
|
||
|
#include<qobject.h>
|
||
|
#include<math.h>
|
||
|
|
||
|
//-------------------------------------------------------------------------//
|
||
|
//-------------------------------------------------------------------------//
|
||
|
//-------------------------------------------------------------------------//
|
||
|
|
||
|
//bool MPCommonSymFactory::m_initialized = false;
|
||
|
//QAsciiDict<MPCommonSymFactory::item> MPCommonSymFactory::m_list;
|
||
|
|
||
|
//-------------------------------------------------------------------------//
|
||
|
|
||
|
MPCommonSymFactory::MPCommonSymFactory()
|
||
|
: MPSymbolFactory()
|
||
|
{
|
||
|
m_initialized = false;
|
||
|
if ( !m_initialized ) {
|
||
|
m_list.setAutoDelete( TRUE );
|
||
|
m_list.insert( "e", new item(CONST, MPSymConstant::E, QT_TR_NOOP(" e - base of the natural logarithm.") ) );
|
||
|
m_list.insert( "pi", new item(CONST, MPSymConstant::PI, QT_TR_NOOP(" pi - 3.141592..." ) ) );
|
||
|
|
||
|
m_list.insert( "floor", new item(FUNC1, MPSymFunction1::FLOOR, QT_TR_NOOP("floor(x) - rounds x downwards to the nearest integer.") ) );
|
||
|
m_list.insert( "ceil", new item(FUNC1, MPSymFunction1::CEIL, QT_TR_NOOP("ceil(x) - rounds x upwards to the nearest integer.") ) );
|
||
|
m_list.insert( "sign", new item(FUNC1, MPSymFunction1::SIGN, QT_TR_NOOP("sign(x) - returns -1 for x<0 and 1 for x>= 0.") ) );
|
||
|
m_list.insert( "abs", new item(FUNC1, MPSymFunction1::ABS, QT_TR_NOOP("abs(x) - returns the absolute value of x") ) );
|
||
|
m_list.insert( "sin", new item(FUNC1, MPSymFunction1::SIN, QT_TR_NOOP("sin(x) - returns the sine of x ( radians )") ) );
|
||
|
m_list.insert( "sinh", new item(FUNC1, MPSymFunction1::SINH, QT_TR_NOOP("sinh(x) - returns the hyperblic sine of x ( radians )") ) );
|
||
|
m_list.insert( "cos", new item(FUNC1, MPSymFunction1::COS, QT_TR_NOOP("cos(x) - returns the cosine of x ( radians )") ) );
|
||
|
m_list.insert( "cosh", new item(FUNC1, MPSymFunction1::COSH, QT_TR_NOOP("cosh(x) - returns the hyperbolic cosine of x ( radians )") ) );
|
||
|
m_list.insert( "tan", new item(FUNC1, MPSymFunction1::TAN, QT_TR_NOOP("tan(x) - returns the tangent of x ( radians ).") ) );
|
||
|
m_list.insert( "tanh", new item(FUNC1, MPSymFunction1::TANH, QT_TR_NOOP("tanh(x) - returns the hyperbolic tangent of x ( radians )") ) );
|
||
|
m_list.insert( "acos", new item(FUNC1, MPSymFunction1::ACOS, QT_TR_NOOP("acos(x) - returns the arc cosine of x for x=<-1,1>") ) );
|
||
|
m_list.insert( "acosh", new item(FUNC1, MPSymFunction1::ACOSH, QT_TR_NOOP("acosh(x) - returns the inverse hyperbolic cosine of x for x>=1") ) );
|
||
|
m_list.insert( "asin", new item(FUNC1, MPSymFunction1::ASIN, QT_TR_NOOP("asin(x) - returns the arc sine of x, x=<-1,1>") ) );
|
||
|
m_list.insert( "asinh", new item(FUNC1, MPSymFunction1::ASINH, QT_TR_NOOP("asinh(x) - returns the inverse hyperbolic sine of x") ) );
|
||
|
m_list.insert( "atan", new item(FUNC1, MPSymFunction1::ATAN, QT_TR_NOOP("atan(x) - returns the arc tangent of x. Result belongs to (-pi/2,pi/2>.") ) );
|
||
|
m_list.insert( "atanh", new item(FUNC1, MPSymFunction1::ATANH, QT_TR_NOOP("atanh(x) - returns the inverse hyperbolic tangent of x.") ) );
|
||
|
m_list.insert( "ln", new item(FUNC1, MPSymFunction1::LN, QT_TR_NOOP("ln(x) - returns the natural logarithm of x.") ) );
|
||
|
m_list.insert( "log10", new item(FUNC1, MPSymFunction1::LOG10, QT_TR_NOOP("log10(x) - returns the base-10 logarithm of x. ") ) );
|
||
|
m_list.insert( "log2", new item(FUNC1, MPSymFunction1::LOG2, QT_TR_NOOP("log2(x) - returns the base-2 logarithm of x.") ) );
|
||
|
m_list.insert( "sqrt", new item(FUNC1, MPSymFunction1::SQRT, QT_TR_NOOP("sqrt(x) - returns the square root of x for x >= 0..") ) );
|
||
|
|
||
|
m_list.insert( "mod", new item(FUNC2, MPSymFunction2::MOD, QT_TR_NOOP("mod(x,y) - returns remainder of dividing x by y.") ) );
|
||
|
m_list.insert( "min", new item(FUNC2, MPSymFunction2::MIN, QT_TR_NOOP("min(x,y) - returns the lower value of pair (x,y). ") ) );
|
||
|
m_list.insert( "max", new item(FUNC2, MPSymFunction2::MAX, QT_TR_NOOP("min(x,y) - returns the greater value of pair (x,y). ") ) );
|
||
|
m_list.insert( "log", new item(FUNC2, MPSymFunction2::LOG, QT_TR_NOOP("log(x,y) - returns the y-base logarithm of x. ") ) );
|
||
|
m_list.insert( "pow", new item(FUNC2, MPSymFunction2::POW, QT_TR_NOOP("pow(x,y) - raises x to the power y. ") ) );
|
||
|
m_list.insert( "atan2", new item(FUNC2, MPSymFunction2::ATAN2, QT_TR_NOOP("atan2(x,y) - returns the arc tangent of y/x. Result belongs to (-PI,PI>.") ) );
|
||
|
m_list.insert( "delunay", new item(DELUNAY, 0, QT_TR_NOOP("delunay(x,y) - performs a delunay triangulation of points in x, y column vectors.") ) );
|
||
|
m_initialized = true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
//-------------------------------------------------------------------------//
|
||
|
|
||
|
MPCommonSymFactory::~MPCommonSymFactory()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------------------//
|
||
|
|
||
|
const char *MPCommonSymFactory::name() const
|
||
|
{
|
||
|
return QT_TR_NOOP("Built-in");
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------------------//
|
||
|
|
||
|
MPSymbol *MPCommonSymFactory::create( const char *identifier, MPSymbolList *args, int colFrom, int colTo )
|
||
|
{
|
||
|
item *new_item = m_list[identifier];
|
||
|
if ( new_item )
|
||
|
switch( new_item->m_type ) {
|
||
|
case CONST: return new MPSymConstant( (MPSymConstant::Constant )new_item->m_function, args, colFrom, colTo, identifier );
|
||
|
case FUNC1: return new MPSymFunction1( (MPSymFunction1::Function )new_item->m_function, args, colFrom, colTo, identifier );
|
||
|
case FUNC2: return new MPSymFunction2( (MPSymFunction2::Function )new_item->m_function, args, colFrom, colTo, identifier );
|
||
|
case DELUNAY: return new MPDelunay( args, colFrom, colTo, identifier );
|
||
|
}
|
||
|
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------------------//
|
||
|
|
||
|
int MPCommonSymFactory::symbolCount() const
|
||
|
{
|
||
|
return m_list.count();
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------------------//
|
||
|
|
||
|
const char *MPCommonSymFactory::symbolIdentifier( int symbolNumber )
|
||
|
{
|
||
|
QAsciiDictIterator<item> it(m_list);
|
||
|
it += symbolNumber;
|
||
|
return it.currentKey();
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------------------//
|
||
|
|
||
|
const char *MPCommonSymFactory::symbolDescription( int symbolNumber )
|
||
|
{
|
||
|
QAsciiDictIterator<item> it(m_list);
|
||
|
it += symbolNumber;
|
||
|
return it.current()->m_description;
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------------------//
|
||
|
//-------------------------------------------------------------------------//
|
||
|
//-------------------------------------------------------------------------//
|
||
|
//-------------------------------------------------------------------------//
|
||
|
//-------------------------------------------------------------------------//
|
||
|
|
||
|
|
||
|
MPSymValue::MPSymValue( double value, int columnFrom, int columnTo, const char *id )
|
||
|
: MPSymbol( NULL, columnFrom, columnTo, id )
|
||
|
{
|
||
|
m_value = value;
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------------------//
|
||
|
|
||
|
MPSymValue::~MPSymValue()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------------------//
|
||
|
|
||
|
void MPSymValue::checkArgs( MPError& )
|
||
|
{
|
||
|
m_rows = 1;
|
||
|
m_cols = 1;
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------------------//
|
||
|
|
||
|
double MPSymValue::value( int, int )
|
||
|
{
|
||
|
return m_value;
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------------------//
|
||
|
//-------------------------------------------------------------------------//
|
||
|
//-------------------------------------------------------------------------//
|
||
|
//-------------------------------------------------------------------------//
|
||
|
//-------------------------------------------------------------------------//
|
||
|
//-------------------------------------------------------------------------//
|
||
|
|
||
|
MPSymColon::MPSymColon( int columnFrom, int columnTo, const char *id )
|
||
|
: MPSymbol( NULL, columnFrom, columnTo, id )
|
||
|
{
|
||
|
m_rows = 0;
|
||
|
m_cols = 0;
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------------------//
|
||
|
|
||
|
double MPSymColon::value( int, int )
|
||
|
{
|
||
|
return sqrt(-1);
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------------------//
|
||
|
//-------------------------------------------------------------------------//
|
||
|
//-------------------------------------------------------------------------//
|
||
|
//-------------------------------------------------------------------------//
|
||
|
//-------------------------------------------------------------------------//
|
||
|
//-------------------------------------------------------------------------//
|
||
|
|
||
|
MPSymColonExpr::MPSymColonExpr( MPSymbolList *args, int columnFrom, int columnTo, const char *id )
|
||
|
: MPSymbol( args, columnFrom, columnTo, id )
|
||
|
{
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------------------//
|
||
|
|
||
|
MPSymColonExpr::~MPSymColonExpr()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------------------//
|
||
|
|
||
|
void MPSymColonExpr::checkArgs( MPError& error )
|
||
|
{
|
||
|
for ( int i=0; i<m_args->count(); i++ ) m_args->at(i)->checkArgs(error);
|
||
|
MPSymbol::checkArgs( error );
|
||
|
if ( m_args->count() != 2 &&
|
||
|
m_args->count() != 3 ) {
|
||
|
error.setWrongNumberOfArguments( m_args->count(), 3, this );
|
||
|
return;
|
||
|
}
|
||
|
for ( int i=0; i<m_args->count(); i++ )
|
||
|
if ( !m_args->at(i)->isScalar() ) {
|
||
|
error.setNonconformantArgument( i, m_args->at(i), this );
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if ( m_args->count() == 3 ) {
|
||
|
m_start = m_args->at(0)->value( 0, 0 );
|
||
|
m_step = m_args->at(1)->value( 0, 0 );
|
||
|
m_stop = m_args->at(2)->value( 0, 0 );
|
||
|
}
|
||
|
else
|
||
|
if ( m_args->count() == 2 ) {
|
||
|
m_start = m_args->at(0)->value( 0, 0 );
|
||
|
m_stop = m_args->at(1)->value( 0, 0 );
|
||
|
m_step = 1.0;
|
||
|
}
|
||
|
if ( m_step == 0.0 ) {
|
||
|
error.setNonconformantArgument( 1, m_args->at(1), this );
|
||
|
return;
|
||
|
}
|
||
|
m_rows = 1;
|
||
|
m_cols = QMAX( (int )floor( (m_stop-m_start)/m_step )+1, 0 );
|
||
|
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------------------//
|
||
|
|
||
|
double MPSymColonExpr::value( int, int col )
|
||
|
{
|
||
|
return m_start + col * m_step;
|
||
|
}
|
||
|
|
||
|
|
||
|
//-------------------------------------------------------------------------//
|
||
|
//-------------------------------------------------------------------------//
|
||
|
//-------------------------------------------------------------------------//
|
||
|
//-------------------------------------------------------------------------//
|
||
|
//-------------------------------------------------------------------------//
|
||
|
|
||
|
const double MPSymConstant::pi = 3.1415926535897932385;
|
||
|
const double MPSymConstant::e = 2.7182818284590452354;
|
||
|
|
||
|
//-------------------------------------------------------------------------//
|
||
|
|
||
|
MPSymConstant::MPSymConstant( Constant c, int columnFrom, int columnTo, const char *id )
|
||
|
: MPSymbol( NULL, columnFrom, columnTo, id )
|
||
|
{
|
||
|
m_c = c;
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------------------//
|
||
|
|
||
|
MPSymConstant::MPSymConstant( Constant c, MPSymbolList *args, int columnFrom, int columnTo, const char *id )
|
||
|
: MPSymbol( args, columnFrom, columnTo, id )
|
||
|
{
|
||
|
m_c = c;
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------------------//
|
||
|
|
||
|
MPSymConstant::~MPSymConstant()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------------------//
|
||
|
|
||
|
void MPSymConstant::checkArgs( MPError& )
|
||
|
{
|
||
|
m_rows = 1;
|
||
|
m_cols = 1;
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------------------//
|
||
|
|
||
|
double MPSymConstant::value( int, int )
|
||
|
{
|
||
|
switch( m_c ) {
|
||
|
case E: return e;
|
||
|
case PI: return pi;
|
||
|
default: return sqrt(-1);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------------------//
|
||
|
//-------------------------------------------------------------------------//
|
||
|
//-------------------------------------------------------------------------//
|
||
|
//-------------------------------------------------------------------------//
|
||
|
|
||
|
MPSymFunction1::MPSymFunction1( Function f, MPSymbolList *args, int columnFrom, int columnTo, const char *id )
|
||
|
: MPSymbol( args, columnFrom, columnTo, id )
|
||
|
{
|
||
|
m_f = f;
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------------------//
|
||
|
|
||
|
MPSymFunction1::~MPSymFunction1()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------------------//
|
||
|
|
||
|
void MPSymFunction1::checkArgs( MPError& error )
|
||
|
{
|
||
|
if ( m_args->count() != 1 ) error.setWrongNumberOfArguments( m_args->count(), 1, this );
|
||
|
MPSymbol::checkArgs( error );
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------------------//
|
||
|
|
||
|
double MPSymFunction1::value( int row, int col )
|
||
|
{
|
||
|
double value = m_args->at(0)->value( row, col );
|
||
|
switch( m_f ) {
|
||
|
case FLOOR: return floor( value );
|
||
|
case CEIL: return ceil( value );
|
||
|
case SIGN: return value >= 0 ? 1.0 : -1.0; // should return 0 for value == 0 ???
|
||
|
case ABS: return fabs(value);
|
||
|
case COS: return cos(value);
|
||
|
case COSH: return cosh(value);
|
||
|
case SIN: return sin(value);
|
||
|
case SINH: return sinh(value);
|
||
|
case TAN: return tan(value);
|
||
|
case TANH: return tanh(value);
|
||
|
case ACOS: return acos(value);
|
||
|
case ACOSH: return acosh(value);
|
||
|
case ASIN: return asin(value);
|
||
|
case ASINH: return asinh(value);
|
||
|
case ATAN: return atan(value);
|
||
|
case ATANH: return atanh(value);
|
||
|
case LN: return log(value);
|
||
|
case LOG2: return log10(value)/log10(2.0);
|
||
|
case LOG10: return log10(value);
|
||
|
case SQRT: return sqrt(value);
|
||
|
case NEG: return -value;
|
||
|
default: return sqrt(-1);
|
||
|
};
|
||
|
}
|
||
|
|
||
|
|
||
|
//-------------------------------------------------------------------------//
|
||
|
//-------------------------------------------------------------------------//
|
||
|
//-------------------------------------------------------------------------//
|
||
|
//-------------------------------------------------------------------------//
|
||
|
//-------------------------------------------------------------------------//
|
||
|
|
||
|
|
||
|
MPSymFunction2::MPSymFunction2( Function f, MPSymbolList *args, int columnFrom, int columnTo, const char *id )
|
||
|
: MPSymbol( args, columnFrom, columnTo, id )
|
||
|
{
|
||
|
m_f = f;
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------------------//
|
||
|
|
||
|
MPSymFunction2::~MPSymFunction2()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------------------//
|
||
|
|
||
|
void MPSymFunction2::checkArgs( MPError& error )
|
||
|
{
|
||
|
if ( m_args->count() != 2 ) error.setWrongNumberOfArguments( m_args->count(), 2, this );
|
||
|
MPSymbol::checkArgs( error );
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------------------//
|
||
|
|
||
|
double MPSymFunction2::value( int row, int col )
|
||
|
{
|
||
|
double val1 = m_args->at(0)->value(row,col);
|
||
|
double val2 = m_args->at(1)->value(row,col);
|
||
|
switch( m_f ) {
|
||
|
case ADD: return val1+val2;
|
||
|
case SUB: return val1-val2;
|
||
|
case MUL: return val1*val2;
|
||
|
case DIV: return val2 ? val1/val2 : sqrt(-1);
|
||
|
case MOD: return fmod( val1, val2 );
|
||
|
case MIN: return min( val1, val2 );
|
||
|
case MAX: return max( val1, val2 );
|
||
|
case LOG: return log10(val1)/log10(val2);
|
||
|
case POW: return pow( val1, val2 );
|
||
|
case ATAN2: return atan2( val1, val2 );
|
||
|
default: return sqrt(-1);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------------------//
|
||
|
//-------------------------------------------------------------------------//
|
||
|
//-------------------------------------------------------------------------//
|
||
|
//-------------------------------------------------------------------------//
|
||
|
//-------------------------------------------------------------------------//
|
||
|
|
||
|
|
||
|
MPSymMatrixIndexer::MPSymMatrixIndexer( MPSymbol *sym, MPSymbolList *args, int columnFrom, int columnTo, const char *id )
|
||
|
: MPSymbol( args, columnFrom, columnTo, id )
|
||
|
{
|
||
|
m_symbol = sym;
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------------------//
|
||
|
|
||
|
MPSymMatrixIndexer::~MPSymMatrixIndexer()
|
||
|
{
|
||
|
delete m_symbol;
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------------------//
|
||
|
|
||
|
void MPSymMatrixIndexer::checkArgs( MPError& error )
|
||
|
// a bit complicated
|
||
|
{
|
||
|
if ( m_args->count() != 2 ) {
|
||
|
error.setWrongNumberOfArguments( m_args->count(), 2, this );
|
||
|
return;
|
||
|
}
|
||
|
m_symbol->checkArgs( error );
|
||
|
for( int i=0; i<m_args->count(); i++ ) m_args->at(i)->checkArgs(error);
|
||
|
if ( error.hasError() ) return;
|
||
|
|
||
|
m_rows = index_size(m_args->at(0)) == 0 ? m_symbol->rows() : index_size(m_args->at(0));
|
||
|
m_cols = index_size(m_args->at(1)) == 0 ? m_symbol->cols() : index_size(m_args->at(1));
|
||
|
|
||
|
for ( int row=0; row<m_rows; row++ )
|
||
|
if ( index_value(m_args->at(0),row) < 0 ||
|
||
|
index_value(m_args->at(0),row) >= m_symbol->rows() )
|
||
|
error.setError( QString(QT_TR_NOOP("Invalid row index value %1")).arg(index_value(m_args->at(0),row)), this );
|
||
|
for ( int col=0; col<m_cols; col++ )
|
||
|
if ( index_value(m_args->at(1),col) < 0 ||
|
||
|
index_value(m_args->at(1),col) >= m_symbol->cols() )
|
||
|
error.setError( QString(QT_TR_NOOP("Invalid column index value %1")).arg(index_value(m_args->at(1),col)), this );
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------------------//
|
||
|
|
||
|
double MPSymMatrixIndexer::value( int row, int col )
|
||
|
{
|
||
|
return m_symbol->value( index_value(m_args->at(0),row), index_value(m_args->at(1),col) );
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------------------//
|
||
|
|
||
|
int MPSymMatrixIndexer::index_size( MPSymbol *index )
|
||
|
{
|
||
|
return index->rows() * index->cols();
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------------------//
|
||
|
|
||
|
int MPSymMatrixIndexer::index_value( MPSymbol *index, int pos )
|
||
|
{
|
||
|
return index->rows() == 0 ? pos : (int )floor( index->value(pos/index->cols(),pos%index->cols()) );
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------------------//
|
||
|
//-------------------------------------------------------------------------//
|
||
|
//-------------------------------------------------------------------------//
|
||
|
//-------------------------------------------------------------------------//
|
||
|
|
||
|
MPSymVectorIndexer::MPSymVectorIndexer( MPSymbol *sym, MPSymbolList *args, int columnFrom, int columnTo, const char *id )
|
||
|
: MPSymbol( args, columnFrom, columnTo, id )
|
||
|
{
|
||
|
m_symbol = sym;
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------------------//
|
||
|
|
||
|
MPSymVectorIndexer::~MPSymVectorIndexer()
|
||
|
{
|
||
|
delete m_symbol;
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------------------//
|
||
|
|
||
|
void MPSymVectorIndexer::checkArgs( MPError& error )
|
||
|
// a bit complicated
|
||
|
{
|
||
|
if ( m_args->count() != 1 ) error.setWrongNumberOfArguments( m_args->count(), 1, this );
|
||
|
m_symbol->checkArgs( error );
|
||
|
m_args->at(0)->checkArgs(error);
|
||
|
if ( m_symbol->rows() != 1 && m_symbol->cols() != 1 ) error.setError( QT_TR_NOOP("Single index only valid for vectors;"), this );
|
||
|
if ( error.hasError() ) return;
|
||
|
|
||
|
// result will be a row vector
|
||
|
if ( m_symbol->rows() == 1 ) {
|
||
|
m_cols = index_size() == 0 ? m_symbol->cols() : index_size();
|
||
|
m_rows = 1;
|
||
|
} else {
|
||
|
// result will be a column vector
|
||
|
m_rows = index_size() == 0 ? m_symbol->rows() : index_size();
|
||
|
m_cols = 1;
|
||
|
}
|
||
|
|
||
|
for( int index=0;index<m_rows*m_cols; index++ )
|
||
|
if ( index_value(index) < 0 || index_value(index) >= m_symbol->rows()*m_symbol->cols() )
|
||
|
error.setError( QString(QT_TR_NOOP("Invalid index value %1")).arg(index_value(index)), this );
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------------------//
|
||
|
|
||
|
double MPSymVectorIndexer::value( int row, int col )
|
||
|
{
|
||
|
int index = index_value(row*m_cols+col);
|
||
|
return m_symbol->value( index/m_symbol->cols(), index%m_symbol->cols() );
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------------------//
|
||
|
|
||
|
int MPSymVectorIndexer::index_size()
|
||
|
{
|
||
|
return m_args->at(0)->rows() * m_args->at(0)->cols();
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------------------//
|
||
|
|
||
|
int MPSymVectorIndexer::index_value( int pos )
|
||
|
{
|
||
|
MPSymbol *index = m_args->at(0);
|
||
|
return index->rows() == 0 ? pos : (int )floor( index->value(pos/index->cols(),pos%index->cols()) );
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------------------//
|
||
|
//-------------------------------------------------------------------------//
|
||
|
//-------------------------------------------------------------------------//
|
||
|
//-------------------------------------------------------------------------//
|
||
|
|
||
|
MPSymTranspose::MPSymTranspose( MPSymbolList *args, int columnFrom, int columnTo, const char *id )
|
||
|
: MPSymbol( args, columnFrom, columnTo, id )
|
||
|
{
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------------------//
|
||
|
|
||
|
MPSymTranspose::~MPSymTranspose()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------------------//
|
||
|
|
||
|
void MPSymTranspose::checkArgs( MPError& error )
|
||
|
{
|
||
|
if ( m_args->count() != 1 ) error.setWrongNumberOfArguments( m_args->count(), 1, this );
|
||
|
m_args->at(0)->checkArgs( error );
|
||
|
m_rows = m_args->at(0)->cols();
|
||
|
m_cols = m_args->at(0)->rows();
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------------------//
|
||
|
|
||
|
double MPSymTranspose::value( int row, int col )
|
||
|
{
|
||
|
return m_args->at(0)->value( col, row );
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------------------//
|
||
|
//-------------------------------------------------------------------------//
|
||
|
//-------------------------------------------------------------------------//
|
||
|
//-------------------------------------------------------------------------//
|
||
|
|
||
|
MPSymVector::MPSymVector( MPSymbolList *args, int columnFrom, int columnTo, const char *id )
|
||
|
: MPSymbol( args, columnFrom, columnTo, id )
|
||
|
{
|
||
|
m_vector = NULL;
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------------------//
|
||
|
|
||
|
MPSymVector::~MPSymVector()
|
||
|
{
|
||
|
delete m_vector;
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------------------//
|
||
|
|
||
|
void MPSymVector::checkArgs( MPError& error )
|
||
|
{
|
||
|
delete m_vector; m_vector = NULL;
|
||
|
MPSymbol::checkArgs( error );
|
||
|
m_rows = 1;
|
||
|
m_cols = 0;
|
||
|
if ( !error.hasError() )
|
||
|
for( int i=0; i<m_args->count(); i++ ) {
|
||
|
if ( m_args->at(i)->rows() != 1 ) { error.setNonconformantArgument( i, m_args->at(i), this ); break; }
|
||
|
m_cols += m_args->at(i)->cols();
|
||
|
}
|
||
|
int curr_col = 0;
|
||
|
m_vector = new double[m_cols];
|
||
|
for( int i=0; i<m_args->count(); i++ )
|
||
|
for( int col=0; col<m_args->at(i)->cols(); col++ )
|
||
|
m_vector[curr_col++] = m_args->at(i)->value(0,col);
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------------------//
|
||
|
|
||
|
double MPSymVector::value( int, int col )
|
||
|
{
|
||
|
return m_vector[col];
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------------------//
|
||
|
//-------------------------------------------------------------------------//
|
||
|
//-------------------------------------------------------------------------//
|
||
|
//-------------------------------------------------------------------------//
|
||
|
//-------------------------------------------------------------------------//
|
||
|
|
||
|
MPSymMatrix::MPSymMatrix( MPSymbolList *args, int columnFrom, int columnTo, const char *id )
|
||
|
: MPSymbol( args, columnFrom, columnTo, id )
|
||
|
{
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------------------//
|
||
|
|
||
|
MPSymMatrix::~MPSymMatrix()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------------------//
|
||
|
|
||
|
void MPSymMatrix::checkArgs( MPError& error )
|
||
|
{
|
||
|
MPSymbol::checkArgs( error );
|
||
|
if ( !error.hasError() ) {
|
||
|
m_cols = m_args->at(0)->cols();
|
||
|
m_rows = m_args->count();
|
||
|
for( int i=0; i<m_args->count(); i++ ) {
|
||
|
if ( m_args->at(i)->rows() != 1 ||
|
||
|
m_args->at(i)->cols() != m_cols ) { error.setNonconformantArgument( i, m_args->at(i), this ); break; }
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------------------//
|
||
|
|
||
|
double MPSymMatrix::value( int row, int col )
|
||
|
{
|
||
|
return m_args->at(row)->value(0,col);
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------------------//
|
||
|
|
||
|
|