void test1() { matrix *mx, *u, *v; dvector *w; NewMatrix(&mx, 4, 5); MatrixSet(mx, 0.f); mx->data[0][0] = 1; mx->data[0][4] = 2; mx->data[1][2] = 3; mx->data[3][1] = 4; PrintMatrix(mx); initMatrix(&u); initMatrix(&v); initDVector(&w); svd(mx, &u, &w, &v); puts("U"); PrintMatrix(u); puts("W"); PrintDVector(w); puts("V"); PrintMatrix(v); DelMatrix(&u); DelMatrix(&v); DelDVector(&w); DelMatrix(&mx); }
void Direct3DRender(HWND hwnd) { gPD3DDevice->Clear(0, nullptr, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0); gPD3DDevice->BeginScene(); InputUpdate(); MatrixSet(); RECT formatRect; GetClientRect(hwnd, &formatRect); for (int i = 0; i < gDwNumMtrl; i++) { gPD3DDevice->SetMaterial(&gPMaterial[i]); gPD3DDevice->SetTexture(0, gPTexture[i]); gPCharacter->DrawSubset(i); } int strLen = swprintf_s(gStrFPS, _T("FPS: %f"), 123.45f); gPTextFPSFont->DrawTextW(nullptr, gStrFPS, strLen, &formatRect, DT_TOP | DT_RIGHT, D3DCOLOR_XRGB(0, 239, 136)); strLen = sizeof(gStrAdapterDesc); gPTextAdapterFont->DrawTextW(nullptr, gStrAdapterDesc, -1, &formatRect, DT_TOP | DT_LEFT, D3DCOLOR_XRGB(23, 23, 236)); formatRect.top = 30; static wchar_t strInfo[256] = { 0 }; swprintf_s(strInfo, -1, L"模型坐标: (%.2f, %.2f, %.2f)", gMatWorld._41, gMatWorld._42, gMatWorld._43); gPTextHelperFont->DrawText(NULL, strInfo, -1, &formatRect, DT_SINGLELINE | DT_NOCLIP | DT_LEFT, D3DCOLOR_RGBA(135, 239, 136, 255)); formatRect.top = WINDOW_HEIGHT * 2 / 3; gPTextInfoFont->DrawTextW(nullptr, _T("控制说明:"), -1, &formatRect, DT_NOCLIP|DT_LEFT | DT_SINGLELINE, D3DCOLOR_XRGB(23, 25, 111)); formatRect.top += 35; formatRect.left += 50; gPTextHelperFont->DrawText(NULL, L"按住鼠标左键并拖动:平移模型", -1, &formatRect, DT_SINGLELINE | DT_NOCLIP | DT_LEFT, D3DCOLOR_RGBA(255, 200, 0, 255)); formatRect.top += 25; gPTextHelperFont->DrawText(NULL, L"按住鼠标右键并拖动:旋转模型", -1, &formatRect, DT_SINGLELINE | DT_NOCLIP | DT_LEFT, D3DCOLOR_RGBA(255, 200, 0, 255)); formatRect.top += 25; gPTextHelperFont->DrawText(NULL, L"滑动鼠标滚轮:拉伸模型", -1, &formatRect, DT_SINGLELINE | DT_NOCLIP | DT_LEFT, D3DCOLOR_RGBA(255, 200, 0, 255)); formatRect.top += 25; gPTextHelperFont->DrawText(NULL, L"W、S、A、D键:平移模型 ", -1, &formatRect, DT_SINGLELINE | DT_NOCLIP | DT_LEFT, D3DCOLOR_RGBA(255, 200, 0, 255)); formatRect.top += 25; gPTextHelperFont->DrawText(NULL, L"上、下、左、右方向键:旋转模型 ", -1, &formatRect, DT_SINGLELINE | DT_NOCLIP | DT_LEFT, D3DCOLOR_RGBA(255, 200, 0, 255)); formatRect.top += 25; gPTextHelperFont->DrawText(NULL, L"ESC键 : 退出程序", -1, &formatRect, DT_SINGLELINE | DT_NOCLIP | DT_LEFT, D3DCOLOR_RGBA(255, 200, 0, 255)); gPD3DDevice->EndScene(); gPD3DDevice->Present(nullptr, nullptr, nullptr, nullptr); }
/* last column must be an integer column which define the classes */ void LDA(matrix *mx, uivector *y, LDAMODEL *lda) { size_t i, j, l, k, cc, imin, imax; array *classes; array *S; matrix *X, *X_T, *Sb, *Sw, *InvSw_Sb; dvector *mutot; dvector *classmu; dvector *evect_, *ldfeature; matrix *covmx; lda->nclass = 0; imin = imax = y->data[0]; for(i = 1; i < y->size; i++){ if(y->data[i] > imax){ imax = y->data[i]; } if(y->data[i] < imin){ imin = y->data[i]; } } /* get the number of classes */ if(imin == 0){ lda->class_start = 0; lda->nclass = imax + 1; } else{ lda->class_start = 1; lda->nclass = imax; } /*printf("nclass %d\n", (int)lda->nclass);*/ /* Copy data */ NewMatrix(&X, mx->row, mx->col); MatrixCopy(mx, &X); MatrixCheck(X); /* for(j = 0; j < mx->col-1; j++){ for(i = 0; i < mx->row; i++){ X->data[i][j] = mx->data[i][j]; } } */ /*create classes of objects */ NewArray(&classes, lda->nclass); UIVectorResize(&lda->classid, mx->row); j = 0; if(imin == 0){ for(k = 0; k < lda->nclass; k++){ cc = 0; for(i = 0; i < X->row; i++){ if(y->data[i] == k) cc++; else continue; } NewArrayMatrix(&classes, k, cc, X->col); cc = 0; for(i = 0; i < X->row; i++){ if(y->data[i] == k){ for(l = 0; l < X->col; l++){ classes->m[k]->data[cc][l] = X->data[i][l]; } lda->classid->data[j] = i; j++; cc++; } else{ continue; } } } } else{ for(k = 0; k < lda->nclass; k++){ cc = 0; for(i = 0; i < X->row; i++){ if(y->data[i] == k+1) cc++; else continue; } NewArrayMatrix(&classes, k, cc, X->col); cc = 0; for(i = 0; i < X->row; i++){ if(y->data[i] == k+1){ for(l = 0; l < X->col; l++){ classes->m[k]->data[cc][l] = X->data[i][l]; } lda->classid->data[j] = i; j++; cc++; } else{ continue; } } } } /*puts("Classes"); PrintArray(classes);*/ /* Compute the prior probability */ for(k = 0; k < classes->order; k++){ DVectorAppend(&lda->pprob, (classes->m[k]->row/(double)X->row)); } /* puts("Prior Probability"); PrintDVector(lda->pprob); */ /*Compute the mean of each class*/ for(k = 0; k < classes->order; k++){ initDVector(&classmu); MatrixColAverage(classes->m[k], &classmu); MatrixAppendRow(&lda->mu, classmu); DelDVector(&classmu); } /*puts("Class Mu"); FindNan(lda->mu); PrintMatrix(lda->mu);*/ /*Calculate the total mean of samples..*/ initDVector(&mutot); MatrixColAverage(X, &mutot); /*puts("Mu tot"); PrintDVector(mutot);*/ /*NewDVector(&mutot, mu->col); for(k = 0; k < mu->row; k++){ for(i = 0; i < mu->col; i++){ mutot->data[i] += mu->data[k][i]; } } for(i = 0; i < mutot->size; i++){ mutot->data[i] /= nclasses; }*/ /*Centering data before computing the scatter matrix*/ for(k = 0; k < classes->order; k++){ for(i = 0; i < classes->m[k]->row; i++){ for(j = 0; j < classes->m[k]->col; j++){ classes->m[k]->data[i][j] -= mutot->data[j]; } } } /* puts("Classes"); for(i = 0; i < classes->order; i++){ FindNan(classes->m[i]); } PrintArray(classes); */ /*Compute the scatter matrix * S = nobj - 1 * covmx */ initArray(&S); NewMatrix(&covmx, X->col, X->col); for(k = 0; k < classes->order; k++){ matrix *m_T; NewMatrix(&m_T, classes->m[k]->col, classes->m[k]->row); MatrixTranspose(classes->m[k], m_T); MatrixDotProduct(m_T, classes->m[k], covmx); for(i = 0; i < covmx->row; i++){ for(j = 0; j < covmx->col; j++){ covmx->data[i][j] /= classes->m[k]->row; } } ArrayAppendMatrix(&S, covmx); MatrixSet(covmx, 0.f); DelMatrix(&m_T); } /* puts("Scatter Matrix"); for(i = 0; i < S->order; i++) FindNan(S->m[i]); PrintArray(S);*/ /* Compute the class scatter which represent the covariance matrix */ NewMatrix(&Sw, X->col, X->col); for(k = 0; k < S->order; k++){ for(i = 0; i < S->m[k]->row; i++){ for(j = 0; j < S->m[k]->col; j++){ Sw->data[i][j] += (double)(classes->m[k]->row/(double)X->row) * S->m[k]->data[i][j]; } } } /* puts("Class scatter matrix Sw"); FindNan(Sw); PrintMatrix(Sw); */ /*Compute the between class scatter matrix Sb*/ NewMatrix(&Sb, X->col, X->col); for(k = 0; k < lda->mu->row; k++){ /*for each class of object*/ cc = classes->m[k]->row; for(i = 0; i < Sb->row; i++){ for(j = 0; j < Sb->col; j++){ Sb->data[i][j] += cc * (lda->mu->data[k][i] - mutot->data[i]) * (lda->mu->data[k][j] - mutot->data[j]); } } } /* puts("Between class scatter matrix Sb"); FindNan(Sb); PrintMatrix(Sb); */ /* Computing the LDA projection */ /*puts("Compute Matrix Inversion");*/ MatrixInversion(Sw, &lda->inv_cov); double ss = 0.f; for(i = 0; i < lda->inv_cov->row; i++){ for(j = 0; j < lda->inv_cov->col; j++){ ss += square(lda->inv_cov->data[i][j]); } if(_isnan_(ss)) break; } if(FLOAT_EQ(ss, 0.f, EPSILON) || _isnan_(ss)){ /*Do SVD as pseudoinversion accordin to Liu et al. because matrix is nonsingular * * JUN LIU et al, Int. J. Patt. Recogn. Artif. Intell. 21, 1265 (2007). DOI: 10.1142/S0218001407005946 * EFFICIENT PSEUDOINVERSE LINEAR DISCRIMINANT ANALYSIS AND ITS NONLINEAR FORM FOR FACE RECOGNITION * * * Sw`^-1 = Q * G^-1 * Q_T * Q G AND Q_T come from SVD */ MatrixPseudoinversion(Sw, &lda->inv_cov); /* NewMatrix(&A_T, Sw->col, Sw->row); MatrixInversion(Sw, &A_T); NewMatrix(&A_T_Sw, A_T->row, Sw->col); MatrixDotProduct(A_T, Sw, A_T_Sw); initMatrix(&A_T_Sw_inv); MatrixInversion(A_T_Sw, &A_T_Sw_inv); MatrixDotProduct(A_T_Sw_inv, A_T, lda->inv_cov); DelMatrix(&A_T); DelMatrix(&A_T_Sw); DelMatrix(&A_T_Sw_inv); */ } /*puts("Inverted Covariance Matrix from Sw"); FindNan(lda->inv_cov); PrintMatrix(lda->inv_cov); */ /*puts("Compute Matrix Dot Product");*/ NewMatrix(&InvSw_Sb, lda->inv_cov->row, Sb->col); MatrixDotProduct(lda->inv_cov, Sb, InvSw_Sb); /*puts("InvSw_Sb"); PrintMatrix(InvSw_Sb);*/ /*puts("Compute Eigenvectors");*/ EVectEval(InvSw_Sb, &lda->eval, &lda->evect); /*EvectEval3(InvSw_Sb, InvSw_Sb->row, &lda->eval, &lda->evect);*/ /*EVectEval(InvSw_Sb, &lda->eval, &lda->evect); */ /* Calculate the new projection in the feature space * * and the multivariate normal distribution */ /* Remove centering data */ for(k = 0; k < classes->order; k++){ for(i = 0; i < classes->m[k]->row; i++){ for(j = 0; j < classes->m[k]->col; j++){ classes->m[k]->data[i][j] += mutot->data[j]; } } } initMatrix(&X_T); for(k = 0; k < classes->order; k++){ /*printf("row %d col %d\n", (int)classes->m[k]->row, (int)classes->m[k]->col);*/ AddArrayMatrix(&lda->features, classes->m[k]->row, classes->m[k]->col); AddArrayMatrix(&lda->mnpdf, classes->m[k]->row, classes->m[k]->col); } NewDVector(&evect_, lda->evect->row); initDVector(&ldfeature); ResizeMatrix(&lda->fmean, classes->order, lda->evect->col); ResizeMatrix(&lda->fsdev, classes->order, lda->evect->col); for(l = 0; l < lda->evect->col; l++){ for(i = 0; i < lda->evect->row; i++){ evect_->data[i] = lda->evect->data[i][l]; } for(k = 0; k < classes->order; k++){ ResizeMatrix(&X_T, classes->m[k]->col, classes->m[k]->row); MatrixTranspose(classes->m[k], X_T); DVectorResize(&ldfeature, classes->m[k]->row); DVectorMatrixDotProduct(X_T, evect_, ldfeature); for(i = 0; i < ldfeature->size; i++){ lda->features->m[k]->data[i][l] = ldfeature->data[i]; } /* Calculate the multivariate normal distribution */ double mean = 0.f, sdev = 0.f; DVectorMean(ldfeature, &mean); DVectorSDEV(ldfeature, &sdev); lda->fmean->data[k][l] = mean; lda->fsdev->data[k][l] = sdev; for(i = 0; i < ldfeature->size; i++){ lda->mnpdf->m[k]->data[i][l] = 1./sqrt(2 * pi* sdev) * exp(-square((ldfeature->data[i] - mean)/sdev)/2.f); } } } DelDVector(&evect_); DelMatrix(&covmx); DelDVector(&ldfeature); DelDVector(&mutot); DelMatrix(&Sb); DelMatrix(&InvSw_Sb); DelArray(&classes); DelArray(&S); DelMatrix(&Sw); DelMatrix(&X_T); DelMatrix(&X); }
void *LDARandomGroupCVModel(void *arg_) { size_t i, j, k, n, g; lda_rgcv_th_arg *arg; matrix *gid; /* randomization and storing id for each random group into a matrix */ /* Matrix for compute the PLS models for groups */ matrix *subX; uivector *subY; LDAMODEL *subm; /*matrix to predict*/ matrix *predictX; uivector *realY; dvector *sens, *spec, *ppv, *npv, *acc; initDVector(&sens); initDVector(&spec); initDVector(&ppv); initDVector(&npv); initDVector(&acc); arg = (lda_rgcv_th_arg*) arg_; NewMatrix(&gid, arg->group, (size_t)ceil(arg->mx->row/(double)arg->group)); /* Divide in group all the Dataset */ MatrixSet(gid, -1); /* step 1 generate the random groups */ k = 0; for(i = 0; i < gid->row; i++){ for(j = 0; j < gid->col; j++){ do{ /*n = randInt(0, arg->mx->row);*/ n = (size_t)myrand_r(&arg->srand_init) % (arg->mx->row); } while(ValInMatrix(gid, n) == 1 && k < (arg->mx->row)); if(k < arg->mx->row){ gid->data[i][j] = n; k++; } else continue; } } /* puts("Gid Matrix"); PrintMatrix(gid); */ /* printf("Excuded the group number %u\n", (unsigned int)g); puts("Sub Model\nX:"); PrintArray(subX); puts("Y:"); PrintArray(subY); puts("\n\nPredict Group\nX:"); PrintArray(predictX); puts("RealY:"); PrintArray(realY); */ /*step 2*/ for(g = 0; g < gid->row; g++){ /*For aeach group */ /* Estimate how many objects are inside the sub model without the group "g" */ n = 0; for(i = 0; i < gid->row; i++){ if(i != g){ for(j = 0; j < gid->col; j++){ if((int)gid->data[i][j] != -1) n++; else continue; } } else continue; } /*Allocate the submodel*/ NewMatrix(&subX, n, arg->mx->col); NewUIVector(&subY, n); /* Estimate how many objects are inside the group "g" to predict*/ n = 0; for(j = 0; j < gid->col; j++){ if((int)gid->data[g][j] != -1) n++; else continue; } /*Allocate the */ NewMatrix(&predictX, n, arg->mx->col); NewUIVector(&realY, n); /* copy the submodel values */ for(i = 0, k = 0; i < gid->row; i++){ if(i != g){ for(j = 0; j < gid->col; j++){ size_t a = (size_t)gid->data[i][j]; /* get the row index */ if(a != -1){ for(n = 0; n < arg->mx->col; n++){ /*setMatrixValue(subX, k, n, getMatrixValue(arg->mx, a, n));*/ subX->data[k][n] = arg->mx->data[a][n]; } subY->data[k] = arg->my->data[a]; k++; } else{ continue; } } } else{ continue; } } /* copy the objects to predict into predictmx*/ for(j = 0, k = 0; j < gid->col; j++){ size_t a = (size_t)gid->data[g][j]; if(a != -1){ for(n = 0; n < arg->mx->col; n++){ predictX->data[k][n] = arg->mx->data[a][n]; } realY->data[k] = arg->my->data[a]; k++; } else{ continue; } } NewLDAModel(&subm); LDA(subX, subY, subm); LDAError(predictX, realY, subm, &sens, &spec, &ppv, &npv, &acc); if(arg->sens->size == 0){ DVectorCopy(sens, &arg->sens); } else{ for(i = 0; i < sens->size; i++){ arg->sens->data[i] += sens->data[i]; } } if(arg->spec->size == 0){ DVectorCopy(spec, &arg->spec); } else{ for(i = 0; i < spec->size; i++){ arg->spec->data[i] += spec->data[i]; } } if(arg->ppv->size == 0){ DVectorCopy(ppv, &arg->ppv); } else{ for(i = 0; i < ppv->size; i++){ arg->ppv->data[i] += ppv->data[i]; } } if(arg->npv->size == 0){ DVectorCopy(npv, &arg->npv); } else{ for(i = 0; i < npv->size; i++){ arg->npv->data[i] += npv->data[i]; } } if(arg->acc->size == 0){ DVectorCopy(acc, &arg->acc); } else{ for(i = 0; i < acc->size; i++){ arg->acc->data[i] += acc->data[i]; } } DelLDAModel(&subm); DelMatrix(&subX); DelUIVector(&subY); DelMatrix(&predictX); DelUIVector(&realY); } DelDVector(&acc); DelDVector(&sens); DelDVector(&spec); DelDVector(&ppv); DelDVector(&npv); DelMatrix(&gid); return 0; }
void Direct3DRender(HWND hwnd) { RECT formatRect; GetClientRect(hwnd, &formatRect); gPD3DDevice->Clear(0, nullptr, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0, 30), 1.0f, 0.0f); gPD3DDevice->BeginScene(); MatrixSet(); WCHAR str[50]; int strCount = swprintf_s(str, _T("Mat, Mesh & Light!")); gPFont->DrawTextW(nullptr, str, strCount, &formatRect, DT_TOP| DT_RIGHT, D3DCOLOR_XRGB(25, 134, 111)); D3DXMATRIX Ry; D3DXMatrixRotationY(&Ry, timeGetTime() / 1000.0f); D3DXMATRIX teaPotWorldTrans; D3DXMatrixTranslation(&teaPotWorldTrans, 2.5f, 2.5f, 2.5f); D3DXMATRIX Sa; D3DXMatrixScaling(&Sa, 2.0f, 2.0f, 2.0f); teaPotWorldTrans = teaPotWorldTrans * Ry * Sa; gPD3DDevice->SetTransform(D3DTS_WORLD, &teaPotWorldTrans); D3DMATERIAL9 material; ZeroMemory(&material, sizeof(material)); material.Ambient = D3DXCOLOR(0.5f, 0.5f, 0.7f, 1.0f); material.Diffuse = D3DXCOLOR(0.4f, 0.6f, 0.6f, 1.0f); material.Specular = D3DXCOLOR(0.3f, 0.3f, 0.3f, 0.3f); material.Emissive = D3DXCOLOR(0.3f, 0.0f, 0.1f, 1.0f); gPD3DDevice->SetMaterial(&material); gPTeapot->DrawSubset(0); D3DXMATRIX boxWorldTrans; D3DXMatrixTranslation(&boxWorldTrans, -5.0f, 5.0f, 5.0f); boxWorldTrans *= Ry; gPD3DDevice->SetTransform(D3DTS_WORLD, &boxWorldTrans); ZeroMemory(&material, sizeof(material)); material.Ambient = D3DXCOLOR(0.3f, 0.1f, 0.5f, 1.0f); material.Diffuse = D3DXCOLOR(0.4f, 0.6f, 0.6f, 1.0f); material.Specular = D3DXCOLOR(0.3f, 0.3f, 0.3f, 1.3f); material.Emissive = D3DXCOLOR(0.3f, 0.0f, 0.1f, 1.0f); gPD3DDevice->SetMaterial(&material); gPBox->DrawSubset(0); D3DXMATRIX torusWorldTrans; D3DXMatrixTranslation(&torusWorldTrans, 5.0f, -5.0f, 5.0f); torusWorldTrans *= Ry; gPD3DDevice->SetTransform(D3DTS_WORLD, &torusWorldTrans); ZeroMemory(&material, sizeof(material)); material.Ambient = D3DXCOLOR(0.5f, 0.2f, 0.3f, 1.0f); material.Diffuse = D3DXCOLOR(0.6f, 0.2f, 0.4f, 1.0f); material.Specular = D3DXCOLOR(0.3f, 0.3f, 0.3f, 0.3f); material.Emissive = D3DXCOLOR(0.3f, 0.0f, 0.1f, 1.0f); gPD3DDevice->SetMaterial(&material); gPTorus->DrawSubset(0); D3DXMATRIX sphereWorldTrans; D3DXMatrixTranslation(&sphereWorldTrans, -5.0f, -5.0f, 5.0f); sphereWorldTrans *= Ry; gPD3DDevice->SetTransform(D3DTS_WORLD, &sphereWorldTrans); ZeroMemory(&material, sizeof(material)); material.Ambient = D3DXCOLOR(0.9f, 0.1f, 0.9f, 1.0f); material.Diffuse = D3DXCOLOR(0.3f, 0.6f, 0.8f, 1.0f); material.Specular = D3DXCOLOR(0.3f, 0.3f, 0.3f, 0.3f); material.Emissive = D3DXCOLOR(0.9f, 0.4f, 0.7f, 1.0f); gPD3DDevice->SetMaterial(&material); gPSphere->DrawSubset(0); LightSet(gPD3DDevice, 1); gPD3DDevice->EndScene(); gPD3DDevice->Present(nullptr, nullptr, nullptr, nullptr); }
void ArraySet(array* t, double val) { size_t i; for(i = 0; i < t->order; i++) MatrixSet(t->m[i], val); }