| 170 | } |
| 171 | |
| 172 | bool TensorSlice::Intersect(const TensorSlice& other, |
| 173 | TensorSlice* result) const { |
| 174 | // First, if two slices have different ranks, they obviously don't overlap |
| 175 | // -- in fact they are not compatible. |
| 176 | if (dims() != other.dims()) { |
| 177 | return false; |
| 178 | } |
| 179 | |
| 180 | // Setting the result to the right dimension |
| 181 | if (result) { |
| 182 | result->SetFullSlice(dims()); |
| 183 | } |
| 184 | // The two slices overlap if they overlap in all dimensions. |
| 185 | for (int d = 0; d < dims(); ++d) { |
| 186 | if (IsFullAt(d)) { |
| 187 | if (result) { |
| 188 | result->set_start(d, other.start(d)); |
| 189 | result->set_length(d, other.length(d)); |
| 190 | } |
| 191 | } else if (other.IsFullAt(d)) { |
| 192 | if (result) { |
| 193 | result->set_start(d, start(d)); |
| 194 | result->set_length(d, length(d)); |
| 195 | } |
| 196 | } else { |
| 197 | // If we have an intersection here, it should have a start that is the |
| 198 | // max of the two starts and an end that is the min of the two ends. |
| 199 | int64 s = std::max(start(d), other.start(d)); |
| 200 | int64 l = std::min(end(d), other.end(d)) - s; |
| 201 | if (l > 0) { |
| 202 | // We have a real intersection |
| 203 | if (result) { |
| 204 | result->set_start(d, s); |
| 205 | result->set_length(d, l); |
| 206 | } |
| 207 | } else { |
| 208 | // We don't have an intersection for this dimension -- thus we don't |
| 209 | // have any intersection at all. |
| 210 | if (result) { |
| 211 | result->Clear(); |
| 212 | } |
| 213 | return false; |
| 214 | } |
| 215 | } |
| 216 | } |
| 217 | // If we are here, we know there is overlap in every dimension. |
| 218 | return true; |
| 219 | } |
| 220 | |
| 221 | bool TensorSlice::operator==(const TensorSlice& other) const { |
| 222 | return dims() == other.dims() && starts_ == other.starts_ && |