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

📄 spbuild.c

📁 DTMK软件开发包,此为开源软件,是一款很好的医学图像开发资源.
💻 C
📖 第 1 页 / 共 3 页
字号:

#if NOT EXPANDABLE
        vASSERT( IntRow <= Matrix->Size, "Matrix size fixed" );
#endif

#if EXPANDABLE
/* Re-size Matrix if necessary. */
        if (IntRow > Matrix->Size)
            EnlargeMatrix( Matrix, IntRow );
        if (Matrix->Error == spNO_MEMORY) return;
#endif

        Matrix->IntToExtRowMap[IntRow] = ExtRow;
        Matrix->IntToExtColMap[IntRow] = ExtRow;
    }

/* Translate external column or node number to internal column or node number.*/
    if ((IntCol = Matrix->ExtToIntColMap[ExtCol]) == -1)
    {   Matrix->ExtToIntRowMap[ExtCol] = ++Matrix->CurrentSize;
        Matrix->ExtToIntColMap[ExtCol] = Matrix->CurrentSize;
        IntCol = Matrix->CurrentSize;

#if NOT EXPANDABLE
        vASSERT( IntCol <= Matrix->Size, "Matrix size fixed" );
#endif

#if EXPANDABLE
/* Re-size Matrix if necessary. */
        if (IntCol > Matrix->Size)
            EnlargeMatrix( Matrix, IntCol );
        if (Matrix->Error == spNO_MEMORY) return;
#endif

        Matrix->IntToExtRowMap[IntCol] = ExtCol;
        Matrix->IntToExtColMap[IntCol] = ExtCol;
    }

    *Row = IntRow;
    *Col = IntCol;
    return;
}
#endif






#if QUAD_ELEMENT
/*!
 *  Performs same function as spGetElement() except rather than one
 *  element, all four matrix elements for a floating two terminal
 *  admittance component are added. This routine also works if component
 *  is grounded.  Positive elements are placed at [Node1,Node2] and
 *  [Node2,Node1].  This routine is only to be used after spCreate()
 *  and before spMNA_Preorder(), spFactor() or spOrderAndFactor().
 *
 *  \return
 *  Error code. Possible errors include \a spNO_MEMORY.
 *  Error is not cleared in this routine.
 *
 *  \param Matrix
 *     Pointer to the matrix that component is to be entered in.
 *  \param Node1
 *     Row and column indices for elements. Must be in the range of [0..Size]
 *     unless the options \a EXPANDABLE or \a TRANSLATE are used. Node zero is the
 *     ground node.  In no case may \a Node1 be less than zero.
 *  \param Node2
 *     Row and column indices for elements. Must be in the range of [0..Size]
 *     unless the options \a EXPANDABLE or \a TRANSLATE are used. Node zero is the
 *     ground node.  In no case may \a Node2 be less than zero.
 *  \param Template
 *     Collection of pointers to four elements that are later used to directly
 *     address elements.  User must supply the template, this routine will
 *     fill it.
 */

spError
spGetAdmittance(
    spMatrix Matrix,
    int Node1,
    int Node2,
    struct spTemplate *Template
)
{

/* Begin `spGetAdmittance'. */
    Template->Element1 = spGetElement(Matrix, Node1, Node1 );
    Template->Element2 = spGetElement(Matrix, Node2, Node2 );
    Template->Element3Negated = spGetElement( Matrix, Node2, Node1 );
    Template->Element4Negated = spGetElement( Matrix, Node1, Node2 );
    if
    (   (Template->Element1 == NULL)
        OR (Template->Element2 == NULL)
        OR (Template->Element3Negated == NULL)
        OR (Template->Element4Negated == NULL)
    )   return spNO_MEMORY;

    if (Node1 == 0)
        SWAP( RealNumber*, Template->Element1, Template->Element2 );

    return spOKAY;
}
#endif /* QUAD_ELEMENT */









#if QUAD_ELEMENT
/*!
 *  Similar to spGetAdmittance(), except that spGetAdmittance() only
 *  handles 2-terminal components, whereas spGetQuad() handles simple
 *  4-terminals as well.  These 4-terminals are simply generalized
 *  2-terminals with the option of having the sense terminals different
 *  from the source and sink terminals.  spGetQuad() adds four
 *  elements to the matrix.  Positive elements occur at [Row1,Col1]
 *  [Row2,Col2] while negative elements occur at [Row1,Col2] and [Row2,Col1].
 *  The routine works fine if any of the rows and columns are zero.
 *  This routine is only to be used after spCreate() and before
 *  spMNA_Preorder(), spFactor() or spOrderAndFactor()
 *  unless \a TRANSLATE is set true.
 *
 *  \return
 *  Error code. Possible errors include \a spNO_MEMORY.
 *  Error is not cleared in this routine.
 *
 *  \param Matrix
 *     Pointer to the matrix that component is to be entered in.
 *  \param Row1
 *     First row index for elements. Must be in the range of [0..Size]
 *     unless the options \a EXPANDABLE or \a TRANSLATE are used. Zero is the
 *     ground row.  In no case may Row1 be less than zero.
 *  \param Row2
 *     Second row index for elements. Must be in the range of [0..Size]
 *     unless the options \a EXPANDABLE or \a TRANSLATE are used. Zero is the
 *     ground row.  In no case may Row2 be less than zero.
 *  \param Col1
 *     First column index for elements. Must be in the range of [0..Size]
 *     unless the options \a EXPANDABLE or \a TRANSLATE are used. Zero is the
 *     ground column.  In no case may Col1 be less than zero.
 *  \param Col2
 *     Second column index for elements. Must be in the range of [0..Size]
 *     unless the options \a EXPANDABLE or \a TRANSLATE are used. Zero is the
 *     ground column.  In no case may Col2 be less than zero.
 *  \param Template
 *     Collection of pointers to four elements that are later used to directly
 *     address elements.  User must supply the template, this routine will
 *     fill it.
 */

spError
spGetQuad(
    spMatrix Matrix,
    int Row1,
    int Row2,
    int Col1,
    int Col2,
    struct  spTemplate  *Template
)
{
/* Begin `spGetQuad'. */
    Template->Element1 = spGetElement( Matrix, Row1, Col1);
    Template->Element2 = spGetElement( Matrix, Row2, Col2 );
    Template->Element3Negated = spGetElement( Matrix, Row2, Col1 );
    Template->Element4Negated = spGetElement( Matrix, Row1, Col2 );
    if
    (   (Template->Element1 == NULL)
        OR (Template->Element2 == NULL)
        OR (Template->Element3Negated == NULL)
        OR (Template->Element4Negated == NULL)
    )   return spNO_MEMORY;

    if (Template->Element1 == &((MatrixPtr)Matrix)->TrashCan.Real)
        SWAP( RealNumber *, Template->Element1, Template->Element2 );

    return spOKAY;
}
#endif /* QUAD_ELEMENT */









#if QUAD_ELEMENT
/*!
 *  Addition of four structural ones to matrix by index.
 *  Performs similar function to spGetQuad() except this routine is
 *  meant for components that do not have an admittance representation.
 *
 *  The following stamp is used: \code
 *         Pos  Neg  Eqn
 *  Pos  [  .    .    1  ]
 *  Neg  [  .    .   -1  ]
 *  Eqn  [  1   -1    .  ]
 *  \endcode
 *
 *  \return
 *  Error code. Possible errors include \a spNO_MEMORY.
 *  Error is not cleared in this routine.
 *
 *  \param Matrix
 *     Pointer to the matrix that component is to be entered in.
 *  \param Pos
 *     See stamp above. Must be in the range of [0..Size]
 *     unless the options \a EXPANDABLE or \a TRANSLATE are used. Zero is the
 *     ground row.  In no case may \a Pos be less than zero.
 *  \param Neg
 *     See stamp above. Must be in the range of [0..Size]
 *     unless the options \a EXPANDABLE or \a TRANSLATE are used. Zero is the
 *     ground row.  In no case may \a Neg be less than zero.
 *  \param Eqn
 *     See stamp above. Must be in the range of [0..Size]
 *     unless the options \a EXPANDABLE or \a TRANSLATE are used. Zero is the
 *     ground row.  In no case may \a Eqn be less than zero.
 *  \param Template
 *     Collection of pointers to four elements that are later used to directly
 *     address elements.  User must supply the template, this routine will
 *     fill it.
 */

spError
spGetOnes(
    spMatrix Matrix,
    int Pos,
    int Neg,
    int Eqn,
    struct spTemplate *Template
)
{
/* Begin `spGetOnes'. */
    Template->Element4Negated = spGetElement( Matrix, Neg, Eqn );
    Template->Element3Negated = spGetElement( Matrix, Eqn, Neg );
    Template->Element2 = spGetElement( Matrix, Pos, Eqn );
    Template->Element1 = spGetElement( Matrix, Eqn, Pos );
    if
    (   (Template->Element1 == NULL)
        OR (Template->Element2 == NULL)
        OR (Template->Element3Negated == NULL)
        OR (Template->Element4Negated == NULL)
    )   return spNO_MEMORY;

    spADD_REAL_QUAD( *Template, 1.0 );
    return spOKAY;
}
#endif /* QUAD_ELEMENT */







/*
 *  FIND DIAGONAL
 *
 *  This routine is used to find a diagonal element.  It will not
 *  create it if it does not exist.
 *
 *  >>> Returned:
 *  A pointer to the desired element, or NULL if it does not exist.
 *
 *  >>> Arguments:
 *  Matrix  <input>  (MatrixPtr)
 *      Pointer to matrix.
 *  Index  <input>  (int)
 *      Row, Col index for diagonal element.
 *
 *  >>> Local variables:
 *  pElement  (ElementPtr)
 *      Pointer to an element in the matrix.
 */

ElementPtr
spcFindDiag(
    MatrixPtr Matrix,
    register int Index
)
{
register ElementPtr  pElement;

/* Begin `spcFindDiag'. */
    pElement = Matrix->FirstInCol[Index];

/* Search column for element. */
    while ((pElement != NULL) AND (pElement->Row < Index))
        pElement = pElement->NextInCol;
    if (pElement AND (pElement->Row == Index))
        return pElement;
    else
        return NULL;
}








/*
 *  CREATE AND SPLICE ELEMENT INTO MATRIX
 *
 *  This routine is used to create new matrix elements and splice them into the
 *  matrix.
 *
 *  >>> Returned:
 *  A pointer to the element that was created is returned.
 *
 *  >>> Arguments:
 *  Matrix  <input>  (MatrixPtr)
 *      Pointer to matrix.
 *  Row  <input>  (int)
 *      Row index for element.
 *  Col  <input>  (int)
 *      Column index for element.
 *  ppToLeft  <input-output>  (ElementPtr *)
 *      This contains the address of the pointer to an element to the left
 *      of the one being created.  It is used to speed the search and if it
 *      is immediately to the left, it is updated with address of the
 *      created element.
 *  ppAbove  <input-output> (ElementPtr *)
 *      This contains the address of the pointer to an element above the
 *      one being created.  It is used to speed the search and it if it
 *      is immediatley above, it is updated with address of the created
 *      element.
 *  Fillin  <input>  (BOOLEAN)
 *      Flag that indicates if created element is to be a fill-in.
 *
 *  >>> Local variables:
 *  pElement  (ElementPtr)
 *      Pointer to an element in the matrix.
 *  pCreatedElement  (ElementPtr)
 *      Pointer to the desired element, the one that was just created.
 *
 *  >>> Possible errors:
 *  spNO_MEMORY
 */

ElementPtr
spcCreateElement(
    MatrixPtr Matrix,
    int Row,
    register int Col,
    register ElementPtr *ppToLeft,
    register ElementPtr *ppAbove,
    BOOLEAN Fillin
)
{
register ElementPtr  pElement, pCreatedElement;

/* Begin `spcCreateElement'. */

/* Find element immediately above the desired element. */
    pElement = *ppAbove;
    while ((pElement != NULL) AND (pElement->Row < Row))
    {   ppAbove = &pElement->NextInCol;
        pElement = *ppAbove;
    }
    if ((pElement != NULL) AND (pElement->Row == Row))
        return pElement;

/* The desired element does not exist, create it. */
    if (Fillin)
    {   pCreatedElement = spcGetFillin( Matrix );
        Matrix->Fillins++;

/* Update Markowitz counts and products. */
        ++Matrix->MarkowitzRow[Row];
        spcMarkoProd( Matrix->MarkowitzProd[Row],
                      Matrix->MarkowitzRow[Row],
                      Matrix->MarkowitzCol[Row] );
        if ((Matrix->MarkowitzRow[Row] == 1) AND
            (Matrix->MarkowitzCol[Row] != 0))
        {
            Matrix->Singletons--;
        }
        ++Matrix->MarkowitzCol[Col];
        spcMarkoProd( Matrix->MarkowitzProd[Col],
                      Matrix->MarkowitzCol[Col],
                      Matrix->MarkowitzRow[Col] );
        if ((Matrix->MarkowitzRow[Col] != 0) AND
            (Matrix->MarkowitzCol[Col] == 1))
        {
            Matrix->Singletons--;
        }
    }
    else
    {   pCreatedElement = spcGetElement( Matrix );
        Matrix->NeedsOrdering = YES;
    }
    if (pCreatedElement == NULL) return NULL;
    Matrix->Elements++;

/* Initialize Element. */
    pCreatedElement->Row = Row;
    pCreatedElement->Col = Col;
    pCreatedElement->Real = 0.0;
#if spCOMPLEX
    pCreatedElement->Imag = 0.0;
#endif

⌨️ 快捷键说明

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