static ERL_NIF_TERM max(ErlNifEnv *env, int32_t argc, const ERL_NIF_TERM *argv) { ErlNifBinary matrix; float max; float *matrix_data; (void)(argc); if (!enif_inspect_binary(env, argv[0], &matrix)) return enif_make_badarg(env); matrix_data = (float *) matrix.data; max = matrix_max(matrix_data); return enif_make_double(env, max); }
/*! @brief Compute matrix infinite norm @param matrix Matrix for which we want the infinite norm @return Infinite norm of matrix */ double matrix_norm_inf (struct Matrix *matrix) { size_t j = 0; // Norm double m_norm = 0; // Vector of the max values of each cols struct Matrix_max *m_vector = NULL; if (!matrix) { printf("matrix_norm_inf: Matrix not allocated\n"); return 0; } m_vector = matrix_max(matrix); // Compute infinite matrix norm for (j = 0; j < matrix->nc; j++) m_norm += m_vector->matrix->data[0][j]; matrix_max_destroy(&m_vector); return m_norm; }
/*! @brief Function which compute the reduce row echelon form of a matrix. This function doesn't work as expected and isn't complete. @param matrix Matrix for which to compute the rref @return The reduce row echelon form of the matrix */ void matrix_rref_gauss_octave (struct Matrix *matrix) { size_t m_row = 0, m_col = 0, k = 0, e = 0, u = 0, maxi = 0, m = 0; size_t i = 0, j = 0; double eps = 2.2e-16, tolerance = 0; // Matrix with zeros struct Matrix *m_used = NULL; struct Matrix_max *m_max = NULL; // Temp matrix double *line = NULL; if (!matrix) { printf("matrix_rref_gauss: Matrix not allocated\n"); return; } // max (rows, cols) // we compare rows and cols if (matrix->nr > matrix->nc) maxi = matrix->nr; else if (matrix->nr < matrix->nc) maxi = matrix->nc; else maxi = matrix->nr; tolerance = eps * maxi * matrix_norm_inf (matrix); // Matrix with zeros m_used = matrix_create(1, matrix->nc); for (m_col = 0; m_col < matrix->nc; m_col++) { m_max = matrix_max(matrix); // index du maximum m = m_max->index; // pivot m_max->index = m_max->index + m_row - 1; if (m_max->matrix->data[0][m] < tolerance) { // A (r:rows, c) = zeros (rows-r+1, 1); for (i = m_row; i < matrix->nr; i++) matrix->data[i][m_col] = 0; } else { // keep track of bound variables m_used->data[0][m_col] = 1; // Swap current row and pivot row line = matrix->data[i]; matrix->data[i] = matrix->data[m_max->index]; matrix->data[m_max->index] = line; // Normalize pivot row for (j = m_col; j < matrix->nc; j++) // A (r, c:cols) = A (r, c:cols) / A (r, c); matrix->data[m_row][j] = matrix->data[m_row][j] / matrix->data[m_row][m_col]; // Eliminate the current column for (i = 0; i < m_row; i++) { for (j = m_col; j < matrix->nc; j++) matrix->data[i][j] = matrix->data[i][j] - matrix->data[i][m_col] * matrix->data[m_row][j]; } for (i = m_row+1; i < matrix->nr; i++) { for (j = m_col; j < matrix->nc; j++) matrix->data[i][j] = matrix->data[i][j] - matrix->data[i][m_col] * matrix->data[m_row][j]; } // Check if done if (++m_row == matrix->nr) break; } /* else ## Swap current row and pivot row A ([pivot, r], c:cols) = A ([r, pivot], c:cols); ## Normalize pivot row A (r, c:cols) = A (r, c:cols) / A (r, c); ## Eliminate the current column ridx = [1:r-1, r+1:rows]; A (ridx, c:cols) = A (ridx, c:cols) - A (ridx, c) * A(r, c:cols); ## Check if done if (r++ == rows) break; endif endif endfor k = find (used); */ } }