Example #1
0
//Red-black Gauss-Seidel relaxation for model problem. Updates the current value of the solution
//u[1..n][1..n], using the right-hand side function rhs[1..n][1..n].
// Red-black, Gauss-Seidel relaxation, Neumann forced, pointwise coupled
void relax(double **u, double **v, double **J[JROWS][JCOLS], int rows, int cols, double alpha) {

	int i, ipass, isw, j, jsw = 1;
	double hx, hy, hx2, hy2, discr, detU, detV;

	hx = 1.0 / (cols-1);
	hy = hx;  //
	hx2 = hx * hx;
	hy2 = hy * hy;

	for (ipass=1; ipass<= 2; ipass++, jsw = 3-jsw) {	//Red and black sweeps.
		isw = jsw;
		for (j=1; j<=cols; j++, isw=3-isw)
			for (i=isw; i<=rows; i+=2) {		//Gauss-Seidel formula.
				if (i>1 && i<rows) {
					if (j>1 && j<cols) {
						discr = lin2by2det(alpha/hx2*2.0 + alpha/hy2*2.0 + J[1][1][i][j],
								J[1][2][i][j],
								J[1][2][i][j],
								alpha/hx2*2.0 + alpha/hy2*2.0 + J[2][2][i][j]);

						if (abs((double)discr)>EPS) {
							detU = lin2by2det(alpha/hx2*(u[i-1][j]+u[i+1][j]) + alpha/hy2*(u[i][j-1]+u[i][j+1]) - J[1][3][i][j],
									J[1][2][i][j],
									alpha/hx2*(v[i-1][j]+v[i+1][j]) + alpha/hy2*(v[i][j-1]+v[i][j+1]) - J[2][3][i][j],
									alpha/hx2*2.0 + alpha/hy2*2.0 + J[2][2][i][j]);
							u[i][j]= detU / discr;

							detV = lin2by2det(alpha/hx2*2.0 + alpha/hy2*2.0 + J[1][1][i][j],
									alpha/hx2 * (u[i-1][j]+u[i+1][j]) + alpha/hy2*(u[i][j-1]+u[i][j+1]) - J[1][3][i][j],
									J[1][2][i][j],
									alpha/hx2 * (v[i-1][j]+v[i+1][j]) + alpha/hy2*(v[i][j-1]+v[i][j+1]) - J[2][3][i][j]);
							v[i][j] = detV / discr;

						} else {
							u[i][j] = (alpha/hx2*(u[i-1][j]+u[i+1][j]) + alpha/hy2*(u[i][j-1]+u[i][j+1]) - (J[1][2][i][j]*v[i][j]+J[1][3][i][j])) / (alpha/hx2*2.0 + alpha/hy2*2.0 + J[1][1][i][j]);
							v[i][j] = (alpha/hx2*(v[i-1][j]+v[i+1][j]) + alpha/hy2*(v[i][j-1]+v[i][j+1]) - (J[1][2][i][j]*u[i][j]+J[2][3][i][j])) / (alpha/hx2*2.0 + alpha/hy2*2.0 + J[2][2][i][j]);
						}
					} else if (j==1) {
						u[i][j] = u[i][j+1];
						v[i][j] = v[i][j+1];
					} else if (j==cols) {
						u[i][j] = u[i][j-1];
						v[i][j] = v[i][j-1];
					} else {
						printf("relax: Bug: Index error(2).\n");
						return;
					}
				} else if (i==1) {
					if(j>1 && j<cols) {
						u[i][j] = u[i+1][j];
						v[i][j] = v[i+1][j];
					} else if (j==1) {
						u[i][j] = u[i+1][j+1];
						v[i][j] = v[i+1][j+1];
					} else if (j==cols) {
						u[i][j] = u[i+1][j-1];
						v[i][j] = v[i+1][j-1];
					} else {
						printf("relax: Bug: Index error.\n");
						return;
					}
				} else if (i==rows) {
					if(j>1 && j<cols) {
						u[i][j] = u[i-1][j];
						v[i][j] = v[i-1][j];
					} else if (j==1) {
						u[i][j] = u[i-1][j+1];
						v[i][j] = v[i-1][j+1];
					} else if (j==cols) {
						u[i][j] = u[i-1][j-1];
						v[i][j] = v[i-1][j-1];
					} else {
						printf("relax: Bug: Index error(3).\n");
						return;
					}
				}
			}
	}
}
/**
 * relaxPointwiseCoupledGaussSeidel
 *
 * Pointwise coupled Gauss-Seidel relaxation iteration for CLG-OF equations.
 * Each call to this function updates the current value of the solution,
 * u[1..m][1..n], v[1..m][1..n], using the motion tensor
 * J[JROWS][JCOLS][1..m][1..n].
 * Neumann boundary conditions are used (derivatives are set to zero).
 * The return value is the total error of the current iteration.
 *
 * Parameters:
 *
 * u               Pointer to the optical flow horizontal component
 *                 matrix/array.
 * v               Pointer to the optical flow vertical component matrix/array.
 * J[JROWS][JCOLS] Pointer to the array that stores the computed (and possibly
 *                 smoothed) derivatives for each image/optical flow pixel.
 * nRows           Number of rows of the optical flow arrrays.
 * nCols           Number of columns of the optical flow arays.
 * alpha           Optical flow global smoothing coefficient.
 *
 */
double relaxPointwiseCoupledGaussSeidel(double **u,
                                        double **v,
                                        double **J[JROWS][JCOLS],
                                        int nRows,
                                        int nCols,
                                        double alpha) {
    int i, j;
    double hx, hy, hx2, hy2, discr, detU, detV, error, ulocal, vlocal;

    // h, could be less than 1.0.
    hx    = 1.0;
    hy    = hx;
    hx2   = hx * hx;
    hy2   = hy * hy;
    error = 0.0;

    for (i=1; i<nRows-1; i++) {
        for (j=1; j<nCols-1; j++) {
            // Point-wise Coupled Gauss-Seidel formula.

            // Coupled system for two variables solved by Cramer's rule.
            // This is the discriminant of that system
            discr = lin2by2det(alpha/hx2*2.0 + alpha/hy2*2.0 + J[0][0][i][j],
                               J[0][1][i][j],
                               J[0][1][i][j],
                               alpha/hx2*2.0 + alpha/hy2*2.0 + J[1][1][i][j]);

            if (abs(discr) > EPS) {
                // Determinant replacing first column to solve
                // the 2x2 system by using Cramer's rule.
                detU = lin2by2det(alpha / hx2 * (u[i-1][j] + u[i+1][j])
                                  + alpha / hy2 * (u[i][j-1] + u[i][j+1])
                                  - J[0][2][i][j],
                                    J[0][1][i][j],
                                    alpha / hx2 * (v[i-1][j] + v[i+1][j])
                                  + alpha / hy2 * (v[i][j-1] + v[i][j+1])
                                  - J[1][2][i][j],
                                    alpha / hx2 * 2.0 + alpha / hy2 * 2.0
                                  + J[1][1][i][j]);

                // Determinant replacing second column to solve
                // the 2x2 system by using Cramer's rule.
                detV = lin2by2det(alpha / hx2 * 2.0 + alpha / hy2 * 2.0
                                  + J[0][0][i][j],
                                    alpha / hx2 * (u[i-1][j] + u[i+1][j])
                                  + alpha / hy2 * (u[i][j-1] + u[i][j+1])
                                  - J[0][2][i][j],
                                    J[0][1][i][j],
                                    alpha / hx2 * (v[i-1][j] + v[i+1][j])
                                  + alpha / hy2 * (v[i][j-1] + v[i][j+1])
                                  - J[1][2][i][j]);

                // Division of two discriminants (Cramer's rule).
                ulocal = detU / discr;
                vlocal = detV / discr;

                error += (ulocal-u[i][j])*(ulocal-u[i][j]);
                error += (vlocal-v[i][j])*(vlocal-v[i][j]);

                u[i][j]=ulocal;
                v[i][j]=vlocal;

                // Normal Gauss-Seidel iteration.
            } else {

                // w_Factor=1.0, thus a Gauss-Seidel iteration.
                error += SOR_at(u, v, J, i, j, alpha, 1.0);

            } // End if.
        } // End columns.
    } // End rows.

    error += boundaryCondition(u, v, nRows, nCols);

    return sqrt(error / (nRows*nCols));;
}