<commit_before>// Copyright (c) 2007, 2008 libmv authors.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.

#ifndef LIBMV_IMAGE_ARRAY_ND_H
#define LIBMV_IMAGE_ARRAY_ND_H

#include <cassert>

#include "libmv/image/tuple.h"

namespace libmv {

class BaseArray {
};

/// A multidimensional array class.
template <typename T, int N>
class ArrayND : public BaseArray {
 public:
  typedef T Scalar;

  /// Type for the multidimensional indices.
  typedef Tuple<int,N> Index;

  /// Create an empty array.
  ArrayND()
      : shape_(0), strides_(0), data_(NULL) {
    Resize(Index(0));
  }

  /// Create an array with the shape.
  ArrayND(const Index &shape)
      : shape_(0), strides_(0), data_(NULL) {
    Resize(shape);
  }

  /// Create an array with the shape.
  ArrayND(int *shape)
      : shape_(0), strides_(0), data_(NULL) {
    Resize(shape);
  }

  /// Copy constructor copies pixel data.
  ArrayND(const ArrayND<T, N> &b)
      : shape_(0), strides_(0), data_(NULL) {
    ResizeLike(b);
    std::memcpy(Data(), b.Data(), sizeof(T) * Size());
  }

  /// Crate a 1D array of lenght s0.
  ArrayND(int s0)
      : shape_(0), strides_(0), data_(NULL) {
    Resize(s0);
  }

  /// Crate a 2D array of shape (s0, s1).
  ArrayND(int s0, int s1)
      : shape_(0), strides_(0), data_(NULL) {
    Resize(s0, s1);
  }

  /// Crate a 3D array of shape (s0, s1, s2).
  ArrayND(int s0, int s1, int s2)
      : shape_(0), strides_(0), data_(NULL) {
    Resize(s0, s1, s2);
  }

  /// Destructor deletes pixel data.
  ~ArrayND() {
    delete [] data_;
  }

  /// Assignation copies pixel data.
  ArrayND &operator=(const ArrayND<T, N> &b) {
    ResizeLike(b);
    std::memcpy(Data(), b.Data(), sizeof(T) * Size());
    return *this;
  }

  const Index &Shapes() const {
    return shape_;
  }

  const Index &Strides() const {
    return strides_;
  }

  /// Create an array of shape s.
  void Resize(const Index &new_shape) {
    if (shape_ == new_shape) { 
      // Don't bother realloacting if the shapes match.
      return;
    }
    shape_.Reset(new_shape);
    strides_(N - 1) = 1;
    for (int i = N - 1; i > 0; --i) {
      strides_(i - 1) = strides_(i) * shape_(i);
    }
    delete [] data_;
    data_ = NULL;
    if (Size() > 0) {
      data_ = new T[Size()];
    }
  }

  template<typename D>
  void ResizeLike(const ArrayND<D,N> &other) {
    Resize(other.Shape());
  }

  /// Resizes the array to shape s.  All data is lost.
  void Resize(const int *new_shape_array) {
    Resize(Index(new_shape_array));
  }

  /// Resize a 1D array to length s0.
  void Resize(int s0) {
    assert(N == 1);
    int shape[] = {s0};
    Resize(shape);
  }

  /// Resize a 2D array to shape (s0,s1).
  void Resize(int s0, int s1) {
    assert(N == 2);
    int shape[] = {s0,s1};
    Resize(shape);
  }

  // Match Eigen2's API.
  void resize(int rows, int cols) {
    Resize(rows, cols);
  }

  /// Resize a 3D array to shape (s0,s1,s2).
  void Resize(int s0, int s1, int s2) {
    assert(N == 3);
    int shape[] = {s0,s1,s2};
    Resize(shape);
  }

  template<typename D>
  void CopyFrom(const ArrayND<D,N> &other) {
    ResizeLike(other);
    T *data = Data();
    const D *other_data = other.Data();<commit_msg>Pad extra dimensions with 1s when resizing Array3D's.<commit_after>// Copyright (c) 2007, 2008 libmv authors.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.

#ifndef LIBMV_IMAGE_ARRAY_ND_H
#define LIBMV_IMAGE_ARRAY_ND_H

#include <cassert>

#include "libmv/image/tuple.h"

namespace libmv {

class BaseArray {
};

/// A multidimensional array class.
template <typename T, int N>
class ArrayND : public BaseArray {
 public:
  typedef T Scalar;

  /// Type for the multidimensional indices.
  typedef Tuple<int,N> Index;

  /// Create an empty array.
  ArrayND()
      : shape_(0), strides_(0), data_(NULL) {
    Resize(Index(0));
  }

  /// Create an array with the shape.
  ArrayND(const Index &shape)
      : shape_(0), strides_(0), data_(NULL) {
    Resize(shape);
  }

  /// Create an array with the shape.
  ArrayND(int *shape)
      : shape_(0), strides_(0), data_(NULL) {
    Resize(shape);
  }

  /// Copy constructor copies pixel data.
  ArrayND(const ArrayND<T, N> &b)
      : shape_(0), strides_(0), data_(NULL) {
    ResizeLike(b);
    std::memcpy(Data(), b.Data(), sizeof(T) * Size());
  }

  /// Crate a 1D array of lenght s0.
  ArrayND(int s0)
      : shape_(0), strides_(0), data_(NULL) {
    Resize(s0);
  }

  /// Crate a 2D array of shape (s0, s1).
  ArrayND(int s0, int s1)
      : shape_(0), strides_(0), data_(NULL) {
    Resize(s0, s1);
  }

  /// Crate a 3D array of shape (s0, s1, s2).
  ArrayND(int s0, int s1, int s2)
      : shape_(0), strides_(0), data_(NULL) {
    Resize(s0, s1, s2);
  }

  /// Destructor deletes pixel data.
  ~ArrayND() {
    delete [] data_;
  }

  /// Assignation copies pixel data.
  ArrayND &operator=(const ArrayND<T, N> &b) {
    ResizeLike(b);
    std::memcpy(Data(), b.Data(), sizeof(T) * Size());
    return *this;
  }

  const Index &Shapes() const {
    return shape_;
  }

  const Index &Strides() const {
    return strides_;
  }

  /// Create an array of shape s.
  void Resize(const Index &new_shape) {
    if (shape_ == new_shape) { 
      // Don't bother realloacting if the shapes match.
      return;
    }
    shape_.Reset(new_shape);
    strides_(N - 1) = 1;
    for (int i = N - 1; i > 0; --i) {
      strides_(i - 1) = strides_(i) * shape_(i);
    }
    delete [] data_;
    data_ = NULL;
    if (Size() > 0) {
      data_ = new T[Size()];
    }
  }

  template<typename D>
  void ResizeLike(const ArrayND<D,N> &other) {
    Resize(other.Shape());
  }

  /// Resizes the array to shape s.  All data is lost.
  void Resize(const int *new_shape_array) {
    Resize(Index(new_shape_array));
  }

  /// Resize a 1D array to length s0.
  void Resize(int s0) {
    assert(N == 1);
    int shape[] = {s0};
    Resize(shape);
  }

  /// Resize a 2D array to shape (s0,s1).
  void Resize(int s0, int s1) {
    int shape[N] = {s0, s1};
    for (int i = 2; i < N; ++i) {
      shape[i] = 1;
    }
    Resize(shape);
  }

  // Match Eigen2's API.
  void resize(int rows, int cols) {
    Resize(rows, cols);
  }

  /// Resize a 3D array to shape (s0,s1,s2).
  void Resize(int s0, int s1, int s2) {
    assert(N == 3);
    int shape[] = {s0,s1,s2};
    Resize(shape);
  }

  template<typename D>
  void CopyFrom(const ArrayND<D,N> &other) {
    ResizeLike(other);
    T *data = Data();
    const D *other_data = other.Data();
{'fraction_non_alphanumeric': 0.13337236533957844, 'fraction_numerical': 0.01791569086651054, 'mean_word_length': 2.8421052631578947, 'pattern_counts': {'":': 0, '<': 22, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5186757', 'n_tokens_mistral': 3045, 'n_tokens_neox': 2875, 'n_words': 994}