Some extensions to the ExternalRuntimeProblem. Changed PropertyDoubleArray and its generic editor to work with multi-dim. arrays (type double[][]).

This commit is contained in:
Marcel Kronfeld 2010-09-28 12:57:38 +00:00
parent 915fba3645
commit e57a2eaea2
25 changed files with 615 additions and 211 deletions

View File

@ -1,26 +1,58 @@
package eva2.gui;
import javax.swing.*;
import java.beans.PropertyEditor;
import java.beans.PropertyChangeSupport;
import java.beans.PropertyChangeListener;
import java.awt.*;
import java.awt.event.ActionListener;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Rectangle;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.KeyListener;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.io.File;
import java.awt.event.KeyListener;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.beans.PropertyEditor;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
/**
* Created by IntelliJ IDEA.
* User: streiche
* Date: 05.03.2004
* Time: 13:51:14
* To change this template use File | Settings | File Templates.
* A simple focus listener with an object ID and callback.
*
* @author mkron
*
*/
class MyFocusListener implements FocusListener {
private int myID = -1;
private GenericDoubleArrayEditor arrEditor = null;
public MyFocusListener(int id, GenericDoubleArrayEditor gdae) {
myID = id;
this.arrEditor = gdae;
}
@Override
public void focusLost(FocusEvent e) { }
@Override
public void focusGained(FocusEvent e) { arrEditor.notifyFocusID(myID);};
};
/**
* A generic editor for PropertyDoubleArray.
*/
public class GenericDoubleArrayEditor extends JPanel implements PropertyEditor {
/** Handles property change notification */
private static final long serialVersionUID = 7749892624600018812L;
/** Handles property change notification */
private PropertyChangeSupport m_Support = new PropertyChangeSupport(this);
/** The label for when we can't edit that type */
private JLabel m_Label = new JLabel("Can't edit", SwingConstants.CENTER);
@ -29,9 +61,11 @@ public class GenericDoubleArrayEditor extends JPanel implements PropertyEditor {
/** The gaphix stuff */
private JPanel m_CustomEditor, m_DataPanel, m_ButtonPanel;
private JTextField[] m_InputTextField;
private JTextField[][] m_InputTextFields;
private JButton m_OKButton, m_AddButton, m_DeleteButton, m_NormalizeButton;
/** Which columns has the focus? **/
private int lastFocussedRow = -1;
public GenericDoubleArrayEditor() {
// compiled code
}
@ -56,7 +90,7 @@ public class GenericDoubleArrayEditor extends JPanel implements PropertyEditor {
this.m_DeleteButton = new JButton("Delete");
this.m_DeleteButton.addActionListener(this.deleteAction);
this.m_NormalizeButton = new JButton("Normalize");
this.m_NormalizeButton.addActionListener(this.mormalizeAction);
this.m_NormalizeButton.addActionListener(this.normalizeAction);
this.m_OKButton = new JButton("OK");
this.m_OKButton.setEnabled(true);
this.m_OKButton.addActionListener(new ActionListener() {
@ -80,71 +114,64 @@ public class GenericDoubleArrayEditor extends JPanel implements PropertyEditor {
*/
ActionListener addAction = new ActionListener() {
public void actionPerformed(ActionEvent event) {
double[] tmpD = m_DoubleArray.getDoubleArray();
double[] newD = new double[tmpD.length+1];
for (int i = 0; i < newD.length; i++) newD[i] = 1.0;
for (int i = 0; i < tmpD.length; i++) newD[i] = tmpD[i];
m_DoubleArray.setDoubleArray(newD);
m_DoubleArray.addRowCopy(lastFocussedRow); // copy the last focussed row
updateEditor();
}
};
/** This action listener removes an element to DoubleArray
/** This action listener removes an element from the DoubleArray.
*/
ActionListener deleteAction = new ActionListener() {
public void actionPerformed(ActionEvent event) {
double[] tmpD = m_DoubleArray.getDoubleArray();
double[] newD = new double[tmpD.length-1];
for (int i = 0; i < newD.length; i++) newD[i] = tmpD[i];
m_DoubleArray.setDoubleArray(newD);
if (!m_DoubleArray.isValidRow(lastFocussedRow)) {
m_DoubleArray.deleteRow(m_DoubleArray.getNumRows()-1);
} else {
m_DoubleArray.deleteRow(lastFocussedRow);
}
updateEditor();
}
};
/** This action listener nomalizes the values of the DoubleArray
/**
* This action listener nomalizes each columng of the values of the DoubleArray.
*/
ActionListener mormalizeAction = new ActionListener() {
ActionListener normalizeAction = new ActionListener() {
public void actionPerformed(ActionEvent event) {
double[] tmpD = m_DoubleArray.getDoubleArray();
double sum = 0;
for (int i = 0; i < tmpD.length; i++) sum += tmpD[i];
if (sum == 0) return;
for (int i = 0; i < tmpD.length; i++) tmpD[i] = tmpD[i]/sum;
m_DoubleArray.setDoubleArray(tmpD);
m_DoubleArray.normalizeColumns();
updateEditor();
}
};
/** This action listener reads all values
*/
KeyListener readDoubleArrayAction = new KeyListener() {
public void keyPressed(KeyEvent event) {
public void keyPressed(KeyEvent event) {
}
public void keyTyped(KeyEvent event) {
}
public void keyReleased(KeyEvent event) {
double[] tmpD = new double[m_InputTextField.length];
double[][] tmpDD = new double[m_InputTextFields.length][m_InputTextFields[0].length];
for (int i = 0; i < tmpD.length; i++) {
try {
double d = 0;
d = new Double(m_InputTextField[i].getText()).doubleValue();
tmpD[i] = d;
} catch (Exception e) {
}
for (int i = 0; i < tmpDD.length; i++) {
for (int j=0; j< tmpDD[0].length; j++) {
try {
double d = 0;
d = new Double(m_InputTextFields[i][j].getText()).doubleValue();
tmpDD[i][j] = d;
} catch (Exception e) {
}
}
//tmpD[i] = new Double(m_InputTextField[i].getText()).doubleValue();
}
m_DoubleArray.setDoubleArray(tmpD);
m_DoubleArray.setDoubleArray(tmpDD);
//updateEditor();
}
};
/** The object may have changed update the editor.
/** The object may have changed update the editor.
*/
private void updateEditor() {
if (this.m_CustomEditor != null) {
@ -154,24 +181,50 @@ public class GenericDoubleArrayEditor extends JPanel implements PropertyEditor {
}
}
// /** This method updates the data panel
// */
// private void updateDataPanelOrig() {
// double[] tmpD = this.m_DoubleArray.getDoubleArray();
//
// this.m_DataPanel.removeAll();
// this.m_DataPanel.setLayout(new GridLayout(tmpD.length, 2));
// this.m_InputTextField = new JTextField[tmpD.length];
// for (int i = 0; i < tmpD.length; i++) {
// JLabel label = new JLabel("Value X"+i+": ");
// this.m_DataPanel.add(label);
// this.m_InputTextField[i] = new JTextField();
// this.m_InputTextField[i].setText(""+tmpD[i]);
// this.m_InputTextField[i].addKeyListener(this.readDoubleArrayAction);
// this.m_DataPanel.add(this.m_InputTextField[i]);
// }
// }
/** This method updates the data panel
*/
private void updateDataPanel() {
double[] tmpD = this.m_DoubleArray.getDoubleArray();
int numRows = m_DoubleArray.getNumRows();
int numCols = m_DoubleArray.getNumCols();
this.m_DataPanel.removeAll();
this.m_DataPanel.setLayout(new GridLayout(tmpD.length, 2));
this.m_InputTextField = new JTextField[tmpD.length];
for (int i = 0; i < tmpD.length; i++) {
this.m_DataPanel.setLayout(new GridLayout(numRows, numCols+1));
this.m_InputTextFields = new JTextField[numRows][numCols];
for (int i = 0; i < numRows; i++) {
JLabel label = new JLabel("Value X"+i+": ");
this.m_DataPanel.add(label);
this.m_InputTextField[i] = new JTextField();
this.m_InputTextField[i].setText(""+tmpD[i]);
this.m_InputTextField[i].addKeyListener(this.readDoubleArrayAction);
this.m_DataPanel.add(this.m_InputTextField[i]);
for (int j=0; j<numCols; j++) {
this.m_InputTextFields[i][j] = new JTextField();
this.m_InputTextFields[i][j].setText(""+m_DoubleArray.getValue(i,j));
this.m_InputTextFields[i][j].addKeyListener(this.readDoubleArrayAction);
this.m_InputTextFields[i][j].addFocusListener(new MyFocusListener(i, this));
this.m_DataPanel.add(this.m_InputTextFields[i][j]);
}
}
}
public void notifyFocusID(int id) {
// notification of which column has the focus
lastFocussedRow =id;
// System.out.println("Focus now on " + id);
}
/** This method will set the value of object that is to be edited.
* @param o an object that must be an array.
@ -254,7 +307,7 @@ public class GenericDoubleArrayEditor extends JPanel implements PropertyEditor {
public void paintValue(Graphics gfx, Rectangle box) {
FontMetrics fm = gfx.getFontMetrics();
int vpad = (box.height - fm.getAscent()) / 2;
String rep = "Edit double[]";
String rep = "Edit double array...";
gfx.drawString(rep, 2, fm.getHeight() + vpad - 3 );
}

View File

@ -1,25 +1,48 @@
package eva2.gui;
/**
* Created by IntelliJ IDEA.
* User: streiche
* Date: 05.03.2004
* Time: 13:48:47
* To change this template use File | Settings | File Templates.
* A property for a double array. May be of dimensions m times n.
*/
public class PropertyDoubleArray implements java.io.Serializable {
public double[] m_DoubleArray;
private double[][] m_DoubleArray;
private int m_numCols = 1;
public PropertyDoubleArray(double[] d) {
this.m_DoubleArray = d;
setDoubleArray(d);
}
public PropertyDoubleArray(double[][] d) {
setDoubleArray(d);
}
public PropertyDoubleArray(PropertyDoubleArray d) {
this.m_DoubleArray = new double[d.m_DoubleArray.length];
System.arraycopy(d.m_DoubleArray, 0, this.m_DoubleArray, 0, this.m_DoubleArray.length);
this.m_DoubleArray = d.m_DoubleArray.clone();
this.m_numCols = d.m_numCols;
// System.arraycopy(d.m_DoubleArray, 0, this.m_DoubleArray, 0, this.m_DoubleArray.length);
}
public Object clone() {
/**
* Constructor that creates a double matrix with given dimensions and fills
* it cyclically with values given.
* @param rows
* @param cols
* @param d
*/
public PropertyDoubleArray(int rows, int cols, double ... d) {
if (rows>0 && cols>0) this.m_DoubleArray = new double[rows][cols];
else this.m_DoubleArray=null;
this.m_numCols=cols;
int index=0;
for (int i=0; i<rows; i++) {
for (int j=0; j<cols; j++) {
m_DoubleArray[i][j]=d[index];
index++;
if (index>=d.length) index=0;
}
}
}
public Object clone() {
return (Object) new PropertyDoubleArray(this);
}
@ -27,14 +50,138 @@ public class PropertyDoubleArray implements java.io.Serializable {
* @param d The double[]
*/
public void setDoubleArray(double[] d) {
this.m_DoubleArray = d;
this.m_DoubleArray = new double[d.length][1];
for (int i=0; i<d.length; i++) m_DoubleArray[i][0] = d[i];
m_numCols=1;
}
/** This method will allow you to set the value of the double array
* @param d The double[]
*/
public void setDoubleArray(double[][] d) {
this.m_DoubleArray = d;
if (d.length>0) m_numCols=d[0].length;
else m_numCols=1;
}
/**
* @return the double array itself (no clone)
*/
public double[][] getDoubleArrayShallow() {
return this.m_DoubleArray;
}
/**
* Return a column as a vector (in copy)
* @return a column as a vector (in copy)
*/
public double[] getDoubleColumnAsVector(int col) {
if (col>=m_numCols) {
throw new IllegalArgumentException("Error, invalid column selected, " + col + " of " + m_numCols);
}
double[] ret = new double[m_DoubleArray.length];
for (int i=0; i<ret.length; i++) ret[i]=m_DoubleArray[i][col];
return ret;
}
public int getNumCols() {
return m_numCols;
}
public int getNumRows() {
return m_DoubleArray.length;
}
public double getValue(int i, int j) {
if (i<0 || j<0 || (i>=getNumRows()) || (j>=getNumCols())) {
throw new IllegalArgumentException("Error, invalid access to double array: " + i + "," + j + " within " + getNumRows() + ","+getNumCols());
}
return m_DoubleArray[i][j];
}
/** This method will return the complete name of the file
* which filepath
* @return The complete filename with path.
*/
public double[] getDoubleArray() {
return this.m_DoubleArray;
}
public void adaptRowCount(int k) {
if (k!=m_DoubleArray.length) {
double[][] newDD = new double[k][m_numCols];
for (int i=0; i<k; i++) {
for (int j=0; j<m_numCols; j++) {
if (i<m_DoubleArray.length) newDD[i][j]=m_DoubleArray[i][j];
else newDD[i][j]=m_DoubleArray[m_DoubleArray.length-1][j];
}
}
setDoubleArray(newDD);
}
}
public void deleteRow(int k) {
if (k<0 || k>=getNumRows()) throw new IllegalArgumentException("Invalid index to deleteRow: " + k + " is not a valid row.");
double[][] newDD = new double[getNumRows()-1][getNumCols()];
int inc=0;
for (int i = 0; i < newDD.length; i++) {
if (i==k) inc=1;
for (int j=0; j<getNumCols(); j++) newDD[i][j] = m_DoubleArray[i+inc][j];
}
setDoubleArray(newDD);
}
/**
* Add a copy of an indexed row at the end. If the given index
* is invalid, the last row is copied.
*
* @param k
*/
public void addRowCopy(int k) {
if (k<0 || k>= getNumRows()) k=getNumRows()-1;
double[][] newDD = new double[getNumRows()+1][getNumCols()];
for (int i = 0; i < getNumRows(); i++)
for (int j=0; j<getNumCols(); j++) newDD[i][j] = m_DoubleArray[i][j];
if (k>=0) for (int j=0; j<getNumCols(); j++) newDD[newDD.length-1][j] = newDD[k][j];
else for (int j=0; j<getNumCols(); j++) newDD[newDD.length-1][j] = 1.; // if the array was empty
setDoubleArray(newDD);
}
/**
* Normalize all columns of the array by dividing through the sum.
*/
public void normalizeColumns() {
double colSum=0;
for (int j=0; j<getNumCols(); j++) {
colSum=0;
for (int i = 0; i < getNumRows(); i++) {
colSum += m_DoubleArray[i][j];
}
if (colSum!=0) for (int i = 0; i < getNumRows(); i++) {
m_DoubleArray[i][j]/=colSum;
}
}
}
/**
* Check if k is a valid row index (within 0 and numRows-1).
* @param k
* @return
*/
public boolean isValidRow(int k) {
return (k>=0) && (k<getNumRows());
}
public String toString() {
return BeanInspector.toString(m_DoubleArray);
}
// /** This method will allow you to set the value of the double array
// * @param d The double[]
// */
// public void setDoubleArray(double[] d) {
// this.m_DoubleArray = new double[d.length][1];
// for (int i=0; i<d.length; i++) m_DoubleArray[i][0] = d[i];
// }
//
// /** This method will return the complete name of the file
// * which filepath
// * @return The complete filename with path.
// */
// public double[] getDoubleArray() {
// return this.m_DoubleArray;
// }
}

View File

@ -274,7 +274,7 @@ public class PropertySheetPanel extends JPanel implements PropertyChangeListener
if (value == null) {
// If it's a user-defined property we give a warning.
String getterClass = m_Properties[i].getReadMethod().getDeclaringClass().getName();
if (getterClass.indexOf("java.") != 0) System.out.println("Warning: Property \"" + name+ "\" has null initial value. Skipping.");
if (getterClass.indexOf("java.") != 0) System.out.println("Warning: Property \"" + name+ "\" of class " + targ.getClass() + " has null initial value. Skipping.");
continue;
}
editor.setValue(value);

View File

@ -259,11 +259,10 @@ public class MOCCOStandalone implements InterfaceGOStandalone, InterfacePopulati
System.out.println(""+s);
if (moso instanceof MOSOWeightedFitness) {
PropertyDoubleArray prop = ((MOSOWeightedFitness)moso).getWeights();
double[] d = prop.getDoubleArray();
s = "Weights : {";
for (int i = 0; i < d.length; i++) {
s += d[i];
if (i < (d.length-1)) s += "; ";
for (int i = 0; i < prop.getNumRows(); i++) {
s += prop.getValue(i,0);
if (i < (prop.getNumRows()-1)) s += "; ";
}
s += "}";
System.out.println(""+s);

View File

@ -204,7 +204,11 @@ public class ESIndividualDoubleData extends AbstractEAIndividual implements Inte
public void init(InterfaceOptimizationProblem opt) {
super.init(opt);
// evil operators may not respect the range, so at least give some hint
if (!Mathematics.isInRange(m_Genotype, m_Range)) EVAERROR.errorMsgOnce("Warning: Individual out of range after initialization (and potential initial crossover/mutation)!");
if (!Mathematics.isInRange(m_Genotype, m_Range)) {
EVAERROR.errorMsgOnce("Warning: Individual out of range after initialization (and potential initial crossover/mutation)!");
// System.err.println("Indy was: " + BeanInspector.toString(m_Genotype));
// System.err.println("Range was " + BeanInspector.toString(m_Range));
}
}
/** This method will init the individual with a given value for the

View File

@ -215,7 +215,7 @@ public class MOCCOParameterizeGDF extends MOCCOPhase implements InterfaceProcess
((AbstractMultiObjectiveOptimizationProblem)m_Mocco.m_State.m_CurrentProblem).setMOSOConverter(wf);
w = mapObjectives2Fitness(w);
PropertyDoubleArray da = new PropertyDoubleArray(w);
wf.setOutputDimension(da.getDoubleArray().length);
wf.setOutputDimension(da.getNumRows());
wf.setWeights(da);
m_Opt.SetProblem(m_Mocco.m_State.m_CurrentProblem);
m_Mocco.m_State.m_Optimizer = m_Opt;

View File

@ -68,7 +68,7 @@ public class ArchivingNSGAII extends ArchivingNSGA implements java.io.Serializab
tmpPop.removeRedundantIndiesUsingFitness();
// Now fetch the n pareto-fronts
Population[] fronts = this.getNonDomiatedSortedFronts(tmpPop);
Population[] fronts = this.getNonDominatedSortedFronts(tmpPop);
tmpPop.clear();
tmpPop = null;
// this.calculateCrowdingDistance(fronts);
@ -100,12 +100,23 @@ public class ArchivingNSGAII extends ArchivingNSGA implements java.io.Serializab
fronts = null;
pop.SetArchive(archive);
}
/**
* Return the pareto front from a given population.
* @param pop
* @return
*/
public static Population getNonDominatedSortedFront(Population pop) {
ArchivingNSGAII arch = new ArchivingNSGAII();
Population[] fronts = arch.getNonDominatedSortedFronts(pop);
return fronts[0];
}
/** This method will dissect a given population into n pareto-fronts
* @param pop The population to analyse
* @return Population[] the n pareto-fronts
*/
public Population[] getNonDomiatedSortedFronts(Population pop) {
public Population[] getNonDominatedSortedFronts(Population pop) {
Population tmpPop, tmpDom, tmpNonDom;
Population[] result = null;
ArrayList tmpResult = new ArrayList();

View File

@ -125,7 +125,7 @@ public class MOClusteringSeparation implements InterfaceMigration, java.io.Seria
// }
// Now lets cluster this stuff
Population[] archives = this.m_NSGAII.getNonDomiatedSortedFronts(collector);
Population[] archives = this.m_NSGAII.getNonDominatedSortedFronts(collector);
Population toCluster = new Population();
int currentFront = 0;
toCluster.addPopulation(archives[currentFront]);

View File

@ -120,7 +120,7 @@ public class MOXMeansSeparation implements InterfaceMigration, java.io.Serializa
// }
// Now lets cluster this stuff
Population[] archives = this.m_NSGAII.getNonDomiatedSortedFronts(collector);
Population[] archives = this.m_NSGAII.getNonDominatedSortedFronts(collector);
Population toCluster = new Population();
int currentFront = 0;
toCluster.addPopulation(archives[currentFront]);

View File

@ -52,8 +52,8 @@ public class MOSOGoalProgramming implements InterfaceMOSOConverter, java.io.Seri
tmpFit = indy.getFitness();
indy.putData("MOFitness", tmpFit);
resultFit[0] = 0;
for (int i = 0; (i < this.m_Goals.m_DoubleArray.length) && (i < tmpFit.length) ; i++)
resultFit[0] += tmpFit[i]-this.m_Goals.m_DoubleArray[i];
for (int i = 0; (i < this.m_Goals.getNumRows()) && (i < tmpFit.length) ; i++)
resultFit[0] += tmpFit[i]-this.m_Goals.getValue(i, 0);
indy.SetFitness(resultFit);
}
@ -66,7 +66,7 @@ public class MOSOGoalProgramming implements InterfaceMOSOConverter, java.io.Seri
double[] newWeights = new double[dim];
for (int i = 0; i < newWeights.length; i++) newWeights[i] = 0.0;
for (int i = 0; (i < this.m_Goals.m_DoubleArray.length) && (i < newWeights.length); i++) newWeights[i] = this.m_Goals.m_DoubleArray[i];
for (int i = 0; (i < this.m_Goals.getNumRows()) && (i < newWeights.length); i++) newWeights[i] = this.m_Goals.getValue(i,0);
this.m_Goals.setDoubleArray(newWeights);
}

View File

@ -56,15 +56,15 @@ public class MOSOLpMetric implements InterfaceMOSOConverter, java.io.Serializabl
if (m_P >= 1) {
// standard Lp Metric
resultFit[0] = 0;
for (int i = 0; (i < this.m_Reference.m_DoubleArray.length) && (i < tmpFit.length); i++) {
resultFit[0] += Math.pow(Math.abs(tmpFit[i]-this.m_Reference.m_DoubleArray[i]), this.m_P);
for (int i = 0; (i < this.m_Reference.getNumRows()) && (i < tmpFit.length); i++) {
resultFit[0] += Math.pow(Math.abs(tmpFit[i]-this.m_Reference.getValue(i,0)), this.m_P);
}
resultFit[0] = Math.pow(resultFit[0], 1/((double)this.m_P));
} else {
// Tchebycheff metric
resultFit[0] = Double.NEGATIVE_INFINITY;
for (int i = 0; (i < this.m_Reference.m_DoubleArray.length) && (i < tmpFit.length); i++) {
resultFit[0] += Math.max(Math.abs(tmpFit[i]-this.m_Reference.m_DoubleArray[i]), resultFit[0]);
for (int i = 0; (i < this.m_Reference.getNumRows()) && (i < tmpFit.length); i++) {
resultFit[0] += Math.max(Math.abs(tmpFit[i]-this.m_Reference.getValue(i,0)), resultFit[0]);
}
}
@ -80,7 +80,7 @@ public class MOSOLpMetric implements InterfaceMOSOConverter, java.io.Serializabl
double[] newWeights = new double[dim];
for (int i = 0; i < newWeights.length; i++) newWeights[i] = 0.0;
for (int i = 0; (i < this.m_Reference.m_DoubleArray.length) && (i < newWeights.length); i++) newWeights[i] = this.m_Reference.m_DoubleArray[i];
for (int i = 0; (i < this.m_Reference.getNumRows()) && (i < newWeights.length); i++) newWeights[i] = this.m_Reference.getValue(i,0);
this.m_Reference.setDoubleArray(newWeights);
}
@ -92,10 +92,9 @@ public class MOSOLpMetric implements InterfaceMOSOConverter, java.io.Serializabl
String result = "Lp Metric\n";
result += " P = "+this.m_P+"\n";
result += " Ref.Fitness = (";
double[] p = this.m_Reference.m_DoubleArray;
for (int i = 0; i < p.length; i++) {
result += p[i];
if (i < (p.length-1)) result += "; ";
for (int i = 0; i < m_Reference.getNumRows(); i++) {
result += m_Reference.getValue(i,0);
if (i < (m_Reference.getNumRows()-1)) result += "; ";
}
result += ")\n";
return result;

View File

@ -31,7 +31,7 @@ public class MOSORankbased implements InterfaceMOSOConverter, java.io.Serializab
*/
public void convertMultiObjective2SingleObjective(Population pop) {
ArchivingNSGAII arch = new ArchivingNSGAII();
arch.getNonDomiatedSortedFronts(pop);
arch.getNonDominatedSortedFronts(pop);
for (int i = 0; i < pop.size(); i++) {
this.convertSingleIndividual((AbstractEAIndividual)pop.get(i));
}

View File

@ -16,16 +16,23 @@ public class MOSOWeightedFitness implements InterfaceMOSOConverter, java.io.Seri
private PropertyDoubleArray m_Weights = null;
public MOSOWeightedFitness() {
double[] tmpD = new double[2];
for (int i = 0; i < tmpD.length; i++) tmpD[i] = 1.0;
double[][] tmpD = new double[2][1];
for (int i = 0; i < tmpD.length; i++) tmpD[i][0] = 1.0;
this.m_Weights = new PropertyDoubleArray(tmpD);
for (int i = 0; i < this.m_Weights.m_DoubleArray.length; i++) this.m_Weights.m_DoubleArray[i] = 1/((double)this.m_Weights.m_DoubleArray.length);
for (int i = 0; i < this.m_Weights.getNumRows(); i++) this.m_Weights.normalizeColumns();
}
public MOSOWeightedFitness(double[][] weights) {
this();
setWeights(new PropertyDoubleArray(weights));
}
public MOSOWeightedFitness(MOSOWeightedFitness b) {
if (b.m_Weights != null) {
this.m_Weights = (PropertyDoubleArray)b.m_Weights;
}
}
public Object clone() {
return (Object) new MOSOWeightedFitness(this);
}
@ -52,16 +59,16 @@ public class MOSOWeightedFitness implements InterfaceMOSOConverter, java.io.Seri
tmpFit = indy.getFitness();
indy.putData("MOFitness", tmpFit);
for (int i = 0; (i < this.m_Weights.m_DoubleArray.length) && (i < tmpFit.length) ; i++)
resultFit[0] += tmpFit[i]*this.m_Weights.m_DoubleArray[i];
for (int i = 0; (i < this.m_Weights.getNumRows()) && (i < tmpFit.length) ; i++)
resultFit[0] += tmpFit[i]*this.m_Weights.getValue(i,0);
indy.SetFitness(resultFit);
}
private void checkingWeights() {
String s = "Using Weights: {";
for (int i = 0; i < this.m_Weights.m_DoubleArray.length; i++) {
s += this.m_Weights.m_DoubleArray[i];
if (i < this.m_Weights.m_DoubleArray.length-1) s+= "; ";
for (int i = 0; i < this.m_Weights.getNumRows(); i++) {
s += this.m_Weights.getValue(i,0);
if (i < this.m_Weights.getNumRows()-1) s+= "; ";
}
System.out.println(s+"}");
}
@ -75,7 +82,7 @@ public class MOSOWeightedFitness implements InterfaceMOSOConverter, java.io.Seri
double[] newWeights = new double[dim];
for (int i = 0; i < newWeights.length; i++) newWeights[i] = 1;
for (int i = 0; (i < this.m_Weights.m_DoubleArray.length) && (i < newWeights.length); i++) newWeights[i] = this.m_Weights.m_DoubleArray[i];
for (int i = 0; (i < this.m_Weights.getNumRows()) && (i < newWeights.length); i++) newWeights[i] = this.m_Weights.getValue(i,0);
this.m_Weights.setDoubleArray(newWeights);
}

View File

@ -41,7 +41,7 @@ public class SelectMONSGAIICrowedTournament implements InterfaceSelection, java.
* @param population The population that is to be processed.
*/
public void prepareSelection(Population population) {
this.m_Fronts = this.m_NSGAII.getNonDomiatedSortedFronts(population);
this.m_Fronts = this.m_NSGAII.getNonDominatedSortedFronts(population);
this.m_NSGAII.calculateCrowdingDistance(this.m_Fronts);
}

View File

@ -65,7 +65,7 @@ public class ReplacementNondominatedSortingDistanceCrowding implements Interface
pop.add(indy);
Population []store=dummyArchive.getNonDomiatedSortedFronts(pop);
Population []store=dummyArchive.getNonDominatedSortedFronts(pop);
dummyArchive.calculateCrowdingDistance(store);//TODO die f<EFBFBD>r das gesamte Archiv am St<EFBFBD>ck berechnen und nicht f<EFBFBD>r die Einzelfronten!
for(int i=0;i<store.length;i++){
synchronized (store[i]) {

View File

@ -430,7 +430,7 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
* This method will allow you to increment the current number of function calls by a number > 1.
* Notice that it might slightly disturb notification if a notifyEvalInterval is set.
*
* @param d The number of function calls to increment.
* @param d The number of function calls to increment by.
*/
public void incrFunctionCallsBy(int d) {
if (doEvalNotify()) {
@ -1063,7 +1063,7 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
* @param n number of individuals to look out for
* @param bBestOrWorst if true, the best n are returned, else the worst n individuals
* @param res sorted result population, will be cleared
* @param comparator the Comparator to use with individuals
* @param comp the Comparator to use with individuals
* @return The m sorted best or worst individuals, where m <= n
*
*/

View File

@ -317,6 +317,7 @@ public abstract class AbstractMultiObjectiveOptimizationProblem extends Abstract
for (int i = 0; i < archive.size(); i++) {
icon = new Chart2DDPointIconCircle();
tmpD = ((AbstractEAIndividual)archive.get(i)).getFitness();
if (tmpD.length<2) throw new RuntimeException("Error, problem seems not to be multi-objective, pareto front plot not possible!");
myPoint = new DPoint(tmpD[0], tmpD[1]);
if (((AbstractEAIndividual)archive.get(i)).getConstraintViolation() > 0) {
icon.setBorderColor(Color.RED);
@ -496,9 +497,13 @@ public abstract class AbstractMultiObjectiveOptimizationProblem extends Abstract
@Override
public Object[] getAdditionalFileStringValue(PopulationInterface pop) {
Object[] result = new Object[2];
result[0] = this.calculateMetric((Population)pop);
result[1] = this.calculateMetric(getLocalParetoFront());
Object[] result = new Object[2];
if (m_MOSOConverter!=null && !(m_MOSOConverter instanceof MOSONoConvert)) {
result[0]=Double.NaN; result[1]=Double.NaN;
} else {
result[0] = this.calculateMetric((Population)pop);
result[1] = this.calculateMetric(getLocalParetoFront());
}
return ToolBox.appendArrays(result, super.getAdditionalFileStringValue(pop));
}
@ -510,7 +515,7 @@ public abstract class AbstractMultiObjectiveOptimizationProblem extends Abstract
public String[] getAdditionalFileStringInfo() {
String[] superInfo = super.getAdditionalFileStringInfo();
return ToolBox.appendArrays(new String[]{"Pareto metric on the current population (per generation)",
"Pareto metric on the collected pareto front"}, superInfo);
"Pareto metric on the collected pareto front"}, superInfo);
}
/*

View File

@ -2,8 +2,8 @@ package eva2.server.go.problems;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
@ -13,27 +13,30 @@ import java.util.ArrayList;
import java.util.List;
import eva2.gui.BeanInspector;
import eva2.gui.PropertyDoubleArray;
import eva2.server.go.individuals.AbstractEAIndividual;
import eva2.server.go.individuals.ESIndividualDoubleData;
import eva2.server.go.individuals.InterfaceDataTypeDouble;
import eva2.server.go.operators.moso.InterfaceMOSOConverter;
import eva2.server.go.operators.moso.MOSONoConvert;
import eva2.server.go.populations.Population;
import eva2.server.go.strategies.InterfaceOptimizer;
import eva2.server.go.problems.Interface2DBorderProblem;
import eva2.tools.math.Mathematics;
public class ExternalRuntimeProblem extends AbstractOptimizationProblem implements Interface2DBorderProblem, InterfaceProblemDouble {
public class ExternalRuntimeProblem extends AbstractOptimizationProblem
implements Interface2DBorderProblem, InterfaceProblemDouble, InterfaceHasInitRange {
protected AbstractEAIndividual m_OverallBest = null;
protected int m_ProblemDimension = 10;
// protected boolean m_UseTestConstraint = false;
protected String m_Command = "";
protected String m_WorkingDir = "";
protected double m_upperBound = 10;
protected double m_lowerBound = 0;
// protected double m_upperBound = 10;
// protected double m_lowerBound = 0;
PropertyDoubleArray m_Range = new PropertyDoubleArray(m_ProblemDimension, 2, -10,10);
PropertyDoubleArray m_initRange = new PropertyDoubleArray(m_ProblemDimension, 2, -10,10);
private String additionalArg="";
protected InterfaceMOSOConverter m_MosoConverter = new MOSONoConvert();
// Private Subclass to redirect Streams within an extra Thread to avoid dead
// locks
@ -56,24 +59,26 @@ public class ExternalRuntimeProblem extends AbstractOptimizationProblem implemen
}
// System.out.println("monitor-thread finished!");
} catch (IOException ioe) {
System.err.println("IOException in MonitorInputStreamThread/ExternalRuntimeProblem: " + ioe.getMessage());
ioe.printStackTrace(System.err);
} finally {
try {
reader.close();
writer.close();
} catch (IOException e) {
// TODO Auto-generated catch block
System.err.println("IOException in MonitorInputStreamThread/ExternalRuntimeProblem: " + e.getMessage());
e.printStackTrace();
}
}
}
}
public ExternalRuntimeProblem() {
this.m_Template = new ESIndividualDoubleData();
((ESIndividualDoubleData)this.m_Template).setDoubleDataLength(m_ProblemDimension);
((ESIndividualDoubleData)this.m_Template).SetDoubleRange(makeRange());
}
public ExternalRuntimeProblem(ExternalRuntimeProblem b) {
//AbstractOptimizationProblem
if (b.m_Template != null)
@ -82,10 +87,15 @@ public class ExternalRuntimeProblem extends AbstractOptimizationProblem implemen
if (b.m_OverallBest != null)
this.m_OverallBest = (AbstractEAIndividual)((AbstractEAIndividual)b.m_OverallBest).clone();
this.m_ProblemDimension = b.m_ProblemDimension;
// this.m_UseTestConstraint = b.m_UseTestConstraint;
m_Command = b.m_Command;
m_lowerBound = b.m_lowerBound;
m_upperBound = b.m_upperBound;
if (b.m_Range!=null) this.m_Range = (PropertyDoubleArray)b.m_Range.clone();
else this.m_Range=null;
if (b.m_initRange!=null) this.m_initRange = (PropertyDoubleArray)b.m_initRange.clone();
else this.m_initRange=null;
if (b.m_MosoConverter!=null) this.m_MosoConverter=(InterfaceMOSOConverter)b.m_MosoConverter.clone();
else this.m_MosoConverter=null;
}
@ -115,26 +125,42 @@ public class ExternalRuntimeProblem extends AbstractOptimizationProblem implemen
}
public double[][] makeRange() {
double[][] range = new double[this.m_ProblemDimension][2];
for (int i = 0; i < range.length; i++) {
range[i][0] = getRangeLowerBound(i);
range[i][1] = getRangeUpperBound(i);
}
return range;
if (m_Range==null) {
System.err.println("Warning, range not set ExternalRuntimeProblem.makeRange!");
}
if (m_Range.getNumRows()!=getProblemDimension()) System.err.println("Warning, problem dimension and range dimension dont match in ExternalRuntimeProblem.makeRange!");
return m_Range.getDoubleArrayShallow().clone();
}
public double getRangeLowerBound(int dim) {
return m_lowerBound;
public void setRange(double[][] range) {
PropertyDoubleArray pRange = new PropertyDoubleArray(range);
this.setRange(pRange);
}
/**
* Set the internal problem range to the given array.
* @param range
*/
public void setRange(PropertyDoubleArray range) {
if (range.getNumRows()<this.m_ProblemDimension) System.err.println("Warning, expected range of dimension " + m_ProblemDimension + " in setRange!");
m_Range.setDoubleArray(range.getDoubleArrayShallow());
}
public PropertyDoubleArray getRange() {
return m_Range;
}
public String rangeTipText() {
return "The domain bounds for the problem";
}
public double getRangeLowerBound(int dim) {
return m_Range.getValue(dim,0);
}
public double getRangeUpperBound(int dim) {
return m_upperBound;
}
protected double[][] getDoubleRange() {
return ((InterfaceDataTypeDouble)this.m_Template).getDoubleRange();
return m_Range.getValue(dim,1);
}
/** This method evaluate a single individual and sets the fitness values
* @param individual The individual that is to be evaluatated
*/
@ -155,6 +181,12 @@ public class ExternalRuntimeProblem extends AbstractOptimizationProblem implemen
}
}
@Override
public void evaluatePopulationEnd(Population population) {
super.evaluatePopulationEnd(population);
if (m_MosoConverter!=null) m_MosoConverter.convertMultiObjective2SingleObjective(population);
}
protected double[] getXVector(AbstractEAIndividual individual) {
double[] x;
x = new double[((InterfaceDataTypeDouble) individual).getDoubleData().length];
@ -170,7 +202,16 @@ public class ExternalRuntimeProblem extends AbstractOptimizationProblem implemen
return runProcess(params, workingDir);
}
/**
* Parse the output values of a process by line and by whitespace characters and some others
* returning a string list.
*
* @param parameters
* @param workingDir
* @return
*/
public static List<String> runProcess(List<String> parameters, String workingDir) {
String colSepRegExp= "[\\s;:|]"; // \s for whitespaces, double quoting necessary!
Process process;
ProcessBuilder pb;
List<String> results = new ArrayList<String>();
@ -184,19 +225,18 @@ public class ExternalRuntimeProblem extends AbstractOptimizationProblem implemen
String line;
while ((line = br.readLine()) != null) {
line = line.trim();
if (line.contains(" ")) {
String[] parts = line.split(" ");
for (String str : parts) {
results.add(str);
}
} else {
results.add(line);
String[] parts = line.split(colSepRegExp);
for (String str : parts) {
results.add(str);
}
// results.add(line);
}
br.close();
} catch (IOException e) {
System.err.println("IO Error when calling external command!");
String msg="IO Error when calling external command! Invalid command for ExternalRuntimeProblem?";
System.err.println(msg);
e.printStackTrace();
throw new RuntimeException(msg);
}
return results;
}
@ -272,19 +312,27 @@ public class ExternalRuntimeProblem extends AbstractOptimizationProblem implemen
public static String globalInfo() {
return "Use an external command as target function.";
}
public String[] getGOEPropertyUpdateLinks() {
return new String[] {"problemDimension", "initialRange", "problemDimension", "range"};
}
/** Length of the x vector at is to be optimized
* @param t Length of the x vector at is to be optimized
/**
* Length of the x vector that is to be optimized. Be sure to keep
* the ranges fit in length.
*
* @param t Length of the x vector that is to be optimized
*/
public void setProblemDimension(int t) {
this.m_ProblemDimension = t;
this.m_Range.adaptRowCount(t);
this.m_initRange.adaptRowCount(t);
}
public int getProblemDimension() {
return this.m_ProblemDimension;
}
public String problemDimensionTipText() {
return "Length of the x vector at is to be optimized.";
return "Domain dimension of the problem";
}
/** Length of the x vector at is to be optimized
@ -326,7 +374,17 @@ public class ExternalRuntimeProblem extends AbstractOptimizationProblem implemen
// return "Just a simple test constraint of x[0] >= 1.";
// }
/** This method allows you to choose the EA individual
public InterfaceMOSOConverter getMosoConverter() {
return m_MosoConverter;
}
public void setMosoConverter(InterfaceMOSOConverter mMosoConverter) {
m_MosoConverter = mMosoConverter;
}
public String mosoConverterTipText() {
return "Possible conversion of multi-objective fitness to single objective fitness.";
}
/** This method allows you to choose the EA individual
* @param indy The EAIndividual type
*/
public void setEAIndividual(InterfaceDataTypeDouble indy) {
@ -342,41 +400,41 @@ public class ExternalRuntimeProblem extends AbstractOptimizationProblem implemen
return Mathematics.expandVector(point, getProblemDimension(), 0.);
}
public double[][] get2DBorder() {
return getDoubleRange();
return getRange().getDoubleArrayShallow();
}
/**
* @return the m_upperBound
*/
public double getRangeUpperBound() {
return m_upperBound;
}
/**
* @param bound the m_upperBound to set
*/
public void setRangeUpperBound(double bound) {
m_upperBound = bound;
}
public String rangeUpperBoundTipText() {
return "Upper bound of the search space in any dimension.";
}
/**
* @return the m_lowerBound
*/
public double getRangeLowerBound() {
return m_lowerBound;
}
/**
* @param bound the m_lowerBound to set
*/
public void setRangeLowerBound(double bound) {
m_lowerBound = bound;
}
public String rangeLowerBoundTipText() {
return "Lower bound of the search space in any dimension.";
}
// /**
// * @return the m_upperBound
// */
// public double getRangeUpperBound() {
// return m_upperBound;
// }
// /**
// * @param bound the m_upperBound to set
// */
// public void setRangeUpperBound(double bound) {
// m_upperBound = bound;
// }
//
// public String rangeUpperBoundTipText() {
// return "Upper bound of the search space in any dimension.";
// }
// /**
// * @return the m_lowerBound
// */
// public double getRangeLowerBound() {
// return m_lowerBound;
// }
// /**
// * @param bound the m_lowerBound to set
// */
// public void setRangeLowerBound(double bound) {
// m_lowerBound = bound;
// }
//
// public String rangeLowerBoundTipText() {
// return "Lower bound of the search space in any dimension.";
// }
public String additionalArgumentTipText() {
return "Optionally define an additional (first) argument for the command line command.";
@ -388,4 +446,34 @@ public class ExternalRuntimeProblem extends AbstractOptimizationProblem implemen
public void setAdditionalArgument(String additionalArg) {
this.additionalArg = additionalArg;
}
// @Override
public Object getInitRange() {
if (m_initRange==null) {
if (m_Range==null) System.err.println("Warning, neither range nor initRange has been set in ExternalRuntimeProblem!");
return m_Range.getDoubleArrayShallow();
} else {
return m_initRange.getDoubleArrayShallow();
}
}
public void setInitialRange(double[][] range) {
PropertyDoubleArray pRange = new PropertyDoubleArray(range);
this.setInitialRange(pRange);
}
public void setInitialRange(PropertyDoubleArray range) {
if (range.getNumRows()<this.m_ProblemDimension) System.err.println("Warning, expected range of dimension " + m_ProblemDimension + " in setInitRange!");
m_initRange = new PropertyDoubleArray(range);
}
public PropertyDoubleArray getInitialRange() {
return m_initRange;
}
public String initialRangeTipText() {
return "Initialization range for the problem";
}
public String[] customPropertyOrder() {
return new String[] {"workingDirectory", "command", "additionalArgument", "problemDimension", "initialRange", "range"};
}
}

View File

@ -28,7 +28,6 @@ import eva2.tools.math.RNG;
* To change this template use File | Settings | File Templates.
*/
public class TF1Problem extends AbstractMultiObjectiveOptimizationProblem implements java.io.Serializable {
protected int m_ProblemDimension = 30;
protected int m_OutputDimension = 2;
protected double m_Noise = 0.0;
@ -359,11 +358,12 @@ public class TF1Problem extends AbstractMultiObjectiveOptimizationProblem implem
// return "Toggle application of constraint (works only for T1).";
// }
/** Since you can apply single objective optimization algorithms on
/**
* Since you can apply single objective optimization algorithms on
* multi-objective problems, the problem needs a way to log the pareto-
* front for such algorithms. This is especially the case for the
* dynamically weighted fitness MOSO.
* @param pop The pareto-front archieve.
* @param pop The pareto-front archive.
*/
public void setParetoFront(Population pop) {
this.m_ParetoFront = pop;

View File

@ -251,8 +251,8 @@ public class MultiObjectiveCMAES implements InterfaceOptimizer, Serializable {
// Ranking
ArchivingNSGAII dummyArchive = new ArchivingNSGAIISMeasure();
Population[] store = dummyArchive
.getNonDomiatedSortedFronts(m_Population);
store = dummyArchive.getNonDomiatedSortedFronts(m_Population);
.getNonDominatedSortedFronts(m_Population);
store = dummyArchive.getNonDominatedSortedFronts(m_Population);
dummyArchive.calculateCrowdingDistance(store);
// Vergleichen und den Successcounter hochz<EFBFBD>hlen wenn wir besser als

View File

@ -2,6 +2,7 @@ package eva2.server.go.strategies;
import eva2.server.go.InterfacePopulationChangedEventListener;
import eva2.server.go.individuals.AbstractEAIndividual;
import eva2.server.go.individuals.AbstractEAIndividualComparator;
import eva2.server.go.operators.archiving.ArchivingNSGAII;
import eva2.server.go.operators.archiving.InformationRetrievalInserting;
import eva2.server.go.operators.archiving.InterfaceArchiving;
@ -220,13 +221,13 @@ public class MultiObjectiveEA implements InterfaceOptimizer, java.io.Serializabl
* @return description
*/
public static String globalInfo() {
return "This is general Evolutionary Multi-Criteria Optimization Framework.";
return "This is a general Multi-objective Evolutionary Optimization Framework.";
}
/** This method will return a naming String
* @return The name of the algorithm
*/
public String getName() {
return "EMO";
return "MOEA";
}
/** Assuming that all optimizer will store thier data in a population
@ -245,7 +246,7 @@ public class MultiObjectiveEA implements InterfaceOptimizer, java.io.Serializabl
}
public InterfaceSolutionSet getAllSolutions() {
return new SolutionSet(getPopulation(), getPopulation().getArchive());
return new SolutionSet(getPopulation(), ArchivingNSGAII.getNonDominatedSortedFront(getPopulation().getArchive()).getSortedPop(new AbstractEAIndividualComparator(0)));
}
/** This method allows you to set/get the optimizing technique to use.

View File

@ -3,9 +3,12 @@ package eva2.server.modules;
import java.io.Serializable;
import eva2.server.go.InterfaceGOParameters;
import eva2.server.go.InterfaceTerminator;
import eva2.server.go.operators.terminators.EvaluationTerminator;
import eva2.server.go.problems.F1Problem;
import eva2.server.go.problems.InterfaceOptimizationProblem;
import eva2.server.go.strategies.GeneticAlgorithm;
import eva2.server.go.strategies.InterfaceOptimizer;
import eva2.tools.Serializer;
@ -63,7 +66,11 @@ public class GOParameters extends AbstractGOParameters implements InterfaceGOPar
super(new GeneticAlgorithm(), new F1Problem(), new EvaluationTerminator(1000));
// ((F1Problem)m_Problem).setEAIndividual(new GAIndividualDoubleData());
}
public GOParameters(InterfaceOptimizer opt, InterfaceOptimizationProblem prob, InterfaceTerminator term) {
super(opt, prob, term);
}
/**
*
*/

View File

@ -61,11 +61,12 @@ public class StatisticsStandalone extends AbstractStatistics implements Interfac
this(resultFileName, 1, resultFileName==null ? StatsParameter.VERBOSITY_NONE : StatsParameter.VERBOSITY_FINAL, false);
}
public StatisticsStandalone(String resultFileName, int multiRuns, int verbosity, boolean showAdditionalInfo) {
public StatisticsStandalone(String resultFileName, int multiRuns, int verbosity, boolean outputAllFieldsAsText) {
this(StatsParameter.getInstance(false));
m_StatsParams.setMultiRuns(multiRuns);
m_StatsParams.setOutputVerbosity(m_StatsParams.getOutputVerbosity().setSelectedTag(verbosity));
m_StatsParams.SetResultFilePrefix(resultFileName);
m_StatsParams.setOutputAllFieldsAsText(outputAllFieldsAsText);
if (resultFileName==null) m_StatsParams.getOutputTo().setSelectedTag(StatsParameter.OUTPUT_WINDOW);
else m_StatsParams.setOutputTo(m_StatsParams.getOutputTo().setSelectedTag(StatsParameter.OUTPUT_FILE));
}

View File

@ -198,7 +198,8 @@ public class BasicResourceLoader implements ResourceLoader
entries = rawData.get(i).split(colSplit);
if (i == 0) { // at the first pass
dat = new double[rawData.size()][(selectedCols == null) ? entries.length : selectedCols.length];
}
}
trimAll(entries);
fillLine(dat, i, entries, selectedCols);
}
} catch (Exception e) {
@ -209,6 +210,10 @@ public class BasicResourceLoader implements ResourceLoader
return dat;
}
private static void trimAll(String[] entries) {
for (int i=0; i<entries.length; i++) if (entries[i]!=null) entries[i]=entries[i].trim();
}
/**
* Walk through a 2-d-array and retrieve the first bunch of lines for which the given column data lies
* within start and end limits, both inclusively. The original array is not altered.
@ -257,6 +262,8 @@ public class BasicResourceLoader implements ResourceLoader
* Fill a line of an array with double values parsed from a String array. A subset of
* Columns may be selected by giving their indices in an integer array cols. If cols
* is null, all are converted.
* If data is missing from the string array, the double array is filled with NaN.
* If more data is delivered, an error message will be printed and the superfluous data disregarded.
*
* @param dest
* @param lineCnt
@ -264,23 +271,27 @@ public class BasicResourceLoader implements ResourceLoader
* @param cols
*/
public static void fillLine(double[][] dest, int lineCnt, String[] entries, int[] cols) {
if (((cols == null) && (dest[lineCnt].length != entries.length)) || (cols != null && (dest[lineCnt].length != cols.length))) {
if (((cols == null) && (dest[lineCnt].length < entries.length)) || (cols != null && (dest[lineCnt].length != cols.length))) {
System.err.println("error, array dimensions dont match! (BasicResourceLoader)");
}
if (cols == null) {
for (int i=0; i<entries.length; i++) {
for (int i=0; i<dest[lineCnt].length; i++) {
try {
dest[lineCnt][i] = Double.valueOf(entries[i]);
if ((i>=entries.length) || (entries[i]==null || (entries[i].length()==0))) dest[lineCnt][i]=Double.NaN;
else dest[lineCnt][i] = Double.valueOf(entries[i]);
} catch(NumberFormatException ex) {
System.err.println("Invalid Double format in line " + lineCnt + ", data was " + entries[i]);
dest[lineCnt][i]=Double.NaN;
}
}
} else {
for (int i=0; i<cols.length; i++) {
try {
dest[lineCnt][i] = Double.valueOf(entries[cols[i]]);
if ((cols[i]>=entries.length) || (entries[cols[i]]==null || (entries[cols[i]].length()==0))) dest[lineCnt][i]=Double.NaN;
else dest[lineCnt][i] = Double.valueOf(entries[cols[i]]);
} catch(NumberFormatException ex) {
System.err.println("Invalid Double format in line " + lineCnt + ", data was " + entries[cols[i]]);
dest[lineCnt][i]=Double.NaN;
}
}
}

View File

@ -1,5 +1,6 @@
package eva2.tools.math;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@ -379,6 +380,20 @@ public class Mathematics {
return (!Double.isInfinite(v) && !Double.isNaN(v));
}
/**
* Check if all numbers are valid (not NaN) and finite. Returns
* -1 if this is the case or the index of the first row with an invalid number.
*
* @param v
* @return
*/
public static int areFinite(double[][] v) {
for (int i=0; i<v.length; i++) {
if (areFinite(v[i])>=0) return i;
}
return -1;
}
/**
* Check if all numbers are valid (not NaN) and finite. Returns
* -1 if this is the case or the index of the first invalid number.
@ -422,6 +437,19 @@ public class Mathematics {
return true;
}
/**
* Returns false if a column vector contains NaN, its squared sum is NaN or the
* absolute sum is smaller than 10^-18.
*
* @param d
* @return
*/
public static boolean isValidVec(double[][] d) {
for (int i=0; i<d.length; i++) {
if (!isValidVec(d[i])) return false;
}
return true;
}
/**
* Returns false if a vector contains NaN, its squared sum is NaN or the
* absolute sum is smaller than 10^-18.
@ -1339,4 +1367,47 @@ public class Mathematics {
vec[i] *= scale;
}
}
/**
* Return an array containing only those lines which have values within
* lower and upper bound (included) in the indexed column.
*
* @param dat
* @param i
* @param d
* @param e
* @return
*/
public static double[][] filterBy(double[][] dat, int i, double lower, double upper) {
if (dat==null||dat.length==0) return dat;
if (i >= dat[0].length) {
System.err.println("Error, invalid column index " + i + " for data array with " + dat[0].length + " columns!");
}
ArrayList<double[]> matching = new ArrayList<double[]>(5);
for (double[] row : dat) {
if (row[i]<=upper && row[i]>=lower) matching.add(row);
}
return matching.toArray(new double[matching.size()][dat[0].length]);
}
/**
* Retrieve a given number of columns from a double matrix. The given
* data array must have valid matrix dimensions (equal number of columns per row).
*
* @param filtered
* @param i
* @param j
* @return
*/
public static double[][] getCols(double[][] data, int ... cols) {
if (data==null || (data[0]==null)) return null;
int nCols = cols.length;
if (nCols>data[0].length) System.err.println("Error, mismatching column count in Mathematics.getCols!");
double[][] ret = new double[data.length][cols.length];
for (int i=0; i<data.length; i++) {
for (int j=0; j<cols.length; j++) ret[i][j] = data[i][cols[j]];
}
return ret;
}
}