Beispiel #1
0
//todo put convergence into one function
structmatrix conjugategradient(structmatrix *A,structmatrix *b){
 const unsigned int MAXITER=100;
  const MATDOUBLE TOL=1e-6;
  MATDOUBLE *xp=calloc(A->nrows,sizeof(MATDOUBLE));//init guess 0s
  MATDOUBLE *x= malloc(A->nrows*sizeof(MATDOUBLE));//
  structmatrix XP=creatematrix(xp
			       ,A->nrows,1//solns in col vector
			       ,endt(MATDOUBLE),rowmjr);
  structmatrix X=creatematrix(x
			      ,A->nrows,1//solns in col vector
			      ,endt(MATDOUBLE),rowmjr);
  structmatrix rP=copymatrix(b); //previous error
  structmatrix pP=copymatrix(b); //CG vec
  structmatrix r=creatematrix(malloc(sizeof(MATDOUBLE)*rP.nrows)
			      ,rP.nrows,1
			      ,endt(MATDOUBLE),rowmjr);
  structmatrix p=creatematrix(malloc(sizeof(MATDOUBLE)*pP.nrows)
			      ,pP.nrows,1
			      ,endt(MATDOUBLE),rowmjr);
  fpidx idxA= getidxingfunc( A);
  fpidx idxb= getidxingfunc( b);
  fpidx idxX= getidxingfunc(&X);
  fpidx idxXP=getidxingfunc(&XP);
  fpidx idxrP=getidxingfunc(&rP);
  fpidx idxpP=getidxingfunc(&pP);
  fpidx idxr =getidxingfunc(&r );
  fpidx idxp =getidxingfunc(&p );
#define Xv(ri,ci)  *(double*)  idxX( &ri,&ci,&X)
#define XPv(ri,ci)  *(double*) idxXP(&ri,&ci,&XP)
#define Av(ri,ci)  *(double*)  idxA( &ri,&ci, A)
#define bv(ri,ci)  *(double*)  idxb( &ri,&ci, b)
#define rPv(ri,ci) *(double*)  idxrP( &ri,&ci, &rP)
#define pPv(ri,ci)  *(double*)  idxb( &ri,&ci, &pP)
#define rv(ri,ci)  *(double*)  idxA(  &ri,&ci, &r)
#define pv(ri,ci)  *(double*)  idxb( &ri,&ci,  &p)

  //result definition
#define ApPv(ri,ci) *(double*) idxApP(&ri,&ci,&ApP)

 unsigned int zero=0;

  unsigned int k=0;
  while(k<MAXITER){ 
    double alpha, beta;//scalars to compute in each interatin

    structmatrix rPT=(vecT(&rP)),pPT=vecT(&pP);
    structmatrix rPTrP=matrixmatrixmuldbl(&rPT,&rP);//1x1
    structmatrix ApP=matrixmatrixmuldbl(A,&pP);// vec nrows
    fpidx idxApP =getidxingfunc(&ApP);
    double alphan=*(double*) rPTrP.data;
    double alphad=*(double*) (matrixmatrixmuldbl(&pPT,&ApP)).data;
    alpha=alphan/alphad;//alpha new
    unsigned int ri;
    for(ri=0;ri<XP.nrows;ri++){
      Xv(ri,zero)=XPv(ri,zero)+alpha*pPv(ri,zero); //new x approx soln
      rv(ri,zero)=rPv(ri,zero)-alpha*ApPv(ri,zero);//new r error
    }
    structmatrix rT=vecT(&r);
    structmatrix rTr=matrixmatrixmuldbl(&rT,&r);
    beta=(*(double*) rTr.data)/(*(double*) rPTrP.data); //scalar/scalar
    for(ri=0;ri<p.nrows;ri++){
      pv(ri,zero)=rv(ri,zero)+beta*pPv(ri,zero);
    }
    double normofr=0;
    for(ri=0;ri<X.nrows;ri++){normofr+=pow(rv(ri,zero),2);}
    normofr=pow(normofr,.5);

    if(normofr<TOL){printf("converged\n in %d iterations\n",k+1);return X;}

    //previous=current
    for(ri=0;ri<X.nrows;ri++){
      XPv(ri,zero)=Xv(ri,zero);
      pPv(ri,zero)=pv(ri,zero);
      rPv(ri,zero)=rv(ri,zero);
    }

    /* todo does not work if i add these free statements
       does the memory get freed with each loop? i thought it would not!*/
    /*
    free(rPT.data);
    free(rPTrP.data);
    free(ApP.data);
    free(rT.data);
    free(rTr.data);
    */
    k++;}


   
  
  free(XP.data);
  free(rP.data);
  free(pP.data);
  free(r.data);
  free(p.data); 
  return X;
#undef Xv
#undef XPv
#undef Av
#undef bv
#undef rPv
#undef pPv
#undef rv
#undef pv
#undef ApPv
}
Beispiel #2
0
//-----------------------------------------------------------------------------
// Name: FrameMove
// Desc:
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::FrameMove()
{
    HRESULT hr;

    //
    // Process keyboard input
    //

    D3DXVECTOR3 vecT(0.0f, 0.0f, 0.0f);
    D3DXVECTOR3 vecR(0.0f, 0.0f, 0.0f);

    if(m_bKey[VK_NUMPAD1] || m_bKey[VK_LEFT])  vecT.x -= 1.0f; // Slide Left
    if(m_bKey[VK_NUMPAD3] || m_bKey[VK_RIGHT]) vecT.x += 1.0f; // Slide Right
    if(m_bKey[VK_DOWN])                        vecT.y -= 1.0f; // Slide Down
    if(m_bKey[VK_UP])                          vecT.y += 1.0f; // Slide Up
    if(m_bKey['W'])                            vecT.z -= 2.0f; // Move Forward
    if(m_bKey['S'])                            vecT.z += 2.0f; // Move Backward
    if(m_bKey['A'] || m_bKey[VK_NUMPAD8])      vecR.x -= 1.0f; // Pitch Down
    if(m_bKey['Z'] || m_bKey[VK_NUMPAD2])      vecR.x += 1.0f; // Pitch Up
    if(m_bKey['E'] || m_bKey[VK_NUMPAD6])      vecR.y -= 1.0f; // Turn Right
    if(m_bKey['Q'] || m_bKey[VK_NUMPAD4])      vecR.y += 1.0f; // Turn Left
    if(m_bKey[VK_NUMPAD9])                     vecR.z -= 2.0f; // Roll CW
    if(m_bKey[VK_NUMPAD7])                     vecR.z += 2.0f; // Roll CCW

    m_vecVelocity = m_vecVelocity * 0.9f + vecT * 0.1f;
    m_vecAngularVelocity = m_vecAngularVelocity * 0.9f + vecR * 0.1f;



    //
    // Update position and view matricies
    //

    D3DXMATRIX matT, matR;
    D3DXQUATERNION qR;

    vecT = m_vecVelocity * m_fElapsedTime * m_fSpeed;
    vecR = m_vecAngularVelocity * m_fElapsedTime * m_fAngularSpeed;

    D3DXMatrixTranslation(&matT, vecT.x, vecT.y, vecT.z);
    D3DXMatrixMultiply(&m_matPosition, &matT, &m_matPosition);

    D3DXQuaternionRotationYawPitchRoll(&qR, vecR.y, vecR.x, vecR.z);
    D3DXMatrixRotationQuaternion(&matR, &qR);

    D3DXMatrixMultiply(&m_matPosition, &matR, &m_matPosition);
    D3DXMatrixInverse(&m_matView, NULL, &m_matPosition);


    //
    // Update simulation
    //

    if(!m_bPause && m_bDrawWater)
    {
        BOOL bCaustics = m_bDrawCaustics && m_pEffect->IsParameterUsed("tCAU");
        D3DXVECTOR3 vecPos(m_matPosition._41, m_matPosition._42, m_matPosition._43);
        D3DXVECTOR3 vecLight(0.0f, 1.0f, 0.0f);

        m_Water.Update(vecPos, vecLight, bCaustics);
        m_fTime += m_fSecsPerFrame;

        if(bCaustics)
        {
            if(SUCCEEDED(m_pRenderToSurface->BeginScene(m_pCausticSurf, NULL)))
            {
                D3DXMATRIX matProj;
                D3DXMATRIX matView;

                D3DXMatrixOrthoRH(&matProj, 63.0f, 63.0f, 1.0f, 100.0f);
                D3DXMatrixRotationX(&matView, 0.5f * D3DX_PI);
                matView._43 = -50.0f;

                m_pd3dDevice->SetTransform(D3DTS_PROJECTION, &matProj);
                m_pd3dDevice->SetTransform(D3DTS_VIEW, &matView);

                m_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0f, 0);

                m_pd3dDevice->SetRenderState(D3DRS_ZENABLE, FALSE);
                m_pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
                m_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);

                m_Water.DrawCaustics();

                m_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
                m_pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW);
                m_pd3dDevice->SetRenderState(D3DRS_ZENABLE, TRUE);

                m_pRenderToSurface->EndScene();
            }
            else
            {
                m_bDrawCaustics = FALSE;
                m_pEffect->SetTexture("tCAU", NULL);

                if(FAILED(hr = GetNextTechnique(0, FALSE)))
                    return hr;
            }
        }
    }

    return S_OK;
}