void mtxmul_eye_tests(float32_t eps) { float32_t errf; ambix_matrix_t *left, *result, *eye; STARTTEST(""); eye=ambix_matrix_init(4, 4, NULL); fail_if((eye!=ambix_matrix_fill(eye, AMBIX_MATRIX_IDENTITY)), __LINE__, "filling unity matrix %p did not return original matrix %p", eye); left=ambix_matrix_init(4, 2, NULL); fail_if(AMBIX_ERR_SUCCESS!=ambix_matrix_fill_data(left, resultdata_4_2), __LINE__, "filling left data failed"); result=ambix_matrix_init(4, 2, NULL); fail_if(AMBIX_ERR_SUCCESS!=ambix_matrix_fill_data(result, resultdata_4_2), __LINE__, "filling result data failed"); fail_if((result!=ambix_matrix_multiply(eye, left, result)), __LINE__, "multiplication into matrix did not return original matrix"); #if 0 matrix_print(eye); matrix_print(result); matrix_print(left); #endif errf=matrix_diff(__LINE__, left, result, eps); fail_if((errf>eps), __LINE__, "diffing matrix M with E*M returned %f (>%f)", errf, eps); ambix_matrix_destroy(left); ambix_matrix_destroy(result); ambix_matrix_destroy(eye); }
void mtxmul_tests(float32_t eps) { float32_t errf; ambix_matrix_t *left=NULL, *right=NULL, *result, *testresult; STARTTEST("\n"); /* fill in some test data */ left=ambix_matrix_init(4, 3, NULL); ambix_matrix_fill_data(left, leftdata_4_3); right=ambix_matrix_init(3, 2, NULL); ambix_matrix_fill_data(right, rightdata_3_2); testresult=ambix_matrix_init(4, 2, NULL); ambix_matrix_fill_data(testresult, resultdata_4_2); errf=matrix_diff(__LINE__, left, left, eps); fail_if(!(errf<eps), __LINE__, "diffing matrix with itself returned %f (>%f)", errf, eps); /* NULL multiplications */ result=ambix_matrix_multiply(NULL, NULL, NULL); fail_if(NULL!=result, __LINE__, "multiplying NULL*NULL returned success"); result=ambix_matrix_multiply(left, NULL, result); fail_if(NULL!=result, __LINE__, "multiplying left*NULL returned success"); result=ambix_matrix_multiply(NULL, left, result); fail_if(NULL!=result, __LINE__, "multiplying NULL*left returned success"); /* do some matrix multiplication */ result=ambix_matrix_multiply(left, right, NULL); fail_if((NULL==result), __LINE__, "multiply into NULL did not create matrix"); fail_if((result!=ambix_matrix_multiply(left, right, result)), __LINE__, "multiply into existing matrix returned new matrix"); #if 0 matrix_print(left); matrix_print(right); matrix_print(result); printf("------------\n"); #endif errf=matrix_diff(__LINE__, testresult, result, eps); fail_if((errf>eps), __LINE__, "diffing two results of same multiplication returned %f (>%f)", errf, eps); ambix_matrix_destroy(left); ambix_matrix_destroy(right); ambix_matrix_destroy(result); ambix_matrix_destroy(testresult); STOPTEST("\n"); }
static void mtxinverse_test(const ambix_matrix_t *mtx, const ambix_matrix_t *result, float32_t eps) { ambix_matrix_t *pinv = 0; ambix_matrix_t *mul=0; ambix_matrix_t *eye=0; float32_t errf; int min_rowcol=(mtx->cols<mtx->rows)?mtx->cols:mtx->rows; fail_if((NULL==mtx), __LINE__, "cannot invert NULL-matrix"); eye=ambix_matrix_init(min_rowcol, min_rowcol, eye); eye=ambix_matrix_fill(eye, AMBIX_MATRIX_IDENTITY); fail_if((NULL==eye), __LINE__, "cannot create eye-matrix for pinv-verification"); pinv=ambix_matrix_pinv(mtx, pinv); if(NULL==pinv)matrix_print(mtx); fail_if((NULL==pinv), __LINE__, "could not invert matrix"); if(mtx->cols < mtx->rows) mul=ambix_matrix_multiply(pinv, mtx, 0); else mul=ambix_matrix_multiply(mtx, pinv, 0); #if 0 matrix_print(mtx); matrix_print(pinv); matrix_print(mul); if(result)matrix_print(result); printf("------------\n"); #endif if(result) { errf=matrix_diff(__LINE__, pinv, result, eps); fail_if((errf>eps), __LINE__, "diffing (pseudo)inverse returned %g (>%g)", errf, eps); errf=matrix_diff(__LINE__, mul, eye, eps); fail_if((errf>eps), __LINE__, "diffing mtx*pinv(mtx) returned %g (>%g)", errf, eps); } else { errf=matrix_diff(__LINE__, mul, eye, eps); fail_if((!(isnan(errf) || isinf(errf) || (errf>eps))), __LINE__, "diffing invalid mtx*pinv(mtx) returned %g (!>%g)", errf, eps); } ambix_matrix_destroy(pinv); ambix_matrix_destroy(mul); ambix_matrix_destroy(eye); }
ambix_matrix_t*inverse_matrices(ambix_matrixtype_t typ, uint32_t rows, uint32_t cols) { ambix_matrixtype_t pyt = (ambix_matrixtype_t)(AMBIX_MATRIX_TO_AMBIX | typ); ambix_matrix_t*mtx=ambix_matrix_init(rows, cols, NULL); ambix_matrix_t*xtm=ambix_matrix_init(cols, rows, NULL); ambix_matrix_t*a2f=ambix_matrix_fill(mtx, typ); ambix_matrix_t*f2a=ambix_matrix_fill(xtm, pyt); // ambix_matrix_t*result=ambix_matrix_multiply(a2f, f2a, NULL); ambix_matrix_t*result=ambix_matrix_multiply(f2a, a2f, NULL); if(a2f!=mtx) ambix_matrix_destroy(a2f); ambix_matrix_destroy(mtx); if(f2a!=xtm) ambix_matrix_destroy(f2a); ambix_matrix_destroy(xtm); return result; }
ambix_err_t ambix_set_adaptormatrix (ambix_t*ambix, const ambix_matrix_t*matrix) { if(0) { } else if((ambix->filemode & AMBIX_READ ) && (AMBIX_BASIC == ambix->info.fileformat)) { ambix_matrix_t*mtx=NULL; /* multiply the matrix with the previous adaptor matrix */ if(AMBIX_EXTENDED == ambix->realinfo.fileformat) { mtx=ambix_matrix_multiply(matrix, &ambix->matrix, &ambix->matrix2); if(mtx != &ambix->matrix2) return AMBIX_ERR_UNKNOWN; ambix->use_matrix=2; return AMBIX_ERR_SUCCESS; } else { if(matrix->cols != ambix->realinfo.ambichannels) { return AMBIX_ERR_INVALID_DIMENSION; } mtx=ambix_matrix_copy(matrix, &ambix->matrix2); ambix->use_matrix=2; } } else if((ambix->filemode & AMBIX_WRITE) && (AMBIX_EXTENDED == ambix->info.fileformat)) { /* too late, writing started already */ if(ambix->startedWriting) return AMBIX_ERR_UNKNOWN; /* check whether the matrix will expand to a full set */ if(!ambix_is_fullset(matrix->rows)) return AMBIX_ERR_INVALID_DIMENSION; if(!ambix_matrix_copy(matrix, &ambix->matrix)) return AMBIX_ERR_UNKNOWN; /* ready to write it to file */ ambix->pendingHeaders=1; return AMBIX_ERR_SUCCESS; } return AMBIX_ERR_UNKNOWN; }