    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. For speed, there are public members. Note, index is not updated
    016 */
    017public abstract class BroadcastIterator extends BroadcastIteratorBase {
    018
    019        public static BroadcastIterator createIterator(Dataset a, Dataset b) {
    020                return createIterator(a, b, null, false);
    021        }
    022
    023        public static BroadcastIterator createIterator(Dataset a, Dataset b, Dataset o) {
    024                return createIterator(a, b, o, false);
    025        }
    026
    027        public static BroadcastIterator createIterator(Dataset a, Dataset b, Dataset o, boolean createIfNull) {
    028                if (Arrays.equals(a.getShapeRef(), b.getShapeRef()) && a.getStrides() == null && b.getStrides() == null) {
    029                        if (o == null || (o.getStrides() == null && Arrays.equals(a.getShapeRef(), o.getShapeRef()))) {
    030                                return new ContiguousPairIterator(a, b, o, createIfNull);
    031                        }
    032                }
    033                return new BroadcastPairIterator(a, b, o, createIfNull);
    034        }
    035
    036        /**
    037         * Index in output dataset
    038         */
    039        public int oIndex;
    040        /**
    041         * Current value in first dataset
    042         */
    043        public double aDouble;
    044        /**
    045         * Current value in first dataset
    046         */
    047        public long aLong;
    048        /**
    049         * Output dataset
    050         */
    051        protected Dataset oDataset;
    052
    053        final protected boolean outputA;
    054        final protected boolean outputB;
    055
    056        protected BroadcastIterator(Dataset a, Dataset b, Dataset o) {
    057                super(a, b);
    058                oDataset = o;
    059                outputA = a == o;
    060                outputB = b == o;
    061                read = DTypeUtils.isDTypeNumerical(a.getDType()) && DTypeUtils.isDTypeNumerical(b.getDType());
    062                asDouble = aDataset.hasFloatingPointElements() || bDataset.hasFloatingPointElements();
    063                BroadcastUtils.checkItemSize(a, b, o);
    064                if (o != null) {
    065                        o.setDirty();
    066                }
    067        }
    068
    069        /**
    070         * @return output dataset (can be null)
    071         */
    072        public Dataset getOutput() {
    073                return oDataset;
    074        }
    075
    076        @Override
    077        protected void storeCurrentValues() {
    078                if (aIndex >= 0) {
    079                        if (asDouble) {
    080                                aDouble = aDataset.getElementDoubleAbs(aIndex);
    081                        } else {
    082                                aLong = aDataset.getElementLongAbs(aIndex);
    083                        }
    084                }
    085                if (bIndex >= 0) {
    086                        if (asDouble) {
    087                                bDouble = bDataset.getElementDoubleAbs(bIndex);
    088                        } else {
    089                                bLong = bDataset.getElementLongAbs(bIndex);
    090                        }
    091                }
    092        }
    093}