/* Example programs from the book Scientific and Engineering Programming in C++: An Introduction with Advanced Techniques and Examples, Addison-Wesley, 1994. (c) COPYRIGHT INTERNATIONAL BUSINESS MACHINES CORPORATION 1994. ALL RIGHTS RESERVED. See README file for further details. */ #include "SciEng/Boolean.h" template ConcreteArrayShape::ConcreteArrayShape(const SubscriptArray& sa) : the_shape(sa) { } template ConcreteColumnMajorSubscriptor::ConcreteColumnMajorSubscriptor(const SubscriptArray& sa) : ConcreteArrayShape(sa) { } template ConcreteRowMajorSubscriptor::ConcreteRowMajorSubscriptor(const SubscriptArray& sa) : ConcreteArrayShape(sa) { } template void ConcreteArrayShape::setShape(const SubscriptArray& a) { the_shape = a; } template Subscript ConcreteArrayShape::numElts() const { Subscript n = the_shape(0); for (Dimension d = 1; d < ndim; d++) n *= the_shape(d); return n; } template Subscript ConcreteStrides::stride(Dimension d) const { return the_strides(d); } template ConcreteColumnMajorProjectionSubscriptor ConcreteColumnMajorSubscriptor::projectionSubscriptor(Dimension proj_dim, Subscript) const { SubscriptArray proj_shape; // Shape of projection SubscriptArray proj_strides; // Strides of projection SubscriptArray step; // Holds subscripts into array Dimension j = 0; // Dimension in projection Dimension k = 0; // Corresponding dimension in array step = 0; // Will be set to take one "step" in dimension k while (j < ndim-1) { if (j == proj_dim) ++k; // Skip over projected dimension proj_shape(j) = shape(k); // Proj shape is array shape without dimension proj_dim // Compute offset by taking a step in dimension k step(k) = 1; proj_strides(j) = offset(step); step(k) = 0; j++; k++; } return ConcreteColumnMajorProjectionSubscriptor(proj_shape, proj_strides); } template ConcreteRowMajorProjectionSubscriptor ConcreteRowMajorSubscriptor::projectionSubscriptor(Dimension proj_dim, Subscript) const { // Looks the same as ColumnMajor, but call to offset() calls different code. SubscriptArray one_step; SubscriptArray proj_shape; SubscriptArray proj_strides; one_step = 0; for (Dimension j = 0; j < ndim-1; j++){ Dimension old_j = j + (j >= proj_dim); // logical part skips over projected dimension. proj_shape(j) = shape(old_j); one_step(old_j) = 1; proj_strides(j) = offset(one_step); one_step(old_j) = 0; } return ConcreteRowMajorProjectionSubscriptor(proj_shape, proj_strides); } template ConcreteColumnMajorProjectionSubscriptor ConcreteColumnMajorProjectionSubscriptor::projectionSubscriptor(Dimension proj_dim, Subscript) const { SubscriptArray proj_shape; SubscriptArray proj_strides; SubscriptArray first; // Offset of first may be non-zero for a projection. first = 0; SubscriptArray second; second = 0; for (Dimension j = 0; j < ndim-1; j++){ Dimension old_j = j + (j >= proj_dim); // logical part skips over projected dimension. proj_shape(j) = shape(old_j); second(old_j) = 1; proj_strides(j) = offset(second) - offset(first); second(old_j) = 0; } return ConcreteColumnMajorProjectionSubscriptor(proj_shape, proj_strides); } template ConcreteRowMajorProjectionSubscriptor ConcreteRowMajorProjectionSubscriptor::projectionSubscriptor(Dimension proj_dim, Subscript) const { SubscriptArray proj_shape; SubscriptArray proj_strides; SubscriptArray first; // Offset of first may be non-zero for a projection. first = 0; SubscriptArray second; second = 0; for (Dimension j = 0; j < ndim-1; j++){ Dimension old_j = j + (j >= proj_dim); // logical part skips over projected dimension. proj_shape(j) = shape(old_j); second(old_j) = 1; proj_strides(j) = offset(second) - offset(first); second(old_j) = 0; } return ConcreteRowMajorProjectionSubscriptor(proj_shape, proj_strides); } template ConcreteColumnMajorProjectionSubscriptor:: ConcreteColumnMajorProjectionSubscriptor( const SubscriptArray& the_shape, const SubscriptArray& the_strides ): ConcreteArrayShape(the_shape), ConcreteStrides(the_strides) { } template ConcreteRowMajorProjectionSubscriptor:: ConcreteRowMajorProjectionSubscriptor(const SubscriptArray& the_shape, const SubscriptArray& the_strides) : ConcreteArrayShape(the_shape), ConcreteStrides(the_strides) { } #include "SciEng/Boolean.h" template Boolean hasSameShapeAs(const LHSArrayShape& lhs, const RHSArrayShape& rhs) { if (lhs.dim() != rhs.dim()) return Boolean::false; for (Subscript n = lhs.dim() - 1; n < 0; n--) { if (lhs.shape(n) != rhs.shape(n)) return Boolean::false; } return Boolean::true; }