Beispiel #1
0
int main(int argc, char** argv)
{
    printf("--------verify--------\n");
    verify_matrix();
    printf("----------------------\n");

    // autorelease関数をbeginとendにはさまないで使うのはNG
    // 全てのallocされた関数は
    // (1) free
    // (2) release
    // (3) begin-endの中でautorelease
    // のいずれかを行う必要がある。
    
    // 擬似逆行列演算がこれくらい簡単に記述できる。
    
    /* 3*2行列aを確保、成分ごとの代入 */
    matrix_t* a = matrix_alloc(3, 2);
    ELEMENT(a, 0, 0) = 1; ELEMENT(a, 0, 1) = 4;
    ELEMENT(a, 1, 0) = 2; ELEMENT(a, 1, 1) = 5;
    ELEMENT(a, 2, 0) = 3; ELEMENT(a, 2, 1) = 6;

    /* 擬似逆行列の演算 */
    // auto releaseモードに入る
    matrix_begin(); 
    // 擬似逆行列を求める。一行だけ!
    matrix_t* inva = matrix_product(matrix_inverse(matrix_product(matrix_transpose(a), a)), matrix_transpose(a));
    // 擬似逆行列の表示 (invaはmatrix_endで解放されるので、begin-end内で。)
    matrix_print(inva);
    // release poolを開放する
    matrix_end();

    /* ちなみに擬似逆行列を求める関数は内部に組んだので、それを使うこともできる。 */
    // auto releaseモードに入る
    matrix_begin(); 
    // 擬似逆行列を求める関数を呼ぶ。
    matrix_t* inva_simple = matrix_pseudo_inverse(a);
    // 擬似逆行列の表示 (invaはmatrix_endで解放されるので、begin-end内で。)
    matrix_print(inva_simple);
    // release poolを開放する
    matrix_end();

    
    // これはautorelease対象でないので、しっかり自分でfree。
    // リテインカウントを実装してあるので、理解できればreleaseの方が高性能。
    //matrix_free(a);
    matrix_release(a);
 
    return 0;
}
Beispiel #2
0
void init_mat(void)
{
    matrix_begin();
    matrix_t* A = matrix_matrix(2, 2);
    ELEMENT(A, 0, 0) = 1.0; ELEMENT(A, 0, 0) = 3.0; 
    ELEMENT(A, 0, 0) = 2.0; ELEMENT(A, 0, 0) = 4.0; 
    sq_init_matrix(A);
    matrix_end();
}
Beispiel #3
0
// autorelease function
matrix_t* matrix_pseudo_inverse(matrix_t* m)
{
    if (m->rows == m->cols) {
        return matrix_inverse(m);
    } else if (m->rows > m->cols) {
        matrix_begin();
        // (A^T A)^{-1} A^T
        matrix_t* ret = matrix_product(matrix_inverse(matrix_product(matrix_transpose(m), m)),matrix_transpose(m));
        matrix_retain(ret);
        matrix_end();

        return matrix_autorelease(ret);
    } else {
        matrix_begin();
        // A^T (A A^T)^{-1} 
        matrix_t* ret = matrix_product(matrix_transpose(m), matrix_inverse(matrix_product(m, matrix_transpose(m))));
        matrix_retain(ret);
        matrix_end();

        return matrix_autorelease(ret);
    }
}
Beispiel #4
0
// autorelease function
matrix_t* matrix_inverse(matrix_t* m)
{
	if (m->rows != m->cols) {
        assert(0); // not a square matrix
    }
	
	int i, j;
	int maxi;
	int nrc;
	nrc = m->rows;
    matrix_t* minv = matrix_alloc(nrc, nrc);
    matrix_t* vtmp = matrix_alloc(1, nrc);

	float tmp;
	
    matrix_begin();
	matrix_t* mtmp = matrix_copy(m);
	for (i = 0; i < nrc * nrc; i++) {
		if (i / nrc == i % nrc) 
            ELEMENT(minv,i/nrc,i%nrc) = 1.0f;
		else
            ELEMENT(minv,i/nrc,i%nrc) = 0.0f;
	}

	if (mtmp == NULL || minv == NULL) 
        return NULL;
	
	for (i=0; i<nrc; i++) {
		maxi = i;
		for (j=i+1; j<nrc; j++) {
			if(ABS(ELEMENT(mtmp,maxi,i)) < ABS(ELEMENT(mtmp,j,i)))
				maxi = j;
		}
		if (ELEMENT(mtmp,maxi,i) == 0.0f) {
			printf("input matrix is invalid!\n");
			break;
		}
		
		// 行入れ替え
		matrix_copy_row(mtmp, i, vtmp, 0);
		matrix_copy_row(mtmp, maxi, mtmp, i);
		matrix_copy_row(vtmp, 0, mtmp, maxi);
		
		// 行入れ替え
		matrix_copy_row(minv, i, vtmp, 0);
		matrix_copy_row(minv, maxi, minv, i);
		matrix_copy_row(vtmp, 0, minv, maxi);
 
		tmp = ELEMENT(mtmp,i,i);

		for (j=0; j<nrc; j++) {
			// j:列番号
			ELEMENT(mtmp, i, j) = ELEMENT(mtmp, i, j)/tmp;
			ELEMENT(minv, i, j) = ELEMENT(minv, i, j)/tmp;
		}

		for (j=0; j<nrc; j++) {
			// j:行番号
			if	(i!=j) {
				tmp = ELEMENT(mtmp,j,i);
                matrix_row_linear_comb(-tmp, mtmp, i, 1.0f, mtmp, j, mtmp, j);
				matrix_row_linear_comb(-tmp, minv, i, 1.0f, minv, j, minv, j);
			}
		}
	}
	
    matrix_end();
	matrix_free(vtmp);

	return matrix_autorelease(minv);
}