Skip to content

Instantly share code, notes, and snippets.

@trueroad
Last active May 10, 2016 14:59
Show Gist options
  • Save trueroad/cb1034269556ba6c93c21cd5368d4a66 to your computer and use it in GitHub Desktop.
Save trueroad/cb1034269556ba6c93c21cd5368d4a66 to your computer and use it in GitHub Desktop.
n-th order tensor storage class
n-th order tensor storage class
CXX = g++
tensor_stor_sample: sample_main.cc tensor_stor.hh
$(CXX) -std=c++11 -o tensor_stor_sample sample_main.cc
clean:
-rm -fr *~
//
// Sample for
// `n-th order tensor storage class (C++ class)'
//
// Copyright (C) 2016 Masamichi Hosoda. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
//
#include "tensor_stor.hh"
#include <vector>
#include <exception>
#include <iostream>
int main()
{
TensorStorage<double> tensor_stor;
tensor_stor.resize ({2, 3, 4});
auto sz = tensor_stor.size ();
auto fa = tensor_stor.get_factor ();
std::cout << "size";
for ( auto x : sz)
{
std::cout << " " << x;
}
std::cout << std::endl;
std::cout << "factor";
for ( auto x : fa)
{
std::cout << " " << x;
}
std::cout << std::endl;
std::cout << "buffer size " << tensor_stor.get_buffer_size () << std::endl;
std::cout << "set values" << std::endl;
tensor_stor.at ({1, 1, 1}) = 0.111;
tensor_stor.at ({1, 2, 1}) = 0.121;
tensor_stor.at ({0, 2, 2}) = 0.022;
std::cout << "get values" << std::endl;
std::cout << tensor_stor.at ({1, 1, 1}) << " "
<< tensor_stor.at ({1, 2, 1}) << " "
<< tensor_stor.at ({0, 2, 2}) << std::endl;
const TensorStorage<double> ctensor_stor { tensor_stor };
std::cout << "get values (const)" << std::endl;
std::cout << ctensor_stor.at ({1, 1, 1}) << " "
<< ctensor_stor.at ({1, 2, 1}) << " "
<< ctensor_stor.at ({0, 2, 2}) << std::endl;
std::cout << "try invalid argument" << std::endl;
try
{
tensor_stor.at ({1, 1}) = 0.11;
}
catch (std::invalid_argument &ia)
{
std::cout << "Exception: invalid_argument: " << ia.what () << std::endl;
}
std::cout << "try out of range" << std::endl;
try
{
tensor_stor.at ({2, 2, 2}) = 0.222;
}
catch (std::out_of_range &oor)
{
std::cout << "Exception: out_of_range: " << oor.what () << std::endl;
}
std::cout << "complete" << std::endl;
return 0;
}
//
// n-th order tensor storage class
//
// Copyright (C) 2016 Masamichi Hosoda. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
//
#ifndef TENSOR_STOR_HH
#define TENSOR_STOR_HH
#include <vector>
#include <stdexcept>
#include <iostream>
// n-th order tensor storage class
template <typename T>
class TensorStorage
{
public:
T& at (const std::vector<int> &index);
const T& at (const std::vector<int> &index) const;
T& operator[] (const std::vector<int> &index);
const T& operator[] (const std::vector<int> &index) const;
resize (const std::vector<int> &n);
resize (const std::vector<int> &n, const T& val);
std::vector<int> size ()
{
return size_;
}
std::vector<int> get_factor ()
{
return factor_;
}
int get_buffer_size ()
{
return buffer_.size();
}
explicit TensorStorage (const std::vector<int> &n);
TensorStorage (const std::vector<int> &n, const T& val);
TensorStorage () = default;
virtual ~TensorStorage () = default;
TensorStorage (TensorStorage const&) = default;
TensorStorage& operator= (TensorStorage const&) = default;
TensorStorage (TensorStorage &&) = default;
TensorStorage& operator= (TensorStorage &&) = default;
protected:
std::vector<int> size_;
std::vector<int> factor_;
std::vector<T> buffer_;
private:
int set_size_and_factor(const std::vector<int> &n);
check_index (const std::vector<int> &index) const;
int calc_index (const std::vector<int> &index) const;
};
template <typename T>
int TensorStorage<T>::set_size_and_factor (const std::vector<int> &n)
{
size_ = n;
factor_.clear ();
factor_.reserve (n.size ());
int f = 1;
for (auto it = n.crbegin (); it != n.crend (); ++it)
{
factor_.insert (factor_.begin (), f);
f = f * *it;
}
return f;
}
template <typename T>
int TensorStorage<T>::check_index (const std::vector<int> &index) const
{
if (index.size () != factor_.size ())
throw std::invalid_argument ("index size is not equal to tensor order.");
auto index_it = index.cbegin ();
auto size_it = size_.cbegin ();
while (index_it != index.cend ())
{
if ((*index_it >= *size_it) || (*index_it < 0))
throw std::out_of_range ("Out of range (tensor).");
++index_it;
++size_it;
}
}
template <typename T>
int TensorStorage<T>::calc_index (const std::vector<int> &index) const
{
int n { 0 };
auto index_it = index.cbegin ();
auto factor_it = factor_.cbegin ();
while (index_it != index.cend ())
{
n += *index_it * *factor_it;
++index_it;
++factor_it;
}
std::cout << "debug: n = " << n << std::endl;
return n;
}
template <typename T>
T& TensorStorage<T>::at (const std::vector<int> &index)
{
check_index (index);
return buffer_.at (calc_index (index));
}
template <typename T>
const T& TensorStorage<T>::at (const std::vector<int> &index) const
{
check_index (index);
return buffer_.at (calc_index (index));
}
template <typename T>
TensorStorage<T>::resize (const std::vector<int> &n)
{
buffer_.resize (set_size_and_factor (n));
}
#endif // TENSOR_STOR_HH
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment