Esempio n. 1
0
float SparMatrix_get(struct SparMatrix *m, int row_num, int col_num)
{
	struct SparMatrixRow *p_row;
	struct SparMatrixCell *p_cell;

	if (row_num < 0 || row_num >= m->h || col_num < 0 || col_num >= m->w) {
		WARNING("SparMatrix_get(): "
			"Invalid Index (row = %d, col = %d)\n",
			row_num, col_num);
		return 0;
	}

	p_row = _get_row(m, row_num);

	if (p_row == NULL) {
		return 0;
	}

	p_cell = p_row->cells;
	while (p_cell && p_cell->col_num < col_num) {
		p_cell = p_cell->next;
	}

	/* cell found */
	if (p_cell && p_cell->col_num == col_num) {
		 return p_cell->data;
	}

	return 0;
}
/**
 * Fills in a square PETSc matrix from MTJ's CompDiagMatrix internal storage
 * 
 * @param env a pointer to the JNI environment
 * @param A a pointer to the the PETSc matrix to fill
 * @param index a pointer to the indices from CompDiagMatrix.getIndex()
 * @param diagonals a pointer to the diagonals from 
 *        CompDiagMatrix.getDiagonals()
 * @return 0 on success, PetscErrorCode on failure
 */
PetscErrorCode _fill_matrix(JNIEnv *env, Mat *A, jintArray *index,
		 jobjectArray *diagonals) {
    // Get matrix dimension
    PetscInt n;
    PetscErrorCode ierr;
    ierr = MatGetSize(*A, &n, NULL); CHKERRQ(ierr);

    // Get size and base pointer for array of diagonal indices
    jsize index_length = (*env) -> GetArrayLength(env, *index);
    jint *index_array = (*env) -> GetIntArrayElements(env, *index, 0);

    // Loop through the array of diagonals
    for (int i = 0; i < index_length; i++) {
        // Get the current diagonal, its size and its base pointer
        jdoubleArray diag = (jdoubleArray) (*env) -> GetObjectArrayElement(
            env, *diagonals, i);
        jsize diag_length = (*env) -> GetArrayLength(env, diag);
        jdouble *diag_array = (*env) -> GetDoubleArrayElements(env, diag, 0);

        // Loop through current diagonal
        for (int j = 0; j < diag_length; j++) {
            int row = _get_row(index_array[i], j);
            int col = _get_col(index_array[i], j);
            ierr = MatSetValue(*A, row, col, diag_array[j], INSERT_VALUES);
            CHKERRQ(ierr);
        }

        (*env) -> ReleaseDoubleArrayElements(env, diag, diag_array, 0);
    }
    
    (*env) -> ReleaseIntArrayElements(env, *index, index_array, 0);
    return 0;
}
Esempio n. 3
0
/* [A] [X] = [B], to calculate  [X], [X] returned in [B]*/
void SparMatrix_Gauss(
		struct SparMatrix *A,	/* will be dirty, backup by user */
		struct SparMatrix *B	/* will be dirty, backup by user */
		)
{
	int row;
	int progress = 0;

	if (!(A && B)) {
		WARNING("SparMatrix_Gauss(A, B): A and B can not be NULL.\n");
		return;
	}

	if (B->w != 1) {
		WARNING("SparMatrix_Gauss(A, B): "
				"B must be a vertical vector.\n");
		return;
	}

	if (A->h != B->h) {
		WARNING("SparMatrix_Gauss(A, B): "
				"A and B must have the same Height.\n");
		return;
	}

	for (row = 0; row < A->h; ++row) {
		int row_i;
		struct SparMatrixRow *p_row;
		struct SparMatrixCell *p_cell;
		float factor;
		float b;

		if ((row*100 / A->h) == progress) {
			printf("%d%%\n", progress);
			progress += 5;
		}

		row_i = find_left_abs_largest(A, row);
		if (row_i < 0) {
			/* continue; */
			break;
		}

		TRACE("EXCHANGE line %d and %d\n", row, row_i);

		SparMatrix_exchange_row(A, row_i, row);
		SparMatrix_exchange_row(B, row_i, row);

		p_row = _get_row(A, row);

		p_cell = p_row->cells;
		factor = p_cell->data;
		p_cell->data = 1;
		p_cell = p_cell->next;
		while (p_cell) {
			p_cell->data /= factor;
			p_cell = p_cell->next;
		}
		TRACE("Line %d divide %f\n", row, factor);

		b = SparMatrix_get(B, row, 0);
		if (b != 0) {
			b /= factor;
			SparMatrix_set(B, row, 0, b);
		}

		for (row_i = 0; row_i < A->h; ++row_i) {
			if (row_i == row) {
				continue;
			}
			p_cell = p_row->cells;
			/* recycled variable factor */
			factor = SparMatrix_get(A, row_i, p_cell->col_num);

			if (factor != 0) {
				TRACE("Line %d eliminated from line %d, "
					"factor = %f\n", row_i, row, factor);
				/* Update [A] */
				SparMatrix_set(A, row_i, p_cell->col_num, 0);
				p_cell = p_cell->next;
				while (p_cell) {
					float value = SparMatrix_get(A, row_i,
							p_cell->col_num);
					SparMatrix_set(A,
						row_i,
						p_cell->col_num,
						value - factor*p_cell->data);
					p_cell = p_cell->next;
				}

				/* Update [B] */
				if (b != 0) {
					float value = SparMatrix_get(B, row_i, 0);
					SparMatrix_set(B, row_i, 0, value - b*factor);
				}
			}
		}
// {
	// int i,j;

	// printf("DUMP Matrizen:\n");
	// for (i = 0; i < A->h; ++i) {
		// float val;
		// for (j = 0; j < A->w; ++j) {
			// val = SparMatrix_get(A, i, j);
			// if (val != 0) {
				// printf("%5.2f ", val);
			// } else {
				// printf("%5.2f ", val);
			// }
		// }

		// val = SparMatrix_get(B, i, 0);
		// if (val != 0) {
			// printf("    %9.4f ", val);
		// } else {
			// printf("    %9.4f", val);
		// }
		// printf("\n");
	// }
// }
	}
}
Esempio n. 4
0
void SparMatrix_set(struct SparMatrix *m, int row_num, int col_num, float value)
{
	struct SparMatrixRow *p_row;

	if (row_num < 0 || row_num >= m->h || col_num < 0 || col_num >= m->w) {
		WARNING("SparMatrix_set(): "
			"Invalid Index (row = %d, col = %d)\n",
			row_num, col_num);
		return;
	}

	if (value != 0) {
		p_row = insert_row(m, row_num);
		if (p_row == NULL) {
			WARNING("SparMatrix_set(): Can not insert a row.\n");
		}
		insert_col(p_row, col_num, value);
	} else {
		/* Delete Cell */
		struct SparMatrixRow *p_row;
		struct SparMatrixCell *p_cell, *p_cell_pre;

		/* find the row */
		p_row = _get_row(m, row_num);
		if (p_row == NULL) {
			return; /* the row does not exist, needn't to release */
		}

		/* find the col */
		p_cell_pre = NULL;	/* p_cell_pre := the cell before the target*/
		p_cell = p_row->cells;	/* p_cell := the target cell (will be deleted) */
		while (p_cell && (p_cell->col_num < col_num)) {
			p_cell_pre = p_cell;
			p_cell = p_cell->next;
		}

		if (p_cell == NULL) {
			/* the row will not at this place be deleted */
			return; /* cell does not exist */
		}

		/* delete this cell and perhaps its row */
		if (p_cell->col_num == col_num) {
			if (p_cell_pre == NULL) {
				/* delete cell */
				p_row->cells = p_cell->next;
				free(p_cell);

				/* then delete the row */
				if (p_row->cells == NULL) {
					struct SparMatrixRow *q_row;

					q_row = m->rows;
					while (/*q_row &&*/ q_row->next != p_row) {
						q_row = q_row->next;
					}
					/* there is no doubt, that p_row must exist,
					   so the NULL situation will not be checked */
					q_row->next = p_row->next;
					free(p_row);
				}
				return;
			} else {
				/* only delete this cell */
				p_cell_pre->next = p_cell->next;
				free(p_cell);
			}
		}

		/* otherwise:  p_cell->col_num > col_num, this cell does not exist*/
	}
}
void test__get_row() {
    assert(2 == _get_row(1, 2));   // above diagonal
    assert(1 == _get_row(0, 1));   // on diagonal
    assert(2 == _get_row(-1, 1));  // below digaonal
}