Int_fuzz.cpp
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:12k
源码类别:

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: Int_fuzz.cpp,v $
  4.  * PRODUCTION Revision 1000.2  2004/06/01 19:32:23  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R6.12
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /* $Id: Int_fuzz.cpp,v 1000.2 2004/06/01 19:32:23 gouriano Exp $
  10.  * ===========================================================================
  11.  *
  12.  *                            PUBLIC DOMAIN NOTICE
  13.  *               National Center for Biotechnology Information
  14.  *
  15.  *  This software/database is a "United States Government Work" under the
  16.  *  terms of the United States Copyright Act.  It was written as part of
  17.  *  the author's official duties as a United States Government employee and
  18.  *  thus cannot be copyrighted.  This software/database is freely available
  19.  *  to the public for use. The National Library of Medicine and the U.S.
  20.  *  Government have not placed any restriction on its use or reproduction.
  21.  *
  22.  *  Although all reasonable efforts have been taken to ensure the accuracy
  23.  *  and reliability of the software and data, the NLM and the U.S.
  24.  *  Government do not and cannot warrant the performance or results that
  25.  *  may be obtained by using this software or data. The NLM and the U.S.
  26.  *  Government disclaim all warranties, express or implied, including
  27.  *  warranties of performance, merchantability or fitness for any particular
  28.  *  purpose.
  29.  *
  30.  *  Please cite the author in any work or product based on this material.
  31.  *
  32.  * ===========================================================================
  33.  *
  34.  * Author:  .......
  35.  *
  36.  * File Description:
  37.  *   .......
  38.  *
  39.  * Remark:
  40.  *   This code was originally generated by application DATATOOL
  41.  *   using specifications from the ASN data definition file
  42.  *   'general.asn'.
  43.  *
  44.  * ===========================================================================
  45.  */
  46. // standard includes
  47. // generated includes
  48. #include <ncbi_pch.hpp>
  49. #include <objects/general/Int_fuzz.hpp>
  50. #include <algorithm>
  51. #include <set>
  52. #include <math.h>
  53. // generated classes
  54. BEGIN_NCBI_SCOPE
  55. BEGIN_objects_SCOPE // namespace ncbi::objects::
  56. // destructor
  57. CInt_fuzz::~CInt_fuzz(void)
  58. {
  59. }
  60. void CInt_fuzz::GetLabel(string* label, TSeqPos pos, bool right) const
  61. {
  62.     char lim = 0;
  63.     switch (Which()) {
  64.     case CInt_fuzz::e_P_m:
  65.         (*label) += "<+-" + NStr::IntToString(GetP_m()) + ">";
  66.         break;
  67.     case CInt_fuzz::e_Range:
  68.         (*label) += "<" + NStr::IntToString(GetRange().GetMin()) +
  69.             "." + NStr::IntToString(GetRange().GetMax()) + ">";
  70.         break;
  71.     case CInt_fuzz::e_Pct:
  72.         (*label) += "<" + NStr::IntToString(GetPct()) + "%>";
  73.         break;
  74.     case CInt_fuzz::e_Lim:
  75.         switch (GetLim()) {
  76.         case eLim_unk:
  77.         case eLim_other:
  78.             (*label) += "<?>";
  79.             break;
  80.         case eLim_gt:
  81.             lim = '>';
  82.             break;
  83.         case eLim_lt:
  84.             lim = '<';
  85.             break;
  86.         case eLim_tr:
  87.             lim = 'r';
  88.             break;
  89.         case eLim_tl:
  90.             lim = '^';
  91.             break;
  92.         default:
  93.             break;
  94.         }
  95.         break;
  96.     default:
  97.         break;
  98.     }
  99.     if (lim  &&  lim != 'r') {
  100.         (*label) += lim;
  101.         lim = 0;
  102.     }
  103.     if (right) {
  104.         (*label) += NStr::IntToString(pos + 1);
  105.     }
  106.     if (lim == 'r') {
  107.         (*label) += '^';
  108.     }
  109.     if (!right) {
  110.         (*label) += NStr::IntToString(pos + 1);
  111.     }
  112. }
  113. void CInt_fuzz::AssignTranslated(const CInt_fuzz& f2, TSeqPos n1, TSeqPos n2)
  114. {
  115.     switch (f2.Which()) {
  116.     case e_Range:
  117.         SetRange().SetMin(f2.GetRange().GetMin() + n1 - n2);
  118.         SetRange().SetMax(f2.GetRange().GetMax() + n1 - n2);
  119.         break;
  120.     case e_Pct:
  121.         // use double to avoid overflow
  122.         SetPct((TSeqPos)((double)f2.GetPct() * n1 / n2));
  123.         break;
  124.     case e_Alt:
  125.         ITERATE (TAlt, it, f2.GetAlt()) {
  126.             SetAlt().push_back(*it + n1 - n2);
  127.         }
  128.         break;
  129.     default:
  130.         Assign(f2);
  131.         break;
  132.     }
  133. }
  134. void CInt_fuzz::Add(const CInt_fuzz& f2, TSeqPos& n1, TSeqPos n2,
  135.                     ECombine mode)
  136. {
  137.     static const double kInfinity = 1.0e20;
  138.     bool                hit_pct = false, hit_unk = false, hit_circle = false;
  139.     double              min_delta = 0.0, max_delta = 0.0;
  140.     set<TSignedSeqPos>  offsets;
  141.     for (int i = 0;  i < 2;  ++i) {
  142.         const CInt_fuzz& f = i ? f2 : *this;
  143.         TSeqPos          n = i ? n2 : n1;
  144.         switch (f.Which()) {
  145.         case e_P_m:
  146.             min_delta -= f.GetP_m();
  147.             max_delta += f.GetP_m();
  148.             break;
  149.         case e_Range:
  150.             min_delta -= n - f.GetRange().GetMin();
  151.             max_delta += f.GetRange().GetMax() - n;
  152.             break;
  153.         case e_Pct:
  154.             min_delta -= 0.001 * n * f.GetPct();
  155.             max_delta += 0.001 * n * f.GetPct();
  156.             hit_pct = true;
  157.             break;
  158.         case e_Lim:
  159.             switch (f.GetLim()) {
  160.             case eLim_unk:
  161.                 hit_unk   = (!hit_unk  ||  mode != eReduce);
  162.                 min_delta = -kInfinity;
  163.                 // fall through
  164.             case eLim_gt:
  165.                 max_delta = kInfinity;
  166.                 break;
  167.             case eLim_lt:
  168.                 min_delta = -kInfinity;
  169.                 break;
  170.             case eLim_tr:
  171.                 min_delta += 0.5;
  172.                 max_delta += 0.5;
  173.                 break;
  174.             case eLim_tl:
  175.                 min_delta -= 0.5;
  176.                 max_delta -= 0.5;
  177.                 break;
  178.             case eLim_circle:
  179.                 hit_circle = (!hit_circle  ||  mode != eReduce);
  180.                 break;
  181.             default:
  182.                 break;
  183.             }
  184.             break;
  185.         case e_Alt:
  186.         {
  187.             if (f.GetAlt().empty()) {
  188.                 break;
  189.             }
  190.             if (offsets.empty()) {
  191.                 ITERATE (TAlt, it, f.GetAlt()) {
  192.                     offsets.insert(*it - n);
  193.                 }
  194.             } else if (mode == eReduce) {
  195.                 // possibly too optimistic; endpoints may balance better
  196.                 // than interior points
  197.                 min_delta = max_delta = f.GetAlt().front();
  198.                 ITERATE (TAlt, it, f.GetAlt()) {
  199.                     if (*it < min_delta) {
  200.                         min_delta = *it;
  201.                     } else if (*it > max_delta) {
  202.                         max_delta = *it;
  203.                     }
  204.                 }
  205.                 min_delta += *offsets.rbegin();
  206.                 max_delta += *offsets.begin();
  207.                 offsets.clear();
  208.             } else {
  209.                 set<TSignedSeqPos> offsets0(offsets);
  210.                 offsets.clear();
  211.                 ITERATE (set<TSignedSeqPos>, it, offsets0) {
  212.                     ITERATE (TAlt, it2, f.GetAlt()) {
  213.                         offsets.insert(*it + *it2 - n);
  214.                     }
  215.                 }
  216.             }
  217.             break;
  218.         }
  219.         default:
  220.             break;
  221.         }
  222.         if (mode == eReduce  &&  max_delta - min_delta < kInfinity / 2) {
  223.             swap(min_delta, max_delta);
  224.         }
  225.     }
  226.     if (min_delta > max_delta) {
  227.         swap(min_delta, max_delta);
  228.     }
  229.     TSignedSeqPos min_delta_sp = TSignedSeqPos(floor(min_delta + 0.5));
  230.     TSignedSeqPos max_delta_sp = TSignedSeqPos(floor(max_delta + 0.5));
  231.     if (min_delta < -kInfinity / 2) {
  232.         if (max_delta > kInfinity / 2) {
  233.             if ( /* mode == eReduce  && */ !hit_unk ) {
  234.                 // assume cancellation
  235.                 SetP_m(0);
  236.             } else {
  237.                 SetLim(eLim_unk);
  238.             }
  239.         } else {
  240.             if ( !offsets.empty() ) {
  241.                 n1 += *offsets.rbegin();
  242.             }
  243.             n1 += max_delta_sp;
  244.             SetLim(eLim_lt);
  245.         }
  246.     } else if (max_delta > kInfinity / 2) {
  247.         if ( !offsets.empty() ) {
  248.             n1 += *offsets.begin();
  249.         }
  250.         n1 += min_delta_sp;
  251.         SetLim(eLim_gt);
  252.     } else if ( !offsets.empty() ) {
  253.         if (max_delta - min_delta < 0.5) {
  254.             TAlt& alt = SetAlt();
  255.             alt.clear();
  256.             ITERATE(set<TSignedSeqPos>, it, offsets) {
  257.                 alt.push_back(n1 + *it + min_delta_sp);
  258.                 }
  259.         } else if (mode == eReduce) {
  260.             TRange& r = SetRange();
  261.             min_delta += *offsets.rbegin();
  262.             max_delta += *offsets.begin();
  263.             if (min_delta > max_delta) {
  264.                 swap(min_delta, max_delta);
  265.             }
  266.             r.SetMin(n1 + min_delta_sp);
  267.             r.SetMax(n1 + max_delta_sp);
  268.         } else {
  269.             // assume there's enough spread to cover any gaps
  270.                 TRange& r = SetRange();
  271.                 r.SetMin(n1 + min_delta_sp + *offsets.begin());
  272.                 r.SetMax(n1 + max_delta_sp + *offsets.rbegin());
  273.         }
  274.     } else if (max_delta - min_delta < 0.5) { // single point identified
  275.         double delta  = 0.5 * (min_delta + max_delta);
  276.         double rdelta = floor(delta + 0.5);
  277.         n1 += (TSignedSeqPos)rdelta;
  278.         if (delta - rdelta > 0.25) {
  279.             SetLim(eLim_tr);
  280.         } else if (delta - rdelta < -0.25) {
  281.             SetLim(eLim_tl);
  282.         } else if (hit_circle) {
  283.             SetLim(eLim_circle);
  284.         } else {
  285.             SetP_m(0);
  286.         }
  287.     } else if (hit_pct) {
  288.         n1 += (TSignedSeqPos)floor(0.5 * (min_delta + max_delta + 1));
  289.         SetPct((TSeqPos)floor(500.0 * (max_delta - min_delta) / n1 + 0.5));
  290.     } else if (min_delta + max_delta < 0.5) { // symmetric
  291.         SetP_m(max_delta_sp);
  292.     } else {
  293.         TRange& r = SetRange();
  294.         r.SetMin(n1 + min_delta_sp);
  295.         r.SetMax(n1 + max_delta_sp);
  296.     }
  297. }
  298. void CInt_fuzz::Negate(TSeqPos n)
  299. {
  300.     switch (Which()) {
  301.     case e_P_m:
  302.     case e_Pct:
  303.         break; // already symmetric
  304.     case e_Range:
  305.     {
  306.         TRange& r       = SetRange();
  307.         TSeqPos old_max = r.GetMax();
  308.         r.SetMax(n + n - r.GetMin());
  309.         r.SetMin(n + n - old_max);
  310.         break;
  311.     }
  312.     case e_Lim:
  313.         switch (GetLim()) {
  314.         case eLim_gt:  SetLim(eLim_lt);  break;
  315.         case eLim_lt:  SetLim(eLim_gt);  break;
  316.         case eLim_tr:  SetLim(eLim_tl);  break;
  317.         case eLim_tl:  SetLim(eLim_tr);  break;
  318.         default:       break;
  319.         }
  320.         break;
  321.     case e_Alt:
  322.         NON_CONST_ITERATE(TAlt, it, SetAlt()) {
  323.             *it = n + n - *it;
  324.         }
  325.         break;
  326.     default:
  327.         break;
  328.     }
  329. }
  330. END_objects_SCOPE // namespace ncbi::objects::
  331. END_NCBI_SCOPE
  332. /*
  333.  * ===========================================================================
  334.  *
  335.  * $Log: Int_fuzz.cpp,v $
  336.  * Revision 1000.2  2004/06/01 19:32:23  gouriano
  337.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R6.12
  338.  *
  339.  * Revision 6.12  2004/05/19 17:21:39  gorelenk
  340.  * Added include of PCH - ncbi_pch.hpp
  341.  *
  342.  * Revision 6.11  2004/04/12 16:51:46  vasilche
  343.  * Fixed conversion warnings.
  344.  *
  345.  * Revision 6.10  2004/01/06 14:36:06  dicuccio
  346.  * Removed unnecessary #include of ncbiapp.hpp and ncbireg.hpp.  Added <set> where
  347.  * needed.
  348.  *
  349.  * Revision 6.9  2003/10/15 19:07:09  ucko
  350.  * Fix some logic errors with lt/gt limits in CInt_fuzz::Add
  351.  *
  352.  * Revision 6.8  2003/10/15 17:37:15  ucko
  353.  * Fix a couple of instances of unintentional fall-through.
  354.  *
  355.  * Revision 6.7  2003/10/15 16:22:24  ucko
  356.  * Sigh, add missing parenthesis.
  357.  *
  358.  * Revision 6.6  2003/10/15 16:20:09  ucko
  359.  * portability fixes to use of double in CInt_fuzz::Add
  360.  *
  361.  * Revision 6.5  2003/10/15 15:43:07  ucko
  362.  * Add more operations: AssignTranslated, Add, Subtract, and Negate/Negative.
  363.  *
  364.  * Revision 6.4  2002/12/26 12:46:37  dicuccio
  365.  * Removed spurious dependency on Seq_point.hpp
  366.  *
  367.  * Revision 6.3  2002/10/08 18:52:21  clausen
  368.  * Changed TSeqPos from 0 based to 1 based in GetLabel()
  369.  *
  370.  * Revision 6.2  2002/10/03 19:11:02  clausen
  371.  * Removed extra whitespace
  372.  *
  373.  * Revision 6.1  2002/10/03 16:47:26  clausen
  374.  * Added GetLabel()
  375.  *
  376.  * ===========================================================================
  377.  */
  378. /* Original file checksum: lines: 61, chars: 1885, CRC32: bf6aceba */