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}