1 /*****************************************************************
2 * HMMER - Biological sequence analysis with profile HMMs
3 * Copyright (C) 1992-1999 Washington University School of Medicine
6 * This source code is distributed under the terms of the
7 * GNU General Public License. See the files COPYING and LICENSE
9 *****************************************************************/
12 * SRE, Mon Nov 18 15:44:08 1996
14 * Support for Dirichlet prior data structure, p7prior_s.
26 static struct p7prior_s *default_amino_prior(void);
27 static struct p7prior_s *default_nucleic_prior(void);
29 /* Function: P7AllocPrior(), P7FreePrior()
31 * Purpose: Allocation and free'ing of a prior structure.
32 * Very simple, but might get more complex someday.
36 { return (struct p7prior_s *) MallocOrDie (sizeof(struct p7prior_s)); }
38 P7FreePrior(struct p7prior_s *pri)
42 /* Function: P7LaplacePrior()
44 * Purpose: Create a Laplace plus-one prior. (single component Dirichlets).
45 * Global alphabet info is assumed to have been set already.
49 * Return: prior. Allocated here; call FreePrior() to free it.
54 struct p7prior_s *pri;
57 pri->strategy = PRI_DCHLET;
61 FSet(pri->t[0], 8, 1.);
65 FSet(pri->m[0], Alphabet_size, 1.);
69 FSet(pri->i[0], Alphabet_size, 1.);
74 /* Function: P7DefaultPrior()
76 * Purpose: Set up a somewhat more realistic single component
77 * Dirichlet prior than Laplace.
82 switch (Alphabet_type) {
83 case hmmAMINO: return default_amino_prior();
84 case hmmNUCLEIC: return default_nucleic_prior();
85 case hmmNOTSETYET: Die("Can't set prior; alphabet type not set yet");
91 /* Function: P7ReadPrior()
93 * Purpose: Input a prior from disk file.
96 P7ReadPrior(char *prifile)
99 struct p7prior_s *pri;
103 if ((fp = fopen(prifile, "r")) == NULL)
104 Die("Failed to open HMMER prior file %s\n", prifile);
105 pri = P7AllocPrior();
107 /* First entry is the strategy:
108 * Only standard Dirichlet prior (simple or mixture) is supported in Plan7 so far
110 sptr = Getword(fp, sqdARG_STRING);
112 if (strcmp(sptr, "DIRICHLET") == 0) pri->strategy = PRI_DCHLET;
113 else Die("No such prior strategy %s; failed to parse file %s", sptr, prifile);
115 /* Second entry is the alphabet type:
118 sptr = Getword(fp, sqdARG_STRING);
120 if (strcmp(sptr, "AMINO") == 0)
122 if (Alphabet_type != hmmAMINO)
123 Die("HMM and/or sequences are DNA/RNA; can't use protein prior %s", prifile);
125 else if (strcmp(sptr, "NUCLEIC") == 0)
127 if (Alphabet_type != hmmNUCLEIC)
128 Die("HMM and/or sequences are protein; can't use DNA/RNA prior %s", prifile);
131 Die("Alphabet \"%s\" in prior file %s isn't valid.", sptr, prifile);
133 /* State transition priors:
135 * then for each mixture:
137 * Dirichlet terms for Tmm, Tmi, Tmd, Tim, Tii, Tid, Tdm, Tdi, Tdd
139 pri->tnum = atoi(Getword(fp, sqdARG_INT));
141 Die("%d is bad; need at least one state transition mixture component", pri->tnum);
142 if (pri->tnum > MAXDCHLET)
143 Die("%d is bad, too many transition components (MAXDCHLET = %d)\n", MAXDCHLET);
144 for (q = 0; q < pri->tnum; q++)
146 pri->tq[q] = (float) atof(Getword(fp, sqdARG_FLOAT));
147 for (x = 0; x < 7; x++)
148 pri->t[q][x] = (float) atof(Getword(fp, sqdARG_FLOAT));
151 /* Match emission priors:
153 * then for each mixture:
155 * Dirichlet terms for Alphabet_size symbols in Alphabet
157 pri->mnum = atoi(Getword(fp, sqdARG_INT));
159 Die("%d is bad; need at least one match emission mixture component", pri->mnum);
160 if (pri->mnum > MAXDCHLET)
161 Die("%d is bad; too many match components (MAXDCHLET = %d)\n", pri->mnum, MAXDCHLET);
163 for (q = 0; q < pri->mnum; q++)
165 pri->mq[q] = (float) atof(Getword(fp, sqdARG_FLOAT));
166 for (x = 0; x < Alphabet_size; x++)
167 pri->m[q][x] = (float) atof(Getword(fp, sqdARG_FLOAT));
170 /* Insert emission priors:
172 * then for each mixture component:
174 * Dirichlet terms for Alphabet_size symbols in Alphabet
176 pri->inum = atoi(Getword(fp, sqdARG_INT));
178 Die("%d is bad; need at least one insert emission mixture component", pri->inum);
179 if (pri->inum > MAXDCHLET)
180 Die("%d is bad; too many insert components (MAXDCHLET = %d)\n", pri->inum, MAXDCHLET);
181 for (q = 0; q < pri->inum; q++)
183 pri->iq[q] = (float) atof(Getword(fp, sqdARG_FLOAT));
184 for (x = 0; x < Alphabet_size; x++)
185 pri->i[q][x] = (float) atof(Getword(fp, sqdARG_FLOAT));
193 /* Function: PAMPrior()
195 * Purpose: Produces an ad hoc "Dirichlet mixture" prior for
196 * match emissions, using a PAM matrix.
198 * Side effect notice: PAMPrior() replaces the match
199 * emission section of an existing Dirichlet prior,
200 * which is /expected/ to be a simple one-component
201 * kind of prior. The insert emissions /must/ be a
202 * one-component prior (because of details in how
203 * PriorifyEmissionVector() is done). However,
204 * the transitions /could/ be a mixture Dirichlet prior
205 * without causing problems. In other words, the
206 * -p and -P options of hmmb can coexist, but there
207 * may be conflicts. PAMPrior() checks for these,
208 * so there's no serious problem, except that the
209 * error message from PAMPrior() might be confusing to
213 PAMPrior(char *pamfile, struct p7prior_s *pri, float wt)
216 char *blastpamfile; /* BLAST looks in aa/ subdirectory of BLASTMAT */
222 if (Alphabet_type != hmmAMINO)
223 Die("PAM prior is only valid for protein sequences");
224 if (pri->strategy != PRI_DCHLET)
225 Die("PAM prior may only be applied over an existing Dirichlet prior");
227 Die("PAM prior requires that the insert emissions be a single Dirichlet");
229 Die("Whoa, code is misconfigured; MAXDCHLET must be >= 20 for PAM prior");
231 blastpamfile = FileConcat("aa", pamfile);
233 if ((fp = fopen(pamfile, "r")) == NULL &&
234 (fp = EnvFileOpen(pamfile, "BLASTMAT", NULL)) == NULL &&
235 (fp = EnvFileOpen(blastpamfile, "BLASTMAT", NULL)) == NULL)
236 Die("Failed to open PAM scoring matrix file %s", pamfile);
237 if (! ParsePAMFile(fp, &pam, &scale))
238 Die("Failed to parse PAM scoring matrix file %s", pamfile);
242 pri->strategy = PRI_PAM;
245 /* Convert PAM entries back to conditional prob's P(xj | xi),
246 * which we'll use as "pseudocounts" weighted by wt.
248 for (xi = 0; xi < Alphabet_size; xi++)
249 for (xj = 0; xj < Alphabet_size; xj++)
251 idx1 = Alphabet[xi] - 'A';
252 idx2 = Alphabet[xj] - 'A';
253 pri->m[xi][xj] = aafq[xj] * exp((float) pam[idx1][idx2] * scale);
256 /* Normalize so that rows add up to wt.
257 * i.e. Sum(xj) mat[xi][xj] = wt for every row xi
259 for (xi = 0; xi < Alphabet_size; xi++)
261 pri->mq[xi] = 1. / Alphabet_size;
262 FNorm(pri->m[xi], Alphabet_size);
263 FScale(pri->m[xi], Alphabet_size, wt);
266 Free2DArray((void **)pam,27);
270 /* Function: P7DefaultNullModel()
272 * Purpose: Set up a default random sequence model, using
273 * global aafq[]'s for protein or 1/Alphabet_size for anything
274 * else. randomseq is alloc'ed in caller. Alphabet information
275 * must already be known.
278 P7DefaultNullModel(float *null, float *ret_p1)
281 if (Alphabet_type == hmmAMINO) {
282 for (x = 0; x < Alphabet_size; x++)
284 *ret_p1 = 350./351.; /* rationale: approx avg protein length. */
286 for (x = 0; x < Alphabet_size; x++)
287 null[x] = 1.0 / (float) Alphabet_size;
288 *ret_p1 = 1000./1001.; /* rationale: approx inter-Alu distance. */
293 P7ReadNullModel(char *rndfile, float *null, float *ret_p1)
300 if ((fp = fopen(rndfile, "r")) == NULL)
301 Die("Failed to open null model file %s\n", rndfile);
302 if ((s = Getword(fp, sqdARG_STRING)) == NULL) goto FAILURE;
304 if (strcmp(s, "NUCLEIC") == 0) type = hmmNUCLEIC;
305 else if (strcmp(s, "AMINO") == 0) type = hmmAMINO;
307 /* check/set alphabet type */
308 if (Alphabet_type == 0)
310 else if (Alphabet_type != type)
311 Die("Alphabet type conflict; null model in %s is inappropriate\n", rndfile);
313 for (x = 0; x < Alphabet_size; x++) {
314 if ((s = Getword(fp, sqdARG_FLOAT)) == NULL) goto FAILURE;
317 if ((s = Getword(fp, sqdARG_FLOAT)) == NULL) goto FAILURE;
325 Die("%s is not in HMMER null model file format", rndfile);
329 /* Function: P7PriorifyHMM()
331 * Purpose: Add pseudocounts to an HMM using Dirichlet priors,
332 * and renormalize the HMM.
334 * Args: hmm -- the HMM to add counts to (counts form)
335 * pri -- the Dirichlet prior to use
338 * HMM returns in probability form.
341 P7PriorifyHMM(struct plan7_s *hmm, struct p7prior_s *pri)
343 int k; /* counter for model position */
344 float d; /* a denominator */
345 float tq[MAXDCHLET]; /* prior distribution over mixtures */
346 float mq[MAXDCHLET]; /* prior distribution over mixtures */
347 float iq[MAXDCHLET]; /* prior distribution over mixtures */
349 /* Model-dependent transitions are handled simply; Laplace.
351 FSet(hmm->begin+2, hmm->M-1, 0.); /* wipe internal BM entries */
352 FSet(hmm->end+1, hmm->M-1, 0.); /* wipe internal ME exits */
353 d = hmm->tbd1 + hmm->begin[1] + 2.;
354 hmm->tbd1 = (hmm->tbd1 + 1.)/ d;
355 hmm->begin[1] = (hmm->begin[1] + 1.)/ d;
356 hmm->end[hmm->M] = 1.0;
358 /* Main model transitions and emissions
360 for (k = 1; k < hmm->M; k++)
362 /* The following code chunk is experimental.
363 * Collaboration with Michael Asman, Erik Sonnhammer, CGR Stockholm.
364 * Only activated if X-PR* annotation has been used, in which
365 * priors are overridden and a single Dirichlet component is
366 * specified for each column (using structural annotation).
367 * If X-PR* annotation is not used, which is usually the case,
368 * the following code has no effect (observe how the real prior
369 * distributions are copied into tq, mq, iq).
371 if (hmm->tpri != NULL && hmm->tpri[k] >= 0)
373 if (hmm->tpri[k] >= pri->tnum) Die("X-PRT annotation out of range");
374 FSet(tq, pri->tnum, 0.0);
375 tq[hmm->tpri[k]] = 1.0;
378 FCopy(tq, pri->tq, pri->tnum);
379 if (hmm->mpri != NULL && hmm->mpri[k] >= 0)
381 if (hmm->mpri[k] >= pri->mnum) Die("X-PRM annotation out of range");
382 FSet(mq, pri->mnum, 0.0);
383 mq[hmm->mpri[k]] = 1.0;
386 FCopy(mq, pri->mq, pri->mnum);
387 if (hmm->ipri != NULL && hmm->ipri[k] >= 0)
389 if (hmm->ipri[k] >= pri->inum) Die("X-PRI annotation out of range");
390 FSet(iq, pri->inum, 0.0);
391 iq[hmm->ipri[k]] = 1.0;
394 FCopy(iq, pri->iq, pri->inum);
396 /* This is the main line of the code:
398 P7PriorifyTransitionVector(hmm->t[k], pri, tq);
399 P7PriorifyEmissionVector(hmm->mat[k], pri, pri->mnum, mq, pri->m, NULL);
400 P7PriorifyEmissionVector(hmm->ins[k], pri, pri->inum, iq, pri->i, NULL);
403 /* We repeat the above steps just for the final match state, M.
405 if (hmm->mpri != NULL && hmm->mpri[hmm->M] >= 0)
407 if (hmm->mpri[hmm->M] >= pri->mnum) Die("X-PRM annotation out of range");
408 FSet(mq, pri->mnum, 0.0);
409 mq[hmm->mpri[hmm->M]] = 1.0;
412 FCopy(mq, pri->mq, pri->mnum);
414 P7PriorifyEmissionVector(hmm->mat[hmm->M], pri, pri->mnum, mq, pri->m, NULL);
416 /* Now we're done. Convert the counts-based HMM to probabilities.
418 Plan7Renormalize(hmm);
422 /* Function: P7PriorifyEmissionVector()
424 * Purpose: Add prior pseudocounts to an observed
425 * emission count vector and renormalize.
427 * Can return the posterior mixture probabilities
428 * P(q | counts) if ret_mix[MAXDCHLET] is passed.
431 * Args: vec - the 4 or 20-long vector of counts to modify
432 * pri - prior data structure
433 * num - pri->mnum or pri->inum; # of mixtures
434 * eq - pri->mq or pri->iq; prior mixture probabilities
435 * e - pri->i or pri->m; Dirichlet components
436 * ret_mix - filled with posterior mixture probabilities, or NULL
439 * The counts in vec are changed and normalized to probabilities.
442 P7PriorifyEmissionVector(float *vec, struct p7prior_s *pri,
443 int num, float eq[MAXDCHLET], float e[MAXDCHLET][MAXABET],
446 int x; /* counter over vec */
447 int q; /* counter over mixtures */
448 float mix[MAXDCHLET]; /* posterior distribution over mixtures */
449 float totc; /* total counts */
450 float tota; /* total alpha terms */
451 float xi; /* X_i term, Sjolander eq. 41 */
453 /* Calculate mix[], which is the posterior probability
454 * P(q | n) of mixture component q given the count vector n
456 * (side effect note: note that an insert vector in a PAM prior
457 * is passed with num = 1, bypassing pam prior code; this means
458 * that inserts cannot be mixture Dirichlets...)
459 * [SRE, 12/24/00: the above comment is cryptic! what the hell does that
460 * mean, inserts can't be mixtures? doesn't seem to be true. it
461 * may mean that in a PAM prior, you can't have a mixture for inserts,
462 * but I don't even understand that. The insert vectors aren't passed
466 if (pri->strategy == PRI_DCHLET && num > 1)
468 for (q = 0; q < num; q++)
470 mix[q] = eq[q] > 0.0 ? log(eq[q]) : -999.;
471 mix[q] += Logp_cvec(vec, Alphabet_size, e[q]);
473 LogNorm(mix, num); /* now mix[q] is P(component_q | n) */
475 else if (pri->strategy == PRI_PAM && num > 1)
476 { /* pam prior uses aa frequencies as `P(q|n)' */
477 for (q = 0; q < Alphabet_size; q++)
479 FNorm(mix, Alphabet_size);
482 /* Convert the counts to probabilities, following Sjolander (1996)
484 totc = FSum(vec, Alphabet_size);
485 for (x = 0; x < Alphabet_size; x++) {
487 for (q = 0; q < num; q++) {
488 tota = FSum(e[q], Alphabet_size);
489 xi += mix[q] * (vec[x] + e[q][x]) / (totc + tota);
493 FNorm(vec, Alphabet_size);
496 for (q = 0; q < num; q++)
502 /* Function: P7PriorifyTransitionVector()
504 * Purpose: Add prior pseudocounts to transition vector,
505 * which contains three different probability vectors
508 * Args: t - state transitions, counts: 3 for M, 2 for I, 2 for D.
509 * prior - Dirichlet prior information
510 * tq - prior distribution over Dirichlet components.
511 * (overrides prior->iq[]; used for alternative
512 * methods of conditioning prior on structural data)
515 * t is changed, and renormalized -- comes back as
516 * probability vectors.
519 P7PriorifyTransitionVector(float *t, struct p7prior_s *prior,
524 float mix[MAXDCHLET];
525 float totm, totd, toti; /* total counts in three transition vecs */
526 float xi; /* Sjolander's X_i term */
528 mix[0] = 1.0; /* default is simple one component */
529 if ((prior->strategy == PRI_DCHLET || prior->strategy == PRI_PAM) && prior->mnum > 1)
531 for (q = 0; q < prior->tnum; q++)
533 mix[q] = tq[q] > 0.0 ? log(tq[q]) : -999.;
534 mix[q] += Logp_cvec(t, 3, prior->t[q]); /* 3 match */
535 mix[q] += Logp_cvec(t+3, 2, prior->t[q]+3); /* 2 insert */
536 mix[q] += Logp_cvec(t+5, 2, prior->t[q]+5); /* 2 delete */
538 LogNorm(mix, prior->tnum); /* mix[q] is now P(q | counts) */
540 /* precalc some denominators */
542 toti = t[TIM] + t[TII];
543 totd = t[TDM] + t[TDD];
545 for (ts = 0; ts < 7; ts++)
548 for (q = 0; q < prior->tnum; q++)
551 case TMM: case TMI: case TMD:
552 xi += mix[q] * (t[ts] + prior->t[q][ts]) /
553 (totm + FSum(prior->t[q], 3));
556 xi += mix[q] * (t[ts] + prior->t[q][ts]) /
557 (toti + prior->t[q][TIM] + prior->t[q][TII]);
560 xi += mix[q] * (t[ts] + prior->t[q][ts]) /
561 (totd + prior->t[q][TDM] + prior->t[q][TDD]);
567 FNorm(t, 3); /* match */
568 FNorm(t+3, 2); /* insert */
569 FNorm(t+5, 2); /* delete */
573 /* Function: default_amino_prior()
575 * Purpose: Set the default protein prior.
577 static struct p7prior_s *
578 default_amino_prior(void)
580 struct p7prior_s *pri;
582 /* default match mixture coefficients */
583 static float defmq[9] = {
584 0.178091, 0.056591, 0.0960191, 0.0781233, 0.0834977,
585 0.0904123, 0.114468, 0.0682132, 0.234585 };
587 /* default match mixture Dirichlet components */
588 static float defm[9][20] = {
589 { 0.270671, 0.039848, 0.017576, 0.016415, 0.014268,
590 0.131916, 0.012391, 0.022599, 0.020358, 0.030727,
591 0.015315, 0.048298, 0.053803, 0.020662, 0.023612,
592 0.216147, 0.147226, 0.065438, 0.003758, 0.009621 },
593 { 0.021465, 0.010300, 0.011741, 0.010883, 0.385651,
594 0.016416, 0.076196, 0.035329, 0.013921, 0.093517,
595 0.022034, 0.028593, 0.013086, 0.023011, 0.018866,
596 0.029156, 0.018153, 0.036100, 0.071770, 0.419641 },
597 { 0.561459, 0.045448, 0.438366, 0.764167, 0.087364,
598 0.259114, 0.214940, 0.145928, 0.762204, 0.247320,
599 0.118662, 0.441564, 0.174822, 0.530840, 0.465529,
600 0.583402, 0.445586, 0.227050, 0.029510, 0.121090 },
601 { 0.070143, 0.011140, 0.019479, 0.094657, 0.013162,
602 0.048038, 0.077000, 0.032939, 0.576639, 0.072293,
603 0.028240, 0.080372, 0.037661, 0.185037, 0.506783,
604 0.073732, 0.071587, 0.042532, 0.011254, 0.028723 },
605 { 0.041103, 0.014794, 0.005610, 0.010216, 0.153602,
606 0.007797, 0.007175, 0.299635, 0.010849, 0.999446,
607 0.210189, 0.006127, 0.013021, 0.019798, 0.014509,
608 0.012049, 0.035799, 0.180085, 0.012744, 0.026466 },
609 { 0.115607, 0.037381, 0.012414, 0.018179, 0.051778,
610 0.017255, 0.004911, 0.796882, 0.017074, 0.285858,
611 0.075811, 0.014548, 0.015092, 0.011382, 0.012696,
612 0.027535, 0.088333, 0.944340, 0.004373, 0.016741 },
613 { 0.093461, 0.004737, 0.387252, 0.347841, 0.010822,
614 0.105877, 0.049776, 0.014963, 0.094276, 0.027761,
615 0.010040, 0.187869, 0.050018, 0.110039, 0.038668,
616 0.119471, 0.065802, 0.025430, 0.003215, 0.018742 },
617 { 0.452171, 0.114613, 0.062460, 0.115702, 0.284246,
618 0.140204, 0.100358, 0.550230, 0.143995, 0.700649,
619 0.276580, 0.118569, 0.097470, 0.126673, 0.143634,
620 0.278983, 0.358482, 0.661750, 0.061533, 0.199373 },
621 { 0.005193, 0.004039, 0.006722, 0.006121, 0.003468,
622 0.016931, 0.003647, 0.002184, 0.005019, 0.005990,
623 0.001473, 0.004158, 0.009055, 0.003630, 0.006583,
624 0.003172, 0.003690, 0.002967, 0.002772, 0.002686 },
627 pri = P7AllocPrior();
628 pri->strategy = PRI_DCHLET;
630 /* Transition priors are subjective, but borrowed from GJM's estimations
635 pri->t[0][TMM] = 0.7939;
636 pri->t[0][TMI] = 0.0278;
637 pri->t[0][TMD] = 0.0135;
638 pri->t[0][TIM] = 0.1551;
639 pri->t[0][TII] = 0.1331;
640 pri->t[0][TDM] = 0.9002;
641 pri->t[0][TDD] = 0.5630;
643 /* Match emission priors are a mixture Dirichlet,
644 * from Kimmen Sjolander (Blocks9)
647 for (q = 0; q < pri->mnum; q++)
649 pri->mq[q] = defmq[q];
650 for (x = 0; x < 20; x++)
651 pri->m[q][x] = defm[q][x];
654 /* These insert emission priors are subjective. Observed frequencies
655 * were obtained from PFAM 1.0, 10 Nov 96;
656 * see ~/projects/plan7/InsertStatistics.
657 * Inserts are slightly biased towards polar residues and away from
658 * hydrophobic residues.
662 pri->i[0][0] = 681.; /* A */
663 pri->i[0][1] = 120.; /* C */
664 pri->i[0][2] = 623.; /* D */
665 pri->i[0][3] = 651.; /* E */
666 pri->i[0][4] = 313.; /* F */
667 pri->i[0][5] = 902.; /* G */
668 pri->i[0][6] = 241.; /* H */
669 pri->i[0][7] = 371.; /* I */
670 pri->i[0][8] = 687.; /* K */
671 pri->i[0][9] = 676.; /* L */
672 pri->i[0][10] = 143.; /* M */
673 pri->i[0][11] = 548.; /* N */
674 pri->i[0][12] = 647.; /* P */
675 pri->i[0][13] = 415.; /* Q */
676 pri->i[0][14] = 551.; /* R */
677 pri->i[0][15] = 926.; /* S */
678 pri->i[0][16] = 623.; /* T */
679 pri->i[0][17] = 505.; /* V */
680 pri->i[0][18] = 102.; /* W */
681 pri->i[0][19] = 269.; /* Y */
687 /* Function: default_nucleic_prior()
689 * Purpose: Set the default DNA prior. (for now, almost a Laplace)
691 static struct p7prior_s *
692 default_nucleic_prior(void)
694 struct p7prior_s *pri;
696 pri = P7AllocPrior();
697 pri->strategy = PRI_DCHLET;
699 /* The use of the Pfam-trained amino acid transition priors
700 * here is TOTALLY bogus. But it works better than a straight
701 * Laplace, esp. for Maxmodelmaker(). For example, a Laplace
702 * prior builds M=1 models for a single sequence GAATTC (at
703 * one time an open "bug").
707 pri->t[0][TMM] = 0.7939;
708 pri->t[0][TMI] = 0.0278;
709 pri->t[0][TMD] = 0.0135;
710 pri->t[0][TIM] = 0.1551;
711 pri->t[0][TII] = 0.1331;
712 pri->t[0][TDM] = 0.9002;
713 pri->t[0][TDD] = 0.5630;
717 FSet(pri->m[0], Alphabet_size, 1.);
721 FSet(pri->i[0], Alphabet_size, 1.);