Example #1
0
Real OneDimSolve::Solve(Real Y, Real X, Real Dev, int Lim)
{
   enum Loop { start, captured1, captured2, binary, finish };
   Tracer et("OneDimSolve::Solve");
   lim=Lim; Captured = false;
   if (Dev==0.0) Throw(SolutionException("Dev is zero"));
   L=0; C=1; U=2; vpol=1; hpol=1; y[C]=0.0; y[U]=0.0;
   if (Dev<0.0) { hpol=-1; Dev = -Dev; }
   YY=Y;                                // target value
   x[L] = X;                            // initial trial value
   if (!function.IsValid(X))
      Throw(SolutionException("Starting value is invalid"));
   Loop TheLoop = start;
   for (;;)
   {
      switch (TheLoop)
      {
      case start:
	 LookAt(L); if (Finish) { TheLoop = finish; break; }
	 if (y[L]>0.0) VFlip();               // so Y[L] < 0

         x[U] = X + Dev * hpol;
         if (!function.maxXinf && x[U] > function.maxX)
            x[U] = (function.maxX + X) / 2.0;
         if (!function.minXinf && x[U] < function.minX)
            x[U] = (function.minX + X) / 2.0;

	 LookAt(U); if (Finish) { TheLoop = finish; break; }
	 if (y[U] > 0.0) { TheLoop = captured1; Captured = true; break; }
	 if (y[U] == y[L])
	    Throw(SolutionException("Function is flat"));
	 if (y[U] < y[L]) HFlip();             // Change direction
	 State(L,U,C);
	 for (i=0; i<20; i++)
	 {
	    // cout << "Searching for crossing point\n";
	    // Have L C then crossing point, Y[L]<Y[C]<0
            x[U] = x[C] + Dev * hpol;
            if (!function.maxXinf && x[U] > function.maxX)
               x[U] = (function.maxX + x[C]) / 2.0;
            if (!function.minXinf && x[U] < function.minX)
               x[U] = (function.minX + x[C]) / 2.0;

	    LookAt(U); if (Finish) { TheLoop = finish; break; }
	    if (y[U] > 0) { TheLoop = captured2; Captured = true; break; }
	    if (y[U] < y[C])
	       Throw(SolutionException("Function is not monotone"));
	    Dev *= 2.0;
	    State(C,U,L);
	 }
	 if (TheLoop != start ) break;
	 Throw(SolutionException("Can't locate a crossing point"));

      case captured1:
	 // cout << "Captured - 1\n";
	 // We have 2 points L and U with crossing between them
	 Linear(L,C,U);                   // linear interpolation
					  // - result to C
	 LookAt(C); if (Finish) { TheLoop = finish; break; }
	 if (y[C] > 0.0) Flip();            // Want y[C] < 0
	 if (y[C] < 0.5*y[L]) { State(C,L,U); TheLoop = binary; break; }

      case captured2:
	 // cout << "Captured - 2\n";
	 // We have L,C before crossing, U after crossing
	 Quadratic(L,C,U);                // quad interpolation
					  // - result to L
	 State(C,L,U);
	 if ((x[C] - x[L])*hpol <= 0.0 || (x[C] - x[U])*hpol >= 0.0)
	    { TheLoop = captured1; break; }
	 LookAt(C); if (Finish) { TheLoop = finish; break; }
	 // cout << "Through first stage\n";
	 if (y[C] > 0.0) Flip();
	 if (y[C] > 0.5*y[L]) { TheLoop = captured2; break; }
	 else { State(C,L,U); TheLoop = captured1; break; }

      case binary:
	 // We have L, U around crossing - do binary search
	 // cout << "Binary\n";
	 for (i=3; i; i--)
	 {
	    x[C] = 0.5*(x[L]+x[U]);
	    LookAt(C); if (Finish) { TheLoop = finish; break; }
	    if (y[C]>0.0) State(L,U,C); else State(C,L,U);
	 }
	 if (TheLoop != binary) break;
	 TheLoop = captured1; break;

      case finish:
	 return x[Last];

      }
   }
}
Example #2
0
//***************************************************************************
Kwave::CurveWidget::CurveWidget(QWidget *parent)
    :QWidget(parent), m_width(0), m_height(0), m_curve(), m_menu(0),
     m_preset_menu(0), m_current(Kwave::Curve::NoPoint),
     m_last(Kwave::Curve::NoPoint),
     m_down(false), m_knob(), m_selected_knob()
{
    KIconLoader icon_loader;

    // set the default curve
    m_curve.fromCommand(_("curve(linear,0,0,1,1)"));

    QPalette pal = palette();
    pal.setColor(QPalette::Window, Qt::black);
    setPalette(pal);

    // create the pixmaps for the selected and non-selected knob
    m_knob = icon_loader.loadIcon(_("knob.xpm"), KIconLoader::Small);
    m_selected_knob = icon_loader.loadIcon(_("selectedknob.xpm"),
                                           KIconLoader::Small);

    // set up the context menu for the right mouse button
    m_menu = new QMenu(this);
    Q_ASSERT(m_menu);
    if (!m_menu) return;

    QMenu *interpolation = m_menu->addMenu(i18n("Interpolation"));
    Q_ASSERT(interpolation);
    if (!interpolation) return;

    m_menu->addSeparator();
    QMenu *transform = m_menu->addMenu(i18n("Transform"));
    Q_ASSERT(transform);
    if (!transform) return;
    transform->addAction(i18n("Flip horizontal"),
	                 this, SLOT(HFlip()));
    transform->addAction(i18n("Flip vertical"),
                         this, SLOT(VFlip()));
    transform->addSeparator();
    transform->addAction(i18n("Into first half"),
                         this, SLOT(firstHalf()));
    transform->addAction(i18n("Into second half"),
                         this, SLOT(secondHalf()));

    QMenu *del = m_menu->addMenu(i18n("Delete"));
    Q_ASSERT(del);
    if (!del) return;

    m_menu->addAction(i18n("Fit In"), this, SLOT(scaleFit()));
    m_menu->addSeparator();

    /* list of presets */
    m_preset_menu = m_menu->addMenu(i18n("Presets"));
    Q_ASSERT(m_preset_menu);
    if (!m_preset_menu) return;
    loadPresetList();
    connect(m_preset_menu, SIGNAL(triggered(QAction*)),
            this, SLOT(loadPreset(QAction*)));

    m_menu->addAction(
	icon_loader.loadIcon(_("document-export"), KIconLoader::Small),
	i18n("Save Preset"),
	this, SLOT(savePreset()));

    del->addAction(
	icon_loader.loadIcon(_("edit-delete"), KIconLoader::Small),
	i18n("Currently Selected Point"),
	this, SLOT(deleteLast()),
	QKeySequence::Delete);
    del->addAction(i18n("Every Second Point"),
	           this, SLOT(deleteSecond()));

    QStringList types = Kwave::Interpolation::descriptions(true);
    int id = 0;
    foreach (const QString &text, types) {
	QAction *action = new QAction(interpolation);
	action->setText(text);
	action->setData(id++);
	interpolation->addAction(action);
    }