Skip to content

Commit

Permalink
Fixed calculation range handling
Browse files Browse the repository at this point in the history
- Fixed calculation limit not updating on increase of calculation range
- Fixed data event handling related to changes in the range. Removed the
TRUNCATED type.
- Fixed copy constructor of NumericProperty not making exact copies of
the property, e.g. discrete state was ignored
- Allowed optimizers to select a larger gradient step for properties
marked discrete
- The gradient step is now relative, rather than absolute
  • Loading branch information
Artem Lunev committed Jun 13, 2021
1 parent 0f2f95b commit 56104c3
Show file tree
Hide file tree
Showing 12 changed files with 79 additions and 57 deletions.
11 changes: 5 additions & 6 deletions src/main/java/pulse/input/ExperimentalData.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import static java.lang.Double.valueOf;
import static java.util.Collections.max;
import static pulse.input.listeners.DataEventType.TRUNCATED;
import static pulse.properties.NumericProperties.derive;
import static pulse.properties.NumericPropertyKeyword.NUMPOINTS;
import static pulse.properties.NumericPropertyKeyword.PULSE_WIDTH;
Expand All @@ -18,6 +17,7 @@
import pulse.AbstractData;
import pulse.baseline.FlatBaseline;
import pulse.input.listeners.DataEvent;
import pulse.input.listeners.DataEventType;
import pulse.input.listeners.DataListener;
import pulse.properties.NumericProperty;
import pulse.ui.Messages;
Expand Down Expand Up @@ -301,10 +301,7 @@ public void truncate() {
final double halfMaximum = halfRiseTime();
final double cutoff = CUTOFF_FACTOR * halfMaximum;

this.range.setUpperBound(derive(UPPER_BOUND, cutoff));
this.indexRange.set(getTimeSequence(), range);

fireDataChanged(new DataEvent(TRUNCATED, this));
this.range.setUpperBound(derive(UPPER_BOUND, cutoff));;
}

/**
Expand Down Expand Up @@ -407,8 +404,10 @@ private void doSetRange() {
indexRange.set(time, range);

addHierarchyListener(l -> {
if (l.getSource() == range)
if (l.getSource() == range) {
indexRange.set(time, range);
this.fireDataChanged(new DataEvent(DataEventType.RANGE_CHANGED, this));
}
});

if (metadata != null)
Expand Down
17 changes: 12 additions & 5 deletions src/main/java/pulse/input/Range.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

import pulse.math.ParameterVector;
import pulse.math.Segment;
import pulse.problem.schemes.solvers.SolverException;
import pulse.properties.Flag;
import pulse.properties.NumericProperty;
import pulse.properties.NumericPropertyKeyword;
Expand Down Expand Up @@ -170,8 +171,8 @@ public void set(NumericPropertyKeyword type, NumericProperty property) {
@Override
public void optimisationVector(ParameterVector output, List<Flag> flags) {

double len = segment.length();
var bounds = new Segment(-0.25 * len, 0.25 * len);
var curve = (ExperimentalData)this.getParent();
Segment bounds;

for (int i = 0, size = output.dimension(); i < size; i++) {

Expand All @@ -180,9 +181,12 @@ public void optimisationVector(ParameterVector output, List<Flag> flags) {
switch (key) {
case UPPER_BOUND:
output.set(i, segment.getMaximum());
var seq = curve.getTimeSequence();
bounds = new Segment( 1.1 * curve.maxAdjustedSignal().getX(), seq.get(seq.size() - 1) );
break;
case LOWER_BOUND:
output.set(i, segment.getMinimum());
bounds = new Segment( 0.0, 0.35 * curve.halfRiseTime() );
break;
default:
continue;
Expand All @@ -198,11 +202,14 @@ public void optimisationVector(ParameterVector output, List<Flag> flags) {
* Tries to assign the upper and lower bound based on {@code params}.
*
* @param params an {@code IndexedVector} which may contain the bounds.
* @throws SolverException
*/

@Override
public void assign(ParameterVector params) {

public void assign(ParameterVector params) throws SolverException {
if(!params.validate())
throw new SolverException("Parameter values not sensible");

NumericProperty p = null;

for (int i = 0, size = params.dimension(); i < size; i++) {
Expand All @@ -219,7 +226,7 @@ public void assign(ParameterVector params) {
default:
continue;
}

}

}
Expand Down
6 changes: 3 additions & 3 deletions src/main/java/pulse/input/listeners/DataEventType.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@
public enum DataEventType {
/**
* <p>
* The {@code TRUNCATED} {@code DataEventType} indicates the range of the
* {@code ExperimentalData} has been truncated. Note this means that only the
* The {@code RANGE_CHANGED} {@code DataEventType} indicates the range of the
* {@code ExperimentalData} has either been truncated or extended. Note this means that only the
* range is affected and not the data itself.
*
* @see pulse.input.ExperimentalData.truncate()
*/

TRUNCATED
RANGE_CHANGED

}
6 changes: 3 additions & 3 deletions src/main/java/pulse/io/export/XMLConverter.java
Original file line number Diff line number Diff line change
Expand Up @@ -177,8 +177,8 @@ public static List<NumericProperty> readXML(InputStream inputStream)
Element eElement = (Element) nNode;
NumericPropertyKeyword keyword = NumericPropertyKeyword.valueOf(eElement.getAttribute("keyword"));
boolean autoAdjustable = Boolean.valueOf(eElement.getAttribute("auto-adjustable"));
boolean discreet = Boolean.valueOf(eElement.getAttribute("discreet"));
String descriptor = eElement.getAttribute("descriptor");
boolean discrete = Boolean.valueOf(eElement.getAttribute("discreet"));
String descriptor = eElement.getAttribute("descriptor");
String abbreviation = eElement.getAttribute("abbreviation");
boolean defSearch = Boolean.valueOf(eElement.getAttribute("default-search-variable"));

Expand All @@ -200,7 +200,7 @@ public static List<NumericProperty> readXML(InputStream inputStream)
np.setDescriptor(descriptor);
np.setAbbreviation(abbreviation);
np.setAutoAdjustable(autoAdjustable);
np.setDiscreet(discreet);
np.setDiscrete(discrete);
np.setDefaultSearchVariable(defSearch);
properties.add(np);
}
Expand Down
7 changes: 1 addition & 6 deletions src/main/java/pulse/problem/statements/Problem.java
Original file line number Diff line number Diff line change
Expand Up @@ -281,12 +281,7 @@ protected void setHeatLossParameter(ParameterVector output, int i, double Bi) {
*/

@Override
public void assign(ParameterVector params) throws SolverException {

if(!params.validate()) {
throw new SolverException("Parameter values not sensible");
}

public void assign(ParameterVector params) throws SolverException {
baseline.assign(params);
for (int i = 0, size = params.dimension(); i < size; i++) {

Expand Down
25 changes: 14 additions & 11 deletions src/main/java/pulse/properties/NumericProperty.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public class NumericProperty implements Property, Comparable<NumericProperty> {
private NumericPropertyKeyword type;

private boolean autoAdjustable;
private boolean discreet;
private boolean discrete;
private boolean defaultSearchVariable;

/**
Expand Down Expand Up @@ -82,14 +82,17 @@ public NumericProperty(NumericPropertyKeyword type, Number... params) {
*/

public NumericProperty(NumericProperty num) {
this.value = num.value;
this.descriptor = num.descriptor;
this.abbreviation = num.abbreviation;
this.minimum = num.minimum;
this.maximum = num.maximum;
this.type = num.type;
this.value = num.value;
this.descriptor = num.descriptor;
this.abbreviation = num.abbreviation;
this.minimum = num.minimum;
this.maximum = num.maximum;
this.type = num.type;
this.discrete = num.discrete;
this.dimensionFactor = num.dimensionFactor;
this.autoAdjustable = num.autoAdjustable;
this.autoAdjustable = num.autoAdjustable;
this.error = num.error;
this.defaultSearchVariable = num.defaultSearchVariable;
}

public NumericPropertyKeyword getType() {
Expand Down Expand Up @@ -270,11 +273,11 @@ public int compareTo(NumericProperty arg0) {
}

public boolean isDiscrete() {
return discreet;
return discrete;
}

public void setDiscreet(boolean discreet) {
this.discreet = discreet;
public void setDiscrete(boolean discrete) {
this.discrete = discrete;
}

@Override
Expand Down
10 changes: 7 additions & 3 deletions src/main/java/pulse/search/direction/GradientBasedOptimiser.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import pulse.math.ParameterVector;
import pulse.math.linear.Vector;
import pulse.problem.schemes.solvers.SolverException;
import pulse.properties.NumericProperties;
import pulse.properties.NumericProperty;
import pulse.properties.NumericPropertyKeyword;
import pulse.properties.Property;
Expand Down Expand Up @@ -78,11 +79,14 @@ public Vector gradient(SearchTask task) throws SolverException {
final var params = task.searchVector();
var grad = new Vector(params.dimension());

boolean discreteGradient = params.getIndices().stream().anyMatch(index -> isDiscrete(index));
final double dxGrid = task.getCurrentCalculation().getScheme().getGrid().getXStep();
final double dx = discreteGradient ? dxGrid : gradientResolution;

final double resolutionHigh = (double) getGradientResolution().getValue();
final double resolutionLow = 5E-2; //TODO

for (int i = 0; i < params.dimension(); i++) {
boolean discrete = NumericProperties.def(params.getIndex(i)).isDiscrete();
double dx = (discrete ? resolutionLow : resolutionHigh) * params.get(i);

final var shift = new Vector(params.dimension());
shift.set(i, 0.5 * dx);

Expand Down
13 changes: 9 additions & 4 deletions src/main/java/pulse/search/direction/LMOptimiser.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import pulse.math.linear.SquareMatrix;
import pulse.math.linear.Vector;
import pulse.problem.schemes.solvers.SolverException;
import pulse.properties.NumericProperties;
import pulse.properties.NumericProperty;
import pulse.properties.NumericPropertyKeyword;
import pulse.properties.Property;
Expand Down Expand Up @@ -174,10 +175,14 @@ public RectangularMatrix jacobian(SearchTask task) throws SolverException {

var jacobian = new double[numPoints][numParams];

final double dx = super.getGradientStep();
final double resolutionHigh = super.getGradientStep();
final double resolutionLow = 1E-2; //TODO

for (int i = 0; i < numParams; i++) {

boolean discrete = NumericProperties.def(params.getIndex(i)).isDiscrete();
double dx = (discrete ? resolutionLow : resolutionHigh) * params.get(i);

final var shift = new Vector(numParams);
shift.set(i, 0.5 * dx);

Expand All @@ -191,7 +196,7 @@ public RectangularMatrix jacobian(SearchTask task) throws SolverException {
task.solveProblemAndCalculateCost();
var r2 = residualVector(residualCalculator);

for (int j = 0; j < numPoints; j++) {
for (int j = 0, realNumPoints = Math.min(numPoints, r2.length); j < realNumPoints; j++) {

jacobian[j][i] = (r1[j] - r2[j]) / dx;

Expand All @@ -217,8 +222,8 @@ public GradientGuidedPath initState(SearchTask t) {
}

private Vector halfGradient(LMPath path) {
var jacobian = path.getJacobian();
var residuals = path.getResidualVector();
var jacobian = path.getJacobian();
var residuals = path.getResidualVector();
return jacobian.transpose().multiply(new Vector(residuals));
}

Expand Down
8 changes: 4 additions & 4 deletions src/main/java/pulse/search/statistics/ResidualStatistic.java
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,11 @@ public void calculateResiduals(SearchTask task) {

var s = estimate.getSplineInterpolation();

int startIndex = max(closestLeft(estimate.timeAt(0), time), indexRange.getLowerBound());
int endIndex = min(closestRight(estimate.timeLimit(), time), indexRange.getUpperBound());

double interpolated;
int startIndex = max(closestLeft(estimate.timeAt(0), time), indexRange.getLowerBound());
int endIndex = min(closestRight(estimate.timeLimit(), time), indexRange.getUpperBound());

double interpolated;

for (int i = startIndex; i <= endIndex; i++) {
/*
* find the point on the calculated heating curve which has the closest time
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/pulse/tasks/SearchTask.java
Original file line number Diff line number Diff line change
Expand Up @@ -220,13 +220,13 @@ public ParameterVector searchVector() {
public void assign(ParameterVector searchParameters) {
try {
current.getProblem().assign(searchParameters);
curve.getRange().assign(searchParameters);
} catch (SolverException e) {
var status = FAILED;
status.setDetails(Details.PARAMETER_VALUES_NOT_SENSIBLE);
setStatus(status);
e.printStackTrace();
}
curve.getRange().assign(searchParameters);
}

/**
Expand Down
19 changes: 14 additions & 5 deletions src/main/java/pulse/ui/components/panels/ChartToolbar.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
import static javax.swing.JOptionPane.showConfirmDialog;
import static javax.swing.JOptionPane.showOptionDialog;
import static javax.swing.SwingUtilities.getWindowAncestor;
import static pulse.properties.NumericProperties.derive;
import static pulse.properties.NumericPropertyKeyword.LOWER_BOUND;
import static pulse.properties.NumericPropertyKeyword.UPPER_BOUND;
import static pulse.tasks.listeners.TaskRepositoryEvent.State.TASK_FINISHED;
import static pulse.ui.Messages.getString;
import static pulse.ui.frames.MainGraphFrame.getChart;
Expand Down Expand Up @@ -234,18 +237,24 @@ private void validateRange(double a, double b) {
sb.append(getString("RangeSelectionFrame.ConfirmationMessage1"));
sb.append("</p><br>");
sb.append(getString("RangeSelectionFrame.ConfirmationMessage2"));
sb.append(expCurve.getEffectiveStartTime());
sb.append(format("%3.6f", expCurve.getEffectiveStartTime()));
sb.append(" to ");
sb.append(expCurve.getEffectiveEndTime());
sb.append(format("%3.6f", expCurve.getEffectiveEndTime()));
sb.append("<br><br>");
sb.append(getString("RangeSelectionFrame.ConfirmationMessage3"));
sb.append(format("%3.4f", a) + " to " + format("%3.4f", b));
sb.append(format("%3.6f", a) + " to " + format("%3.6f", b));
sb.append("</html>");

var dialogResult = showConfirmDialog(getWindowAncestor(this), sb.toString(), "Confirm chocie", YES_NO_OPTION);

if (dialogResult == YES_OPTION)
expCurve.setRange(new Range(a, b));
if (dialogResult == YES_OPTION) {
if(expCurve.getRange() == null)
expCurve.setRange(new Range(a, b));
else {
expCurve.getRange().setLowerBound(derive(LOWER_BOUND, a));
expCurve.getRange().setUpperBound(derive(UPPER_BOUND, b));
}
}

}

Expand Down
12 changes: 6 additions & 6 deletions src/main/resources/NumericProperty.xml
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@
<NumericProperty keyword="ITERATION_LIMIT"
abbreviation="Iteration limit" auto-adjustable="true"
descriptor="Iteration limit" dimensionfactor="1" maximum="1000"
minimum="1" primitive-type="int" value="128" discreet="false">
minimum="1" primitive-type="int" value="256" discreet="false">
</NumericProperty>
<NumericProperty
abbreviation="&lt;i&gt;a&lt;/i&gt;&lt;sub&gt;c&lt;/sub&gt; (mm&lt;sup&gt;2&lt;/sup&gt;s&lt;sup&gt;-1&lt;/sup&gt;) "
Expand Down Expand Up @@ -409,7 +409,7 @@
<NumericProperty abbreviation="Resolution (total)"
auto-adjustable="false" descriptor="Resolution (total)"
dimensionfactor="1.0" keyword="ERROR_TOLERANCE" maximum="0.1"
minimum="1.0E-7" value="0.0001" primitive-type="double"
minimum="1.0E-7" value="0.00001" primitive-type="double"
discreet="false" default-search-variable="false" />
<NumericProperty abbreviation="FOV&lt;sub&gt;inner&lt;/sub&gt; (mm)"
auto-adjustable="true"
Expand All @@ -423,7 +423,7 @@
descriptor="Field of view (outer), FOV&lt;sub&gt;outer&lt;/sub&gt; (mm)"
dimensionfactor="1000.0" keyword="FOV_OUTER" maximum="0.1"
minimum="1.0E-6" value="0.01" primitive-type="double" discreet="true"
default-search-variable="true" />
default-search-variable="false" />
<NumericProperty abbreviation="Baseline (slope)"
auto-adjustable="true" descriptor="Baseline (slope)"
dimensionfactor="1.0" keyword="BASELINE_SLOPE" maximum="10.0"
Expand All @@ -439,7 +439,7 @@
descriptor="Heat loss (side surface), Bi&lt;sub&gt;s&lt;/sub&gt;"
dimensionfactor="1.0" keyword="HEAT_LOSS_SIDE" maximum="10.0"
minimum="0.0" value="0.2" primitive-type="double" discreet="false"
default-search-variable="true" />
default-search-variable="true" ></NumericProperty>
<NumericProperty keyword="HEAT_LOSS" abbreviation="Bi"
auto-adjustable="true" descriptor="Heat loss, Bi" dimensionfactor="1"
maximum="10" minimum="0.0" primitive-type="double" value="0.2"
Expand Down Expand Up @@ -496,15 +496,15 @@
abbreviation="&lt;i&gt;t&lt;/i&gt;&lt;sub&gt;min&lt;/sub&gt;"
auto-adjustable="false"
descriptor="Lower bound, &lt;i&gt;t&lt;/i&gt;&lt;sub&gt;min&lt;/sub&gt;"
dimensionfactor="1" discreet="false" keyword="LOWER_BOUND"
dimensionfactor="1" discreet="true" keyword="LOWER_BOUND"
maximum="100" minimum="-100" primitive-type="double" value="0.0"
default-search-variable="false">
</NumericProperty>
<NumericProperty
abbreviation="&lt;i&gt;t&lt;/i&gt;&lt;sub&gt;max&lt;/sub&gt;"
auto-adjustable="false"
descriptor="Upper bound, &lt;i&gt;t&lt;/i&gt;&lt;sub&gt;max&lt;/sub&gt;"
dimensionfactor="1" discreet="false" keyword="UPPER_BOUND"
dimensionfactor="1" discreet="true" keyword="UPPER_BOUND"
maximum="100" minimum="-100" primitive-type="double" value="1.0"
default-search-variable="false">
</NumericProperty>
Expand Down

0 comments on commit 56104c3

Please sign in to comment.