Bug 137957 - Add -MinIndex and -MaxIndex automatic scalars
Summary: Add -MinIndex and -MaxIndex automatic scalars
Status: RESOLVED FIXED
Alias: None
Product: kst
Classification: Applications
Component: general (show other bugs)
Version: 1.3.1
Platform: unspecified Solaris
: NOR wishlist
Target Milestone: ---
Assignee: kst
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-11-27 10:46 UTC by Nicolas Brisset
Modified: 2007-07-05 17:34 UTC (History)
0 users

See Also:
Latest Commit:
Version Fixed In:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Nicolas Brisset 2006-11-27 10:46:02 UTC
Version:           1.3.1 (using KDE 3.4.0, compiled sources)
Compiler:          gcc version 3.4.3
OS:                SunOS (sun4u) release 5.8

As already discussed in bug #135090 (comment number 8 and others) it could be useful to generate -MinIndex and -MaxIndex scalars. It would not be very expensive either, and might even be used to speed up range computations when zooming for instance (though I'm not sure about the latter).
I can add the scalars if you agree, but I don't know where in the code they might be used. And without indexed access into vectors for labels like "Min value: [Vec-Min] obtained at [Time[Vec-MinIndex]]"it might not be very useful from userland...
Comment 1 Andrew Walker 2007-07-04 20:50:07 UTC
SVN commit 683457 by arwalker:

BUG:137957 Add minIndex and maxIndex. In the case where the min or max value is not unique the lowest index value will be given. Also modify vector view dialog so indices start at 0 rather than 1.

 M  +1 -1      libkst/kstrvector.cpp  
 M  +32 -10    libkst/kstvector.cpp  
 M  +11 -4     libkst/kstvector.h  
 M  +0 -1      libkstapp/ksthsdialog_i.cpp  
 M  +10 -6     libkstapp/kstvectortable.cpp  
 M  +1 -1      libkstapp/kstviewscalarsdialog_i.cpp  
 M  +12 -6     libkstapp/kstviewvectorsdialog_i.cpp  


--- branches/work/kst/1.5/kst/src/libkst/kstrvector.cpp #683456:683457
@@ -464,7 +464,7 @@
 
 // Some things to consider about the following routine...
 // Frames:
-//    Some data sources have data devided into frames.  Each field
+//    Some data sources have data divided into frames.  Each field
 //    has a fixed number of samples per frame.  For some (eg, ascii files)
 //    each frame has 1 sample.  For others (eg, dirfiles) you may have more.
 //    Different fields in the same data source may have different samples per frame.
--- branches/work/kst/1.5/kst/src/libkst/kstvector.cpp #683456:683457
@@ -78,7 +78,7 @@
   }
   _is_rising = false;
 
-  CreateScalars();
+  createScalars();
   blank();
 
   KST::vectorList.lock().writeLock();
@@ -129,7 +129,7 @@
     KstObject::setTagName(KST::suggestUniqueVectorTag(in_tag));
   }
 
-  CreateScalars();
+  createScalars();
   resize(sz, true);
 
   if (!qba.isEmpty()) {
@@ -309,9 +309,11 @@
   return _v[i];
 }
 
-void KstVector::CreateScalars() {
+void KstVector::createScalars() {
   if (!_isScalarList) {
     _min = _max = _mean = _minPos = 0.0;
+    _minIndex = -1;
+    _maxIndex = -1;
 
     KstWriteLocker sl(&KST::scalarList.lock());
     KST::scalarList.setUpdateDisplayTags(false);
@@ -321,6 +323,10 @@
     sp->_KShared_ref();
     _scalars.insert("min", sp = new KstScalar(KstObjectTag("Min", tag()), this));
     sp->_KShared_ref();
+    _scalars.insert("maxindex", sp = new KstScalar(KstObjectTag("MaxIndex", tag()), this));
+    sp->_KShared_ref();
+    _scalars.insert("minindex", sp = new KstScalar(KstObjectTag("MinIndex", tag()), this));
+    sp->_KShared_ref();
     _scalars.insert("last", sp = new KstScalar(KstObjectTag("Last", tag()), this));
     sp->_KShared_ref();
     _scalars.insert("first", sp = new KstScalar(KstObjectTag("First", tag()), this));
@@ -344,13 +350,15 @@
   }
 }
 
-void KstVector::RenameScalars() {
+void KstVector::renameScalars() {
   if (!_isScalarList) {
     KstWriteLocker sl(&KST::scalarList.lock());
     KST::scalarList.setUpdateDisplayTags(false);
 
     _scalars["max"]->setTagName(KstObjectTag("Max", tag()));
     _scalars["min"]->setTagName(KstObjectTag("Min", tag()));
+    _scalars["maxindex"]->setTagName(KstObjectTag("MaxIndex", tag()));
+    _scalars["minindex"]->setTagName(KstObjectTag("MinIndex", tag()));
     _scalars["last"]->setTagName(KstObjectTag("Last", tag()));
     _scalars["first"]->setTagName(KstObjectTag("First", tag()));
     _scalars["mean"]->setTagName(KstObjectTag("Mean", tag()));
@@ -461,10 +469,12 @@
   double sum, sum2, last, first, v;
   double last_v;
   double dv2 = 0.0, dv, no_spike_max_dv;
-  
+
   _max = _min = sum = sum2 = _minPos = last = first = KST::NOPOINT;
+  _maxIndex = -1;
+  _minIndex = -1;
   _nsum = 0;
-  
+
   if (_size > 0) {
     _is_rising = true;
 
@@ -479,6 +489,8 @@
         _scalars["sumsquared"]->setValue(sum2);
         _scalars["max"]->setValue(_max);
         _scalars["min"]->setValue(_min);
+        _scalars["maxindex"]->setValue(_maxIndex);
+        _scalars["minindex"]->setValue(_minIndex);
         _scalars["minpos"]->setValue(_minPos);
         _scalars["last"]->setValue(last);
         _scalars["first"]->setValue(first);
@@ -486,7 +498,7 @@
       _ns_max = _ns_min = 0;
 
       updateScalars();
-      
+
       return setLastUpdateResult(providerRC);
     }
 
@@ -497,6 +509,8 @@
     }
 
     _max = _min = _v[i0];
+    _maxIndex = i0;
+    _minIndex = i0;
     sum = sum2 = 0.0;
 
     if (_v[i0] > 0.0) {
@@ -506,7 +520,7 @@
     }
 
     last_v = _v[i0];
-    
+
     for (i = i0; i < _size; i++) {
       v = _v[i]; // get rid of redirections
 
@@ -528,8 +542,10 @@
 
         if (v > _max) {
           _max = v;
+          _maxIndex = i;
         } else if (v < _min) {
           _min = v;
+          _minIndex = i;
         }
         if (v < _minPos && v > 0.0) {
           _minPos = v;
@@ -568,11 +584,15 @@
 
     if (_isScalarList) {
       _max = _min = _minPos = 0.0;
+      _maxIndex = 0;
+      _minIndex = 0;
     } else {
       _scalars["sum"]->setValue(sum);
       _scalars["sumsquared"]->setValue(sum2);
       _scalars["max"]->setValue(_max);
       _scalars["min"]->setValue(_min);
+      _scalars["maxindex"]->setValue(_maxIndex);
+      _scalars["minindex"]->setValue(_minIndex);
       _scalars["minpos"]->setValue(_minPos);
       _scalars["last"]->setValue(last);
       _scalars["first"]->setValue(first);
@@ -613,7 +633,7 @@
 
   KST::vectorList.doRename(this, newTag);
 
-  RenameScalars();
+  renameScalars();
 }
 
 
@@ -668,11 +688,13 @@
   xv->_saveable = false;
 
   for (int i = 0; i < n; i++) {
-    xv->value()[i] = x0 + double(i) * (x1 - x0) / (n - 1);
+    xv->value()[i] = x0 + double(i) * (x1 - x0) / double(n - 1);
   }
 
   xv->_scalars["min"]->setValue(x0);
   xv->_scalars["max"]->setValue(x1);
+  xv->_scalars["minindex"]->setValue(0);
+  xv->_scalars["maxindex"]->setValue(n-1);
   xv->updateScalars();
 
   return xv;
--- branches/work/kst/1.5/kst/src/libkst/kstvector.h #683456:683457
@@ -74,12 +74,18 @@
     /** Return V[i] uninterpolated */
     double value(int i);
 
-    /** Return Minimum value in Vector */
+    /** Return minimum value in Vector */
     inline double min() const { return _min; }
 
-    /** Return max value in Vector */
+    /** Return maximum value in Vector */
     inline double max() const { return _max; }
 
+    /** Return index of minimum value in Vector */
+    inline double minIndex() const { return _minIndex; }
+
+    /** Return index of maximum value in Vector */
+    inline double maxIndex() const { return _maxIndex; }
+
     /** Return SpikeInsensitive max value in vector **/
     inline double ns_max() const { return _ns_max; }
 
@@ -194,10 +200,11 @@
     bool _saveData : 1;
 
     double _min, _max, _mean, _minPos;
+    int _minIndex, _maxIndex;
 
     /** Scalar Maintenance methods */
-    void CreateScalars();
-    void RenameScalars();
+    void createScalars();
+    void renameScalars();
 
     QString _label;
 
--- branches/work/kst/1.5/kst/src/libkstapp/ksthsdialog_i.cpp #683456:683457
@@ -357,7 +357,6 @@
 
   hsPtr->setRecursed(false);
   if (hsPtr->recursion()) {
-    printf("5\n");
     hsPtr->setRecursed(true);
     hsPtr->unlock();
     KMessageBox::error(this, i18n("There is a recursion resulting from the histogram you entered."));
--- branches/work/kst/1.5/kst/src/libkstapp/kstvectortable.cpp #683456:683457
@@ -28,7 +28,6 @@
 }
 
 void KstVectorTable::paintCell( QPainter* painter, int row, int col, const QRect& cr, bool selected, const QColorGroup& cg ) {
-  KstVectorPtr vector = *KST::vectorList.findTag(_strVector);
   QString str;
 
   painter->eraseRect( 0, 0, cr.width(), cr.height() );
@@ -40,11 +39,16 @@
     painter->setPen(cg.text());
   }
 
-  if( col == 0 && vector) {
-    str.setNum(vector->value(row), 'g', 16);
+  if (col == 0) {
+    str.setNum(row);
+    painter->drawText(0, 0, cr.width(), cr.height(), AlignLeft, str);
+  } else if (col == 1) {
+    KstVectorPtr vector = *KST::vectorList.findTag(_strVector);
+
+    if (vector) {
+      str.setNum(vector->value(row), 'g', 16);
+      painter->drawText(0, 0, cr.width(), cr.height(), AlignLeft, str);
+    }
   }
-
-  painter->drawText(0, 0, cr.width(), cr.height(), AlignLeft, str);
 }
 
-// vim: ts=2 sw=2 et
--- branches/work/kst/1.5/kst/src/libkstapp/kstviewscalarsdialog_i.cpp #683456:683457
@@ -85,7 +85,7 @@
   setCaption(i18n("View Scalar Values"));
   listViewScalars->header()->setLabel(0, i18n("Scalar"));
   listViewScalars->header()->setLabel(1, i18n("Value"));
-  KstViewScalarsDialog::languageChange();      
+  KstViewScalarsDialog::languageChange();
 }
 
 
--- branches/work/kst/1.5/kst/src/libkstapp/kstviewvectorsdialog_i.cpp #683456:683457
@@ -31,21 +31,25 @@
 : KstViewVectorsDialog(parent, name, modal, fl) {
   tableVectors = new KstVectorTable(this, "tableVectors");
   tableVectors->setNumRows(0);
-  tableVectors->setNumCols(1);
+  tableVectors->setNumCols(2);
   tableVectors->setReadOnly(true);
   tableVectors->setSorting(false);
+  tableVectors->setLeftMargin(0);
   tableVectors->setSelectionMode(QTable::Single);
+  if (tableVectors->verticalHeader()) {
+    tableVectors->verticalHeader()->hide();
+  }
   layout2->insertWidget(1, tableVectors);
 
   connect(Cancel, SIGNAL(clicked()), this, SLOT(close()));
   connect(vectorSelector, SIGNAL(selectionChanged(const QString&)), this, SLOT( vectorChanged(const QString&)));
   connect(vectorSelector, SIGNAL(newVectorCreated(const QString&)), this, SLOT(vectorChanged(const QString&)));
 
-  if (tableVectors->numCols() != 1) {  
+  if (tableVectors->numCols() != 2) {
     for (; 0 < tableVectors->numCols(); ) {
       tableVectors->removeColumn(0);
     }
-    tableVectors->insertColumns(0, 1);
+    tableVectors->insertColumns(0, 2);
   }
 
   tableVectors->setReadOnly(true);
@@ -85,7 +89,8 @@
     tableVectors->setNumRows(needed);
   }
   QRect rect = tableVectors->horizontalHeader()->rect();
-  tableVectors->setColumnWidth(0, rect.width());
+  tableVectors->setColumnWidth(0, rect.width() / 5);
+  tableVectors->setColumnWidth(1, rect.width() - (rect.width() / 5));
 }
 
 
@@ -110,7 +115,8 @@
  */
 void KstViewVectorsDialogI::languageChange() {
   setCaption(i18n("View Vector Values"));
-  tableVectors->horizontalHeader()->setLabel(0, i18n("Values"));
+  tableVectors->horizontalHeader()->setLabel(0, i18n("Index"));
+  tableVectors->horizontalHeader()->setLabel(1, i18n("Value"));
   KstViewVectorsDialog::languageChange();
 }
 
@@ -120,4 +126,4 @@
 }
 
 #include "kstviewvectorsdialog_i.moc"
-// vim: ts=2 sw=2 et
+
Comment 2 Nicolas Brisset 2007-07-05 08:53:22 UTC
I had almost forgotten about that one... Thanks :-)
It also reminds me of the question of indexed access into vectors: is it possible now to do e.g. [VEC1[VEC1-MaxIndex]] (possibly with a different syntax) ? I keep wondering about that, sorry if the question has been answered before but we discussed this quite a few times and somehow I can't remember whether it has been implemented.
Comment 3 Andrew Walker 2007-07-05 17:34:46 UTC
It is possible. The syntax is as you indicated.