/*-
* Copyright (c) 2012 Diamond Light Source Ltd.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package uk.ac.diamond.scisoft.analysis.fitting.functions;
import org.eclipse.dawnsci.analysis.api.fitting.functions.IFunction;
import org.eclipse.dawnsci.analysis.api.fitting.functions.IPeak;
import org.eclipse.january.dataset.Dataset;
import org.eclipse.january.dataset.DatasetFactory;
import org.eclipse.january.dataset.DatasetUtils;
import org.eclipse.january.dataset.DoubleDataset;
import org.eclipse.january.dataset.Maths;
/**
* Class which contains all the information about a particular function which is made up out of several other
* functions
*/
public class CompositeFunction extends Add {
/**
* This constructor is simply to start an empty composite function.
*/
public CompositeFunction() {
super();
}
/**
* Create a set of datasets each containing the composite function and its constituent
* parts evaluated over the values
*
* @param values
* datasets containing all the values to evaluate the function at
* @return an array of datasets
*/
public DoubleDataset[] display(DoubleDataset... values) {
if (values == null || values.length == 0) {
}
int noOfFunctions = getNoOfFunctions();
DoubleDataset[] outputs = new DoubleDataset[noOfFunctions + 1];
outputs[0] = calculateValues(values);
outputs[0].setName("Composite function");
// now add the data for each bit in turn
int j = 1;
for (IFunction f : functions) {
outputs[j] = (DoubleDataset) DatasetUtils.cast(f.calculateValues(values), Dataset.FLOAT64);
outputs[j++].setName(f.getName());
}
return outputs;
}
/**
* Create a set of datasets each containing the composite function and its constituent
* parts evaluated over the values
*
* @param XValues
* A dataset containing all the X values to calculate the data at
* @param DataValues
* The data that is being fitted too, for visual help.
* @return an array of datasets
*/
public DoubleDataset[] display(DoubleDataset XValues, DoubleDataset DataValues) {
int noOfFunctions = getNoOfFunctions();
DoubleDataset[] outputs = new DoubleDataset[noOfFunctions + 4];
outputs[0] = DataValues.clone();
// now add the data
outputs[1] = calculateValues(XValues);
outputs[1].setName("Composite function");
// now add the errors to the graph, this should provide a good view to
// how good the fit is quite nicely.
outputs[2] = (DoubleDataset) Maths.subtract(outputs[1], DataValues);
outputs[2].setName("Error Value");
double offset = DataValues.min().doubleValue() - ((DataValues.max().doubleValue() - DataValues.min().doubleValue()) / 5.0);
outputs[2].isubtract(offset);
outputs[3] = DatasetFactory.zeros(DoubleDataset.class, XValues.getShapeRef());
outputs[3].setName("Error Offset");
outputs[3].fill(offset);
// now add the data for each bit in turn
int j = 4;
for (IFunction f : functions) {
outputs[j] = (DoubleDataset) DatasetUtils.cast(f.calculateValues(XValues), Dataset.FLOAT64);
outputs[j++].setName(f.getName());
}
return outputs;
}
/**
* Attempts to cast and return the function at i as a Peak
* @param i
* @return IPeak
* @throws ClassCastException
*/
public IPeak getPeak(int i) {
return (IPeak) getFunction(i);
}
@Override
public CompositeFunction copy() throws Exception {
return (CompositeFunction)super.copy();
}
}