/*-
* Copyright (c) 2013 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 java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.dawnsci.analysis.api.fitting.functions.IFunction;
import org.eclipse.dawnsci.analysis.api.fitting.functions.IOperator;
import org.eclipse.dawnsci.analysis.api.fitting.functions.IParameter;
/**
* An abstract operator
*/
abstract public class AOperator extends AFunction implements IOperator {
protected List<IParameter> params; // unique parameters
public AOperator() {
super();
params = new ArrayList<>();
}
@Override
public void updateParameters() {
params.clear();
for (int i = 0, imax = getNoOfFunctions(); i < imax; i++) {
IFunction f = getFunction(i);
if (f == null)
continue;
for (int j = 0, jmax = f.getNoOfParameters(); j < jmax; j++) {
IParameter p = f.getParameter(j);
boolean add = true;
for (IParameter param : params) {
if (p == param) {
add = false;
break;
}
}
if (add) {
params.add(p);
}
}
}
setDirty(true);
if (parent != null) {
parent.updateParameters();
}
}
@Override
protected int indexOfParameter(IParameter p) {
for (int i = 0, imax = params.size(); i < imax; i++) {
if (p == params.get(i))
return i;
}
return -1;
}
@Override
public int getNoOfParameters() {
return params.size();
}
@Override
public IParameter getParameter(int index) {
return params.get(index);
}
@Override
public void setParameter(int index, IParameter parameter) {
IParameter op = params.get(index);
for (int i = 0, imax = getNoOfFunctions(); i < imax; i++) {
IFunction f = getFunction(i);
int j = f instanceof AFunction ? ((AFunction) f).indexOfParameter(op) : indexOfParameter(f, op);
if (j >= 0)
f.setParameter(j, parameter);
}
params.set(index, parameter);
setDirty(true);
}
@Override
public IParameter[] getParameters() {
int n = params.size();
IParameter[] nParameters = new IParameter[n];
for (int i = 0; i < n; i++) {
nParameters[i] = params.get(i);
}
return nParameters;
}
@Override
public double getParameterValue(int index) {
return params.get(index).getValue();
}
@Override
public void setParameterValues(double... parameters) {
int n = Math.min(parameters.length, params.size());
for (int i = 0; i < n; i++) {
params.get(i).setValue(parameters[i]);
}
setDirty(true);
}
@Override
protected boolean isDuplicated(IParameter param) {
return false;
}
@Override
public void setDirty(boolean isDirty) {
super.setDirty(isDirty);
int nf = getNoOfFunctions();
for (int i = 0; i < nf; i++) {
IFunction f = getFunction(i);
if (f != null)
f.setDirty(isDirty);
}
}
protected final String OPERATOR_NO_FUNCTIONS = "Operator has no functions";
@Override
public String toString() {
StringBuffer out = new StringBuffer();
int nf = getNoOfFunctions();
for (int i = 0; i < nf; i++) {
IFunction f = getFunction(i);
if (f != null) {
if (nf > 1)
out.append(String.format("Function %d - \n", i));
out.append(f.toString());
out.append('\n');
}
}
return out.length() == 0 ? OPERATOR_NO_FUNCTIONS : out.substring(0, out.length() - 1);
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (dirty ? 1231 : 1237);
result = prime * result + (name == null ? 0 : name.hashCode());
result = prime * result + params.hashCode();
for (IFunction f : getFunctions()) {
if (f != null) {
result = prime * result + f.hashCode();
} else {
result = prime * result;
}
}
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
AOperator other = (AOperator) obj;
if (dirty != other.dirty)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (!params.equals(other.params))
return false;
int nf = getNoOfFunctions();
if (nf != other.getNoOfFunctions())
return false;
for (int i = 0; i < nf; i++) {
IFunction fa = getFunction(i);
IFunction fo = other.getFunction(i);
if (fa == null) {
if (fo != null)
return false;
} else if (!fa.equals(fo)) {
return false;
}
}
return true;
}
@Override
public boolean isValid() {
if (!super.isValid())
return false;
for (IFunction function : getFunctions()) {
if (function == null)
return false;
if (!function.isValid())
return false;
}
return true;
}
@Override
public AOperator copy() throws Exception {
Constructor<? extends AOperator> c = getClass().getConstructor();
AOperator operator = c.newInstance();
for (IFunction f : getFunctions()) {
if (f == null) {
operator.addFunction(null);
} else {
operator.addFunction(f.copy());
}
}
return operator;
}
}