⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 matrix.c

📁 利用语言编写的有限元分析软件
💻 C
📖 第 1 页 / 共 5 页
字号:

   return (q);
}

QUANTITY *MatrixL2Norm(m)
MATRIX   *m;
{
QUANTITY *q;
double   sum = 0.0;
int i;

#ifdef DEBUG
       printf("*** Enter MatrixL2Norm() : m->iNoRows    = %4d\n", m->iNoRows);
       printf("                         : m->iNoColumns = %4d\n", m->iNoColumns);
#endif

   /* Check that matrix is either a column (or row) vector */

      if((m->iNoRows != 1) && (m->iNoColumns != 1)) {
          FatalError("In MatrixL2Norm() : Matrix is not a row (or column) vector",(char *)NULL);
      }

   /* Compute L2 Norm for column/row vector */

   sum       =  dVmatrixL2Norm(m->uMatrix.daa, m->iNoRows, m->iNoColumns);
   q         = (QUANTITY *) MyCalloc(1,sizeof(QUANTITY));
   q->value  = sum;
   if(CheckUnits() == ON) {
      q->dimen  = (DIMENSIONS *) MyCalloc(1,sizeof(DIMENSIONS));
      ZeroUnits(q->dimen);
   } else
      q->dimen  = (DIMENSIONS *)NULL;

   return (q);
}

/* 
 *  =================
 *  Matrix Dimensions 
 *  ================= 
 */ 

#ifdef __STDC__
MATRIX *MatrixDimension(MATRIX *m1)
#else
MATRIX *MatrixDimension(m1)
MATRIX *m1;
#endif
{
MATRIX *m2;

      m2 = MatrixAllocIndirect("Dimensions", DOUBLE_ARRAY, 1, 2);
      m2->uMatrix.daa[0][0]  = m1->iNoRows;
      m2->uMatrix.daa[0][1]  = m1->iNoColumns;
      if(CheckUnits()==ON) {
         ZeroUnits(&(m2->spRowUnits[0]));
         ZeroUnits(&(m2->spColUnits[0]));
         ZeroUnits(&(m2->spColUnits[1]));
      }

      return (m2);
}

/* 
 *  ================================================= 
 *  MatrixScale() : Scale a matrix by a double factor
 *  ================================================= 
 */ 

#ifdef __STDC__
MATRIX *MatrixScale(MATRIX *spA, double factor )
#else
MATRIX *MatrixScale(spA, factor )
MATRIX  *spA;
double  factor;
#endif
{
MATRIX *spB;

#ifdef DEBUG
       printf("*** Enter MatrixScale() : spA->iNoRows    = %4d\n", spA->iNoRows);
       printf("                        : spA->iNoColumns = %4d\n", spA->iNoColumns);
#endif
 
       switch((int) spA->eRep) {
           case INDIRECT:
                switch((int) spA->eType) {
                    case DOUBLE_ARRAY:
                         spB = MatrixScaleIndirectDouble( spA, factor );
                         break;
                    default:
                         FatalError("In MatrixScale() : Undefined spA->eType",
                                   (char *) NULL);
                         break;
                }
                break;
           case SKYLINE:
                spB = MatrixScaleSkyline( spA, factor );
                break;
          default:
                FatalError("In MatrixScale() : Undefined spA->eRep",
                          (char *) NULL);
                break;
       }

#ifdef DEBUG
       printf("*** Leave MatrixScale()\n");
#endif
       return ( spB );
}

#ifdef __STDC__
double MatrixContentScale(MATRIX *spA, int row_no, int col_no )
#else
double MatrixContentScale(spA, row_no, col_no )
MATRIX  *spA;
int row_no;        /* row number    */
int col_no;        /* column number */
#endif
{
double  da;

#ifdef DEBUG
       printf("*** Enter MatrixContentScale() : spA->iNoRows    = %4d\n", spA->iNoRows);
       printf("                        : spA->iNoColumns = %4d\n", spA->iNoColumns);
#endif
      if(CheckUnits()==OFF) 
         FatalError("You have to set units ON to use this function","In MatrixScale",(char *)NULL );
 
     /* [a] Scale for Column of matrix spA */

       switch((int) spA->eRep) {
           case INDIRECT:
                switch((int) spA->eType) {
                    case DOUBLE_ARRAY:
                         da = MatrixContentScaleIndirectDouble( spA, row_no, col_no );
                         break;
                    default:
                         FatalError("In MatrixContentScale() : Undefined spA->eType",
                                   (char *) NULL);
                         break;
                }
                break;
           case SKYLINE:
                da = MatrixContentScaleSkyline( spA, row_no, col_no );
                break;
          default:
                FatalError("In MatrixContentScale() : Undefined spA->eRep",
                          (char *) NULL);
                break;
       }

#ifdef DEBUG
       printf("*** Leave MatrixContentScale()\n");
#endif

       return ( da );
}

/* ======================================
   Operations between QUANTITY and MATRIX
   ====================================== */

#ifdef __STDC__
MATRIX *MatrixQuanMult(QUANTITY *q1, MATRIX *m2)
#else
MATRIX *MatrixQuanMult(q1, m2)
QUANTITY *q1;
MATRIX   *m2;
#endif
{
MATRIX     *m3;
int      i,j,k;
int     length;
DIMENSIONS *d1;

   /* [a] : Multiply a quantity to a matrix */

   m3 = MatrixScale( m2, q1->value );
       
   if( CheckUnits() == ON ) {
       for(i = 1; i <= m2->iNoRows; i++) {
           UnitsCopy( &(m3->spRowUnits[i-1]), &(m2->spRowUnits[i-1]) );
           for(j = 1; j <= m2->iNoColumns; j++)
               UnitsMultRep( &(m3->spColUnits[j-1]), q1->dimen, &(m2->spColUnits[j-1]) );
       }
   }

   return (m3);
}

#ifdef __STDC__
MATRIX *MatrixQuanDiv(MATRIX *m2, QUANTITY *q1)
#else
MATRIX *MatrixQuanDiv(m2, q1)
QUANTITY *q1;
MATRIX   *m2;
#endif
{
MATRIX         *m3;
DIMENSIONS     *d1;
int          i,j,k;
int         length;

    /* [a] : matrix is divdied by a quantity */

    m3 = MatrixScale( m2, 1.0/q1->value );
       
    if( CheckUnits()==ON ) {
        for(i = 1; i <= m2->iNoRows; i++) {
            UnitsCopy( &(m3->spRowUnits[i-1]), &(m2->spRowUnits[i-1]) );
            for(j = 1; j <= m2->iNoColumns; j++)
                UnitsDivRep( &(m3->spColUnits[j-1]), &(m2->spColUnits[j-1]), q1->dimen, YES);
        }
    }

    return (m3);
}

/* 
 *  =================================================
 *  QuantityCast() : convert 1x1 matrix into quantity 
 *  =================================================
 */ 

#ifdef __STDC__
QUANTITY *QuantityCast( MATRIX *m )
#else
QUANTITY *QuantityCast(m)
MATRIX   *m;
#endif
{
QUANTITY         *q;
int          length;

   /* [a] : Check that matrix is either a column (or row) vector */

   if((m->iNoRows != 1) || (m->iNoColumns != 1)) {
       FatalError("In Quantity_Cast() : Matrix is not a 1x1 Matrix",(char *)NULL);
   }

   q            = (QUANTITY *) MyCalloc(1,sizeof(QUANTITY));
   q->value     = m->uMatrix.daa[0][0];

   switch(CheckUnits()) {
      case ON:
           q->dimen = UnitsMult( &(m->spRowUnits[0]), &(m->spColUnits[0]) );
           break;
      case OFF:
           q->dimen = (DIMENSIONS *)NULL;
           break;
   }
     
   return (q);
}


/* 
 *  ==========================================================
 *  MatrixColumnUnits() : Specify Column Units in a Matrix
 *  
 *  Usage:  1st Argument is pointer to matrix concerned.
 *          2nd Argument is matrix of units to be applied.
 *          3rd Argument column number for units.
 *  
 *  Examples : matrix = ColumnUnits( matrix, [ kg ] );
 *             matrix = ColumnUnits( matrix, [ kg ], [2] );
 *  ==========================================================
 */ 

#ifdef  __STDC__
MATRIX *MatrixColumnUnits(MATRIX *first_matrix, ...) {
#else
MATRIX *MatrixColumnUnits(va_alist)
va_dcl
{
MATRIX     *first_matrix;
#endif

va_list          arg_ptr;
MATRIX                *p;
MATRIX *m, *m1, *units_m;
int     i, j, k, counter;
int    NO_COL_WITH_UNITS;
int NO_COL_WITH_NO_UNITS;
int               *COUNT;
int           ID, COL_NO;
int               length;
int       iFLAG  = FALSE;
int       iFLAG1 = FALSE;

   /* [a] : Check units flags and get appropriate units */

   if( CheckUnits() == OFF) {
       FatalError("In MatrixColumnUnits () : To call this function, units must be set to ON ",
                 (char *)NULL );
   }

   /* [b] : Get appropriate units */

#ifdef  __STDC__
    va_start(arg_ptr, first_matrix);
#else
    va_start(arg_ptr);
    first_matrix = va_arg(arg_ptr, MATRIX *);
#endif

    m1 = first_matrix;
    units_m = va_arg(arg_ptr, MATRIX *);
    p       = va_arg(arg_ptr, MATRIX *);
    m       = MatrixCopyIndirectDouble(m1);
    va_end(arg_ptr);

   /* [c] : Retrieve and check appropriate units */

   if( p != NULL) {
       ID = 1; 
       COL_NO  = p->uMatrix.daa[0][0]; 
   } else
       ID = 2;

   if(units_m->iNoRows != 1) 
      FatalError("Fatal Error in MatrixColumnUnits(): Units_matrix should be a 1xn vector",
                (char *) NULL); 

   /* [d] : Case 1 : Update "column units" in one column only.              */
   /*                                                                       */
   /*       Two cases exist -- (1.1) Column i of matrix m has no units      */
   /*                          (1.2) Column i of matrix m has units.        */
   /*                                Check compatibility with units_m.      */
   /*                                Copy unmits_m to m.                    */
   /*                                                                       */
   /*       Examples : stiff = Matrix([2,2]);                               */
   /*                  stiff = ColumnUnits ( stiff, [  sec], [1] );         */
   /*                  stiff = ColumnUnits ( stiff, [sec^2], [2] );         */
   /*                                                                       */

   if (ID == 1) {

      if(units_m->iNoColumns != 1) 
         FatalError("In MatrixColumnUnits(): too many units for one column ",(char *)NULL);

      i = COL_NO; /* column no i is to be assigned an unit  */

      if(m->spColUnits[i-1].length_expnt == 0 &&
         m->spColUnits[i-1].time_expnt == 0   &&
         m->spColUnits[i-1].mass_expnt == 0   &&
         m->spColUnits[i-1].temp_expnt == 0) {

         /* Case (1.1) : Assign units from units_m to m */
          
         UnitsCopy( &(m->spColUnits[i-1]), &(units_m->spColUnits[0]) );
         for(j = 1; j <= m->iNoRows; j++)
             m->uMatrix.daa[j-1][i-1] = 
                units_m->spColUnits[0].scale_factor*m->uMatrix.daa[j-1][i-1];
      } else {

         /* Case (1.2) : Check with units_m, and copy units_m to units of m */
           
         if( SameUnits( &(m->spColUnits[i-1]), &(units_m->spColUnits[0])) == TRUE ){
             UnitsCopy( &(m->spColUnits[i-1]), &(units_m->spColUnits[0]) );
         } else {
             FatalError("In MatrixColumnUnits(): Inconsistent units",
                       (char *) NULL );
         }
      }
   }

   /* [e] : Case 2 : Update "units" in multiple matrix columns.                      */
   /*                                                                                */
   /*       Cases -- (2.1) Matrix m and units_m have the same number of columns.     */
   /*                (2.1.1) : Matrix m has no units. Assign units from units_m to m */
   /*                (2.1.2) : Matrix m has units. Copy units_m to units of m.       */
   /*                (2.2) Matrices m and units_m have different number of columns.  */
   /*                (2.2.1) : matrix m rows have no units. Assign all columns of m  */
   /*                          with units of units_m                                 */
   /*                (2.2.2) : Assign unit_m to columns of m where they match.       */
   /*                                                                                */
   /*       Examples : stiff = Matrix([3,3]);                                        */
   /*                  stiff = ColumnUnits ( stiff, [cm/sec^2], [1] );               */
   /*                  stiff = ColumnUnits ( stiff, [sec] );                         */
   /*                  stiff = ColumnUnits ( stiff, [in/sec^2] );                    */
   /*                                                                                */

   if (ID == 2) {

      /* Case (2.1) : Matrices m and units_m have same number of columns */

      if(units_m->iNoColumns == m->iNoColumns) {
         for (i = 1; i <= m->iNoColumns; i++) { 

            if(m->spColUnits[i-1].length_expnt == 0 && 
               m->spColUnits[i-1].time_expnt == 0   &&
               m->spColUnits[i-1].mass_expnt == 0   &&
               m->spColUnits[i-1].temp_expnt == 0) {

               /* Case (2.1.1) : Matrix m has no units -- Assign units from units_m to m */

               UnitsCopy( &(m->spColUnits[i-1]), &(units_m->spColUnits[i-1]) );
               for(j = 1; j <= m->iNoRows; j++)
                   m->uMatrix.daa[j-1][i-1] = 
                      units_m->spColUnits[i-1].scale_factor*m->uMatrix.daa[j-1][i-1];

            } else {

               /* Case (2.1.2) : Matrix m has units. Che

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -