teichmann@4800: package de.intevation.flys.artifacts.model;
teichmann@4800: 
teichmann@4800: /** A pretty naive pointwise algorithm to find out the columns
teichmann@4800:  *  of a WSTValueTable which imfold ("umhuellen") a set of WQKMs
teichmann@4800:  *  in terms of Q.
teichmann@4800:  *  A better implemention would exploit the fact that the
teichmann@4800:  *  Qs normally are constant for a while along km. This would
teichmann@4800:  *  reduce the runtime complexity to only a few Q spans instead
teichmann@4800:  *  of the pointwise evaluation.
teichmann@4800:  */
teichmann@4800: public class InfoldingColumns
teichmann@4800: {
teichmann@4800:     private QRangeTree.QuickQFinder [] qFinders;
teichmann@4800: 
teichmann@4800:     private boolean [] infoldingColumns;
teichmann@4800: 
teichmann@4800:     public InfoldingColumns() {
teichmann@4800:     }
teichmann@4800: 
teichmann@4800:     public InfoldingColumns(WstValueTable.Column [] columns) {
teichmann@4800: 
teichmann@4800:         qFinders = new QRangeTree.QuickQFinder[columns.length];
teichmann@4800:         for (int i = 0; i < qFinders.length; ++i) {
teichmann@4800:             qFinders[i] = columns[i].getQRangeTree().new QuickQFinder();
teichmann@4800:         }
teichmann@4800: 
teichmann@4800:         infoldingColumns = new boolean[columns.length];
teichmann@4800:     }
teichmann@4800: 
teichmann@4800:     public boolean [] getInfoldingColumns() {
teichmann@4800:         return infoldingColumns;
teichmann@4800:     }
teichmann@4800: 
teichmann@4819:     public void markInfoldingColumns(QKms [] qkms) {
teichmann@4819:         for (QKms qk: qkms) {
teichmann@4819:             markInfoldingColumns(qk);
teichmann@4800:         }
teichmann@4800:     }
teichmann@4800: 
teichmann@4819:     public void markInfoldingColumns(QKms qkms) {
teichmann@4819:         int N = qkms.size();
teichmann@4800:         int C = qFinders.length-1;
teichmann@4800:         for (int i = 0; i < N; ++i) {
teichmann@4819:             double km       = qkms.getKm(i);
teichmann@4819:             double q        = qkms.getQ(i);
teichmann@4800:             double above    =  Double.MAX_VALUE;
teichmann@4800:             double below    = -Double.MAX_VALUE;
teichmann@4800:             int    aboveIdx = -1;
teichmann@4800:             int    belowIdx = -1;
teichmann@4800: 
teichmann@4800:             for (int j = C; j >= 0; --j) {
teichmann@4800:                 double qc = qFinders[j].findQ(km);
teichmann@4800:                 if (Double.isNaN(qc)) {
teichmann@4800:                     continue;
teichmann@4800:                 }
teichmann@4800:                 if (qc <= q) {
teichmann@4800:                     if (qc > below) {
teichmann@4800:                         below    = qc;
teichmann@4800:                         belowIdx = j;
teichmann@4800:                     }
teichmann@4800:                 }
teichmann@4800:                 else if (qc < above) { // qc > q
teichmann@4800:                     above    = qc;
teichmann@4800:                     aboveIdx = j;
teichmann@4800:                 }
teichmann@4800:             }
teichmann@4800: 
teichmann@4800:             if (aboveIdx != -1) {
teichmann@4800:                 infoldingColumns[aboveIdx] = true;
teichmann@4800:             }
teichmann@4800: 
teichmann@4800:             if (belowIdx != -1) {
teichmann@4800:                 infoldingColumns[belowIdx] = true;
teichmann@4800:             }
teichmann@4800:         }
teichmann@4800:     }
teichmann@4800: }
teichmann@4800: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :