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}