    001/*-
    002 * Copyright 2015, 2016 Diamond Light Source Ltd.
    003 *
    004 * All rights reserved. This program and the accompanying materials
    005 * are made available under the terms of the Eclipse Public License v1.0
    006 * which accompanies this distribution, and is available at
    007 * http://www.eclipse.org/legal/epl-v10.html
    008 */
    009
    010package org.eclipse.january.dataset;
    011
    012import java.util.Arrays;
    013
    014/**
    015 * Base class for broadcast iterators of pairs with output.<p>
    016 * For speed, there are public members. Note, index is not updated
    017 */
    018public abstract class BroadcastIterator extends BroadcastIteratorBase {
    019
    020        /**
    021         * @param a dataset to iterate over
    022         * @param b dataset to iterate over
    023         * @return broadcast iterator
    024         */
    025        public static BroadcastIterator createIterator(Dataset a, Dataset b) {
    026                return createIterator(a, b, null, false);
    027        }
    028
    029        /**
    030         * @param a dataset to iterate over
    031         * @param b dataset to iterate over
    032         * @param o output (can be null for new dataset, or a)
    033         * @return broadcast iterator
    034         */
    035        public static BroadcastIterator createIterator(Dataset a, Dataset b, Dataset o) {
    036                return createIterator(a, b, o, false);
    037        }
    038
    039        /**
    040         * @param a dataset to iterate over
    041         * @param b dataset to iterate over
    042         * @param o output (can be null for new dataset, or a)
    043         * @param createIfNull if true, create new dataset if o is null
    044         * @return broadcast iterator
    045         */
    046        public static BroadcastIterator createIterator(Dataset a, Dataset b, Dataset o, boolean createIfNull) {
    047                if (Arrays.equals(a.getShapeRef(), b.getShapeRef()) && a.getStrides() == null && b.getStrides() == null) {
    048                        if (o == null || (o.getStrides() == null && Arrays.equals(a.getShapeRef(), o.getShapeRef()))) {
    049                                return new ContiguousPairIterator(a, b, o, createIfNull);
    050                        }
    051                }
    052                return new BroadcastPairIterator(a, b, o, createIfNull);
    053        }
    054
    055        /**
    056         * Index in output dataset
    057         */
    058        public int oIndex;
    059        /**
    060         * Current value in first dataset
    061         */
    062        public double aDouble;
    063        /**
    064         * Current value in first dataset
    065         */
    066        public long aLong;
    067        /**
    068         * Output dataset
    069         */
    070        protected Dataset oDataset;
    071
    072        final protected boolean outputA;
    073        final protected boolean outputB;
    074
    075        /**
    076         * @param a dataset to iterate over
    077         * @param b dataset to iterate over
    078         * @param o output (can be null for new dataset, or a)
    079         */
    080        protected BroadcastIterator(Dataset a, Dataset b, Dataset o) {
    081                super(a, b);
    082                oDataset = o;
    083                outputA = a == o;
    084                outputB = b == o;
    085                read = InterfaceUtils.isNumerical(a.getClass()) && InterfaceUtils.isNumerical(b.getClass());
    086                asDouble = aDataset.hasFloatingPointElements() || bDataset.hasFloatingPointElements();
    087                BroadcastUtils.checkItemSize(a, b, o);
    088                if (o != null) {
    089                        o.setDirty();
    090                }
    091        }
    092
    093        /**
    094         * @return output dataset (can be null)
    095         */
    096        public Dataset getOutput() {
    097                return oDataset;
    098        }
    099
    100        @Override
    101        protected void storeCurrentValues() {
    102                if (aIndex >= 0) {
    103                        if (asDouble) {
    104                                aDouble = aDataset.getElementDoubleAbs(aIndex);
    105                        } else {
    106                                aLong = aDataset.getElementLongAbs(aIndex);
    107                        }
    108                }
    109                if (bIndex >= 0) {
    110                        if (asDouble) {
    111                                bDouble = bDataset.getElementDoubleAbs(bIndex);
    112                        } else {
    113                                bLong = bDataset.getElementLongAbs(bIndex);
    114                        }
    115                }
    116        }
    117}