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]; } } }
//*************************************************************************** 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); }