/*makecopy:当前有m位(偶数)选手,分成两组,每组由m/2位选手构成 由第一组的m/2位选手的安排来构成第二组的比赛安排,第一 组与第二组的比赛安排。要区分m/2为奇数和偶数两种情况*/ void makecopy(int m) { if (isodd(m / 2)) //m/2为奇数 copyodd(m / 2); else //m/2为偶数 copyeven(m / 2); }
/*init:初始化,设置问题规模N值,分配内存,用schedule指向; 把A构造成一个二维数组 */ void init() { int i, n; char line[100] = { '\0' }; printf("请输入选手人数:"); fgets(line, sizeof(line), stdin); N = atoi(line); if (N <= 0) { exit(-1); } if (isodd(N)) n = N + 1; else n = N; //schedule是行化的二维数组 schedule = (int *)calloc(n*n, sizeof(int)); A = (int **)calloc(n, sizeof(int *)); if (!schedule || A == NULL) exit(-2); for (i = 0; i<n; i++) //把A等价为二维数组 { A[i] = schedule + i*n; A[i][0] = i + 1;//初始化这个数组的第一列 } return; }
//交互递归实现判断奇数还是偶数 int iseven(int n) { if(n == 0) return 1; else { return isodd(n-1); } }
void get8SVX(int file,ULONG size, struct svx_info *info) { while ((size-=getCk(file, info)) >0) ; if (size < 0) readerror ("Decrepit input in form 8SVX: size incorrect", info); if (isodd(size)) skip1(file); }
/* Determine basis size */ int BasisSize() /*======================================================================= */ { /* Loop variables */ int L1, jK1, K1, M1, pS1, qS1, pI1, qI1, pI1b, qI1b; /* Min and max values for loop variables */ int K1max, M1max, qS1max, qI1max, qI1bmax; int iRow = 0; double I = Sys.I; double Ib = Sys.Ib; for (L1=0;L1<=Lemax;L1++) { if (isodd(L1) && (L1>Lomax)) continue; for (jK1=jKmin;jK1<=1;jK1+=2) { K1max = mini(Kmax,L1); for (K1=0;K1<=K1max;K1+=deltaK) { if ((K1==0)&(parity(L1)!=jK1)) continue; M1max = mini(Mmax,L1); for (M1=-M1max;M1<=M1max;M1++) { for (pS1=pSmin;pS1<=1;pS1++) { qS1max = 1 - abs(pS1); for (qS1=-qS1max;qS1<=qS1max;qS1+=2) { for (pI1 = -pImax;pI1<=pImax;pI1++) { qI1max = (int)(2*I) - abs(pI1); for (qI1=-qI1max;qI1<=qI1max;qI1+=2) { for (pI1b = -pIbmax;pI1b<=pIbmax;pI1b++) { if ((MeirovitchSymm) && (Sys.DirTilt==0)&&((pI1+pI1b+pS1-1)!=M1)) continue; qI1bmax = (int)(2*Ib) - abs(pI1b); for (qI1b=-qI1bmax;qI1b<=qI1bmax;qI1b+=2) { /*mexPrintf("%3d %3d %3d %3d %2d %2d %2d %2d %2d %2d\n",L1,jK1,K1,M1,pS1,qS1,pI1,qI1,pI2,qI2);*/ iRow++; } /* qI1b */ } /* pI1b */ } /* qI1 */ } /* pI1 */ } /* qS1 */ } /* pS1 */ } /* M1 */ } /* K1 */ } /* jK1 */ } /* L1 */ return iRow; /* number of rows */ }
vx_convolution vxCreateConvolution(vx_context context, vx_size columns, vx_size rows) { vx_convolution_t *convolution = NULL; if (vxIsValidContext((vx_context_t *)context) == vx_true_e && isodd(columns) && columns >= 3 && isodd(rows) && rows >= 3) { convolution = VX_CALLOC(vx_convolution_t); if (convolution) { vxInitReference(&convolution->base.base, (vx_context_t *)context, VX_TYPE_CONVOLUTION); vxIncrementReference(&convolution->base.base); vxAddReference(convolution->base.base.context, &convolution->base.base); convolution->base.type = VX_TYPE_INT16; convolution->base.columns = columns; convolution->base.rows = rows; convolution->base.memory.ndims = 2; convolution->base.memory.nptrs = 1; convolution->base.memory.dims[0][0] = sizeof(vx_int16); convolution->base.memory.dims[0][1] = (vx_int32)(columns*rows); convolution->scale = 1; } } return (vx_convolution)convolution; }
int wvCellBgColor (int whichrow, int whichcell, int nocells, int norows, TLP * tlp) { if (whichrow == norows - 1) whichrow = 3; else if (whichrow > 0) { if (isodd (whichrow)) whichrow = 2; else whichrow = 1; } if (whichcell == nocells - 1) whichcell = 3; else if (whichcell > 0) { if (isodd (whichcell)) whichcell = 2; else whichcell = 1; } wvTrace ( ("the cell index and bgcolor is %d %d %d,%d (last cell and row are %d %d)\n", tlp->itl, whichrow, whichcell, cellbgcolors[tlp->itl][whichrow][whichcell], nocells, norows)); if (tlp->itl >= 40) { wvWarning ("Table Look %d requested, but theres only %d in the list\n", tlp->itl + 1, 40); return (8); } return (cellbgcolors[tlp->itl][whichrow][whichcell]); }
void ethwstrt(struct etblk *etptr, char *buf, int len, int setup) { struct dcmd *dcmptr; struct dqregs *dqptr; dqptr = etptr->eioaddr; //while (!(dqptr->d_csr & DQ_XLI)); // XXX Hack for simulator. etptr->etwtry = EXRETRY; dcmptr = etptr->ewcmd; dcmptr->dc_bufh = DC_VALID | DC_ENDM | (etptr->etsetup = setup); if (isodd(len)) dcmptr->dc_bufh |= DC_LBIT; dcmptr->dc_buf = buf; dcmptr->dc_len = dqlen(len); dcmptr->dc_st1 = dcmptr->dc_st2 = DC_INIT; dcmptr->dc_flag = DC_NUSED; dqptr->d_wcmd = (char *)dcmptr; dqptr->d_wcmdh = NULL; }
void tournament(int m) { if (m == 1) { A[0][0] = 1; return; } else if (isodd(m)) //如果m为奇数,则m+1是偶数 { tournament(m + 1); //按照偶数个选手来求解 replaceVirtual(m + 1); //然后把第m+1号虚选手置成0 return; } else //m是偶数, { tournament(m / 2); //则先安排第1组的m/2人比赛 makecopy(m); //然后根据算法,构造左下、右下、右上、右下的矩阵 } return; }
ULONG getCk(int file, struct svx_info *info) { ULONG ckID, ckSize; UBYTE *ckData; ckID = getID(file); printf(""); ckSize = getID(file); if ((ckData = (UBYTE *)AllocMem(ckSize+1,MEMF_CHIP)) == 0) readerror("Out of memory: getCk", info); else { read(file,ckData,ckSize); ckData [ckSize] = 0; IFFRet(ckID,ckData,ckSize,info); if (isodd(ckSize)) skip1(file); } return ckSize; }
long long solve(int x, long long &y, char *n, int m) { if(n[0]=='1' && n[1]==0) { y = x; return 1; } bool f = isodd(n); rightshift(n); long long r = solve(x, y, n, m); r = r * (1 + y); y = y * y; if(f) { r = r + y; y = y * x; } y = y % m; return r % m; }
//------------------------------------------------------------------------ // udpsend - send one UDP datagram to a given (foreign) IP address //------------------------------------------------------------------------ int udpsend(IPaddr faddr, int fport, int lport, struct epacket *packet, int datalen) { struct udp *udpptr; struct ip *ipptr; // Fill in UDP header; pass to ipsend to fill in IP header ipptr = (struct ip *)packet->ep_data; ipptr->i_proto = IPRO_UDP; udpptr = (struct udp *)ipptr->i_data; udpptr->u_sport = hs2net(lport); udpptr->u_dport = hs2net(fport); udpptr->u_udplen = hs2net(UHLEN + datalen); if (isodd(datalen)) udpptr->u_data[datalen] = (char)0; udpptr->u_ucksum = 0; return ipsend(faddr, packet, UHLEN + datalen); }
// Median by sorting. // Divide and conquer would be quicker (linear vs n log(n) ) real_t median( const real_t * x, const bool * allowed, const uint_fast32_t n){ if(NULL==x){ return NAN;} if(0==n){ return NAN;} real_t * xc = calloc(n,sizeof(double)); if(NULL==xc){ return NAN;} uint_fast32_t nallowed = 0; for ( int i=0 ; i<n ; i++){ if(NULL!=allowed && !allowed[i]){ continue; } xc[nallowed] = x[i]; nallowed++; } qsort(xc,nallowed,sizeof(real_t),cmpReal); int minIdx = (nallowed-1)/2; real_t ret = isodd(nallowed)?xc[minIdx]:0.5*(xc[minIdx]+xc[minIdx+1]); free(xc); return ret; }
//print:打印赛程 void print() { int i, j, row, col; if (isodd(N)) { row = N; col = N + 1; } else { row = N; col = N; } printf("第1列是选手编号\n"); for (i = 0; i<row; i++) { for (j = 0; j<col; j++) { printf("%4d", A[i][j]); } printf("\n"); } }
/*copyeven:m为偶数时用,由前1组的m位选手的安排,来构成第2组m位选手 的赛程安排,以及两组之间的比赛安排 */ void copyeven(int m) { if (isodd(m)) return; int i, j; for (j = 0; j<m; j++) //1. 求第2组的安排(+m) { for (i = 0; i<m; i++) { A[i + m][j] = A[i][j] + m; } } for (j = m; j<2 * m; j++)//两组间比赛的安排 { for (i = 0; i<m; i++) //2. 第1组和第2组 { A[i][j] = A[i + m][j - m]; //把左下角拷贝到右上角 } for (i = m; i<2 * m; i++) //3. 对应的,第2组和第1组 { A[i][j] = A[i - m][j - m]; //把左上角拷贝到右下角 } } return; }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { double *m, *h, *g, *iwm, *f_ptr, *buf, *iwm_out_ptr; double *m_ptr, *iwm_ptr, *col_ptr, *in_ptr, *out_ptr, *pos, *f_pos; double *d_start_h, *d_start_g, *d_end_h, *d_end_g; double d, res1, res2; int dlp, dhp, dlp_12, dhp_12, odd_dlp, odd_dhp, n_cols, col; int st_wrap_h, st_wrap_g, len_mid, len_h_12_p, len_g_12_p, dlp_12_p, dhp_12_p; int reco_detail, len_h_12, len_g_12, len_x_12_m_h, len_x_12_m_g; int len_x, len_x_12, len_h, len_g, len_buf, i, j, k, odd_h, odd_g; long int size_m; if (nrhs < 5) mexErrMsgTxt("Need at least matrix, two filters, two delays."); if (nlhs > 1) mexErrMsgTxt("Only one output returned."); if (mxIsComplex(M)) mexErrMsgTxt("Cannot wt complex matrix."); if (mxGetClassID(M) != mxDOUBLE_CLASS) mexErrMsgTxt("Input matrix should be of class double"); if (nrhs > 5) reco_detail = ((int)*(mxGetPr(RECO_D))!=0); else reco_detail = 1; /* Assign pointers to the parameters */ m = mxGetPr(M); h = mxGetPr(RH); g = mxGetPr(RG); /* get delay lengths */ dlp = (int)*(mxGetPr(DLP)); dlp_12 = dlp/2; odd_dlp = isodd(dlp); dhp = (int)*(mxGetPr(DHP)); dhp_12 = dhp/2; odd_dhp = isodd(dhp); /* get dimensions */ len_x = mxGetM(M); n_cols = mxGetN(M); size_m = len_x * n_cols; len_h = mxGetM(RH) * mxGetN(RH); len_h_12 = len_h/2; odd_h = isodd(len_h); len_g = mxGetM(RG) * mxGetN(RG); len_g_12 = len_g/2; odd_g = isodd(len_g); /* check length divisible by 2 */ if (isodd(len_x)) mexErrMsgTxt("Length of x dimension must be divisible by 2."); len_x_12 = len_x/2; /* prepare altered lengths for odd filter delays */ len_x_12_m_h = len_x_12 - odd_dlp; len_x_12_m_g = len_x_12 - odd_dhp; len_h_12_p = len_h_12 + odd_h; dlp_12_p = dlp_12 + odd_dlp; len_g_12_p = len_g_12 + odd_g; dhp_12_p = dhp_12 + odd_dhp; /* check constants */ if (dlp < 0 || dlp > len_h || dhp < 0 || dhp > len_g) mexErrMsgTxt("Filter delays seem to be out of range."); /* make output matrix */ IWM = mxCreateNumericArray(mxGetNumberOfDimensions(M), mxGetDimensions(M), mxDOUBLE_CLASS, mxREAL); iwm = mxGetPr(IWM); m_ptr = m; iwm_ptr = iwm; for (i=0; i<size_m; i++) *(iwm_ptr++) = *(m_ptr++); /* make buffer to contain whole row sample, wraparounds */ st_wrap_h = max((len_h_12 + odd_h - dlp_12 - 1), 0); /* start wrap size for h */ st_wrap_g = max((len_g_12 + odd_g - dhp_12 - 1), 0); /* start wrap size for g */ len_mid = min(dlp_12 + odd_dlp, st_wrap_h + len_x_12); len_buf = st_wrap_h + len_x_12 + len_mid + len_x_12 + dhp_12 + odd_dhp; buf = (double *)mxCalloc(len_buf, sizeof(double)); d_start_h = buf + st_wrap_h; d_end_h = d_start_h + len_x_12 - 1; d_start_g = d_end_h + 1 + len_mid; d_end_g = d_start_g + len_x_12 - 1; /* for each x column */ col_ptr = iwm; for (col=0; col < n_cols; col++) { /* copy the row data to buffer */ out_ptr = d_start_h; in_ptr = col_ptr; for (i=0; i<len_x_12; i++) *(out_ptr++) = *(in_ptr++); if (reco_detail) { out_ptr = d_start_g; for (i=0; i<len_x_12; i++) *(out_ptr++) = *(in_ptr++); } /* do low pass filter */ iwm_out_ptr = col_ptr; /* make end wrap */ out_ptr = d_end_h + 1; in_ptr = d_start_h; for (i=0; i < dlp_12_p; i++) { *(out_ptr++) = *(in_ptr++); if (in_ptr > d_end_h) in_ptr = d_start_h; } /* make start wrap */ out_ptr = d_start_h-1; in_ptr = d_end_h; for (i=0; i < st_wrap_h; i++) { *(out_ptr--) = *(in_ptr--); if (in_ptr < d_start_h) in_ptr = d_end_h; } /* do convolution */ pos = d_start_h + dlp_12; /* do start conv for odd delay */ if (odd_dlp) { /* move back along even part of filter */ f_ptr = h; f_pos = pos++; res2 = 0; for (j=0; j<len_h_12; j++) { res2 += *(f_pos--) * *(++f_ptr); f_ptr++; } *(iwm_out_ptr++) = res2; } /* move along row */ for (i=0; i<len_x_12_m_h; i++) { /* taking into account odd_delay */ f_ptr = h; f_pos = pos++; res1 = 0; res2 = 0; /* move back along filter */ for (j=0; j<len_h_12; j++) { d = *f_pos--; res1 += d * *(f_ptr++); /* odd portion of filter */ res2 += d * *(f_ptr++); /* even portion */ } if (odd_h) res1 += *(f_pos) * *(f_ptr); *(iwm_out_ptr++) = res1; *(iwm_out_ptr++) = res2; } /* along row */ /* do end conv for odd delay */ if (odd_dlp) { /* move back along odd part of filter */ f_ptr = h; f_pos = pos; res1 = 0; for (j=0; j<len_h_12_p; j++) { res1 += *(f_pos--) * *(f_ptr++); f_ptr++; } *(iwm_out_ptr++) = res1; } /* end conv */ /* high pass filter if required */ if (reco_detail) { iwm_out_ptr = col_ptr; /* make end wrap */ out_ptr = d_end_g + 1; in_ptr = d_start_g; for (i=0; i < dhp_12_p; i++) { *(out_ptr++) = *(in_ptr++); if (in_ptr > d_end_g) in_ptr = d_start_g; } /* make start wrap */ out_ptr = d_start_g-1; in_ptr = d_end_g; for (i=0; i < st_wrap_g; i++) { *(out_ptr--) = *(in_ptr--); if (in_ptr < d_start_g) in_ptr = d_end_g; } /* do convolution */ pos = d_start_g + dhp_12; /* do start conv for odd delay */ if (odd_dhp) { /* move back along even part of filter */ f_ptr = g; f_pos = pos++; res2 = 0; for (j=0; j<len_g_12; j++) { res2 += *(f_pos--) * *(++f_ptr); f_ptr++; } *(iwm_out_ptr++) += res2; } /* move along row */ for (i=0; i<len_x_12_m_g; i++) { /* taking into account odd_delay */ f_ptr = g; f_pos = pos++; res1 = 0; res2 = 0; /* move back along filter */ for (j=0; j<len_g_12; j++) { d = *f_pos--; res1 += d * *(f_ptr++); /* odd portion of filter */ res2 += d * *(f_ptr++); /* even portion */ } if (odd_g) res1 += *(f_pos) * *(f_ptr); *(iwm_out_ptr++) += res1; *(iwm_out_ptr++) += res2; } /* along row */ /* do end conv for odd delay */ if (odd_dhp) { /* move back along odd part of filter */ f_ptr = g; f_pos = pos; res1 = 0; for (j=0; j<len_g_12_p; j++) { res1 += *(f_pos--) * *(f_ptr++); f_ptr++; } *(iwm_out_ptr++) += res1; } /* end conv */ } /* end if reco_detail */ /* move to next row */ col_ptr += len_x; } /* for each column */ /* free memory */ mxFree(buf); }
__inline int parity(int k) { return (isodd(k) ? -1 : +1); }
/*============================================================================ */ void makematrix() { const double EZI0 = Sys.EZI0; const double *ReEZI2 = Sys.ReEZI2; const double *ImEZI2 = Sys.ImEZI2; const double I = Sys.I; const double NZI0 = Sys.NZI0; const double HFI0 = Sys.HFI0; const double *ReHFI2 = Sys.ReHFI2; const double *ImHFI2 = Sys.ImHFI2; const double Ib = Sys.Ib; const double NZI0b = Sys.NZI0b; const double HFI0b = Sys.HFI0b; const double *ReHFI2b = Sys.ReHFI2b; const double *ImHFI2b = Sys.ImHFI2b; /* Diffusion parameters */ /*--------------------------------------------- */ const double DirTilt = Sys.DirTilt; const double *d2psi = Sys.d2psi; const double Rxx = Diff.Rxx; const double Ryy = Diff.Ryy; const double Rzz = Diff.Rzz; const double ExchangeFreq = Diff.Exchange; const double *xlk = Diff.xlk; /* Lband = (lptmx>=2) ? lptmx*2 : 2; */ const int Lband = 8; /* Kband = kptmx*2; */ const int Kband = 8; /*========================================================== */ /* Loop variables */ int L1, jK1, K1, M1, pS1, qS1, pI1, qI1, pI1b, qI1b; int L2, jK2, K2, M2, pS2, qS2, pI2, qI2, pI2b, qI2b; int Ld, Ls, jKd, Kd, Ks, KK; /* Min and max values for loop variables */ int K1max, M1max, qS1max, qI1max, qI1bmax; int L2max, jK2min, K2min, K2max, M2min, M2max; int pS2min, qS2min, qS2max, pI2min, qI2min, qI2max, pI2bmin, qI2bmin, qI2bmax; int iRow = 0, iCol = 0, iElement = 0; bool Potential = Diff.maxL>=0; bool ExchangePresent = (ExchangeFreq!=0); double IsoDiffKdiag, IsoDiffKm2, IsoDiffKp2, PotDiff; bool diagRC, Ld2, diagLK, diagS, diagI; double N_L, N_K, NormFactor; double R_EZI2, R_HFI2, R_HFI2b, a1, a1b, g1, a2, a2b, g2; int parityLK2, L, pId, qId, pIbd, qIbd; double Term1, Term2, X; int pd; bool includeRank0; double LiouvilleElement, GammaElement, t; double d2jjj; const bool RhombicDiff = (Rxx!=Ryy); if (Display) { mexPrintf(" Potential: %d Exchange: %d\n",Potential, ExchangePresent); mexPrintf(" Lemax Lomax: %d %d %d\n",Lemax,Lomax); mexPrintf(" jKmin Kmax Mmax: %d %d %d\n",jKmin,Kmax,Mmax); mexPrintf(" pSmin; I Ib, pImax pIbmax: %d; %g %g, %d %d\n",pSmin,I,Ib,pImax,pIbmax); mexPrintf(" NZI0a %0.3e HFI0a %0.3e\n",NZI0,HFI0); mexPrintf(" NZI0b %0.3e HFI0b %0.3e\n",NZI0b,HFI0b); mexPrintf(" ReHFI2a %0.3e %0.3e %0.3e %0.3e %0.3e\n",ReHFI2[0],ReHFI2[1],ReHFI2[2],ReHFI2[3],ReHFI2[4]); mexPrintf(" ReHFI2b %0.3e %0.3e %0.3e %0.3e %0.3e\n",ReHFI2b[0],ReHFI2b[1],ReHFI2b[2],ReHFI2b[3],ReHFI2b[4]); if (ImHFI2) mexPrintf(" ReHFI2a %0.3e %0.3e %0.3e %0.3e %0.3e\n",ImHFI2[0],ImHFI2[1],ImHFI2[2],ImHFI2[3],ImHFI2[4]); if (ImHFI2b) mexPrintf(" ReHFI2b %0.3e %0.3e %0.3e %0.3e %0.3e\n",ImHFI2b[0],ImHFI2b[1],ImHFI2b[2],ImHFI2b[3],ImHFI2b[4]); mexPrintf(" entering loops...\n"); } /* All equation numbers refer to Meirovitch et al, J.Chem.Phys. 77 (1982) */ for (L1=0;L1<=Lemax;L1++) { if (isodd(L1) && (L1>Lomax)) continue; for (jK1=jKmin;jK1<=1;jK1+=2) { K1max = mini(Kmax,L1); for (K1=0;K1<=K1max;K1+=deltaK) { if ((K1==0)&&(parity(L1)!=jK1)) continue; /* Potential-independent part of diffusion operator */ /*-------------------------------------------------------- */ /* depends only on L and K and is diagonal in all except K */ IsoDiffKdiag = (Rxx+Ryy)/2*(L1*(L1+1))+K1*K1*(Rzz-(Rxx+Ryy)/2); if (RhombicDiff) { KK = K1-2; IsoDiffKm2 = (Rxx-Ryy)/4*sqrt((L1-KK-1)*(L1-KK)*(L1+KK+1)*(L1+KK+2)); KK = K1+2; IsoDiffKp2 = (Rxx-Ryy)/4*sqrt((L1+KK-1)*(L1+KK)*(L1-KK+1)*(L1-KK+2)); } else { IsoDiffKp2 = IsoDiffKm2 = 0; } /*-------------------------------------------------------- */ M1max = mini(Mmax,L1); for (M1=-M1max;M1<=M1max;M1++) { for (pS1=pSmin;pS1<=1;pS1++) { qS1max = 1 - abs(pS1); for (qS1=-qS1max;qS1<=qS1max;qS1+=2) { for (pI1 = -pImax;pI1<=pImax;pI1++) { qI1max = ((int)(2*I)) - abs(pI1); for (qI1=-qI1max;qI1<=qI1max;qI1+=2) { for (pI1b = -pIbmax;pI1b<=pIbmax;pI1b++) { if ((MeirovitchSymm) && (DirTilt==0) && ((pI1+pI1b+pS1-M1)!=1)) continue; /* Eq. (A47), see Misra (A13) */ qI1bmax = ((int)(2*Ib)) - abs(pI1b); for (qI1b=-qI1bmax;qI1b<=qI1bmax;qI1b+=2) { iCol = iRow; diagRC = true; L2max = mini(Lemax,L1+Lband); for (L2=L1;L2<=L2max;L2++) { if (isodd(L2)&&(L2>Lomax)) continue; Ld = L1 - L2; Ls = L1 + L2; Ld2 = abs(Ld)<=2; /* N_L normalisation factor, see after Eq. (A11) */ N_L = sqrt((double)((2.0*L1+1.0)*(2.0*L2+1.0))); jK2min = (diagRC) ? jK1 : jKmin; for (jK2=jK2min;jK2<=1;jK2+=2) { jKd = jK1 - jK2; K2max = mini(Kmax,L2); K2min = (diagRC) ? K1 : 0; for (K2=K2min;K2<=K2max;K2+=deltaK) { if ((K2==0)&&(parity(L2)!=jK2)) continue; diagLK = (L1==L2) && (K1==K2); Kd = K1 - K2; Ks = K1 + K2; parityLK2 = parity(L2+K2); /*---------------------------------------------------------------------- */ /* Pre-calculations for Liouville matrix elements, Eq. (A41) */ /*---------------------------------------------------------------------- */ /* R(mu=EZI,HFI;l=2), see Eq. (A42) and (A44) */ /*---------------------------------------------- */ R_EZI2 = 0; R_HFI2 = 0; R_HFI2b = 0; if (Ld2) { g1 = 0; a1 = 0; a1b = 0; if (abs(Kd)<=2) { const double coeff = jjj(L1,2,L2,K1,-Kd,-K2); /*mexPrintf("[wigner3j(%d,%d,%d,%d,%d,%d) %g]\n",L1,2,L2,K1,-Kd,-K2,coeff); */ if (jK1==jK2) { g1 = coeff*ReEZI2[Kd+2]; a1 = coeff*ReHFI2[Kd+2]; a1b = coeff*ReHFI2b[Kd+2]; } else { if (ImEZI2) g1 = coeff*ImEZI2[Kd+2]*jK1; if (ImHFI2) a1 = coeff*ImHFI2[Kd+2]*jK1; if (ImHFI2b) a1b = coeff*ImHFI2b[Kd+2]*jK1; } } g2 = 0; a2 = 0; a2b = 0; if (abs(Ks)<=2) { const double coeff = jjj(L1,2,L2,K1,-Ks,K2); if (jK1==jK2) { g2 = coeff*ReEZI2[Ks+2]; a2 = coeff*ReHFI2[Ks+2]; a2b = coeff*ReHFI2b[Ks+2]; } else { if (ImEZI2) g2 = coeff*ImEZI2[Ks+2]*jK1; if (ImHFI2) a2 = coeff*ImHFI2[Ks+2]*jK1; if (ImHFI2b) a2b = coeff*ImHFI2b[Ks+2]*jK1; } } R_EZI2 = g1 + jK2*parityLK2*g2; R_HFI2 = a1 + jK2*parityLK2*a2; R_HFI2b = a1b + jK2*parityLK2*a2b; } /* N_K(K_1,K_2) normalization factor, Eq. (A43) */ N_K = 1.0; if (K1==0) N_K /= sqrt(2.0); if (K2==0) N_K /= sqrt(2.0); /* Normalisation prefactor in Eq.(A40) and Eq.(A41) */ NormFactor = N_L*N_K*parity(M1+K1); /*---------------------------------------------------------------------- */ /*---------------------------------------------------------------------- */ /* Potential-dependent term of diffusion operator, Eq. (A40) */ /*---------------------------------------------------------------------- */ PotDiff = 0; if (Potential) { if ((abs(Ld)<=Lband)&&(parity(Ks)==1)&& (jKd==0)&&(abs(Kd)<=Kband)&&(abs(Ks)<=Kband)) { for (L=0; L<=Lband; L+=2) { Term1 = 0; if (Kd>=-L) { X = xlk[(Kd+L)*(Diff.maxL+1) + L]; /* X^L_{K1-K2} */ if (X!=0) Term1 = X * jjj(L1,L,L2,K1,-Kd,-K2); } Term2 = 0; if (Ks<=L) { X = xlk[(Ks+L)*(Diff.maxL+1) + L]; /* X^L_{K1+K2} */ if (X!=0) Term2 = parityLK2*jK2* X * jjj(L1,L,L2,K1,-Ks,K2); } if (Term1 || Term2) PotDiff += (Term1+Term2) * jjj(L1,L,L2,M1,0,-M1); } PotDiff *= NormFactor; if (Display) if (abs(PotDiff)>1e-10) mexPrintf(" pot (%d,%d;%d,%d): %e\n",L1,L2,K1,K2,PotDiff); } } /*---------------------------------------------------------------------- */ M2max = mini(Mmax,L2); M2min = (diagRC) ? M1 : -M2max; for (M2=M2min;M2<=M2max;M2++) { int Md = M1 - M2; bool diagLKM = diagLK && (jKd==0) && (Md==0); /* Pre-compute 3j symbol in Eq. (A41) for l = 2 */ const double Liou3j = (Ld2) ? jjj(L1,2,L2,M1,-Md,-M2) : 0; pS2min = (diagRC) ? pS1 : pSmin; for (pS2=pS2min;pS2<=1;pS2++) { int pSd = pS1 - pS2; qS2max = 1 - abs(pS2); qS2min = (diagRC) ? qS1 : -qS2max; for (qS2=qS2min;qS2<=qS2max;qS2+=2) { int qSd = qS1 - qS2; diagS = (pS1==pS2) && (qS1==qS2); pI2min = (diagRC) ? pI1 : -pImax; for (pI2=pI2min;pI2<=pImax;pI2++) { pId = pI1 - pI2; qI2max = ((int)(2*I)) - abs(pI2); qI2min = (diagRC) ? qI1 : -qI2max; for (qI2=qI2min;qI2<=qI2max;qI2+=2) { qId = qI1 - qI2; pI2bmin = (diagRC) ? pI1b : -pIbmax; for (pI2b=pI2bmin;pI2b<=pIbmax;pI2b++) { if ((MeirovitchSymm) && (DirTilt==0) && ((pI2+pI2b+pS2-1)!=M2)) continue; /* Eq. (A47), see Misra (A13) */ pIbd = pI1b - pI2b; qI2bmax = ((int)(2*Ib)) - abs(pI2b); qI2bmin = (diagRC) ? qI1b : -qI2bmax; for (qI2b=qI2bmin;qI2b<=qI2bmax;qI2b+=2) { qIbd = qI1b - qI2b; diagI = (pId==0) && (qId==0) && (pIbd==0) && (qIbd==0); pd = pSd + pId + pIbd; /* not sure here; Misra (A11a) */ /*---------------------------------------------------------------------------- */ /* Matrix element of Liouville operator (Hamiltonian superoperator) */ /*---------------------------------------------------------------------------- */ /* For the rank-0 terms in (A41), the following simplifcations hold. */ /* - L1==L2, K1==K2 and M1==M2, otherwise the 3j are zero */ /* - The prefactor N_L*(-1)^(M1+K1) is canceled by the product of */ /* wigner3j(L,M;0,0;L,-M) within the sum and wigner3j(L,K;0,0;L,-K) from R. */ /* ( wigner3j(L,M;0,0;L,-M) = (-1)^(-M-L)/sqrt(2L+1) */ /* - The N_K factor is not needed because */ /* the l=0 ISTO components have not been transformed by */ /* the K-symmetrization. (following the formula, N_K is */ /* cancelled by R_0) */ LiouvilleElement = 0; if (Ld2 && /* if |L1-L2| is not 2 or less, all 3j symbols in (A41) are zero */ (abs(Md)<=2) && /* otherwise first 3j symbol in (A41) is zero */ ((DirTilt!=0) || (pd==Md)) && /* no director tilt -> d2 is diagonal, i.e. d2(DirTilt)(pd,Md) zero unless pd==Md */ (abs(pSd)<=1) && (abs(pId)<=1) && (abs(pIbd)<=1) && /* otherwise Clebsch-Gordans in (B7) and (B8) are zero */ (abs(pSd)==abs(qSd)) && (abs(pId)==abs(qId)) && (abs(pIbd)==abs(qIbd))) { includeRank0 = diagLKM && /* l=0 in (A41) means L1=L2, M2-M1=0 and K2-K1=0 (3j symbols)*/ (pd==0); /* ? (A41): for DirTilt=0, d2 is diagonal, and M2-M1=0 means that pd=0 */ d2jjj = d2psi[(pd+2)+(Md+2)*5]*Liou3j; /* for l=2, see (A41) */ /* Electronic Zeeman interaction */ /*----------------------------------------- */ if (diagI) { /* diagonal in nuclear subspace, i.e. pId==0 and qId==0 for all nuclei */ /* Rank-2 term, Eq. (B7) and (B8) */ double C2, S_g; if (pSd==0) { /* since pId==0, pSd and pSd+pId are equal */ C2 = +sqrt23; /* (112|000) */ S_g = pS1; } else { C2 = +sqrt12; /* (112|-10-1), (112|101) */ S_g = -qSd/sqrt(2.0); } LiouvilleElement += NormFactor*d2jjj*R_EZI2*(C2*S_g); /* Rank-0 term */ if (includeRank0) { const double C0 = -sqrt13; /* (110|000) */ LiouvilleElement += EZI0*(C0*pS1); } } /* Hyperfine interaction, nucleus 1 */ /*----------------------------------------- */ if ((I>0) && (pSd*pId==qSd*qId) && (pIbd==0) && (qIbd==0)) { /* Compute Clebsch-Gordan coeffs and S_A from Eq. (B7) */ double C0, C2, S_A; C0 = 0; C2 = 0; S_A = 0; if (pId==0) { if (pSd==0) { S_A = (pS1*qI1+pI1*qS1)/2.0; C0 = -sqrt13; /* (110|000) */ C2 = +sqrt23; /* (112|000) */ } else { S_A = -(pI1*pSd+qI1*qSd)/sqrt(8.0); C0 = 0; /* no rank 0 term */ C2 = +sqrt12; /* (112|101), (112|-10-1) */ } } else { int t = qI1*qId + pI1*pId; double KI = sqrt(I*(I+1.0)-t*(t-2.0)/4.0); if (pSd==0) { S_A = -(pS1*pId+qS1*qId)*KI/sqrt(8.0); C0 = 0; /* no rank 0 term */ C2 = +sqrt12; /* (112|011), (112|0-1-1) */ } else { S_A = pSd*qId*KI/2.0; C0 = +sqrt13; /* (110|1-10), (110|-110) */ if (pSd+pId==0) C2 = +sqrt(1.0/6.0); /* (112|1-10), (112|-110) */ else C2 = +1.0; /* (112|112), (112|-1-1-2) */ } } /* Rank-2 term, Eq. (A41) */ LiouvilleElement += NormFactor*d2jjj*R_HFI2 * (C2*S_A); /* Eq. (A41) and (B7)*/ /* Rank-0 term */ if (includeRank0) LiouvilleElement += HFI0*(C0*S_A); } /* Hyperfine interaction, nucleus b */ /*----------------------------------------- */ if ((Ib>0) && (pSd*pIbd==qSd*qIbd) && (pId==0) && (qId==0)) { /* Compute Clebsch-Gordan coeffs and S_A from Eq. (B7) */ double C0, C2, S_A; C0 = 0; C2 = 0; S_A = 0; if (pIbd==0) { if (pSd==0) { S_A = (pS1*qI1b+pI1b*qS1)/2.0; C0 = -sqrt13; /* (110|000) */ C2 = +sqrt23; /* (112|000) */ } else { S_A = -(pI1b*pSd+qI1b*qSd)/sqrt(8.0); C0 = 0; /* no rank 0 term */ C2 = +sqrt12; /* (112|101), (112|-10-1) */ } } else { int t = qI1b*qIbd + pI1b*pIbd; double KIb = sqrt(Ib*(Ib+1.0)-t*(t-2.0)/4.0); if (pSd==0) { S_A = -(pS1*pIbd+qS1*qIbd)*KIb/sqrt(8.0); C0 = 0; /* no rank 0 term */ C2 = +sqrt12; /* (112|011), (112|0-1-1) */ } else { S_A = pSd*qIbd*KIb/2.0; C0 = +sqrt13; /* (110|1-10), (110|-110) */ if (pSd+pIbd==0) C2 = +sqrt(1.0/6.0); /* (112|1-10), (112|-110) */ else C2 = +1.0; /* (112|112), (112|-1-1-2) */ } } /* Rank-2 term, Eq. (A41) */ LiouvilleElement += NormFactor*d2jjj*R_HFI2b * (C2*S_A); /* Eq. (A41) and (B7)*/ /* Rank-0 term */ if (includeRank0) LiouvilleElement += HFI0b*(C0*S_A); } /* Nuclear Zeeman interaction */ /*----------------------------------------- */ /* has only a rank-0 component */ if (diagS && diagI && includeRank0) { const double C0 = -sqrt13; /* (110|000) */ LiouvilleElement += NZI0*C0*pI1; LiouvilleElement += NZI0b*C0*pI1b; } } /*------------------------------------------- */ /*------------------------------------------------------ */ /* Matrix element of diffusion superoperator */ /*------------------------------------------------------ */ GammaElement = 0; if (diagS && diagI) { /* all potential terms are diagonal in the spin space */ /* Potential-independent terms, Eq. (A15) */ if ((Ld==0) && (Md==0) && (jKd==0)) { if (Kd==0) GammaElement += IsoDiffKdiag; else if (Kd==+2) GammaElement += IsoDiffKm2/N_K; else if (Kd==-2) GammaElement += IsoDiffKp2/N_K; } /* Potential-dependent terms, Eq. (A40) */ if (Potential) { if ((Md==0) && (jKd==0)) GammaElement += PotDiff; } } /* Exchange term */ if (ExchangePresent) { if ((pSd==0) && (pId==0) && (pIbd==0) && diagLKM) { t = 0; if ((qId==0) && (qIbd==0) && (qSd==0)) t += 1.0; if ((qId==0) && (qIbd==0) && (pS1==0)) t -= 0.5; if ((pI1==0) && (pI1b==0) && (qSd==0)) t -= 1.0/(2.0*I+1)/(2.0*Ib+1); GammaElement += t*ExchangeFreq; } } /*------------------------------------------- */ /*------------------------------------------- */ /* Store element values and indices */ /*------------------------------------------- */ if ((GammaElement!=0) || (LiouvilleElement!=0)) { MatrixRe[iElement] = GammaElement; MatrixIm[iElement] = -LiouvilleElement; ridx[iElement] = iRow; cidx[iElement] = iCol; iElement++; if (!diagRC) { MatrixRe[iElement] = GammaElement; MatrixIm[iElement] = -LiouvilleElement; ridx[iElement] = iCol; cidx[iElement] = iRow; iElement++; } if (iElement>=maxElements) mexErrMsgTxt("Number of non-zero elements too large. Increase Opt.Allocation(1)."); } /*------------------------------------------- */ iCol++; diagRC = false; if (iCol>=maxRows) mexErrMsgTxt("Dimension too large. Increase Opt.Allocation(2)."); } /* qI2b */ } /* pI2b */ } /* qI2 */ } /* pI2 */ } /* qS2 */ } /* pS2 */ } /* M2 */ } /* K2 */ } /* jK2 */ } /* L2 */ /* all column index loops */ iRow++; if (iRow>=maxRows) mexErrMsgTxt("Dimension too large. Increase Opt.Allocation(2)."); } /* qI1b */ } /* pI1b */ } /* qI1 */ } /* pI1 */ } /* qS1 */ } /* pS1 */ } /* M1 */ } /* K1 */ } /* jK1 */ } /* L1; all row index loops */ nRows = iRow; nElements = iElement; if (Display) mexPrintf(" %d elements, %d rows;\n",nElements,nRows); }