Esempio n. 1
0
int main(int argc, char* argv[]){
  static const char *optString = "o:l:f:r:";
  int c;
  char* picture;
  char* output;
  double lambda;
  int factor;

  while((c = getopt(argc, argv, optString)) != -1){
    switch(c){
      case 'l': { lambda  = atof(optarg); break; }
      case 'f': { picture = optarg; break; }
      case 'o': { output = optarg; break; }
      case 'r': { factor = atoi(optarg); break; }
      default:  { printf("Cannot parse.\n"); }
    }
  }

  PGMInfo pgm_info = parse_pgm(picture,factor);
  Matrix matrix = build_matrix(lambda, &pgm_info);
  double results[pgm_info.fHeight * pgm_info.fWidth];

  gauss(matrix, &pgm_info);
  solve_equations(matrix, &pgm_info, results);
  create_new_picture(results, output, &pgm_info);

  free_pixels_memory(&pgm_info);

  return 0;
}
Esempio n. 2
0
/*
 *	solve_equations()
 *
 *	Solve linear equations or indeterminate equations.
 *
 *	@matrix: the matrix
 *	@mx: the number of columns of the matrix
 *	@my: the number of rows of the matrix
 *	@unknowns: the next unknown's id
 *	@base_offset_x, @base_offset_y: the offset of the sub matrix to be solved
 */
exp* solve_equations(fact **matrix, int mx, int my, int unknowns, int base_offset_x, int base_offset_y) {
	int idx;
	fact *temp, *ptr_equ, **ptr_matrix, *prepare, *pc;
	exp *ret, *rpptr, *solve_equ, *retptr, step;

	matrix += base_offset_y;

	/*  Exchange equations  */
	for (ptr_matrix = matrix; ptr_matrix < matrix + my; ptr_matrix++)
		if (fraction_compare(read_matrix(ptr_matrix, base_offset_x, 0), F_ZERO) != 0) {
			temp = *matrix;
			*matrix = *ptr_matrix;
			*ptr_matrix = temp;
			break;
		}

	/*  Allocate memory areas for the results  */
	ret = (exp*) malloc((mx - 1)*sizeof(exp));
	if (!ret)
		return(NULL);

	/*  CAUTION: this step is pretty important, the memory area of the new expression stack must be filled with zero.  */
	memset(ret, 0, (mx - 1) * sizeof(exp));

	/*  Nothing to exchange, remove the first column  */
	if (fraction_compare(read_matrix(matrix, base_offset_x, 0), F_ZERO) == 0) {
		*ret = expression_create(0, 1);
		/*  Push a new unknown symbol into the expression stack  */
		if (!push_expression_node_ex(ret, unknowns + 1, fraction_create(1, 1), fraction_plus)) {
			free_expression_stack(ret, mx - 1);
			return(NULL);
		}
		if (mx > 2) {
			/*  Remove the first column  */
			solve_equ = solve_equations(matrix, mx - 1, my, unknowns + 2, base_offset_x + 1, 0);
			if (!solve_equ) {
				free_expression_stack(ret, mx - 1);
				return(NULL);
			}
			for (rpptr = solve_equ, retptr = ret + 1, idx = 0; idx < mx - 2; idx++, rpptr++, retptr++)
				if (!expression_memcpy(retptr, *rpptr, false)) {
					free_expression_stack(ret, mx - 1);
					return(NULL);
				}
			free_expression_stack(solve_equ, mx - 2);

		}
		return(ret);
	}

	if (my == 1 || mx == 2) {
		/*  Only one unknown, get the result of it  */
		step = expression_create(matrix_offset(matrix, base_offset_x + mx - 1, 0)->numerator, matrix_offset(matrix, base_offset_x + mx - 1, 0)->denominator);
		for (rpptr = ret + 1, ptr_equ = matrix_offset(matrix, base_offset_x + 1, 0), pc = matrix_offset(matrix, base_offset_x + mx - 2, 0); ptr_equ <= pc; ptr_equ++, rpptr++) {
			*rpptr = expression_create(0, 1);
			/*  Generate a new unknown  */
			/*  and then copy values of other unknowns to the result  */
			if (push_expression_node_ex(rpptr, ++unknowns, fraction_create(1, 1), fraction_plus)) {
				if (!expression_double_operation(&step, fraction_minus, *rpptr, fraction_multiplination, *ptr_equ)) {
					free_expression_stack(ret, mx - 1);
					free_expression(&step);
					return(NULL);
				}
			} else {
				free_expression_stack(ret, mx - 1);
				return(NULL);
			}
		}
		expression_division(&step, read_matrix(matrix, base_offset_x, 0));

		if (!simplify_expression_node(&step)) {
			free_expression_stack(ret, mx - 1);
			free_expression(&step);
			return(NULL);
		}

		*ret = step;
	} else {
		/*  Have more than one unknown, eliminating  */
		/*  Allocate enough memory areas to contain new equations  */
		for (ptr_matrix = matrix; ptr_matrix < matrix + my; ptr_matrix++)
			if (fraction_compare(read_matrix(ptr_matrix, base_offset_x, 0), F_ZERO) != 0) {
				for (ptr_equ = matrix_offset(ptr_matrix, base_offset_x + mx - 1, 0), pc = matrix_offset(ptr_matrix, base_offset_x, 0); ptr_equ >= pc; ptr_equ--)
					*ptr_equ = fraction_division(*ptr_equ, read_matrix(ptr_matrix, base_offset_x, 0));
				if (ptr_matrix != matrix)
					for (prepare = matrix_offset(matrix, base_offset_x, 0), ptr_equ = matrix_offset(ptr_matrix, base_offset_x, 0); ptr_equ < matrix_offset(ptr_matrix, base_offset_x + mx, 0); prepare++, ptr_equ++)
						*ptr_equ = fraction_minus(*ptr_equ, *prepare);
			}

		/*  Generate the eliminated equations  */
		solve_equ = solve_equations(matrix, mx - 1, my - 1, unknowns, base_offset_x + 1, 1);
		if (!solve_equ) {
			free_expression_stack(ret, mx - 1);
			return(NULL);
		}

		/*  Calculate the value of the unknown in the first column  */
		step = expression_create(matrix_offset(matrix, base_offset_x + mx - 1, 0)->numerator, matrix_offset(matrix, base_offset_x + mx - 1, 0)->denominator);
		for (rpptr = solve_equ, ptr_equ = matrix_offset(matrix, base_offset_x + 1, 0); ptr_equ <= matrix_offset(matrix, base_offset_x + mx - 2, 0); rpptr++, ptr_equ++)
			if (!expression_double_operation(&step, fraction_minus, *rpptr, fraction_multiplination, *ptr_equ)) {
				free_expression_stack(ret, mx - 1);
				free_expression(&step);
				return(NULL);
			}

		if (!simplify_expression_node(&step)) {
			free_expression_stack(ret, mx - 1);
			free_expression(&step);
			return(NULL);
		}

		/*  Copy values of other unknowns to the result  */
		for (*ret = step, rpptr = solve_equ, retptr = ret + 1, idx = 0; idx < mx - 2; idx++, rpptr++, retptr++)
			if (!expression_memcpy(retptr, *rpptr, false)) {
				free_expression_stack(ret, mx - 1);
				return(NULL);
			}
		free_expression_stack(solve_equ, mx - 2);
	}

	return(ret);
}