Changeset 4239


Ignore:
Timestamp:
07/23/08 13:44:16 (12 years ago)
Author:
nor
Message:

Made changes to CurveFitter: it is now an abstract superclass, so children can call the ChiSquaredError methods.

Location:
trunk/loci/slim
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/loci/slim/CurveFitter.java

    r4235 r4239  
    3434 * @author Eric Kjellman egkjellman at wisc.edu 
    3535 */ 
    36 public interface CurveFitter { 
     36public abstract class CurveFitter { 
     37 
     38  protected int[] curveData; 
     39  protected double[][] curveEstimate; 
     40  protected int firstindex; 
     41  protected int lastindex; 
    3742 
    3843  /** 
     
    4146   * information returned by getCurve and getChiSquaredError. 
    4247   */ 
    43   void iterate(); 
     48  public abstract void iterate(); 
    4449 
    4550  /** Returns the Chi Squared Error of the current curve estimate. */ 
    46   double getChiSquaredError(); 
     51  public double getChiSquaredError() { 
     52    double total = 0.0d; 
     53    double[] expected = getEstimates(curveData, curveEstimate); 
     54    for (int i = firstindex; i < curveData.length && i <= lastindex; i++) { 
     55      if (expected[i] > 0) {  
     56        double observed = (double) curveData[i]; 
     57        double term = (observed - expected[i]); 
     58        // (o-e)^2 
     59        term *= term; 
     60        // (o-e)^2 / e 
     61        term /= expected[i]; 
     62        total += term; 
     63      }  
     64    }  
     65    return total; 
     66  }  
     67 
     68  public double getChiSquaredError(double[][] estCurve) { 
     69    double total = 0.0d; 
     70    double[] expected = getEstimates(curveData, estCurve); 
     71    for (int i = firstindex; i < curveData.length && i <= lastindex; i++) { 
     72      if (expected[i] > 0) { 
     73        double observed = curveData[i]; 
     74        double term = (observed - expected[i]); 
     75        // (o-e)^2 
     76        term *= term; 
     77        // (o-e)^2 / e 
     78        term /= expected[i]; 
     79        //System.out.println("Obs: " + observed + 
     80        //  " Expect: " + expected[i] + " Term: " + term); 
     81        total += term; 
     82      } 
     83    } 
     84    return total; 
     85  } 
    4786 
    4887  /** 
     
    5190   * of exponentials in setComponentCount. 
    5291   */ 
    53   double getReducedChiSquaredError(); 
     92  public double getReducedChiSquaredError() { 
     93    int df = 1 + (curveEstimate.length * 2); 
     94    int datapoints = curveData.length; 
     95    if (datapoints - df > 0) { 
     96      return getChiSquaredError() / (datapoints - df); 
     97    }  
     98    return Double.MAX_VALUE; 
     99  }  
     100   
     101  public double getReducedChiSquaredError(double[][] estCurve) { 
     102    int df = 1 + (estCurve.length * 2); 
     103    int datapoints = curveData.length; 
     104    if (datapoints - df > 0) { 
     105      return getChiSquaredError(estCurve) / (datapoints - df); 
     106    } 
     107    return Double.MAX_VALUE; 
     108  } 
     109 
     110  public double[] getEstimates(int[] data, double[][] estimate) { 
     111    double[] toreturn = new double[data.length]; 
     112    for (int i = 0; i < toreturn.length; i++) { 
     113      double value = 0; 
     114      for (int j = 0; j < estimate.length; j++) { 
     115        // e^-bt 
     116        double term = Math.pow(Math.E, -estimate[j][1] * i); 
     117        // ae^-bt 
     118        term *= estimate[j][0]; 
     119        // ae^-bt + c 
     120        term += estimate[j][2]; 
     121        value += term; 
     122      } 
     123      toreturn[i] = value; 
     124    } 
     125    return toreturn; 
     126  } 
     127 
    54128 
    55129  /** 
     
    58132   * we can assume that the datapoints are evenly spaced. 
    59133   */ 
    60   void setData(int[] data); 
     134  public abstract void setData(int[] data); 
    61135 
    62136  /** 
     
    65139   * we can assume that the datapoints are evenly spaced. 
    66140   */ 
    67   int[] getData(); 
     141  public abstract int[] getData(); 
    68142 
    69143  /** Sets how many exponentials are expected to be fitted. */ 
    70   void setComponentCount(int numExp); 
     144  public abstract void setComponentCount(int numExp); 
    71145 
    72146  /** Returns the number of exponentials to be fitted. */ 
    73   int getComponentCount(); 
     147  public abstract int getComponentCount(); 
    74148 
    75149  /** Initializes the curve fitter with a starting curve estimate. */ 
    76   void estimate(); 
     150  public abstract void estimate(); 
    77151 
    78152  /** 
     
    83157   * TODO: Make multiple exponentials a class, to remove multi-c stupidity 
    84158   */ 
    85   double[][] getCurve(); 
     159  public abstract double[][] getCurve(); 
    86160 
    87161  /** 
     
    90164   * See getCurve for information about the array to pass. 
    91165   */ 
    92   void setCurve(double[][] curve); 
     166  public abstract void setCurve(double[][] curve); 
    93167 
    94   void setFirst(int firstindex); 
     168  public abstract void setFirst(int firstindex); 
    95169 
    96   void setLast(int lastindex); 
     170  public abstract void setLast(int lastindex); 
    97171} 
  • trunk/loci/slim/GACurveFitter.java

    r4237 r4239  
    3636 * @author Eric Kjellman egkjellman at wisc.edu 
    3737 */ 
    38 public class GACurveFitter implements CurveFitter { 
     38public class GACurveFitter extends CurveFitter { 
    3939 
    4040  // -- Fields -- 
     
    4242  protected int[] curveData; 
    4343  protected double[][] curveEstimate; 
    44   protected int numExponentials; 
     44  protected int components; 
    4545  protected double[][][] geneticData; 
    4646  protected double[] fitness; 
     
    7070  public void initialize() { 
    7171    curveData = null; 
    72     numExponentials = 1; 
    73     curveEstimate = new double[numExponentials][3]; 
     72    components = 1; 
     73    curveEstimate = new double[components][3]; 
    7474    geneticData = null; 
    7575    fitness = null; 
     
    9696 
    9797    // TODO: Move these out, reuse them. Synchronized? 
    98     double[][][] newGeneration = new double[SPECIMENS][numExponentials][3]; 
     98    double[][][] newGeneration = new double[SPECIMENS][components][3]; 
    9999    Random r = new Random(); 
    100100 
     
    108108      mutationFactor *= MUTATION_FACTOR_REDUCTION; 
    109109      for (int i = 1; i < newGeneration.length; i++) { 
    110         for (int j = 0; j < numExponentials; j++) { 
     110        for (int j = 0; j < components; j++) { 
    111111          for (int k = 0; k < 3; k++) { 
    112112            double factor = r.nextDouble() * STALLED_FACTOR; 
     
    115115        } 
    116116      } 
    117       for (int j = 0; j < numExponentials; j++) { 
     117      for (int j = 0; j < components; j++) { 
    118118        for (int k = 0; k < 3; k++) { 
    119119          newGeneration[0][j][k] = curveEstimate[j][k]; 
     
    144144        } 
    145145        double minfluence = r.nextDouble(); 
    146         for (int j = 0; j < numExponentials; j++) { 
     146        for (int j = 0; j < components; j++) { 
    147147          for (int k = 0; k < 3; k++) { 
    148148            newGeneration[q][j][k] = 
     
    153153      } 
    154154      for (int i = 0; i < newGeneration.length; i++) { 
    155         for (int j = 0; j < numExponentials; j++) { 
     155        for (int j = 0; j < components; j++) { 
    156156          for (int k = 0; k < 3; k++) { 
    157157            // mutate, if necessary 
     
    185185      stallGenerations = 0; 
    186186      currentRCSE = best; 
    187       for (int j = 0; j < numExponentials; j++) { 
     187      for (int j = 0; j < components; j++) { 
    188188        for (int k = 0; k < 3; k++) { 
    189189          curveEstimate[j][k] = geneticData[bestindex][j][k]; 
     
    194194      if(DEBUG) System.out.println("c" + q + ": " + curveEstimate[q][2]); 
    195195    } 
    196   } 
    197  
    198   // Returns the Chi Squared Error of the current curve estimate 
    199   public double getChiSquaredError() { 
    200     if(DEBUG) System.out.println("**********"); 
    201     double total = 0.0d; 
    202     double[] expected = getEstimates(curveData, curveEstimate); 
    203     for (int i = firstindex; i < curveData.length && i <= lastindex; i++) { 
    204       if (expected[i] > 0) { 
    205         int observed = curveData[i]; 
    206         double term = (observed - expected[i]); 
    207         // (o-e)^2 
    208         term *= term; 
    209         // (o-e)^2 / e 
    210         term /= expected[i]; 
    211         if(DEBUG) System.out.println("Obs: " + observed + 
    212           " Expect: " + expected[i] + " Term: " + term); 
    213         total += term; 
    214       } 
    215     } 
    216     return total; 
    217   } 
    218  
    219   public double getReducedChiSquaredError() { 
    220     int df = 1 + (numExponentials * 2); 
    221     int datapoints = curveData.length; 
    222     if (datapoints - df > 0) { 
    223       return getChiSquaredError() / (datapoints - df); 
    224     } 
    225     return Double.MAX_VALUE; 
    226196  } 
    227197 
     
    249219   **/ 
    250220  public void setComponentCount(int numExp) { 
    251     numExponentials = numExp; 
    252     curveEstimate = new double[numExponentials][3]; 
    253   } 
    254  
     221    components = numExp; 
     222    curveEstimate = new double[numExp][3]; 
     223  } 
     224 
     225  // Returns the number of exponentials to be fitted. 
    255226  public int getComponentCount() { 
    256     return numExponentials; 
     227    return components; 
    257228  } 
    258229 
    259230  // Initializes the curve fitter with a starting curve estimate. 
    260231  public void estimate() { 
    261     if (numExponentials >= 1) { 
     232    if (components >= 1) { 
    262233      // TODO: Estimate c, factor it in below. 
    263234 
     
    315286      if (curveEstimate[0][1] <= 0) curveEstimate[0][1] = 1000; 
    316287    } 
    317     if (numExponentials == 2) { 
     288    if (components == 2) { 
    318289      double guessC = Double.MAX_VALUE; 
    319290      //for(int i = 0; i < curveData.length; i++) { 
     
    446417   **/ 
    447418  public void setCurve(double[][] curve) { 
    448     if (curve.length != numExponentials) { 
    449       throw new IllegalArgumentException("Incorrect number of exponentials."); 
     419    if (curve.length != components) { 
     420      throw new IllegalArgumentException("Incorrect number of components."); 
    450421    } 
    451422    if (curve[0].length != 3) { 
     
    457428  } 
    458429 
    459   // -- Helper methods -- 
    460  
    461   // TODO: Do I actually need the data anymore? 
    462   private double[] getEstimates(int[] data, double[][] estimate) { 
    463     double[] toreturn = new double[data.length]; 
    464     for (int i = 0; i < toreturn.length; i++) { 
    465       double value = 0; 
    466       for (int j = 0; j < estimate.length; j++) { 
    467         // e^-bt 
    468         double term = Math.pow(Math.E, -estimate[j][1] * i); 
    469         // ae^-bt 
    470         term *= estimate[j][0]; 
    471         // ae^-bt + c 
    472         term += estimate[j][2]; 
    473         value += term; 
    474       } 
    475       // TODO: Ask Curtis if this is correct. 
    476       // TODO: Answer: Make a boolean flag in the API for it. 
    477       // The idea is that, since we can't actually get double values, we can 
    478       // not expect double precision from our answers? 
    479       // If we don't do this, we often get very strange chi square error numbers 
    480       // toreturn[i] = (int) (value + 0.5); 
    481       toreturn[i] = value; 
    482     } 
    483     return toreturn; 
    484   } 
    485  
    486   // Split this stuff out into a CurveUtils class 
    487   private double getChiSquaredError(double[][] estCurve) { 
    488     double total = 0.0d; 
    489     double[] expected = getEstimates(curveData, estCurve); 
    490     for (int i = firstindex; i < curveData.length && i <= lastindex; i++) { 
    491       if (expected[i] > 0) { 
    492         double observed = curveData[i]; 
    493         double term = (observed - expected[i]); 
    494         // (o-e)^2 
    495         term *= term; 
    496         // (o-e)^2 / e 
    497         term /= expected[i]; 
    498         //System.out.println("Obs: " + observed + 
    499         //  " Expect: " + expected[i] + " Term: " + term); 
    500         total += term; 
    501       } 
    502     } 
    503     return total; 
    504   } 
    505  
    506   private double getReducedChiSquaredError(double[][] estCurve) { 
    507     int df = 1 + (numExponentials * 2); 
    508     int datapoints = curveData.length; 
    509     if (datapoints - df > 0) { 
    510       return getChiSquaredError(estCurve) / (datapoints - df); 
    511     } 
    512     return Double.MAX_VALUE; 
    513   } 
    514  
    515430  public void setFirst(int index) { 
    516431    firstindex = index; 
  • trunk/loci/slim/LMCurveFitter.java

    r4235 r4239  
    4040 * @author Curtis Rueden ctrueden at wisc.edu 
    4141 */ 
    42 public class LMCurveFitter implements CurveFitter { 
     42public class LMCurveFitter extends CurveFitter { 
    4343 
    4444  // -- Fields -- 
Note: See TracChangeset for help on using the changeset viewer.