COMPLEX64 dlm_get_det_trfC(COMPLEX64* A, INT32 nXA, void* ipiv) { INT32 iXA = 0; COMPLEX64 det = CMPLX(1.0); BOOL neg = FALSE; integer* p_ipiv = (integer*) ipiv; for (iXA = 0; iXA < nXA; ++iXA) { det = CMPLX_MULT(det,A[iXA+iXA*nXA]); neg = (p_ipiv[iXA] != (iXA + 1)) ? !neg : neg; } return neg ? CMPLX_NEG(det) : det; }
static void SolveComplexTransposedMatrix(MatrixPtr Matrix, RealVector RHS, RealVector Solution IMAG_VECTORS ) { register ElementPtr pElement; register ComplexVector Intermediate; register int I, *pExtOrder, Size; register ComplexVector ExtVector; ElementPtr pPivot; ComplexNumber Temp; /* Begin `SolveComplexTransposedMatrix'. */ Size = Matrix->Size; Intermediate = (ComplexVector)Matrix->Intermediate; /* Correct array pointers for ARRAY_OFFSET. */ #if NOT ARRAY_OFFSET #if spSEPARATED_COMPLEX_VECTORS --RHS; --iRHS; --Solution; --iSolution; #else RHS -= 2; Solution -= 2; #endif #endif /* Initialize Intermediate vector. */ pExtOrder = &Matrix->IntToExtColMap[Size]; #if spSEPARATED_COMPLEX_VECTORS for (I = Size; I > 0; I--) { Intermediate[I].Real = RHS[*(pExtOrder)]; Intermediate[I].Imag = iRHS[*(pExtOrder--)]; } #else ExtVector = (ComplexVector)RHS; for (I = Size; I > 0; I--) { Intermediate[I] = ExtVector[*(pExtOrder--)]; } #endif /* Forward elimination. */ for (I = 1; I <= Size; I++) { Temp = Intermediate[I]; /* This step of the elimination is skipped if Temp equals zero. */ if ((Temp.Real != 0.0) OR (Temp.Imag != 0.0)) { pElement = Matrix->Diag[I]->NextInRow; while (pElement != NULL) { /* Cmplx expr: Intermediate[Element->Col] -= Temp * *Element. */ CMPLX_MULT_SUBT_ASSIGN( Intermediate[pElement->Col], Temp, *pElement); pElement = pElement->NextInRow; } } } /* Backward Substitution. */ for (I = Size; I > 0; I--) { pPivot = Matrix->Diag[I]; Temp = Intermediate[I]; pElement = pPivot->NextInCol; while (pElement != NULL) { /* Cmplx expr: Temp -= Intermediate[Element->Row] * *Element. */ CMPLX_MULT_SUBT_ASSIGN(Temp, Intermediate[pElement->Row], *pElement); pElement = pElement->NextInCol; } /* Cmplx expr: Intermediate = Temp * (1.0 / *pPivot). */ CMPLX_MULT(Intermediate[I], Temp, *pPivot); } /* Unscramble Intermediate vector while placing data in to Solution vector. */ pExtOrder = &Matrix->IntToExtRowMap[Size]; #if spSEPARATED_COMPLEX_VECTORS for (I = Size; I > 0; I--) { Solution[*(pExtOrder)] = Intermediate[I].Real; iSolution[*(pExtOrder--)] = Intermediate[I].Imag; } #else ExtVector = (ComplexVector)Solution; for (I = Size; I > 0; I--) { ExtVector[*(pExtOrder--)] = Intermediate[I]; } #endif return; }
static void SolveComplexTransposedMatrix(MatrixPtr Matrix, RealVector RHS, RealVector Solution , RealVector iRHS, RealVector iSolution ) { ElementPtr pElement; ComplexVector Intermediate; int I, *pExtOrder, Size; ElementPtr pPivot; ComplexNumber Temp; /* Begin `SolveComplexTransposedMatrix'. */ Size = Matrix->Size; Intermediate = (ComplexVector)Matrix->Intermediate; /* Initialize Intermediate vector. */ pExtOrder = &Matrix->IntToExtColMap[Size]; for (I = Size; I > 0; I--) { Intermediate[I].Real = RHS[*(pExtOrder)]; Intermediate[I].Imag = iRHS[*(pExtOrder--)]; } /* Forward elimination. */ for (I = 1; I <= Size; I++) { Temp = Intermediate[I]; /* This step of the elimination is skipped if Temp equals zero. */ if ((Temp.Real != 0.0) || (Temp.Imag != 0.0)) { pElement = Matrix->Diag[I]->NextInRow; while (pElement != NULL) { /* Cmplx expr: Intermediate[Element->Col] -= Temp * *Element. */ CMPLX_MULT_SUBT_ASSIGN( Intermediate[pElement->Col], Temp, *pElement); pElement = pElement->NextInRow; } } } /* Backward Substitution. */ for (I = Size; I > 0; I--) { pPivot = Matrix->Diag[I]; Temp = Intermediate[I]; pElement = pPivot->NextInCol; while (pElement != NULL) { /* Cmplx expr: Temp -= Intermediate[Element->Row] * *Element. */ CMPLX_MULT_SUBT_ASSIGN(Temp,Intermediate[pElement->Row],*pElement); pElement = pElement->NextInCol; } /* Cmplx expr: Intermediate = Temp * (1.0 / *pPivot). */ CMPLX_MULT(Intermediate[I], Temp, *pPivot); } /* Unscramble Intermediate vector while placing data in to Solution vector. */ pExtOrder = &Matrix->IntToExtRowMap[Size]; for (I = Size; I > 0; I--) { Solution[*(pExtOrder)] = Intermediate[I].Real; iSolution[*(pExtOrder--)] = Intermediate[I].Imag; } return; }
SPcomplex * oxideAdmittance(TWOdevice *pDevice, TWOcontact *pContact, BOOLEAN delVContact, double *xReal, double *xImag, SPcomplex *cOmega) { TWOnode *pNode, *pHNode = NULL, *pVNode = NULL; TWOedge *pHEdge, *pVEdge; int index, i, indexPsi, numContactNodes; TWOelem *pElem; SPcomplex psiAc; SPcomplex prod1, prod2; NG_IGNORE(pDevice); CMPLX_ASSIGN_VALUE(yTotal, 0.0, 0.0); numContactNodes = pContact->numNodes; for (index = 0; index < numContactNodes; index++) { pNode = pContact->pNodes[index]; for (i = 0; i <= 3; i++) { pElem = pNode->pElems[i]; if (pElem != NULL) { switch (i) { case 0: /* the TL element */ pHNode = pElem->pBLNode; pVNode = pElem->pTRNode; pHEdge = pElem->pBotEdge; pVEdge = pElem->pRightEdge; break; case 1: /* the TR element */ pHNode = pElem->pBRNode; pVNode = pElem->pTLNode; pHEdge = pElem->pBotEdge; pVEdge = pElem->pLeftEdge; break; case 2: /* the BR element */ pHNode = pElem->pTRNode; pVNode = pElem->pBLNode; pHEdge = pElem->pTopEdge; pVEdge = pElem->pLeftEdge; break; case 3: /* the BL element */ pHNode = pElem->pTLNode; pVNode = pElem->pBRNode; pHEdge = pElem->pTopEdge; pVEdge = pElem->pRightEdge; break; } /* displacement current terms */ if (pHNode->nodeType != CONTACT) { indexPsi = pHNode->psiEqn; CMPLX_ASSIGN_VALUE(psiAc, xReal[indexPsi], xImag[indexPsi]); CMPLX_MULT_SCALAR(prod1, *cOmega, pElem->epsRel * 0.5 * pElem->dyOverDx); CMPLX_MULT(prod2, prod1, psiAc); CMPLX_SUBT_ASSIGN(yTotal, prod2); if (delVContact) { CMPLX_ADD_ASSIGN(yTotal, prod1); } } if (pVNode->nodeType != CONTACT) { indexPsi = pVNode->psiEqn; CMPLX_ASSIGN_VALUE(psiAc, xReal[indexPsi], xImag[indexPsi]); CMPLX_MULT_SCALAR(prod1, *cOmega, pElem->epsRel * 0.5 * pElem->dxOverDy); CMPLX_MULT(prod2, prod1, psiAc); CMPLX_SUBT_ASSIGN(yTotal, prod2); if (delVContact) { CMPLX_ADD_ASSIGN(yTotal, prod1); } } } } } return (&yTotal); }
SPcomplex * contactAdmittance(TWOdevice *pDevice, TWOcontact *pContact, BOOLEAN delVContact, double *xReal, double *xImag, SPcomplex *cOmega) { TWOnode *pNode, *pHNode = NULL, *pVNode = NULL; TWOedge *pHEdge = NULL, *pVEdge = NULL; int index, i, indexPsi, indexN, indexP, numContactNodes; TWOelem *pElem; SPcomplex psiAc, nAc, pAc; SPcomplex prod1, prod2, sum; double temp; NG_IGNORE(pDevice); CMPLX_ASSIGN_VALUE(yTotal, 0.0, 0.0); numContactNodes = pContact->numNodes; for (index = 0; index < numContactNodes; index++) { pNode = pContact->pNodes[index]; for (i = 0; i <= 3; i++) { pElem = pNode->pElems[i]; if (pElem != NULL) { switch (i) { case 0: /* the TL element */ pHNode = pElem->pBLNode; pVNode = pElem->pTRNode; pHEdge = pElem->pBotEdge; pVEdge = pElem->pRightEdge; if (pElem->elemType == SEMICON) { /* compute the derivatives with n,p */ if (pHNode->nodeType != CONTACT) { indexN = pHNode->nEqn; indexP = pHNode->pEqn; CMPLX_ASSIGN_VALUE(nAc, xReal[indexN], xImag[indexN]); CMPLX_ASSIGN_VALUE(pAc, xReal[indexP], xImag[indexP]); CMPLX_MULT_SCALAR(prod1, nAc, pHEdge->dJnDn); CMPLX_MULT_SCALAR(prod2, pAc, pHEdge->dJpDp); CMPLX_ADD(sum, prod1, prod2); CMPLX_MULT_SCALAR(prod1, sum, 0.5 * pElem->dy); CMPLX_SUBT_ASSIGN(yTotal, prod1); } if (pVNode->nodeType != CONTACT) { indexN = pVNode->nEqn; indexP = pVNode->pEqn; CMPLX_ASSIGN_VALUE(nAc, xReal[indexN], xImag[indexN]); CMPLX_ASSIGN_VALUE(pAc, xReal[indexP], xImag[indexP]); CMPLX_MULT_SCALAR(prod1, nAc, pVEdge->dJnDn); CMPLX_MULT_SCALAR(prod2, pAc, pVEdge->dJpDp); CMPLX_ADD(sum, prod1, prod2); CMPLX_MULT_SCALAR(prod1, sum, 0.5 * pElem->dx); CMPLX_SUBT_ASSIGN(yTotal, prod1); } } break; case 1: /* the TR element */ pHNode = pElem->pBRNode; pVNode = pElem->pTLNode; pHEdge = pElem->pBotEdge; pVEdge = pElem->pLeftEdge; if (pElem->elemType == SEMICON) { /* compute the derivatives with n,p */ if (pHNode->nodeType != CONTACT) { indexN = pHNode->nEqn; indexP = pHNode->pEqn; CMPLX_ASSIGN_VALUE(nAc, xReal[indexN], xImag[indexN]); CMPLX_ASSIGN_VALUE(pAc, xReal[indexP], xImag[indexP]); CMPLX_MULT_SCALAR(prod1, nAc, pHEdge->dJnDnP1); CMPLX_MULT_SCALAR(prod2, pAc, pHEdge->dJpDpP1); CMPLX_ADD(sum, prod1, prod2); CMPLX_MULT_SCALAR(prod1, sum, 0.5 * pElem->dy); CMPLX_ADD_ASSIGN(yTotal, prod1); } if (pVNode->nodeType != CONTACT) { indexN = pVNode->nEqn; indexP = pVNode->pEqn; CMPLX_ASSIGN_VALUE(nAc, xReal[indexN], xImag[indexN]); CMPLX_ASSIGN_VALUE(pAc, xReal[indexP], xImag[indexP]); CMPLX_MULT_SCALAR(prod1, nAc, pVEdge->dJnDn); CMPLX_MULT_SCALAR(prod2, pAc, pVEdge->dJpDp); CMPLX_ADD(sum, prod1, prod2); CMPLX_MULT_SCALAR(prod1, sum, 0.5 * pElem->dx); CMPLX_SUBT_ASSIGN(yTotal, prod1); } } break; case 2: /* the BR element */ pHNode = pElem->pTRNode; pVNode = pElem->pBLNode; pHEdge = pElem->pTopEdge; pVEdge = pElem->pLeftEdge; if (pElem->elemType == SEMICON) { /* compute the derivatives with n,p */ if (pHNode->nodeType != CONTACT) { indexN = pHNode->nEqn; indexP = pHNode->pEqn; CMPLX_ASSIGN_VALUE(nAc, xReal[indexN], xImag[indexN]); CMPLX_ASSIGN_VALUE(pAc, xReal[indexP], xImag[indexP]); CMPLX_MULT_SCALAR(prod1, nAc, pHEdge->dJnDnP1); CMPLX_MULT_SCALAR(prod2, pAc, pHEdge->dJpDpP1); CMPLX_ADD(sum, prod1, prod2); CMPLX_MULT_SCALAR(prod1, sum, 0.5 * pElem->dy); CMPLX_ADD_ASSIGN(yTotal, prod1); } if (pVNode->nodeType != CONTACT) { indexN = pVNode->nEqn; indexP = pVNode->pEqn; CMPLX_ASSIGN_VALUE(nAc, xReal[indexN], xImag[indexN]); CMPLX_ASSIGN_VALUE(pAc, xReal[indexP], xImag[indexP]); CMPLX_MULT_SCALAR(prod1, nAc, pVEdge->dJnDnP1); CMPLX_MULT_SCALAR(prod2, pAc, pVEdge->dJpDpP1); CMPLX_ADD(sum, prod1, prod2); CMPLX_MULT_SCALAR(prod1, sum, 0.5 * pElem->dx); CMPLX_ADD_ASSIGN(yTotal, prod1); } } break; case 3: /* the BL element */ pHNode = pElem->pTLNode; pVNode = pElem->pBRNode; pHEdge = pElem->pTopEdge; pVEdge = pElem->pRightEdge; if (pElem->elemType == SEMICON) { /* compute the derivatives with n,p */ if (pHNode->nodeType != CONTACT) { indexN = pHNode->nEqn; indexP = pHNode->pEqn; CMPLX_ASSIGN_VALUE(nAc, xReal[indexN], xImag[indexN]); CMPLX_ASSIGN_VALUE(pAc, xReal[indexP], xImag[indexP]); CMPLX_MULT_SCALAR(prod1, nAc, pHEdge->dJnDn); CMPLX_MULT_SCALAR(prod2, pAc, pHEdge->dJpDp); CMPLX_ADD(sum, prod1, prod2); CMPLX_MULT_SCALAR(prod1, sum, 0.5 * pElem->dy); CMPLX_SUBT_ASSIGN(yTotal, prod1); } if (pVNode->nodeType != CONTACT) { indexN = pVNode->nEqn; indexP = pVNode->pEqn; CMPLX_ASSIGN_VALUE(nAc, xReal[indexN], xImag[indexN]); CMPLX_ASSIGN_VALUE(pAc, xReal[indexP], xImag[indexP]); CMPLX_MULT_SCALAR(prod1, nAc, pVEdge->dJnDnP1); CMPLX_MULT_SCALAR(prod2, pAc, pVEdge->dJpDpP1); CMPLX_ADD(sum, prod1, prod2); CMPLX_MULT_SCALAR(prod1, sum, 0.5 * pElem->dx); CMPLX_ADD_ASSIGN(yTotal, prod1); } } break; } if (pElem->elemType == SEMICON) { if (pHNode->nodeType != CONTACT) { indexPsi = pHNode->psiEqn; CMPLX_ASSIGN_VALUE(psiAc, xReal[indexPsi], xImag[indexPsi]); temp = 0.5 * pElem->dy * (pHEdge->dJnDpsiP1 + pHEdge->dJpDpsiP1); CMPLX_MULT_SCALAR(prod1, psiAc, temp); CMPLX_ADD_ASSIGN(yTotal, prod1); if (delVContact) { CMPLX_ADD_SELF_SCALAR(yTotal, -temp); } } if (pVNode->nodeType != CONTACT) { indexPsi = pVNode->psiEqn; CMPLX_ASSIGN_VALUE(psiAc, xReal[indexPsi], xImag[indexPsi]); temp = 0.5 * pElem->dx * (pVEdge->dJnDpsiP1 + pVEdge->dJpDpsiP1); CMPLX_MULT_SCALAR(prod1, psiAc, temp); CMPLX_ADD_ASSIGN(yTotal, prod1); if (delVContact) { CMPLX_ADD_SELF_SCALAR(yTotal, -temp); } } } /* displacement current terms */ if (pHNode->nodeType != CONTACT) { indexPsi = pHNode->psiEqn; CMPLX_ASSIGN_VALUE(psiAc, xReal[indexPsi], xImag[indexPsi]); CMPLX_MULT_SCALAR(prod1, *cOmega, pElem->epsRel * 0.5 * pElem->dyOverDx); CMPLX_MULT(prod2, prod1, psiAc); CMPLX_SUBT_ASSIGN(yTotal, prod2); if (delVContact) { CMPLX_ADD_ASSIGN(yTotal, prod1); } } if (pVNode->nodeType != CONTACT) { indexPsi = pVNode->psiEqn; CMPLX_ASSIGN_VALUE(psiAc, xReal[indexPsi], xImag[indexPsi]); CMPLX_MULT_SCALAR(prod1, *cOmega, pElem->epsRel * 0.5 * pElem->dxOverDy); CMPLX_MULT(prod2, prod1, psiAc); CMPLX_SUBT_ASSIGN(yTotal, prod2); if (delVContact) { CMPLX_ADD_ASSIGN(yTotal, prod1); } } } } } return (&yTotal); /* XXX */ }
/** * Polymorphic set operations. * * @param lpsOpname * <p>Operator name</p> * <table> * <tr><th><code>lpsOpname</code></th><th>Boolean</th><th>Numeric</th><th>String</th><th>Instance</th></tr> * <tr><td><code>= </code></td><td>x</td><td>x</td><td>x</td><td>x</td></tr> * <tr><td><code>+= </code></td><td>x</td><td>x</td><td>x</td><td>-</td></tr> * <tr><td><code>-= </code></td><td>-</td><td>x</td><td>-</td><td>-</td></tr> * <tr><td><code>*= </code></td><td>x</td><td>x</td><td>-</td><td>-</td></tr> * <tr><td><code>/= </code></td><td>-</td><td>x</td><td>-</td><td>-</td></tr> * <tr><td><code>++=</code></td><td>-</td><td>x</td><td>-</td><td>-</td></tr> * <tr><td><code>--=</code></td><td>-</td><td>x</td><td>-</td><td>-</td></tr> * </table> * <p>For type conversion rules see * <code><a href="function.html"><code�class="link">CFunction</code></a><code>::StackLogic</code>, * <code><a href="function.html"><code�class="link">CFunction</code></a><code>::StackNumber</code>, * <code><a href="function.html"><code�class="link">CFunction</code></a><code>::StackString</code> and * <code><a href="function.html"><code�class="link">CFunction</code></a><code>::StackInstance</code>. * </p> * @return <code>O_K</code> if successfull, a (negative) error code otherwise */ INT16 CGEN_PROTECTED CVar_SetOp(CVar *_this,const char* lpsOpname) { StkItm si; if (dlp_strcmp(lpsOpname,"++=")!=0 && dlp_strcmp(lpsOpname,"--=")!=0) { if (!CDlpObject_MicGet(BASEINST(_this))->GetX) return IERROR(_this,VAR_NOTSUPPORTED,"Polymorphic signatures"," by caller",0); if (!MIC_GET_X(1,&si)) return NOT_EXEC; } if (dlp_strcmp(lpsOpname,"=")==0) switch (si.nType) { case T_BOOL : return CVar_Bset(_this,si.val.b); case T_COMPLEX : return CVar_Vset(_this,si.val.n); case T_STRING : return CVar_Sset(_this,si.val.s); case T_INSTANCE: return CVar_Iset(_this,si.val.i); default: DLPASSERT(FMSG("Unknown variable type")); return NOT_EXEC; } else if (dlp_strcmp(lpsOpname,"+=")==0) { if (_this->m_nType==T_COMPLEX) return CVar_Vset(_this,CMPLX_PLUS(_this->m_nNVal,si.val.n)); if (_this->m_nType==T_STRING) { char* lpsSi = NULL; MIC_PUT_X(&si); lpsSi = MIC_GET_S(1,0); _this->m_lpsSVal = (char*)dlp_realloc(_this->m_lpsSVal, dlp_strlen(_this->m_lpsSVal)+dlp_strlen(lpsSi)+1,sizeof(char)); if (!_this->m_lpsSVal) return IERROR(_this,ERR_NOMEM,0,0,0); dlp_strcat(_this->m_lpsSVal,lpsSi); return O_K; } if (_this->m_nType==T_BOOL) { MIC_PUT_X(&si); _this->m_bBVal|=MIC_GET_B(1,0); return O_K; } return IERROR(_this,VAR_NOTSUPPORTED,"Operator +="," for this variable type",0); } else if (dlp_strcmp(lpsOpname,"*=")==0) { if (_this->m_nType==T_COMPLEX) return CVar_Vset(_this,CMPLX_MULT(_this->m_nNVal,si.val.n)); if (_this->m_nType==T_BOOL) { MIC_PUT_X(&si); _this->m_bBVal&=MIC_GET_B(1,0); return O_K; } return IERROR(_this,VAR_NOTSUPPORTED,"Operator *="," for this variable type",0); } else if (dlp_strcmp(lpsOpname,"-=")==0) { if (_this->m_nType==T_COMPLEX) return CVar_Vset(_this,CMPLX_MINUS(_this->m_nNVal,si.val.n)); return IERROR(_this,VAR_NOTSUPPORTED,"Operator -="," for this variable type",0); } else if (dlp_strcmp(lpsOpname,"/=")==0) { if (_this->m_nType==T_COMPLEX) return CVar_Vset(_this,CMPLX_MULT(_this->m_nNVal,CMPLX_INVT(si.val.n))); return IERROR(_this,VAR_NOTSUPPORTED,"Operator /="," for this variable type",0); } else if (dlp_strcmp(lpsOpname,"++=")==0) { if (_this->m_nType==T_COMPLEX) return CVar_Vset(_this,CMPLX_INC(_this->m_nNVal)); return IERROR(_this,VAR_NOTSUPPORTED,"Operator ++="," for this variable type",0); } else if (dlp_strcmp(lpsOpname,"--=")==0) { if (_this->m_nType==T_COMPLEX) return CVar_Vset(_this,CMPLX_DEC(_this->m_nNVal)); return IERROR(_this,VAR_NOTSUPPORTED,"Operator --="," for this variable type",0); } return NOT_EXEC; }