float matrix::get_x_scale() const { float scale = sqrtf(m_[0][0] * m_[0][0] + m_[0][1] * m_[0][1]); // Are we turned inside out? if (get_determinant() < 0.f) { scale = -scale; } return scale; }
/** * Berechnet die Determinante einer quadratischen Matrix * * @param matrix - Matrix zu der die Determinante berechnet werden soll * @param size - Groesse der Matrix * * @return Determinante der Matrix oder im Fehlerfall 0.0 */ double get_determinant (double matrix[MAX_SIZE][MAX_SIZE], int size) { if (size < 1 || size > MAX_SIZE) { printf ("Size Parameter falsch"); return 0.0; } else if (size == 1) { return matrix[0][0]; } else if (size == 2) { return matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0]; } else { double det = 0; /* Ausgerechnete Determinante */ double matrix2[MAX_SIZE][MAX_SIZE]; /* Untermatrix */ int p; /* Laufvariable für die Laplaceformel */ int i; /* Laufvariable um horizontal über die Matrix zu laufen */ int j; /* Laufvariable um vertikal über die Matrix zu laufen */ int h; /* Laufvariable um horizontal über die Untermatrix zu laufen */ int k; /* Laufvariable um vertikal über die Untermatrix zu laufen */ for (p = 0; p < size; p++) { h = 0; k = 0; for (i = 1; i < size; i++) { for (j = 0; j < size; j++) { if (j == p) { continue; } matrix2[h][k] = matrix[i][j]; k++; if (k == size - 1) { h++; k = 0; } } } det += (p % 2 == 0 ? 1 : -1) * matrix[0][p] * get_determinant(matrix2, size - 1); } return det; } }
float matrix::get_rotation() const { if (get_determinant() < 0.f) { // We're turned inside out; negate the // x-component used to compute rotation. // // Matches get_x_scale(). // // @@ this may not be how Macromedia does it! Test this! return atan2f(m_[1][0], -m_[0][0]); } else { return atan2f(m_[1][0], m_[0][0]); } }
inline struct map_type *get_inverse( struct map_type *map ) { struct map_type *result; if( map->i_size == 1 && map->j_size == 1 ) { result = allocate( 2, 2 ); result->i_size = 1; result->j_size = 1; __float128 value = *( *( map->memory + 0 ) + 0 ); *( *( result->memory + 0 ) + 0 ) = value == 0 ? 0 : powf( value, -1 ); } else { __float128 determinant = get_determinant( map ); result = multiplicate_on_value( powf( determinant, -1 ), map ); } return result; }
/** * Compute command. */ void command_compute(char* line) { char cmd[MAX_BUFFER]; char key[MAX_BUFFER]; char func[MAX_BUFFER]; char arg1[MAX_BUFFER]; int argc = sscanf(line, "%s %s %s %s", cmd, func, key, arg1); if (argc < 3) { goto invalid; } MATRIX_GUARD(key); float result = 0; if (strcasecmp(func, "sum") == 0) { result = get_sum(m); } else if (strcasecmp(func, "trace") == 0) { result = get_trace(m); } else if (strcasecmp(func, "minimum") == 0) { result = get_minimum(m); } else if (strcasecmp(func, "maximum") == 0) { result = get_maximum(m); } else if (strcasecmp(func, "determinant") == 0) { result = get_determinant(m); } else if (strcasecmp(func, "frequency") == 0) { ssize_t count = get_frequency(m, atof(arg1)); printf("%zu\n", count); return; } else { goto invalid; } printf("%.2f\n", result); return; invalid: puts("invalid arguments"); }
static char *test_compute_inverse() { Matrix *a = create_matrix(3, 3); // The matrix b will contain the value of the a's inverse. Matrix *b = create_matrix(3, 3); b->value[0][0] = -1; b->value[0][1] = 0.5; b->value[0][2] = 0; b->value[1][0] = 0.5; b->value[1][1] = -1; b->value[1][2] = 0.5; b->value[2][0] = 0.3333333; b->value[2][1] = 0.5; b->value[2][2] = -0.333333; for(int i = 0, k = 1; i < 3; i++) { for(int j = 0; j < 3; j++, k++) { if(k != 5) { a->value[i][j] = k; } else { // The matrix that has all the values from 1 to 9 in spiral // has no inverse, so I replaced the 5 with an four. a->value[i][j] = 4; } } } a->determinant = get_determinant(a); compute_inverse(a); mu_assert("The invers is not equal to the matrix b", compare_matrices( a->inverse, b)); destroy_matrix(a); destroy_matrix(b); return 0; }