Beispiel #1
0
/**
 @param[in] vetrices array of vetrices (so far only for 3)
 @param[in] E material constatn E
 @param[in] mi material constatn mi
 @param[in] fs volume force vector
 @param[out] stifMat stifness matrix (array 36 long)
 @param[out]
 */
void elastLoc(Point *vetrices[], PetscReal E, PetscReal mi, PetscReal *fs,
              PetscReal *stifMat, PetscReal *bL) {

    PetscReal
    T[] =
    { 1, 1, 1, vetrices[0]->x, vetrices[1]->x, vetrices[2]->x, vetrices[0]->y, vetrices[1]->y, vetrices[2]->y };

    PetscReal phiGrad[] = { vetrices[1]->y - vetrices[2]->y, vetrices[2]->x
                            - vetrices[1]->x, vetrices[2]->y - vetrices[0]->y, vetrices[0]->x
                            - vetrices[2]->x, vetrices[0]->y - vetrices[1]->y, vetrices[1]->x
                            - vetrices[0]->x
                          };

    //PetscPrintf(PETSC_COMM_SELF, "DET:%e \n", matrixDet(T, 3));

    PetscReal detT = fabs(matrixDet(T, 3));

    PetscReal phiGradT[6];
    matrixTranspose(phiGrad, 3, 2, phiGradT);

    double Cmu[] = { 2, 0, 0, 0, 2, 0, 0, 0, 1 };
    //double Clm[] = { 1, 1, 0, 1, 1, 0, 0, 0, 0 }; Why is this never used?
    PetscReal C[] = { 1 - mi, mi, 0, mi, 1 - mi, 0, 0, 0, (1 - 2 * mi) / 2 };

    matrixSum(C, E / ((1 + mi) * (1 - 2 * mi)), Cmu, 0, C, 3, 3);

    double R[18], RT[18];
    for (int i = 0; i < 18; i++)
        R[i] = 0;

    int idxR1[] = { 0, 2 };
    int idxC1[] = { 0, 2, 4 };
    int idxR2[] = { 2, 1 };
    int idxC2[] = { 1, 3, 5 };

    matrixSetSub(R, 3, 6, idxR1, 2, idxC1, 3, phiGradT);
    matrixSetSub(R, 3, 6, idxR2, 2, idxC2, 3, phiGradT);

    matrixTranspose(R, 3, 6, RT);

    PetscReal temp[18];

    matrixMult(C, 3, 3, R, 3, 6, temp);
    matrixMult(RT, 6, 3, temp, 3, 6, stifMat);

    matrixSum(stifMat, 1 / (2 * detT), stifMat, 0, stifMat, 6, 6);
    //PetscPrintf(PETSC_COMM_SELF, "%e %e \n", fs[0], fs[1]);

    //Volume Force
    for (int i = 0; i < 3; i++) {
        bL[i * 2] = detT / 6 * fs[0];
        bL[i * 2 + 1] = detT / 6 * fs[1];
    }

    //@TODO Edge Force!!!
}
Beispiel #2
0
void Regulate(float *Coord_cur, float *Speed_cur, float *tAlphZad,float *V_etalon,float *alphZad, float *V_local)
{
float t_alph_cur[2][2], t_alph_delta[2][2];
float uS, uE, u[2];
float buf[2][2],buf1[2][2],buf3[2][1];
float cosAlphCur;
float sinAlphCur;

float resultVector = sqrtf((*Coord_cur) * (*Coord_cur) + (*(Coord_cur+1)) * (*(Coord_cur+1)));

if (resultVector==0.0)
{
  cosAlphCur=cosf(*alphZad);
  sinAlphCur=sinf(*alphZad);
}
else
{
cosAlphCur = (*Coord_cur)/resultVector;
sinAlphCur = (*(Coord_cur+1))/resultVector;
}

  t_alph_cur[0][0] =  cosAlphCur;
  t_alph_cur[0][1] =  sinAlphCur;
  t_alph_cur[1][0] = -sinAlphCur;
  t_alph_cur[1][1] =  cosAlphCur;

  matrixTranspose(&t_alph_cur[0][0], 2, 2, &buf[0][0]);   //tDeltaAlph=tAlphCur'
  matrixMultiplyM2M(tAlphZad, 2, 2,&buf[0][0],2,2,&t_alph_delta[0][0]);
  matrixTranspose(&t_alph_delta[0][0], 2, 2, &buf1[0][0]);  // We have current traectory error in buf1 now

////////////////////////////////////////////////////////////////////////////////
//radSpeed.current = (*(Speed_cur+2));
//radSpeed.target = *(V_etalon+1);//controlBoard.x2;
//pidCalc(&radSpeed);
*(V_local+2) =*(V_etalon+1);//// radSpeed.output;
////////////////////////////////////////////////////////////////////////////////
//trackSpeed.current = *(Speed_cur);
//trackSpeed.target = *(V_etalon);//controlBoard.x2;
//pidCalc(&trackSpeed);
//uS = trackSpeed.output;
////////////////////////////////////////////////////////////////////////////////
ortoPos.current =  (*(Coord_cur+1));
ortoPos.target = 0.0;//controlBoard.x2;
pidCalc(&ortoPos);
uE = ortoPos.output;
////////////////////////////////////////////////////////////////////////////////

  uS =(*V_etalon);
  //uE = KOFF_ORTO_TRACE * (*(Coord_cur+1));
  u[0] = uS;
  u[1] = uE;

  matrixMultiplyM2M(&buf1[0][0], 2, 2, &u[0], 2, 1, &buf3[0][0]);
  matrixMultiplyM2M(&buf[0][0],2,2,&buf3[0][0],2,1,V_local);
}
Beispiel #3
0
int main()
{
    printf("Testing work:\n");
    int n = 9;
    int m = 1;
    Matrix a = matrixNew(n, m);
    for (int i = 0; i < matrixGetRows(a); i++)
        for (int j = 0; j < matrixGetCols(a); j++)
            matrixSet(a, i, j, (float)(i + 1) / (j + 1));
    for (int i = 0; i < matrixGetRows(a); i++)
    {
        for (int j = 0; j < matrixGetCols(a); j++)
            printf("%.5f ", matrixGet(a, i, j));
        printf("\n");
    }
    printf("\n");
    Matrix b = matrixScale(a, 10);
    for (int i = 0; i < matrixGetRows(b); i++)
    {
        for (int j = 0; j < matrixGetCols(b); j++)
            printf("%.5f ", matrixGet(b, i, j));
        printf("\n");
    }
    printf("\n");
    Matrix c = matrixAdd(a, b);
    for (int i = 0; i < matrixGetRows(c); i++)
    {
        for (int j = 0; j < matrixGetCols(c); j++)
            printf("%.5f ", matrixGet(c, i, j));
        printf("\n");
    }
    printf("\n");
    Matrix d = matrixTranspose(c);
    for (int i = 0; i < matrixGetRows(d); i++)
    {
        for (int j = 0; j < matrixGetCols(d); j++)
            printf("%.5f ", matrixGet(d, i, j));
        printf("\n");
    }

    /*c = matrixAdd(a, matrixNew(1, 1));
    if (c == NULL)
        printf("Yeah\n"), c = matrixNew(3, 3);*/
    Matrix e = matrixMul(c, d);
    printf("%i %i\n", matrixGetRows(e), matrixGetCols(e));
    for (int i = 0; i < matrixGetRows(e); i++)
    {
        for (int j = 0; j < matrixGetCols(e); j++)
            printf("%.5f ", matrixGet(e, i, j));
        printf("\n");
    }
    matrixDelete(a);
    matrixDelete(b);
    matrixDelete(c);
    matrixDelete(d);
    matrixDelete(e);
	return 0;
}
Beispiel #4
0
void matrixNormalTransform(matrix* r, matrix m) {
	m.v[3] = 0;
	m.v[7] = 0;
	m.v[11] = 0;
	m.v[15] = 1;
	matrix t;
	matrixInverse( &t, m );
	matrixTranspose( r, t );
}
Beispiel #5
0
void Frustum::Extract(const Matrix44f &view, const Projection &proj) {
  static const int LBN = kLBNCorner, LTN = kLTNCorner, LBF = kLBFCorner,
                   LTF = kLTFCorner, RBN = kRBNCorner, RTN = kRTNCorner,
                   RBF = kRBFCorner, RTF = kRTFCorner;

  const float lnear = -proj.get_near();
  const float lfar = -proj.get_far();
  const Vec3f nearNorm(0.0f, 0.0f, -1.0f);
  const Vec3f farNorm(0.0f, 0.0f, 1.0f);

  // kLeftPlane plane
  const Vec3f ltn(proj.get_left(), proj.get_top(), lnear),
      lbn(proj.get_left(), proj.get_bottom(), lnear),
      ltf(proj.get_far_left(), proj.get_far_top(), lfar),
      lbf(proj.get_far_left(), proj.get_far_bottom(), lfar);

  const Vec3f leftNorm = vecNormal(
      vecCross(lbn - ltn, ltf - ltn));

  // kRightPlane plane
  const Vec3f rtn(proj.get_right(), proj.get_top(), lnear), // right top near
      rbn(proj.get_right(), proj.get_bottom(), lnear), // right bottom near
      rtf(proj.get_far_right(), proj.get_far_top(), lfar); // right top far

  const Vec3f rightNorm = vecNormal(vecCross(rtf - rtn, rbn - rtn));

  // kTopPlane plane
  const Vec3f topNorm = vecNormal(vecCross(ltf - ltn, rtn - ltn));

  // kBottomPlane plane lbn rbf
  const Vec3f rbf(proj.get_far_right(), proj.get_far_bottom(), lfar);
  const Vec3f botNorm = vecNormal(vecCross(rbf - rbn, lbn - rbn));

  Matrix44f viewSpace, viewSpaceN;
  matrixInverse(view, &viewSpace);

  viewSpaceN = matrixTranspose(view);

  m_conners[LBN] = lbn * viewSpace;
  m_conners[LTN] = ltn * viewSpace;
  m_conners[LBF] = lbf * viewSpace;
  m_conners[LTF] = ltf * viewSpace;
  m_conners[RBN] = rbn * viewSpace;
  m_conners[RTN] = rtn * viewSpace;
  m_conners[RBF] = rbf * viewSpace;
  m_conners[RTF] = rtf * viewSpace;

  m_planes[kLeftPlane] = Planef(leftNorm * viewSpaceN, m_conners[LTN]);
  m_planes[kRightPlane] = Planef(rightNorm * viewSpaceN, m_conners[RTN]);
  m_planes[kTopPlane] = Planef(topNorm * viewSpaceN, m_conners[RTN]);
  m_planes[kBottomPlane] = Planef(botNorm * viewSpaceN, m_conners[LBN]);
  m_planes[kNearPlane] = Planef(nearNorm * viewSpaceN, m_conners[LBN]);
  m_planes[kFarPlane] = Planef(farNorm * viewSpaceN, m_conners[RTF]);
}
Beispiel #6
0
static void
loadTextureProjection(int texUnit, GLfloat m[16])
{
  GLfloat mInverse[4][4];

  /* Should use true inverse, but since m consists only of rotations, we can
     just use the transpose. */
  matrixTranspose((GLfloat *) mInverse, m);

  ActiveTexture(GL_TEXTURE0_ARB + texUnit);
  glMatrixMode(GL_TEXTURE);
  glLoadIdentity();
  glTranslatef(0.5, 0.5, 0.0);
  glScalef(0.5, 0.5, 1.0);
  glFrustum(xmin, xmax, ymin, ymax, nnear, ffar);
  glTranslatef(0.0, 0.0, distance);
  glMultMatrixf((GLfloat *) mInverse);
  glMatrixMode(GL_MODELVIEW);
}
Beispiel #7
0
void testMatrixTranspose(void)
{
	int **matrixA;
	int	**matrixAT;
	int	rowNumOfA, colNumOfA;
	int rowNumOfAT, colNumOfAT;

	rowNumOfA = 2;
	colNumOfA = 3;
	matrixA = generateMatrix(rowNumOfA, colNumOfA);

	rowNumOfAT = colNumOfA;
	colNumOfAT = rowNumOfA;
	matrixAT = make2DArray(rowNumOfAT, colNumOfAT);

	printf("----------- test: matrix transpose ------------------\n");
	matrixTranspose(matrixAT, matrixA, rowNumOfA, colNumOfA);

	printf("matrixA\n");
	printMatrix(matrixA, rowNumOfA, colNumOfA);

	printf("matrixAT\n");
	printMatrix(matrixAT, rowNumOfAT, colNumOfAT);		
}
Beispiel #8
0
void nebu_Camera_Rotate(nebu_Camera *pCamera, int flags,
                        float dx, float dy)
{
    // adjust up vector, so that it is orthogonal to
    // view direction
    vec3 vDiff, vView, vRight, vUp;
    vec3 vdx, vdy;
    vec3 *pvCenter, *pvMoving;

    switch(flags & NEBU_CAMERA_ROTATE_MASK)
    {
    case NEBU_CAMERA_ROTATE_AROUND_EYE:
        pvCenter = &pCamera->vEye;
        pvMoving = &pCamera->vLookAt;
        break;
    case NEBU_CAMERA_ROTATE_AROUND_LOOKAT:
        pvCenter = &pCamera->vLookAt;
        pvMoving = &pCamera->vEye;
        break;
    default:
        assert(0);
        return;
    }

    vec3_Sub(&vDiff, pvCenter, pvMoving);
    vec3_Normalize(&vView, &vDiff);
    vec3_Cross(&vRight, &pCamera->vUp, &vView);
    vec3_Normalize(&vRight, &vRight);
    vec3_Cross(&vUp, &vView, &vRight);
    vec3_Normalize(&vUp, &vUp);

    // horizontal movement (dx):
    if(dx == 0) {
        vec3_Zero(&vdx);
    } else {
        // rotate moving around up vector through center point
        vec3 v = vDiff;
        float fAngle = dx * 2 * (float)M_PI / 360.0f;
        matrix matRotation;
        matrixRotationAxis(&matRotation, fAngle, &vUp);
        vec3_Transform(&v, &vDiff, &matRotation);
        vec3_Sub(&vdx, &v, &vDiff);
    }

    // vertical movement (dy):
    if(dy == 0) {
        vec3_Zero(&vdy);
    } else {
        // rotate eye point around up vector through lookAt point
        vec3 v = vDiff;
        float fAngle = dy * 2 * (float)M_PI / 360.0f;
        matrix matRotation;
        matrixRotationAxis(&matRotation, fAngle, &vRight);
        vec3_Transform(&v, &vDiff, &matRotation);
        vec3_Sub(&vdy, &v, &vDiff);

        matrixTranspose(&matRotation, &matRotation);
        if(!(flags & NEBU_CAMERA_FIXED_UP))
            vec3_Transform(&pCamera->vUp, &pCamera->vUp, &matRotation);
    }

    {
        vec3 v;
        vec3_Add(&v, &vdx, &vdy);
        vec3_Add(&v, &v, pvMoving);
        vec3_Sub(&v, &v, pvCenter);
        vec3_Normalize(&v, &v);
        // printf("up dot view: %.4f\n", - vec3_Dot(&v, &pCamera->vUp));
        vec3_Scale(&v, &v, vec3_Length(&vDiff));
        vec3_Add(pvMoving, &v, pvCenter);

    }
}
// LLSQ Approx. Trilateration
void locateLLSQ(int numantennas, double* antennas, double* distances, double* x)
{
	// function saves triangulated position in vector x
	// input *antennas holds
	// x1, y1, z1,
	// x2, y2, z2,
	// x3, y3, z3,
	// x4, y4, z4;
	// numantennas holds integer number of antennas (min 5)
	// double *distances holds pointer to array holding distances from each antenna
	// Theory used:
	// http://inside.mines.edu/~whereman/talks/TurgutOzal-11-Trilateration.pdf

	// define some locals
	int m = (numantennas - 1); // Number of rows in A
	int n = 3; // Number of columns in A (always three)
	if (m >= 4)n = 4; // Number of columns in A: three coordinates plus K
	double A[m * n];
	double b[m * 1];
	double r;
	double Atranspose[n * m];
	double AtAinA[n * m];
	double AtA[n * n];

	//Calculating b vector
	for (int i = 0; i < m; i++)
	{
		r = dist(antennas[0], antennas[1], antennas[2], antennas[(i + 1) * 3], antennas[(i + 1) * 3 + 1], antennas[(i + 1) * 3 + 2]);
		b[i] = 0.5*(distances[0] * distances[0] - distances[i + 1] * distances[i + 1] + r * r); // If given exact distances
		if (n == 4)b[i] = 0.5 * r*r; // For the case when we calculate K, overwrite b
	}

#ifdef VERBOSE
	matrixPrint(b, m, 1, "b");
#endif // DEBUG


	//Calculating A matrix
	for (int i = 0; i < m; i++)
	{
		A[i * n] = antennas[(i + 1) * 3] - antennas[0];         //xi-x1
		A[i * n + 1] = antennas[(i + 1) * 3 + 1] - antennas[1]; //yi-y1
		A[i * n + 2] = antennas[(i + 1) * 3 + 2] - antennas[2]; //zi-z1
		if (n == 4) A[i * n + 3] = -0.5 * (distances[0] * distances[0] - distances[i + 1] * distances[i + 1]); // for K
	}

#ifdef VERBOSE
	matrixPrint(A, m, n, "A");
#endif // DEBUG

	matrixTranspose(A, m, n, Atranspose);
	matrixMult(Atranspose, A, n, m, n, AtA);

	if (matrixInvert(AtA, n) == 1)   //well behaved
	{
		matrixMult(AtA, Atranspose, n, n, m, AtAinA);
		matrixMult(AtAinA, b, n, m, 1, x);

	}
	else      // Ill-behaved A
	{

		double Q[m * m], Qtranspose[m * m], Qtransposeb[m * 1];
		double R[m * m];
		QR(A, m, n, Q, R);
		matrixTranspose(Q, m, m, Qtranspose);
		matrixMult(Qtranspose, b, m, m, 1, Qtransposeb);
		matrixInvert(R, m);
		matrixMult(R, Qtransposeb, m, m, 1, x);
	}

	// Adding back the reference point
	x[0] = x[0] + antennas[0];
	x[1] = x[1] + antennas[1];
	x[2] = x[2] + antennas[2];
	if (n == 4)x[3] = 1 / sqrt(x[3]); // Calculate K
}
Beispiel #10
0
// QR Factorization
void QR(double* A, int m, int n, double* Q, double* R)
{
	// Not a very efficient approach, but simple and effective
	// Written by Nico van Duijn, 9/13/2015
	// Source of algorithm (adjusted by me):
	// http://www.keithlantz.net/2012/05/qr-decomposition-using-householder-transformations/
	// A is the (m*n) matrix to be factorized A=Q*R

	double mag, alpha;
	double u[m], v[m], vtrans[m];
	double P[m * m], I[m * m], vvtrans[m * m], Rbackup[m * m], Qbackup[m * m];
	matrixCopy(A, m, m, R); // Initialize R to A

	// Initialize Q, P, I to Identity
	for (int i = 0; i < m * m; i++)Q[i] = 0;
	for (int i = 0; i < m; i++)Q[i * n + i] = 1;
	for (int i = 0; i < m * m; i++)P[i] = 0;
	for (int i = 0; i < m; i++)P[i * n + i] = 1;
	for (int i = 0; i < m * m; i++)I[i] = 0;
	for (int i = 0; i < m; i++)I[i * n + i] = 1;

	for (int i = 0; i < n; i++)  //loop through all columns
	{
		for (int q = 0; q < m; q++)u[q] = 0; // set u and v to zero
		for (int q = 0; q < m; q++)v[q] = 0;

		mag = 0.0; //set mag to zero

		for (int j = i; j < m; j++)
		{
			u[j] = R[j * n + i];
			mag += u[j] * u[j];
		}
		mag = sqrt(mag);

		alpha = u[i] < 0 ? mag : -mag;

		mag = 0.0;
		for (int j = i; j < m; j++)
		{
			v[j] = j == i ? u[j] + alpha : u[j];
			mag += v[j] * v[j];
		}
		mag = sqrt(mag);

		if (mag < 0.0000000001) continue;

		for (int j = i; j < m; j++) v[j] /= mag;

		// P = I - (v * v.transpose()) * 2.0;
		matrixTranspose(v, m, 1, vtrans);
		matrixMult(v, vtrans, m, 1, m, vvtrans);
		matrixScale(vvtrans, m, m, 2.0);
		matrixSub(I, vvtrans, m, m, P);

		// R = P * R;
		matrixMult(P, R, m, m, m, Rbackup);
		matrixCopy(Rbackup, m, m, R);

		//Q = Q * P;
		matrixMult(Q, P, m, m, m, Qbackup);
		matrixCopy(Qbackup, m, m, Q);
	}

}
    Matrix Matrix::matrixInvert(Matrix *matrix)
    {
        Matrix result;
        float matrix3x3[9];

        /* Find the cofactor of each element. */
        /* Element (i, j) (1, 1) */
        matrix3x3[0] = matrix->elements[ 5];
        matrix3x3[1] = matrix->elements[ 6];
        matrix3x3[2] = matrix->elements[ 7];
        matrix3x3[3] = matrix->elements[ 9];
        matrix3x3[4] = matrix->elements[10];
        matrix3x3[5] = matrix->elements[11];
        matrix3x3[6] = matrix->elements[13];
        matrix3x3[7] = matrix->elements[14];
        matrix3x3[8] = matrix->elements[15];
        result.elements[0] = matrixDeterminant(matrix3x3);

        /* Element (i, j) (1, 2) */
        matrix3x3[0] = matrix->elements[ 1];
        matrix3x3[1] = matrix->elements[ 2];
        matrix3x3[2] = matrix->elements[ 3];
        matrix3x3[3] = matrix->elements[ 9];
        matrix3x3[4] = matrix->elements[10];
        matrix3x3[5] = matrix->elements[11];
        matrix3x3[6] = matrix->elements[13];
        matrix3x3[7] = matrix->elements[14];
        matrix3x3[8] = matrix->elements[15];
        result.elements[4] = -matrixDeterminant(matrix3x3);

        /* Element (i, j) (1, 3) */
        matrix3x3[0] = matrix->elements[ 1];
        matrix3x3[1] = matrix->elements[ 2];
        matrix3x3[2] = matrix->elements[ 3];
        matrix3x3[3] = matrix->elements[ 5];
        matrix3x3[4] = matrix->elements[ 6];
        matrix3x3[5] = matrix->elements[ 7];
        matrix3x3[6] = matrix->elements[13];
        matrix3x3[7] = matrix->elements[14];
        matrix3x3[8] = matrix->elements[15];
        result.elements[8] = matrixDeterminant(matrix3x3);

        /* Element (i, j) (1, 4) */
        matrix3x3[0] = matrix->elements[ 1];
        matrix3x3[1] = matrix->elements[ 2];
        matrix3x3[2] = matrix->elements[ 3];
        matrix3x3[3] = matrix->elements[ 5];
        matrix3x3[4] = matrix->elements[ 6];
        matrix3x3[5] = matrix->elements[ 7];
        matrix3x3[6] = matrix->elements[ 9];
        matrix3x3[7] = matrix->elements[10];
        matrix3x3[8] = matrix->elements[11];
        result.elements[12] = -matrixDeterminant(matrix3x3);

        /* Element (i, j) (2, 1) */
        matrix3x3[0] = matrix->elements[ 4];
        matrix3x3[1] = matrix->elements[ 6];
        matrix3x3[2] = matrix->elements[ 7];
        matrix3x3[3] = matrix->elements[ 8];
        matrix3x3[4] = matrix->elements[10];
        matrix3x3[5] = matrix->elements[11];
        matrix3x3[6] = matrix->elements[12];
        matrix3x3[7] = matrix->elements[14];
        matrix3x3[8] = matrix->elements[15];
        result.elements[1] = -matrixDeterminant(matrix3x3);

        /* Element (i, j) (2, 2) */
        matrix3x3[0] = matrix->elements[ 0];
        matrix3x3[1] = matrix->elements[ 2];
        matrix3x3[2] = matrix->elements[ 3];
        matrix3x3[3] = matrix->elements[ 8];
        matrix3x3[4] = matrix->elements[10];
        matrix3x3[5] = matrix->elements[11];
        matrix3x3[6] = matrix->elements[12];
        matrix3x3[7] = matrix->elements[14];
        matrix3x3[8] = matrix->elements[15];
        result.elements[5] = matrixDeterminant(matrix3x3);

        /* Element (i, j) (2, 3) */
        matrix3x3[0] = matrix->elements[ 0];
        matrix3x3[1] = matrix->elements[ 2];
        matrix3x3[2] = matrix->elements[ 3];
        matrix3x3[3] = matrix->elements[ 4];
        matrix3x3[4] = matrix->elements[ 6];
        matrix3x3[5] = matrix->elements[ 7];
        matrix3x3[6] = matrix->elements[12];
        matrix3x3[7] = matrix->elements[14];
        matrix3x3[8] = matrix->elements[15];
        result.elements[9] = -matrixDeterminant(matrix3x3);

        /* Element (i, j) (2, 4) */
        matrix3x3[0] = matrix->elements[ 0];
        matrix3x3[1] = matrix->elements[ 2];
        matrix3x3[2] = matrix->elements[ 3];
        matrix3x3[3] = matrix->elements[ 4];
        matrix3x3[4] = matrix->elements[ 6];
        matrix3x3[5] = matrix->elements[ 7];
        matrix3x3[6] = matrix->elements[ 8];
        matrix3x3[7] = matrix->elements[10];
        matrix3x3[8] = matrix->elements[11];
        result.elements[13] = matrixDeterminant(matrix3x3);

        /* Element (i, j) (3, 1) */
        matrix3x3[0] = matrix->elements[ 4];
        matrix3x3[1] = matrix->elements[ 5];
        matrix3x3[2] = matrix->elements[ 7];
        matrix3x3[3] = matrix->elements[ 8];
        matrix3x3[4] = matrix->elements[ 9];
        matrix3x3[5] = matrix->elements[11];
        matrix3x3[6] = matrix->elements[12];
        matrix3x3[7] = matrix->elements[13];
        matrix3x3[8] = matrix->elements[15];
        result.elements[2] = matrixDeterminant(matrix3x3);

        /* Element (i, j) (3, 2) */
        matrix3x3[0] = matrix->elements[ 0];
        matrix3x3[1] = matrix->elements[ 1];
        matrix3x3[2] = matrix->elements[ 3];
        matrix3x3[3] = matrix->elements[ 8];
        matrix3x3[4] = matrix->elements[ 9];
        matrix3x3[5] = matrix->elements[11];
        matrix3x3[6] = matrix->elements[12];
        matrix3x3[7] = matrix->elements[13];
        matrix3x3[8] = matrix->elements[15];
        result.elements[6] = -matrixDeterminant(matrix3x3);

        /* Element (i, j) (3, 3) */
        matrix3x3[0] = matrix->elements[ 0];
        matrix3x3[1] = matrix->elements[ 1];
        matrix3x3[2] = matrix->elements[ 3];
        matrix3x3[3] = matrix->elements[ 4];
        matrix3x3[4] = matrix->elements[ 5];
        matrix3x3[5] = matrix->elements[ 7];
        matrix3x3[6] = matrix->elements[12];
        matrix3x3[7] = matrix->elements[13];
        matrix3x3[8] = matrix->elements[15];
        result.elements[10] = matrixDeterminant(matrix3x3);

        /* Element (i, j) (3, 4) */
        matrix3x3[0] = matrix->elements[ 0];
        matrix3x3[1] = matrix->elements[ 1];
        matrix3x3[2] = matrix->elements[ 3];
        matrix3x3[3] = matrix->elements[ 4];
        matrix3x3[4] = matrix->elements[ 5];
        matrix3x3[5] = matrix->elements[ 7];
        matrix3x3[6] = matrix->elements[ 8];
        matrix3x3[7] = matrix->elements[ 9];
        matrix3x3[8] = matrix->elements[11];
        result.elements[14] = -matrixDeterminant(matrix3x3);

        /* Element (i, j) (4, 1) */
        matrix3x3[0] = matrix->elements[ 4];
        matrix3x3[1] = matrix->elements[ 5];
        matrix3x3[2] = matrix->elements[ 6];
        matrix3x3[3] = matrix->elements[ 8];
        matrix3x3[4] = matrix->elements[ 9];
        matrix3x3[5] = matrix->elements[10];
        matrix3x3[6] = matrix->elements[12];
        matrix3x3[7] = matrix->elements[13];
        matrix3x3[8] = matrix->elements[14];
        result.elements[3] = -matrixDeterminant(matrix3x3);

        /* Element (i, j) (4, 2) */
        matrix3x3[0] = matrix->elements[ 0];
        matrix3x3[1] = matrix->elements[ 1];
        matrix3x3[2] = matrix->elements[ 2];
        matrix3x3[3] = matrix->elements[ 8];
        matrix3x3[4] = matrix->elements[ 9];
        matrix3x3[5] = matrix->elements[10];
        matrix3x3[6] = matrix->elements[12];
        matrix3x3[7] = matrix->elements[13];
        matrix3x3[8] = matrix->elements[14];
        result.elements[7] = matrixDeterminant(matrix3x3);

        /* Element (i, j) (4, 3) */
        matrix3x3[0] = matrix->elements[ 0];
        matrix3x3[1] = matrix->elements[ 1];
        matrix3x3[2] = matrix->elements[ 2];
        matrix3x3[3] = matrix->elements[ 4];
        matrix3x3[4] = matrix->elements[ 5];
        matrix3x3[5] = matrix->elements[ 6];
        matrix3x3[6] = matrix->elements[12];
        matrix3x3[7] = matrix->elements[13];
        matrix3x3[8] = matrix->elements[14];
        result.elements[11] = -matrixDeterminant(matrix3x3);

        /* Element (i, j) (4, 4) */
        matrix3x3[0] = matrix->elements[ 0];
        matrix3x3[1] = matrix->elements[ 1];
        matrix3x3[2] = matrix->elements[ 2];
        matrix3x3[3] = matrix->elements[ 4];
        matrix3x3[4] = matrix->elements[ 5];
        matrix3x3[5] = matrix->elements[ 6];
        matrix3x3[6] = matrix->elements[ 8];
        matrix3x3[7] = matrix->elements[ 9];
        matrix3x3[8] = matrix->elements[10];
        result.elements[15] = matrixDeterminant(matrix3x3);

        /* The adjoint is the transpose of the cofactor matrix. */
        matrixTranspose(&result);

        /* The inverse is the adjoint divided by the determinant. */
        result = matrixScale(&result, 1.0f / matrixDeterminant(matrix));

        return result;
    }
Beispiel #12
0
int main(int argc, char *argv[])
{
	//initialize
	int i, j, k, l, mpi_rank, mpi_size, mpi_rowsize, mpi_colsize, subN, sqrtP;
	int row_rank, col_rank, row, col, destR, destC, src, srcR, srcC;
	// declare variables to store time of parallelism
	double execTime, execStart, execEnd;

	MPI_Comm rowComm, colComm;
	
	MPI_Init(&argc, &argv);

	MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
	MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);

	if (argc < 2) {
		printf("error: need one argument for filename");
		exit(-1);
	}

	// declare variables of type vector to read matrices
	vector * mat1;
	vector * mat2;
	float * vector1;
	float * vector2;
	//create data on root
	// read matrices 
	if (mpi_rank == ROOT)
	{
		mat1 = readfile(argv[1], N, N);
		mat2 = readfile(argv[2], N, N);
		vector1 = mat1->data;
		vector2 = mat2->data;
	}
	// find the sub matrix dimention
	sqrtP = (int) sqrt(mpi_size);
	subN = N/sqrtP;

	//allocate memory for N/4xN rows, and NxN/4 columns
	float * row_mat, *col_mat, *row_mat_rec, *col_mat_rec, *col_matT;
	double *can_res, *can_out;

	//allocate memory for the buffers
	row_mat = allocateFloatMatrix(subN, subN);
	row_mat_rec = allocateFloatMatrix(subN, subN);
	col_mat = allocateFloatMatrix(subN, subN);
	col_matT = allocateFloatMatrix(subN, subN);
	col_mat_rec = allocateFloatMatrix(subN, subN);
	can_res = allocateDoubleMatrix(subN, subN);
	can_out = allocateDoubleMatrix(N, N);

	//create and commit datatypes
	MPI_Datatype arrtype, resized_arrtype, arrtypeD, resized_arrtypeD;

	int sizes[2] = { N,N };
	int subsizes[2] = { subN,subN };
	int starts[2] = { 0,0 };

	MPI_Type_create_subarray(2, sizes, subsizes, starts, MPI_ORDER_C, MPI_FLOAT, &arrtype);
	MPI_Type_create_resized(arrtype, 0, subN * sizeof(float), &resized_arrtype);
	MPI_Type_commit(&resized_arrtype);
	
	MPI_Type_create_subarray(2, sizes, subsizes, starts, MPI_ORDER_C, MPI_DOUBLE, &arrtypeD);
	MPI_Type_create_resized(arrtypeD, 0, subN * sizeof(double), &resized_arrtypeD);
	MPI_Type_commit(&resized_arrtypeD);

	//calculate send counts and displacements
	int * counts, * displs;
	counts = (int *) malloc(mpi_size * sizeof(int));
	displs = (int *) malloc(mpi_size * sizeof(int));

	for(i = 0; i < mpi_size; i++)
	{		
		counts[i] = 1;
		displs[i] = N*(i/sqrtP) + (i%sqrtP);
	}	
	
	//start timer, compute dot product and record execution time 
	execStart = MPI_Wtime();
	
	//scatterv subarrays
	MPI_Scatterv(vector1, counts, displs, resized_arrtype, row_mat, subN*subN, MPI_FLOAT, ROOT, MPI_COMM_WORLD);
	MPI_Scatterv(vector2, counts, displs, resized_arrtype, col_mat, subN*subN, MPI_FLOAT, ROOT, MPI_COMM_WORLD);
	
	//get row comm and rank
	row = mpi_rank/sqrtP;
	MPI_Comm_split(MPI_COMM_WORLD,row,mpi_rank,&rowComm);
	MPI_Comm_rank(rowComm,&row_rank);
	MPI_Comm_size(rowComm, &mpi_rowsize);
	//get col comm and rank
	col = mpi_rank%sqrtP;
	MPI_Comm_split(MPI_COMM_WORLD,col,mpi_rank,&colComm);
	MPI_Comm_rank(colComm,&col_rank);
	MPI_Comm_size(colComm, &mpi_colsize);
	
	//MPI_Barrier(MPI_COMM_WORLD);
	
	// find the source and destination in row communicator - to left shift rows by row number
	destR = row_rank-row;
    if (destR < 0) {
        destR = destR + mpi_rowsize;
    }
	
	srcR = row_rank+row;
	if (srcR > (mpi_rowsize-1)) {
        srcR = srcR - mpi_rowsize;
    }
	
	// find the source and destination in column communicator  - to north shift columns by column number
	destC = col_rank - col;
    if (destC < 0) {
        destC = destC + mpi_colsize;
    }
	srcC = col_rank+col;
	if (srcC > (mpi_colsize-1)) {
        srcC = srcC - mpi_colsize;
    }
	// left shift rows by row number
	MPI_Sendrecv(row_mat, subN*subN, MPI_FLOAT, destR, 0, row_mat_rec, subN*subN, MPI_FLOAT, srcR, MPI_ANY_TAG, rowComm, MPI_STATUS_IGNORE);

	//north shift columns by column number
	MPI_Sendrecv(col_mat, subN*subN, MPI_FLOAT, destC, 1, col_mat_rec, subN*subN, MPI_FLOAT, srcC, MPI_ANY_TAG, colComm, MPI_STATUS_IGNORE);

	 
	
	for (l=0; l<sqrtP; l++)
	{
		memcpy(row_mat, row_mat_rec, sizeof(float)*subN*subN);
		memcpy(col_mat, col_mat_rec, sizeof(float)*subN*subN);
		
		// Finding the transpose of matrix B
		matrixTranspose(subN, col_mat, col_matT);
		//perform a partial matrix-vector multiplication on each process
		matrixMultiplyT(subN, row_mat, col_matT, can_res);
		
		// find the source and destination in row communicator  - to left shift all rows once
	    if (row_rank != 0) {
			destR = row_rank - 1;
		} else {
			destR = mpi_rowsize - 1;
		}
		
	    srcR = row_rank + 1;
		if (srcR == mpi_rowsize) {
			srcR = 0;
		}
		// find the source and destination in column communicator  - to north shift all columns once
		if (col_rank != 0) {
		destC = col_rank - 1;
		} else {
			destC = mpi_colsize - 1;
		}
		
	    srcC = col_rank + 1;
		if (srcC == mpi_colsize) {
			srcC = 0;
		}
		
		//left shift all rows once
		MPI_Sendrecv(row_mat, subN*subN, MPI_FLOAT, destR, 2, row_mat_rec, subN*subN, MPI_FLOAT, srcR, MPI_ANY_TAG, rowComm, MPI_STATUS_IGNORE);
		
		//north shift all columns once
		MPI_Sendrecv(col_mat, subN*subN, MPI_FLOAT, destC, 3, col_mat_rec, subN*subN, MPI_FLOAT, srcC, MPI_ANY_TAG, colComm, MPI_STATUS_IGNORE);
	}

	// gather the matrix multiplication results from all procs
	MPI_Gatherv(can_res, subN*subN, MPI_DOUBLE, can_out, counts, displs, resized_arrtypeD, ROOT, MPI_COMM_WORLD);
	
		//stop timer
	execEnd = MPI_Wtime();
	execTime = execEnd - execStart;

    //free datatypes
	MPI_Type_free(&resized_arrtype);
	MPI_Type_free(&resized_arrtypeD);
	if (mpi_rank == ROOT)
	{
		printf("Execution time for dot product: %f seconds\n", execTime);
		printf("Result: %f, %f, %f \n ", can_out[0], can_out[2047*N + 2047], can_out[4095*N + 4095]);
		free(vector1);
		free(vector2);
	}
	free(row_mat);
	free(col_mat);
	free(row_mat_rec);
	free(col_mat_rec);
	free(col_matT);
	free(can_res);
	free(can_out);

	//shut down MPI
	MPI_Finalize();

	return 0;
}
Beispiel #13
0
void nebu_Camera_RotateAroundTarget(nebu_Camera *pCamera,
																		float dx, float dy) {
	// adjust up vector, so that it is orthogonal to
	// view direction
	vec3 vDiff, vView, vRight, vUp;
	vec3 vdx, vdy;
	
	vec3_Sub(&vDiff, &pCamera->vLookAt, &pCamera->vEye);
	vec3_Normalize(&vView, &vDiff);
	vec3_Cross(&vRight, &pCamera->vUp, &vView);
	vec3_Normalize(&vRight, &vRight);
	vec3_Cross(&vUp, &vView, &vRight);
	vec3_Normalize(&vUp, &vUp);
	
	// horizontal movement (dx):
	if(dx == 0) {
		vec3_Zero(&vdx);
	} else {
		// rotate eye point around up vector through lookAt point
		vec3 v = vDiff;
		float fAngle = dx * 2 * M_PI / 360.0;
		matrix matRotation;
		matrixRotationAxis(&matRotation, fAngle, &vUp);
		vec3_Transform(&v, &vDiff, &matRotation);
		vec3_Sub(&vdx, &v, &vDiff);
	}

	// vertical movement (dy):
	if(dy == 0) {
		vec3_Zero(&vdy);
	} else {
		// rotate eye point around up vector through lookAt point
		vec3 v = vDiff;
		float fAngle = dy * 2 * M_PI / 360.0;
		matrix matRotation;
		matrixRotationAxis(&matRotation, fAngle, &vRight);
		vec3_Transform(&v, &vDiff, &matRotation);
		vec3_Sub(&vdy, &v, &vDiff);

		matrixTranspose(&matRotation, &matRotation);
		vec3_Transform(&pCamera->vUp, &pCamera->vUp, &matRotation);
	}

	// add relative movements to camera position
	
	/*
	vec3_Add(&pCamera->vEye, &pCamera->vEye, &vdx);
	vec3_Add(&pCamera->vEye, &pCamera->vEye, &vdy);
	*/
	{
		vec3 v;
		vec3_Add(&v, &vdx, &vdy);
		vec3_Add(&v, &v, &pCamera->vEye);
		vec3_Sub(&v, &v, &pCamera->vLookAt);
		vec3_Normalize(&v, &v);
		// printf("up dot view: %.4f\n", - vec3_Dot(&v, &pCamera->vUp));
		vec3_Scale(&v, &v, vec3_Length(&vDiff));
		vec3_Add(&pCamera->vEye, &v, &pCamera->vLookAt);

	}
}
/*!
 * This sub-routine computes the velocity vector, given a magnitude, a unit normal vector from the
 * point on the surface where the regolith is lofted from, and the two conic angles which describe
 * the velocity vector's direction relative to the normal vector. A backwards approach is used
 * to go from the velocity vector in the final rotated intermediate frame back to the body fixed
 * frame. More details are given in the thesis report and author's personal notes.
 *
 */
void computeRegolithVelocityVector( std::vector< double > regolithPositionVector,
                                    const double velocityMagnitude,
                                    const double coneAngleAzimuth,
                                    const double coneAngleDeclination,
                                    std::vector< double > &unitNormalVector,
                                    std::vector< double > &regolithVelocityVector )
{
    // form the velocity vector, assuming that the intermediate frame's z-axis, on the surface of
    // the asteroid, is along the final velocity vector
    regolithVelocityVector[ 0 ] = 0.0;
    regolithVelocityVector[ 1 ] = 0.0;
    regolithVelocityVector[ 2 ] = velocityMagnitude;

    // get the rotatin matrix to go from the rotated intermediate frame back to the initial
    // frame where the z-axis was along the normal axis and the x-axis was pointing towards north
    // direction
    std::vector< std::vector< double > > zBasicRotationMatrix
            { { std::cos( coneAngleAzimuth ), std::sin( coneAngleAzimuth ), 0.0 },
              { -std::sin( coneAngleAzimuth ), std::cos( coneAngleAzimuth ), 0.0 },
              { 0.0, 0.0, 1.0 } };

    std::vector< std::vector< double > > yBasicRotationMatrix
            { { std::cos( coneAngleDeclination ), 0.0, -std::sin( coneAngleDeclination ) },
              { 0.0, 1.0, 0.0 },
              { std::sin( coneAngleDeclination ), 0.0, std::cos( coneAngleDeclination ) } };

    std::vector< std::vector< double > > nonTransposedRotationMatrix( 3, std::vector< double > ( 3 ) );

    matrixMultiplication( yBasicRotationMatrix,
                          zBasicRotationMatrix,
                          nonTransposedRotationMatrix,
                          3,
                          3,
                          3,
                          3 );

    std::vector< std::vector< double > > intermediateFrameRotationMatrix( 3, std::vector< double > ( 3 ) );

    matrixTranspose( nonTransposedRotationMatrix, intermediateFrameRotationMatrix );

    std::vector< std::vector< double > > rotatedIntermediateFrameVelocityVector
                { { regolithVelocityVector[ 0 ] },
                  { regolithVelocityVector[ 1 ] },
                  { regolithVelocityVector[ 2 ] } };

    std::vector< std::vector< double > > intermediateFrameVelocityVector( 3, std::vector< double > ( 1 ) );

    matrixMultiplication( intermediateFrameRotationMatrix,
                          rotatedIntermediateFrameVelocityVector,
                          intermediateFrameVelocityVector,
                          3,
                          3,
                          3,
                          1 );

    // now obtain the basis vectors for the intermediate frame expressed in the
    // body fixed frame coordinates
    std::vector< double > xUnitVector( 3 );
    std::vector< double > yUnitVector( 3 );
    std::vector< double > zUnitVector( 3 );

    zUnitVector = unitNormalVector;

    std::vector< double > bodyFrameZUnitVector { 0.0, 0.0, 1.0 };

    // get the intermediate RTN frame at the surface point
    std::vector< double > unitR = normalize( regolithPositionVector );

    std::vector< double > unitT = normalize( crossProduct( unitR, bodyFrameZUnitVector ) );

    // get the x basis vector, pointing to north
    xUnitVector = normalize( crossProduct( unitT, zUnitVector ) );

    // get the y basis vector
    yUnitVector = normalize( crossProduct( zUnitVector, xUnitVector ) );

    std::vector< double > zPrincipalAxisBodyFrame { 0.0, 0.0, 1.0 };
    std::vector< double > zNegativePrincipalAxisBodyFrame { 0.0, 0.0, -1.0 };

    // check if the position vector is along the poles
    const double positionDotPrincipalZ
            = dotProduct( normalize( regolithPositionVector ), zPrincipalAxisBodyFrame );
    const double positionDotNegativePrincipalZ
            = dotProduct( normalize( regolithPositionVector ), zNegativePrincipalAxisBodyFrame );
    if( positionDotPrincipalZ == 1.0 )
    {
        // the position vector is pointing to the poles, hence x basis vector pointing to the north
        // direction wouldn't work
        xUnitVector = { 1.0, 0.0, 0.0 };
        yUnitVector = { 0.0, 1.0, 0.0 };
    }
    else if( positionDotNegativePrincipalZ == 1.0 )
    {
        xUnitVector = { -1.0, 0.0, 0.0 };
        yUnitVector = { 0.0, 1.0, 0.0 };
    }

    // put the basis vectors in a 3x3 matrix
    std::vector< std::vector< double > > intermediateFrameBasisMatrix
            { { xUnitVector[ 0 ], yUnitVector[ 0 ], zUnitVector[ 0 ] },
              { xUnitVector[ 1 ], yUnitVector[ 1 ], zUnitVector[ 1 ] },
              { xUnitVector[ 2 ], yUnitVector[ 2 ], zUnitVector[ 2 ] } };

    std::vector< std::vector< double > > bodyFrameVelocityVector( 3, std::vector< double >( 1 ) );

    matrixMultiplication( intermediateFrameBasisMatrix,
                          intermediateFrameVelocityVector,
                          bodyFrameVelocityVector,
                          3,
                          3,
                          3,
                          1 );

    // return the final regolith velocity vector, expressed in body frame coordinates
    regolithVelocityVector[ 0 ] = bodyFrameVelocityVector[ 0 ][ 0 ];
    regolithVelocityVector[ 1 ] = bodyFrameVelocityVector[ 1 ][ 0 ];
    regolithVelocityVector[ 2 ] = bodyFrameVelocityVector[ 2 ][ 0 ];
}