/*- * 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 org.eclipse.dawnsci.analysis.api.fitting.functions.IOperator; import org.eclipse.dawnsci.analysis.api.fitting.functions.IParameter; import org.eclipse.january.dataset.Dataset; import org.eclipse.january.dataset.DatasetFactory; import org.eclipse.january.dataset.DatasetUtils; import org.eclipse.january.dataset.DoubleDataset; /** * Divide two functions (missing functions are treated as unity) */ public class Divide extends ABinaryOperator implements IOperator { private static final String NAME = "Divide"; private static final String DESC = "Divide one function by another"; public Divide() { super(); } @Override protected void setNames() { setNames(NAME, DESC); } @Override public double val(double... values) { double y = fa == null ? 1 : fa.val(values); if (fb != null) { y /= fb.val(values); } return y; } @Override public void fillWithValues(DoubleDataset data, CoordinatesIterator it) { if (fa != null) { if (fa instanceof AFunction) { ((AFunction) fa).fillWithValues(data, it); } else { data.setSlice(DatasetUtils.convertToDataset(fa.calculateValues(it.getValues()))); } } else { data.fill(1); } if (fb != null) { if (fb instanceof AFunction) { DoubleDataset temp = DatasetFactory.zeros(DoubleDataset.class, it.getShape()); ((AFunction) fb).fillWithValues(temp, it); data.idivide(temp); } else { data.idivide(DatasetUtils.convertToDataset(fb.calculateValues(it.getValues()))); } } } @Override public double partialDeriv(IParameter param, double... values) { double a; double d; if (fa != null) { a = fa.val(values); d = fa.partialDeriv(param, values); } else { a = 1; d = 0; } if (fb != null) { double b = fb.val(values); double db = fb.partialDeriv(param, values); d = (d * b - a * db) / (b * b); } return d; } @Override public void fillWithPartialDerivativeValues(IParameter param, DoubleDataset data, CoordinatesIterator it) { if (fa == null) { data.fill(0); } else { if (fa instanceof AFunction) { if (((AFunction) fa).indexOfParameter(param) >= 0) { ((AFunction) fa).fillWithPartialDerivativeValues(param, data, it); } } else { if (indexOfParameter(fa, param) >= 0) { data.setSlice(DatasetUtils.convertToDataset(fa.calculatePartialDerivativeValues(param, it.getValues()))); } } } if (fb != null) { Dataset b = DatasetUtils.convertToDataset(fb.calculateValues(it.getValues())); data.imultiply(b); b.imultiply(b); Dataset a; if (fa instanceof AFunction) { a = DatasetFactory.zeros(DoubleDataset.class, it.getShape()); ((AFunction) fa).fillWithValues((DoubleDataset) a, it); } else { a = DatasetUtils.convertToDataset(fa.calculateValues(it.getValues())); } if (indexOfParameter(fb, param) >= 0) { a.imultiply(DatasetUtils.convertToDataset(fb.calculatePartialDerivativeValues(param, it.getValues()))); data.isubtract(a); } data.idivide(b); } } }