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