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}