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        }
065
066        /**
067         * @return output dataset (can be null)
068         */
069        public Dataset getOutput() {
070                return oDataset;
071        }
072
073        @Override
074        protected void storeCurrentValues() {
075                if (aIndex >= 0) {
076                        if (asDouble) {
077                                aDouble = aDataset.getElementDoubleAbs(aIndex);
078                        } else {
079                                aLong = aDataset.getElementLongAbs(aIndex);
080                        }
081                }
082                if (bIndex >= 0) {
083                        if (asDouble) {
084                                bDouble = bDataset.getElementDoubleAbs(bIndex);
085                        } else {
086                                bLong = bDataset.getElementLongAbs(bIndex);
087                        }
088                }
089        }
090}