void getLongestSymmetrySubString_helper(string & s, int pos, int &longestLen) { int left=pos-1; int right=pos; // even len checkSymmetry(s, left, right, longestLen); left = pos-1; right = pos+1; checkSymmetry(s, left, right, longestLen); }
//Recursion to verify the symmetry of the tree. bool checkSymmetry(struct TreeNode* l, struct TreeNode* r) { if (!l && !r) return true; if (!l || !r) return false; if (l->val == r->val) return checkSymmetry(l->left, r->right) && checkSymmetry(l->right, r->left); else return false; }
/* * Determine if a tree is symmetric or not */ bool isSymmetric(struct TreeNode* root) { if(!root) return true; return checkSymmetry(root->left,root->right); }
returnValue RungeKuttaExport::initializeButcherTableau( const DMatrix& _AA, const DVector& _bb, const DVector& _cc ) { if( _cc.isEmpty() || !_AA.isSquare() || _AA.getNumRows() != _bb.getDim() || _bb.getDim() != _cc.getDim() ) return RET_INVALID_OPTION; numStages = _cc.getDim(); is_symmetric = checkSymmetry( _cc ); // std::cout << "Symmetry of the chosen method: " << is_symmetric << "\n"; AA = _AA; bb = _bb; cc = _cc; return SUCCESSFUL_RETURN; }
// This is the main MFE calculator. Actually finds all suboptimal folds // with energy below fixedSubOptRange, which if < 0, does MFE DBL_TYPE mfeFullWithSym_SubOpt( int inputSeq[], int seqLen, dnaStructures *mfeStructures, int complexity, int naType, int dangles, DBL_TYPE temperature, int symmetry, DBL_TYPE fixedSubOptRange, int onlyOne, DBL_TYPE sodiumconc, DBL_TYPE magnesiumconc, int uselongsalt) { //if fixedSubOptRange > 0, then enumerate all structures with fsor, rather than find mfe DBL_TYPE result; int seqlength; DBL_TYPE *F = NULL; DBL_TYPE *Fb = NULL; DBL_TYPE *Fm = NULL; //N^3 DBL_TYPE *Fx = NULL; DBL_TYPE *Fx_1 = NULL; DBL_TYPE *Fx_2 = NULL; DBL_TYPE *Fs = NULL; DBL_TYPE *Fms = NULL; //PKNOTS DBL_TYPE *Fp = NULL; DBL_TYPE *Fz = NULL; //O(N^2) DBL_TYPE *Fg = NULL; //O(N^4) //N^5 DBL_TYPE *FgIx = NULL; DBL_TYPE *FgIx_1 = NULL; DBL_TYPE *FgIx_2 = NULL; DBL_TYPE *Fgls = NULL; DBL_TYPE *Fgrs = NULL; DBL_TYPE *Fgl = NULL; DBL_TYPE *Fgr = NULL; //O(N^4) space /* F-type matrices are dynamically allocated matrices that contain minimum energies restricted to a subsequence of the strand. Each of the above should be accessed by the call F[ pf_index(i, j, seqlength)] to indicate the partition function between i and j, inclusive. Descriptions of each are in the referenced paper (see pfunc.c) */ int i, j, k; // the beginning and end bases for F long int maxIndex; int L; //This the length of the current subsequence DBL_TYPE min_energy; int pf_ij; DBL_TYPE tempMin; extern long int maxGapIndex; short *possiblePairs; int nicks[ MAXSTRANDS]; //the entries must be strictly increasing //nicks[i] = N means a strand ends with base N, and a new one starts at N+1 int **etaN; int arraySize; int nStrands; int *seq; int *foldparens; DBL_TYPE mfeEpsilon; DBL_TYPE *minILoopEnergyBySize; int *maxILoopSize; DBL_TYPE localEnergy; int oldp1; int symmetryOfStruct = 1; // Must be initialized int *thepairs; //assign global variables TEMP_K = temperature + ZERO_C_IN_KELVIN; DNARNACOUNT = naType; DANGLETYPE = dangles; SODIUM_CONC = sodiumconc; MAGNESIUM_CONC = magnesiumconc; USE_LONG_HELIX_FOR_SALT_CORRECTION = uselongsalt; // Get dG_salt. It will be used to calculate DBL_TYPE salt_correction = computeSaltCorrection(sodiumconc,magnesiumconc,uselongsalt); seqlength = getSequenceLengthInt( inputSeq, &nStrands); mfeEpsilon = kB*TEMP_K*LOG_FUNC(symmetry); //max range to search when looking for mfe if( fixedSubOptRange > 0) { mfeEpsilon = fixedSubOptRange + mfeEpsilon; } for( i = 0; i < MAXSTRANDS; i++) { //initialize nicks array nicks[i] = -1; } seq = (int *) malloc( (seqLen+1)*sizeof( int) ); processMultiSequence( inputSeq, seqlength, nStrands, seq, nicks); foldparens = (int*) malloc( (seqLen+nStrands)*sizeof(int)); if( nStrands >= 2 && complexity >= 5) { printf("Warning, pseudoknots not allowed for multi-stranded complexes!"); printf(" Pseudoknots disabled.\n"); complexity = 3; } LoadEnergies(); if( complexity >= 5) //pseudoknotted initMfe( seqlength); arraySize = seqlength*(seqlength+1)/2 + (seqlength+1); // Allocate and Initialize Matrices InitLDoublesMatrix( &F, arraySize, "F"); InitLDoublesMatrix( &Fb, arraySize, "Fb"); InitLDoublesMatrix( &Fm, arraySize, "Fm"); etaN = (int**) malloc( arraySize*sizeof( int*)); InitEtaN( etaN, nicks, seqlength); maxILoopSize = (int*) malloc( arraySize*sizeof( int)); minILoopEnergyBySize = (DBL_TYPE*) malloc( seqlength*sizeof( DBL_TYPE)); if( complexity == 3) { InitLDoublesMatrix( &Fs, arraySize, "Fs"); InitLDoublesMatrix( &Fms, arraySize, "Fms"); } if( complexity >= 5) { InitLDoublesMatrix( &Fp, arraySize, "Fp"); InitLDoublesMatrix( &Fz, arraySize, "Fz"); InitLDoublesMatrix( &Fg, maxGapIndex, "Fg"); if( complexity == 5) { InitLDoublesMatrix( &Fgl, maxGapIndex, "Fgl"); InitLDoublesMatrix( &Fgr, maxGapIndex, "Fgr"); InitLDoublesMatrix( &Fgls, maxGapIndex, "Fgls"); InitLDoublesMatrix( &Fgrs, maxGapIndex, "Fgrs"); CheckPossiblePairs( &possiblePairs, seqlength, seq); } } //Initialization to NAD_INFINITY if( complexity >= 5) maxIndex = maxGapIndex; //beware overflow else maxIndex = arraySize; for( i = 0; i < maxIndex; i++) { if( i < arraySize ) { F[i] = Fb[i] = Fm[i] = NAD_INFINITY; if( complexity == 3) Fs[i] = Fms[i] = NAD_INFINITY; if( complexity >= 5) Fp[i] = Fz[i] = NAD_INFINITY; } if( complexity >= 5) { Fg[i] = NAD_INFINITY; if( complexity == 5) Fgl[i] = Fgr[i] = Fgls[i] = Fgrs[i] = NAD_INFINITY; } } for( i = 0; i <= seqlength; i++) { pf_ij = pf_index( i, i-1, seqlength); F[ pf_ij] = NickDangle(i, i-1, nicks, etaN, FALSE, seq, seqlength); if( complexity >= 5) Fz[ pf_ij] = F[ pf_ij]; } for( L = 1; L <= seqlength; L++) { /* Calculate all sub energies for length = 0, then 1, then 2.... */ int iMin = 0; int iMax = seqlength - L; if( complexity == 3) manageFx( &Fx, &Fx_1, &Fx_2, L-1, seqlength); //allocate/deallocate memory if( complexity == 5) manageFgIx( &FgIx, &FgIx_1, &FgIx_2, L-1, seqlength); //manageQgIx manages the temporary matrices needed for //calculating Qg_closed in time n^5 for( i = iMin; i <= iMax; i++) { j = i + L - 1; pf_ij = pf_index( i, j, seqlength); //store the maximum iloop size with mfeEpsilon of mfe for( k = 0; k < L; k++) minILoopEnergyBySize[k] = NAD_INFINITY; //initialize to zero; /* Recursions for Fb */ /* bp = base pairs, pk = pseudoknots */ min_energy = NAD_INFINITY; if( CanPair( seq[ i], seq[ j]) == FALSE) { Fb[ pf_ij] = NAD_INFINITY; } else { min_energy = MinHairpin( i, j, seq, seqlength, etaN); // Exactly 1 bp if( complexity == 3) { if( etaN[ EtaNIndex(i+0.5, i+0.5, seqlength)][0] == 0 && etaN[ EtaNIndex(j-0.5, j-0.5, seqlength)][0] == 0) { //regular multiloop. No top-level nicks tempMin = MinMultiloops(i, j, seq, Fms, Fm, seqlength, etaN); min_energy = MIN( tempMin, min_energy); } if( etaN[ EtaNIndex(i+0.5, j-0.5, seqlength)][0] >= 1) { //Exterior loop (created by nick) tempMin = MinExteriorLoop( i, j, seq, seqlength, F, nicks, etaN); min_energy = MIN( tempMin, min_energy); } } if( complexity != 3) { // Interior Loop and Multiloop Case tempMin = MinInterior_Multi( i, j, seq, seqlength, Fm, Fb, nicks, etaN); min_energy = MIN( tempMin, min_energy); } if( complexity >= 5) { tempMin = MinFb_Pk( i, j, seq, seqlength, Fp, Fm ); min_energy = MIN( tempMin, min_energy); } } if( complexity == 3) MinFastILoops( i, j, L, seqlength, seq, etaN, Fb, Fx, Fx_2, minILoopEnergyBySize); Fb[pf_ij] = MIN( Fb[ pf_ij], min_energy); maxILoopSize[ pf_ij] = 0; if( CanPair( seq[i], seq[j]) == TRUE) { for( k = 0; k < L; k++) { if( minILoopEnergyBySize[k] < Fb[ pf_ij] + mfeEpsilon + ENERGY_TOLERANCE ) { maxILoopSize[ pf_ij] = k; } } } // Recursions for Fg, Fgls, Fgrs, Fgl, Fgr if( complexity == 5) { MakeFg_N5(i, j, seq, seqlength, Fg, Fm, Fgls, Fgrs, FgIx, FgIx_2, possiblePairs); MakeFgls( i, j, seq, seqlength, Fg, Fm, Fgls); MakeFgrs( i, j, seq, seqlength, Fg, Fm, Fgrs); MakeFgl(i, j, seq, seqlength, Fg, Fgl, Fz); MakeFgr(i, j, seq, seqlength, Fgr, Fgl, Fz); Fp[ pf_ij] = MinFp_N5( i, j, seq, seqlength, Fgl, Fgr, Fg, Fz); } else if( complexity == 8) { //MakeFg_N8( i, j, seq, seqlength, Fg, Fm); //Fp[ pf_ij] = MinFp_N8( i, j, seq, seqlength, Fg, Fz); } if( complexity == 3) { /* Recursions for Fms, Fs */ MakeFs_Fms( i, j, seq, seqlength, Fs, Fms, Fb, nicks, etaN); /* Recursions for Q, Qm, Qz */ MakeF_Fm_N3( i, j, seq, seqlength, F, Fs, Fms, Fm, nicks,etaN); } #ifdef test if( complexity == 4) MakeF_Fm_N4( i, j, seq, seqlength, F, Fm, Fb); #endif if( complexity >= 5) MakeF_Fm_Fz(i, j, seq, seqlength, F, Fm, Fz, Fb, Fp); } } result = F[ pf_index(0,seqlength-1,seqlength)]; if( result < NAD_INFINITY/2.0) { initMfeStructures( mfeStructures, seqlength); if( complexity == 3) { if( fixedSubOptRange <= 0) { bktrF_Fm_N3( 0, seqlength - 1, seq, seqlength, F, Fb, Fm, Fs, Fms, nicks, etaN, mfeStructures, "F", maxILoopSize, 0, onlyOne && !NUPACK_VALIDATE); thepairs = mfeStructures->validStructs[0].theStruct; symmetryOfStruct = checkSymmetry( thepairs, seqlength, nicks, symmetry, nStrands); // THIS IS WHERE WE KNOW WHETHER OR NOT WE HAVE TO DO THE ENUMERATION mfeEpsilon = kB*TEMP_K*LOG_FUNC( (DBL_TYPE) symmetryOfStruct); //default search space is within RT log( sym) of the mfe if( mfeEpsilon > ENERGY_TOLERANCE) { for( i = 0; i < seqlength; i++) { //check structures that differ by one base pair before doing full enumeration oldp1 = thepairs[i]; if( oldp1 >= 0) { thepairs[i] = -1; thepairs[ oldp1] = -1; //no symmetry is possible if the original structure was symmetric localEnergy = naEnergyPairsOrParensFull( thepairs, NULL, inputSeq, naType, dangles, temperature, SODIUM_CONC, MAGNESIUM_CONC, USE_LONG_HELIX_FOR_SALT_CORRECTION) - ( BIMOLECULAR + SALT_CORRECTION ) *(nStrands-1); //for comparison purposes, remove bimolecular term mfeEpsilon = MIN( mfeEpsilon, localEnergy - result); thepairs[i] = oldp1; thepairs[oldp1] = i; } } } } //find all structures within mfeEpsilon of the mfe if (fixedSubOptRange > 0 || symmetryOfStruct > 1) { clearDnaStructures( mfeStructures); initMfeStructures( mfeStructures, seqlength); bktrF_Fm_N3( 0, seqlength - 1, seq, seqlength, F, Fb, Fm, Fs, Fms, nicks, etaN, mfeStructures, "F", maxILoopSize, mfeEpsilon, FALSE); } } else if( complexity == 5) { if( fixedSubOptRange < 0) mfeEpsilon = 0; bktrF_Fm_FzN5( 0, seqlength - 1, seq, seqlength, F, Fb, Fm, Fp, Fz, Fg, Fgls, Fgrs, Fgl, Fgr, mfeStructures, nicks, etaN, mfeEpsilon, "F"); } #ifdef test else if( complexity == 4) bktrF_Fm_N4( 0, seqlength - 1, seq, seqlength, result, F, Fb, Fm, , "F"); else if( complexity == 8)