Пример #1
0
const ExprChi& ExprChi::new_(const ExprNode& a, const ExprNode& b, const ExprNode& c) {
	if (!(a.type() == Dim::SCALAR)) throw DimException("\"chi\" expects scalar arguments");
	if (!(b.type() == Dim::SCALAR)) throw DimException("\"chi\" expects scalar arguments");
	if (!(c.type() == Dim::SCALAR)) throw DimException("\"chi\" expects scalar arguments");
	const ExprNode* args2[3] = {&a,&b,&c};
	return *new ExprChi(args2);
}
Пример #2
0
const ExprChi& ExprChi::new_(const ExprNode& a, const ExprNode& b, const ExprNode& c) {
	if (!(a.type() == Dim::SCALAR)) throw DimException("\"chi\" expects scalar arguments");
	if (!(b.type() == Dim::SCALAR)) throw DimException("\"chi\" expects scalar arguments");
	if (!(c.type() == Dim::SCALAR)) throw DimException("\"chi\" expects scalar arguments");

	return *new ExprChi(Array<const ExprNode>(a,b,c));
}
Пример #3
0
Dim mul_dim(const Dim& l, const Dim& r) {
	if (l.dim1!=1 || r.dim1!=1)
		throw DimException("cannot multiply a matrix array");

	if (l.type()==Dim::SCALAR) // scalar multiplication.
		return r;
	else {
		if (l.dim3!=r.dim2) {
			if (l.dim2==r.dim2) {
				if (r.dim3==1) // dot product
					return Dim::scalar();
				else // vector-matrix product
					return Dim::row_vec(r.dim3);
			}
			throw DimException("mismatched dimensions in matrix multiplication");
		} else {
			if (l.dim2==1)
				if (r.dim3==1) return Dim::scalar();
				else return Dim::row_vec(r.dim3);
			else
				if (r.dim3==1) return Dim::col_vec(l.dim2);
				else return Dim::matrix(l.dim2,r.dim3);
		}
	}
}
Пример #4
0
Dim vec_dim(const Array<const Dim>& comp, bool in_a_row) {
	int n=comp.size();

	if (n==0) throw DimException("a 0-sized vector has no dimension");

	const Dim& d=comp[0];

	if (d.is_scalar()) {
		if (in_a_row) {
			for (int i=0; i<n; i++)
				// we could allow concatenation of
				// row vectors of different size
				// in a single row vector;
				// (but not implemented yet)
				if (comp[i].type()!=Dim::SCALAR) goto error;
			return Dim::row_vec(n);
		}
		else {
			for (int i=0; i<n; i++)
				// we could allow concatenation of
				// column vectors of different size
				// in a single column vector;
				// (but not implemented yet)
				if (comp[i].type()!=Dim::SCALAR) goto error;
			return Dim::col_vec(n);
		}
	} else if (d.is_vector()) {
		if (in_a_row) {
			for (int i=0; i<n; i++)
				// same comment as above: we could also
				// put matrices with different number of columns
				// in a row. Not implemented. Only column vectors are accepted
				if (comp[i].type()!=Dim::COL_VECTOR || comp[i].dim2!=d.dim2) goto error;
			return Dim::matrix(d.dim2,n);
		} else {
			for (int i=0; i<n; i++) {
				// same comment as above: we could also
				// put matrices with different number of rows
				// in column. Not implemented. Only row vectors are accepted
				if (comp[i].type()!=Dim::ROW_VECTOR || comp[i].dim3!=d.dim3) goto error;
			}
			return Dim::matrix(n,d.dim3);
		}
	}

	// notice: array of matrix expressions are only used
	// so far in unvectorizing (for symbols corresponding to matrix arrays)
	else if (d.type()==Dim::MATRIX) {
		for (int i=0; i<n; i++)
			if (comp[i].type()!=Dim::MATRIX || comp[i].dim2!=d.dim2 || comp[i].dim3!=d.dim3) goto error;
		return Dim::matrix_array(n,d.dim2,d.dim3);
	}

	error:
	throw DimException("impossible to form a vector with heterogeneous components");
}
Пример #5
0
Dim Dim::transpose_dim() const {
	switch (type()) {
	case SCALAR:       return *this;
	case ROW_VECTOR:   return col_vec(vec_size());
	case COL_VECTOR:   return row_vec(vec_size());
	case MATRIX:       return matrix(dim3,dim2);
	case MATRIX_ARRAY:
	default:           throw DimException("cannot transpose an array of matrices");
	                   return *this;
	}
}
Пример #6
0
ExprApply::ExprApply(const Function& f, const ExprNode** args) :
		ExprNAryOp(args,f.nb_arg(),f.expr().dim),
		func(f) {
	for (int i=0; i<f.nb_arg(); i++) {

		if (args[i]->dim.is_vector()) {
			// we allow automatic transposition of vector arguments
			if (f.arg(i).dim.is_vector() && (args[i]->dim.vec_size()==f.arg(i).dim.vec_size())) continue;
		} else {
			// otherwise, dimensions must match exactly.
			if (args[i]->dim == f.arg(i).dim) continue;
		}

		stringstream s;
		s << "dimension of the " << (i+1) << "th argument passed to \"" << f.name << "\" ";
		s << "do not match that of the formal argument \"" << f.arg_name(i) << "\"";
		throw DimException(s.str());
	}
}
Пример #7
0
ExprIndex::ExprIndex(const ExprNode& subexpr, int index)
: ExprNode(subexpr.height+1, subexpr.size+1, subexpr.dim.index_dim()), expr(subexpr), index(index) {
	if (index<0 || index>subexpr.dim.max_index())
		throw DimException("index out of bounds");
	((ExprNode&) (subexpr)).fathers.add(*this);
}
Пример #8
0
ExprAtanh::ExprAtanh(const ExprNode& expr) : ExprUnaryOp(expr,expr.dim) {
	if (!expr.dim.is_scalar()) throw DimException("\"atanh\" expects a scalar argument");
}
Пример #9
0
ExprSin::ExprSin(const ExprNode& expr) : ExprUnaryOp(expr,expr.dim) {
	if (!expr.dim.is_scalar()) throw DimException("\"sin\" expects a scalar argument");
}
Пример #10
0
ExprAtan2::ExprAtan2(const ExprNode& left, const ExprNode& right) :
			ExprBinaryOp(left,right,Dim()) {
	if (!(left.type() == Dim::SCALAR)) throw DimException("\"atan2\" expects scalar arguments");
	if (!(right.type() == Dim::SCALAR)) throw DimException("\"atan2\" expects scalar arguments");
}
Пример #11
0
ExprDiv::ExprDiv(const ExprNode& left, const ExprNode& right) :
						ExprBinaryOp(left,right,Dim()) {
	if (!(left.type() == Dim::SCALAR)) throw DimException("cannot divide a non-scalar expression");
	if (!(right.type() == Dim::SCALAR)) throw DimException("cannot divide by a non-scalar expression");
}
Пример #12
0
ExprSub::ExprSub(const ExprNode& left, const ExprNode& right) :
				ExprBinaryOp(left,right,left.dim) {
	if (!(left.dim == right.dim)) throw DimException("mismatched dimensions in subtraction");
}
Пример #13
0
ExprAdd::ExprAdd(const ExprNode& left, const ExprNode& right) :
				ExprBinaryOp(left,right,left.dim) {
	if (!(left.dim == right.dim)) throw DimException("mismatched dimensions in addition");
}
Пример #14
0
const ExprChi& ExprChi::new_(const ExprNode** args) {
	if (!(args[0]->type() == Dim::SCALAR)) throw DimException("\"chi\" expects scalar arguments");
	if (!(args[1]->type() == Dim::SCALAR)) throw DimException("\"chi\" expects scalar arguments");
	if (!(args[2]->type() == Dim::SCALAR)) throw DimException("\"chi\" expects scalar arguments");
	return *new ExprChi(args);
}