void SystemMatrix::ypAx(escript::Data& y, escript::Data& x) const { if (x.isComplex() || y.isComplex()) { throw PasoException("SystemMatrix::ypAx: complex arguments not supported."); } if (x.getDataPointSize() != getColumnBlockSize()) { throw PasoException("matrix vector product: column block size does not match the number of components in input."); } else if (y.getDataPointSize() != getRowBlockSize()) { throw PasoException("matrix vector product: row block size does not match the number of components in output."); } else if (x.getFunctionSpace() != getColumnFunctionSpace()) { throw PasoException("matrix vector product: column function space and function space of input don't match."); } else if (y.getFunctionSpace() != getRowFunctionSpace()) { throw PasoException("matrix vector product: row function space and function space of output don't match."); } x.expand(); y.expand(); x.requireWrite(); y.requireWrite(); double* x_dp = x.getExpandedVectorReference(static_cast<escript::DataTypes::real_t>(0)).data(); double* y_dp = y.getExpandedVectorReference(static_cast<escript::DataTypes::real_t>(0)).data(); MatrixVector(1., x_dp, 1., y_dp); }
//Draw the line to the XPM file. //This applies the 2D transformations specified in the command-line inputs //and applies Cohen-Sutherland to clip the lines to the world window. //This includes an implementation of Bresenham's line-drawing algorithm. void Line::execute(XPMData *thefile) { //Create the composite transformation matrix //from the command-line inputs. CreateTransformationMatrix(thefile); // With the matrix, we can transform both endpoints of the line double VectorToTransform[3]; double TransformedVector1[3]; double TransformedVector2[3]; VectorToTransform[0] = x1; VectorToTransform[1] = y1; VectorToTransform[2] = 1; MatrixVector(TransformedVector1, TransformationMatrix, VectorToTransform); x1 = TransformedVector1[0]; y1 = TransformedVector1[1]; VectorToTransform[0] = x2; VectorToTransform[1] = y2; VectorToTransform[2] = 1; MatrixVector(TransformedVector2, TransformationMatrix, VectorToTransform); x2 = TransformedVector2[0]; y2 = TransformedVector2[1]; // Clip to world window, do not draw anything if length = 0 if (!Clip(thefile->getCmdLine()->getlowX(), thefile->getCmdLine()->getupperX(), thefile->getCmdLine()->getlowY(), thefile->getCmdLine()->getupperY())) return; // Now everything is clipped and transformed. Let's draw the line. // First, we need to handle vertical lines (they have an undefined slope) if ((x2-x1) == 0) { if (y2 > y1) { for(int y = y1; y <= y2; y++) { thefile->plot(x1, y); } } else { for(int y = y2; y <= y1; y++) { thefile->plot(x1, y); } } return; } // Bresnehan's algorithm should handle everything else. double slope = fabs(y2 - y1) / fabs(x2-x1); if (slope > 1) { //for steep lines, we can reflect to get a lesser slope int temp = x1; x1 = y1; y1 = temp; temp = x2; x2 = y2; y2 = temp; } if (x1 > x2) { // we can swap the points and still get the same line // this is done to help generalize the algorithm int temp = x1; x1 = x2; x2 = temp; temp = y1; y1 = y2; y2 = temp; } int dx = x2 - x1; int dy = abs(y2 - y1); int D = dx/2; int y = y1; for (int x = x1; x <= x2; x++) { if (slope > 1) { thefile->plot(y, x); } else thefile->plot(x, y); D = D - dy; if (D < 0) { if (y1 < y2) y++; else y--; D += dx; } } }