<commit_before>/* Copyright 2015 The TensorFlow Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/

#include "tensorflow/core/kernels/save_restore_tensor.h"
#include <numeric>
#include <unordered_map>
#include <utility>
#include <vector>

#include "tensorflow/core/framework/op_kernel.h"
#include "tensorflow/core/framework/register_types.h"
#include "tensorflow/core/framework/types.h"
#include "tensorflow/core/kernels/bounds_check.h"
#include "tensorflow/core/lib/gtl/array_slice.h"
#include "tensorflow/core/lib/strings/strcat.h"
#include "tensorflow/core/lib/strings/stringprintf.h"
#include "tensorflow/core/platform/logging.h"
#include "tensorflow/core/platform/types.h"
#include "tensorflow/core/util/tensor_bundle/tensor_bundle.h"
#include "tensorflow/core/util/tensor_slice_reader.h"
#include "tensorflow/core/util/tensor_slice_reader_cache.h"
#include "tensorflow/core/util/tensor_slice_writer.h"

namespace tensorflow {

void SaveTensors(
    OpKernelContext* context,
    checkpoint::TensorSliceWriter::CreateBuilderFunction builder_func,
    bool save_slices) {
  const Tensor& filename_t = context->input(0);
  {
    const int64 size = filename_t.NumElements();
    OP_REQUIRES(
        context, size == 1,
        errors::InvalidArgument(
            "Input 0 (filename) must be a string scalar; got a tensor of ",
            size, "elements"));
  }

  // Path, names, and slices if save_slices is true.
  const int kFixedInputs = save_slices ? 3 : 2;
  const Tensor& tensor_names_t = context->input(1);
  OP_REQUIRES(context,
              FastBoundsCheck(tensor_names_t.NumElements() + kFixedInputs,
                              std::numeric_limits<int>::max()),
              errors::InvalidArgument("Too many inputs to SaveTensors"));
  const int N = static_cast<int>(tensor_names_t.NumElements());
  const string* tensor_shapes_and_slices_ptr = nullptr;
  if (save_slices) {
    const Tensor& tensor_shapes_and_slices_t = context->input(2);
    OP_REQUIRES(
        context,
        tensor_shapes_and_slices_t.NumElements() == static_cast<int64>(N),
        errors::InvalidArgument("Expected ", N,
                                " elements for the tensor "
                                "shapes and slices but got ",
                                tensor_shapes_and_slices_t.NumElements()));
    tensor_shapes_and_slices_ptr =
        tensor_shapes_and_slices_t.flat<string>().data();
  }
  OP_REQUIRES(context, context->num_inputs() == N + kFixedInputs,
              errors::InvalidArgument("Expected totally ", N + kFixedInputs,
                                      " inputs as input #1 (which is a string "
                                      "tensor of saved names) contains ",
                                      N, " names, but received ",
                                      context->num_inputs(), " inputs"));

  VLOG(1) << "About to save tensors to file " << filename_t.flat<string>()(0)
          << "...";
  checkpoint::TensorSliceWriter writer(filename_t.flat<string>()(0),
                                       std::move(builder_func));

  Status s;
  auto tensor_names_flat = tensor_names_t.flat<string>();

  // Process tensors in sorted name order.  This allows us to avoid seeking
  // during restoration in the common case where we are restoring a full
  // checkpoint.
  std::vector<size_t> sorted_name_idx(tensor_names_flat.size());
  std::iota(sorted_name_idx.begin(), sorted_name_idx.end(), 0);
  std::sort(sorted_name_idx.begin(), sorted_name_idx.end(),
            [&tensor_names_flat](size_t a, size_t b) {
              return tensor_names_flat(a) < tensor_names_flat(b);
            });

  for (size_t i : sorted_name_idx) {
    const string& name = tensor_names_flat(i);
    const Tensor& input = context->input(i + kFixedInputs);
    TensorShape shape(input.shape());
    TensorSlice slice(input.dims());
    if (save_slices && !tensor_shapes_and_slices_ptr[i].empty()) {
      const string& shape_spec = tensor_shapes_and_slices_ptr[i];
      TensorShape slice_shape;
      OP_REQUIRES_OK(context, checkpoint::ParseShapeAndSlice(
                                  shape_spec, &shape, &slice, &slice_shape));
      OP_REQUIRES(context, slice_shape.IsSameSize(input.shape()),
                  errors::InvalidArgument(
                      "Slice in shape_and_slice "
                      "specification does not match the "
                      "shape of the tensor to  save: ",
                      shape_spec, ", tensor: ", input.shape().DebugString()));
    }

#define WRITER_ADD(T)                                           \
  case DataTypeToEnum<T>::value:                                \
    s = writer.Add(name, shape, slice, input.flat<T>().data()); \
    break;

    switch (input.dtype()) {
      TF_CALL_SAVE_RESTORE_TYPES(WRITER_ADD)
      default:
        context->SetStatus(errors::Unimplemented("Saving data type ",
                                                 DataTypeString(input.dtype()),
                                                 " not yet supported"));
        return;
    }
#undef WRITER_ADD
    if (!s.ok()) {
      context->SetStatus(s);
      return;
    }
  }

  s = writer.Finish();
  if (!s.ok()) {
    context->SetStatus(s);
  }
}

void RestoreTensor(OpKernelContext* context,
                   checkpoint::TensorSliceReader::OpenTableFunction open_func,
                   int preferred_shard, bool restore_slice, int restore_index) {
  const Tensor& file_pattern_t = context->input(0);
  {
    const int64 size = file_pattern_t.NumElements();
    OP_REQUIRES(
        context, size == 1,
        errors::InvalidArgument(
            "Input 0 (file_pattern) must be a string scalar; got a tensor of ",
            size, "elements"));
  }
  const string& file_pattern = file_pattern_t.flat<string>()(0);

  const Tensor& tensor_name_t = context->input(1);
  const string& tensor_name = tensor_name_t.flat<string>()(restore_index);

  // If we cannot find a cached reader we will allocate our own.
  std::unique_ptr<checkpoint::TensorSliceReader> allocated_reader;

  const checkpoint::TensorSliceReader* reader =
      context->slice_reader_cache()->GetReader(file_pattern, open_func,
                                               preferred_shard);
  if (!reader) {
    allocated_reader.reset(new checkpoint::TensorSliceReader(
        file_pattern, open_func, preferred_shard));
    reader = allocated_reader.get();
  }
  OP_REQUIRES_OK(context, CHECK_NOTNULL(reader)->status());

  // Get the shape and type from the save file.
  DataType type;
  TensorShape saved_shape;
  OP_REQUIRES(
      context, reader->HasTensor(tensor_name, &saved_shape, &type),
      errors::NotFound("Tensor name \"", tensor_name,
                       "\" not found in checkpoint files ", file_pattern));
  OP_REQUIRES(
      context, type == context->expected_output_dtype(restore_index),
      errors::InvalidArgument("Expected to restore a tensor of type ",
                              DataTypeString(context->expected_output_dtype(0)),
                              ", got a tensor of type ", DataTypeString(type),
                              " instead: tensor_name = ", tensor_name));

  // Shape of the output and slice to load.
  TensorShape output_shape(saved_shape);
  TensorSlice slice_to_load(saved_shape.dims());
  if (restore_slice) {
    const string& shape_spec = context->input(2).flat<string>()(restore_index);
    if (!shape_spec.empty()) {
      TensorShape parsed_shape;
      OP_REQUIRES_OK(context, checkpoint::ParseShapeAndSlice(
                                  shape_spec, &parsed_shape, &slice_to_load,
                                  &output_shape));
      OP_REQUIRES(
          context, parsed_shape.IsSameSize(saved_shape),
          errors::InvalidArgument(
              "Shape in shape_and_slice spec does not match the shape in the "
              "save file: ",
              parsed_shape.DebugString(),
              ", save file shape: ", saved_shape.DebugString()));
    }
  }

  Tensor* t = nullptr;
  OP_REQUIRES_OK(context,
                 context->allocate_output(restore_index, output_shape, &t));

  if (output_shape.num_elements() == 0) return;

#define READER_COPY(T)                                                \
  case DataTypeToEnum<T>::value:                                      \
    OP_REQUIRES(context,                                              \
                reader->CopySliceData(tensor_name, slice_to_load,     \
                                      t->flat<T>().data()),           \
                errors::InvalidArgument("Error copying slice data")); \
    break;

  switch (type) {
    TF_CALL_SAVE_RESTORE_TYPES(READER_COPY)
    default:
      context->SetStatus(errors::Unimplemented(
          "Restoring data type ", DataTypeString(type), " not yet supported"));
  }
#undef READER_COPY
}

Status RestoreTensorsV2(OpKernelContext* context, const Tensor& prefix,
                        const Tensor& tensor_names,
                        const Tensor& shape_and_slices,
                        gtl::ArraySlice<DataType> dtypes) {
  const string& prefix_string = prefix.scalar<string>()();

  const auto& tensor_names_flat = tensor_names.flat<string>();
  const auto& shape_and_slices_flat = shape_and_slices.flat<string>();

  // Sort lookup keys to improve locality when reading multiple tensors.
  std::vector<size_t> sorted_name_idx(tensor_names_flat.size());
  std::iota(sorted_name_idx.begin(), sorted_name_idx.end(), 0);
  std::sort(sorted_name_idx.begin(), sorted_name_idx.end(),
            [&tensor_names_flat](size_t a, size_t b) {
              return tensor_names_flat(a) < tensor_names_flat(b);
            });

  BundleReader reader(Env::Default(), prefix_string);
  TF_RETURN_IF_ERROR(reader.status());

  // TODO(zongheng): potential optimization: one Seek() in first lookup.
  // TODO(zongheng): consider measuring speed and issuing concurrent lookups
  // within a fixed memory budget.
  TensorShape restored_full_shape;
  std::vector<string> mismatched_errors;
  for (auto i : sorted_name_idx) {
    DataType original_dtype;
    const string& tensor_name = tensor_names_flat(i);
    TF_RETURN_IF_ERROR(
        reader.LookupDtypeAndShape(tensor_name,
                                   &original_dtype, &restored_full_shape));
    if (dtypes[i] != original_dtype) {
      string error_msg = strings::StrCat(
          "tensor_name = ", tensor_name,
          "; expected dtype ", DataTypeString(dtypes[i]),
          " does not equal original dtype ", DataTypeString(original_dtype));
      mismatched_errors.emplace_back(error_msg);
    }
  }
  if (!mismatched_errors.empty()) {
    string error_msg = std::accumulate(mismatched_errors.begin(),
                                       mismatched_errors.end(),
                                       string());
    return errors::InvalidArgument(error_msg);
  }

  Tensor* restored_tensor = nullptr;
  for (auto i : sorted_name_idx) {
    const string& tensor_name = tensor_names_flat(i);
    const string& shape_and_slice = shape_and_slices_flat(i);

    TF_RETURN_IF_ERROR(
        reader.LookupTensorShape(tensor_name, &restored_full_shape));

    if (shape_and_slice.empty()) {
      // Lookup the full tensor.
      TF_RETURN_IF_ERROR(
          context->allocate_output(i, restored_full_shape, &restored_tensor));
      TF_RETURN_IF_ERROR(reader.Lookup(tensor_name, restored_tensor));
    } else {
      // Lookup the slice.
      TensorShape parsed_full_shape;
      TensorSlice parsed_slice;
      TensorShape parsed_slice_shape;

      TF_RETURN_IF_ERROR(
          checkpoint::ParseShapeAndSlice(shape_and_slice, &parsed_full_shape,
                                         &parsed_slice, &parsed_slice_shape));
      if (!restored_full_shape.IsSameSize(parsed_full_shape)) {
        return errors::InvalidArgument(
            "tensor_name = ", tensor_name, "; shape in shape_and_slice spec ",
            parsed_full_shape.DebugString(),
            " does not match the shape stored in checkpoint: ",
            restored_full_shape.DebugString());
      }

      TF_RETURN_IF_ERROR(
          context->allocate_output(i, parsed_slice_shape, &restored_tensor));
      TF_RETURN_IF_ERROR(
          reader.LookupSlice(tensor_name, parsed_slice, restored_tensor));
    }
    if (dtypes[i] != restored_tensor->dtype()) {
      return errors::InvalidArgument(
          "tensor_name = ", tensor_name, "; expected dtype ",
          DataTypeString(dtypes[i]), " does not equal restored dtype ",
          DataTypeString(restored_tensor->dtype()));
    }
  }
  return Status::OK();
}

}  // namespace tensorflow
<commit_msg>CLN: use str_util::Join<commit_after>/* Copyright 2015 The TensorFlow Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/

#include "tensorflow/core/kernels/save_restore_tensor.h"
#include <numeric>
#include <unordered_map>
#include <utility>
#include <vector>

#include "tensorflow/core/framework/op_kernel.h"
#include "tensorflow/core/framework/register_types.h"
#include "tensorflow/core/framework/types.h"
#include "tensorflow/core/kernels/bounds_check.h"
#include "tensorflow/core/lib/gtl/array_slice.h"
#include "tensorflow/core/lib/strings/str_util.h"
#include "tensorflow/core/lib/strings/strcat.h"
#include "tensorflow/core/lib/strings/stringprintf.h"
#include "tensorflow/core/platform/logging.h"
#include "tensorflow/core/platform/types.h"
#include "tensorflow/core/util/tensor_bundle/tensor_bundle.h"
#include "tensorflow/core/util/tensor_slice_reader.h"
#include "tensorflow/core/util/tensor_slice_reader_cache.h"
#include "tensorflow/core/util/tensor_slice_writer.h"

namespace tensorflow {

void SaveTensors(
    OpKernelContext* context,
    checkpoint::TensorSliceWriter::CreateBuilderFunction builder_func,
    bool save_slices) {
  const Tensor& filename_t = context->input(0);
  {
    const int64 size = filename_t.NumElements();
    OP_REQUIRES(
        context, size == 1,
        errors::InvalidArgument(
            "Input 0 (filename) must be a string scalar; got a tensor of ",
            size, "elements"));
  }

  // Path, names, and slices if save_slices is true.
  const int kFixedInputs = save_slices ? 3 : 2;
  const Tensor& tensor_names_t = context->input(1);
  OP_REQUIRES(context,
              FastBoundsCheck(tensor_names_t.NumElements() + kFixedInputs,
                              std::numeric_limits<int>::max()),
              errors::InvalidArgument("Too many inputs to SaveTensors"));
  const int N = static_cast<int>(tensor_names_t.NumElements());
  const string* tensor_shapes_and_slices_ptr = nullptr;
  if (save_slices) {
    const Tensor& tensor_shapes_and_slices_t = context->input(2);
    OP_REQUIRES(
        context,
        tensor_shapes_and_slices_t.NumElements() == static_cast<int64>(N),
        errors::InvalidArgument("Expected ", N,
                                " elements for the tensor "
                                "shapes and slices but got ",
                                tensor_shapes_and_slices_t.NumElements()));
    tensor_shapes_and_slices_ptr =
        tensor_shapes_and_slices_t.flat<string>().data();
  }
  OP_REQUIRES(context, context->num_inputs() == N + kFixedInputs,
              errors::InvalidArgument("Expected totally ", N + kFixedInputs,
                                      " inputs as input #1 (which is a string "
                                      "tensor of saved names) contains ",
                                      N, " names, but received ",
                                      context->num_inputs(), " inputs"));

  VLOG(1) << "About to save tensors to file " << filename_t.flat<string>()(0)
          << "...";
  checkpoint::TensorSliceWriter writer(filename_t.flat<string>()(0),
                                       std::move(builder_func));

  Status s;
  auto tensor_names_flat = tensor_names_t.flat<string>();

  // Process tensors in sorted name order.  This allows us to avoid seeking
  // during restoration in the common case where we are restoring a full
  // checkpoint.
  std::vector<size_t> sorted_name_idx(tensor_names_flat.size());
  std::iota(sorted_name_idx.begin(), sorted_name_idx.end(), 0);
  std::sort(sorted_name_idx.begin(), sorted_name_idx.end(),
            [&tensor_names_flat](size_t a, size_t b) {
              return tensor_names_flat(a) < tensor_names_flat(b);
            });

  for (size_t i : sorted_name_idx) {
    const string& name = tensor_names_flat(i);
    const Tensor& input = context->input(i + kFixedInputs);
    TensorShape shape(input.shape());
    TensorSlice slice(input.dims());
    if (save_slices && !tensor_shapes_and_slices_ptr[i].empty()) {
      const string& shape_spec = tensor_shapes_and_slices_ptr[i];
      TensorShape slice_shape;
      OP_REQUIRES_OK(context, checkpoint::ParseShapeAndSlice(
                                  shape_spec, &shape, &slice, &slice_shape));
      OP_REQUIRES(context, slice_shape.IsSameSize(input.shape()),
                  errors::InvalidArgument(
                      "Slice in shape_and_slice "
                      "specification does not match the "
                      "shape of the tensor to  save: ",
                      shape_spec, ", tensor: ", input.shape().DebugString()));
    }

#define WRITER_ADD(T)                                           \
  case DataTypeToEnum<T>::value:                                \
    s = writer.Add(name, shape, slice, input.flat<T>().data()); \
    break;

    switch (input.dtype()) {
      TF_CALL_SAVE_RESTORE_TYPES(WRITER_ADD)
      default:
        context->SetStatus(errors::Unimplemented("Saving data type ",
                                                 DataTypeString(input.dtype()),
                                                 " not yet supported"));
        return;
    }
#undef WRITER_ADD
    if (!s.ok()) {
      context->SetStatus(s);
      return;
    }
  }

  s = writer.Finish();
  if (!s.ok()) {
    context->SetStatus(s);
  }
}

void RestoreTensor(OpKernelContext* context,
                   checkpoint::TensorSliceReader::OpenTableFunction open_func,
                   int preferred_shard, bool restore_slice, int restore_index) {
  const Tensor& file_pattern_t = context->input(0);
  {
    const int64 size = file_pattern_t.NumElements();
    OP_REQUIRES(
        context, size == 1,
        errors::InvalidArgument(
            "Input 0 (file_pattern) must be a string scalar; got a tensor of ",
            size, "elements"));
  }
  const string& file_pattern = file_pattern_t.flat<string>()(0);

  const Tensor& tensor_name_t = context->input(1);
  const string& tensor_name = tensor_name_t.flat<string>()(restore_index);

  // If we cannot find a cached reader we will allocate our own.
  std::unique_ptr<checkpoint::TensorSliceReader> allocated_reader;

  const checkpoint::TensorSliceReader* reader =
      context->slice_reader_cache()->GetReader(file_pattern, open_func,
                                               preferred_shard);
  if (!reader) {
    allocated_reader.reset(new checkpoint::TensorSliceReader(
        file_pattern, open_func, preferred_shard));
    reader = allocated_reader.get();
  }
  OP_REQUIRES_OK(context, CHECK_NOTNULL(reader)->status());

  // Get the shape and type from the save file.
  DataType type;
  TensorShape saved_shape;
  OP_REQUIRES(
      context, reader->HasTensor(tensor_name, &saved_shape, &type),
      errors::NotFound("Tensor name \"", tensor_name,
                       "\" not found in checkpoint files ", file_pattern));
  OP_REQUIRES(
      context, type == context->expected_output_dtype(restore_index),
      errors::InvalidArgument("Expected to restore a tensor of type ",
                              DataTypeString(context->expected_output_dtype(0)),
                              ", got a tensor of type ", DataTypeString(type),
                              " instead: tensor_name = ", tensor_name));

  // Shape of the output and slice to load.
  TensorShape output_shape(saved_shape);
  TensorSlice slice_to_load(saved_shape.dims());
  if (restore_slice) {
    const string& shape_spec = context->input(2).flat<string>()(restore_index);
    if (!shape_spec.empty()) {
      TensorShape parsed_shape;
      OP_REQUIRES_OK(context, checkpoint::ParseShapeAndSlice(
                                  shape_spec, &parsed_shape, &slice_to_load,
                                  &output_shape));
      OP_REQUIRES(
          context, parsed_shape.IsSameSize(saved_shape),
          errors::InvalidArgument(
              "Shape in shape_and_slice spec does not match the shape in the "
              "save file: ",
              parsed_shape.DebugString(),
              ", save file shape: ", saved_shape.DebugString()));
    }
  }

  Tensor* t = nullptr;
  OP_REQUIRES_OK(context,
                 context->allocate_output(restore_index, output_shape, &t));

  if (output_shape.num_elements() == 0) return;

#define READER_COPY(T)                                                \
  case DataTypeToEnum<T>::value:                                      \
    OP_REQUIRES(context,                                              \
                reader->CopySliceData(tensor_name, slice_to_load,     \
                                      t->flat<T>().data()),           \
                errors::InvalidArgument("Error copying slice data")); \
    break;

  switch (type) {
    TF_CALL_SAVE_RESTORE_TYPES(READER_COPY)
    default:
      context->SetStatus(errors::Unimplemented(
          "Restoring data type ", DataTypeString(type), " not yet supported"));
  }
#undef READER_COPY
}

Status RestoreTensorsV2(OpKernelContext* context, const Tensor& prefix,
                        const Tensor& tensor_names,
                        const Tensor& shape_and_slices,
                        gtl::ArraySlice<DataType> dtypes) {
  const string& prefix_string = prefix.scalar<string>()();

  const auto& tensor_names_flat = tensor_names.flat<string>();
  const auto& shape_and_slices_flat = shape_and_slices.flat<string>();

  // Sort lookup keys to improve locality when reading multiple tensors.
  std::vector<size_t> sorted_name_idx(tensor_names_flat.size());
  std::iota(sorted_name_idx.begin(), sorted_name_idx.end(), 0);
  std::sort(sorted_name_idx.begin(), sorted_name_idx.end(),
            [&tensor_names_flat](size_t a, size_t b) {
              return tensor_names_flat(a) < tensor_names_flat(b);
            });

  BundleReader reader(Env::Default(), prefix_string);
  TF_RETURN_IF_ERROR(reader.status());

  // TODO(zongheng): potential optimization: one Seek() in first lookup.
  // TODO(zongheng): consider measuring speed and issuing concurrent lookups
  // within a fixed memory budget.
  TensorShape restored_full_shape;
  std::vector<string> mismatched_errors;
  for (auto i : sorted_name_idx) {
    DataType original_dtype;
    const string& tensor_name = tensor_names_flat(i);
    TF_RETURN_IF_ERROR(
        reader.LookupDtypeAndShape(tensor_name,
                                   &original_dtype, &restored_full_shape));
    if (dtypes[i] != original_dtype) {
      string error_msg = strings::StrCat(
          "tensor_name = ", tensor_name,
          "; expected dtype ", DataTypeString(dtypes[i]),
          " does not equal original dtype ", DataTypeString(original_dtype));
      mismatched_errors.emplace_back(error_msg);
    }
  }
  if (!mismatched_errors.empty()) {
    const string error_msg = str_util::Join(mismatched_errors, "\n");
    return errors::InvalidArgument(error_msg);
  }

  Tensor* restored_tensor = nullptr;
  for (auto i : sorted_name_idx) {
    const string& tensor_name = tensor_names_flat(i);
    const string& shape_and_slice = shape_and_slices_flat(i);

    TF_RETURN_IF_ERROR(
        reader.LookupTensorShape(tensor_name, &restored_full_shape));

    if (shape_and_slice.empty()) {
      // Lookup the full tensor.
      TF_RETURN_IF_ERROR(
          context->allocate_output(i, restored_full_shape, &restored_tensor));
      TF_RETURN_IF_ERROR(reader.Lookup(tensor_name, restored_tensor));
    } else {
      // Lookup the slice.
      TensorShape parsed_full_shape;
      TensorSlice parsed_slice;
      TensorShape parsed_slice_shape;

      TF_RETURN_IF_ERROR(
          checkpoint::ParseShapeAndSlice(shape_and_slice, &parsed_full_shape,
                                         &parsed_slice, &parsed_slice_shape));
      if (!restored_full_shape.IsSameSize(parsed_full_shape)) {
        return errors::InvalidArgument(
            "tensor_name = ", tensor_name, "; shape in shape_and_slice spec ",
            parsed_full_shape.DebugString(),
            " does not match the shape stored in checkpoint: ",
            restored_full_shape.DebugString());
      }

      TF_RETURN_IF_ERROR(
          context->allocate_output(i, parsed_slice_shape, &restored_tensor));
      TF_RETURN_IF_ERROR(
          reader.LookupSlice(tensor_name, parsed_slice, restored_tensor));
    }
    if (dtypes[i] != restored_tensor->dtype()) {
      return errors::InvalidArgument(
          "tensor_name = ", tensor_name, "; expected dtype ",
          DataTypeString(dtypes[i]), " does not equal restored dtype ",
          DataTypeString(restored_tensor->dtype()));
    }
  }
  return Status::OK();
}

}  // namespace tensorflow
<|endoftext|>


<commit_before>/*-----------------------------------------------------------------------------------------------
The MIT License (MIT)

Copyright (c) 2015-2017 OSRE ( Open Source Render Engine ) by Kim Kulling

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.
-----------------------------------------------------------------------------------------------*/
#include "AbstractRenderTest.h"
#include "RenderTestUtils.h"

#include <osre/Common/Logger.h>
#include <osre/RenderBackend/RenderBackendService.h>
#include <osre/RenderBackend/RenderCommon.h>
#include <src/Engine/RenderBackend/OGLRenderer/OGLShader.h>
#include <osre/Scene/GeometryBuilder.h>

#include <GL/gl.h>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>

#ifdef OSRE_WINDOWS
#   include "GL/wglew.h"
#endif

namespace OSRE {
namespace RenderTest {

using namespace ::OSRE::RenderBackend;

const String VsSrc =
    "#version 400 core\n"
    "\n"
    "layout(location = 0) in vec3 position;	     // object space vertex position\n"
    "layout(location = 1) in vec3 normal;	     // object space vertex normal\n"
    "layout(location = 2) in vec3 color0;        // per-vertex colour\n"
    "\n"
    "// output from the vertex shader\n"
    "smooth out vec4 vSmoothColor;		//smooth colour to fragment shader\n"
    "\n"
    "// uniform\n"
    "uniform mat4 M[25];	// model matrix per instance\n"
    "uniform mat4 VP;	    // combined modelview projection matrix\n"
    "\n"
    "void main() {\n"
    "    //assign the per-vertex color to vSmoothColor varying\n"
    "    vSmoothColor = vec4(color0,1);\n"
    "\n"
    "    //get the clip space position by multiplying the combined MVP matrix with the object space\n"
    "    //vertex position\n"
    "    gl_Position = VP*M[ gl_InstanceID ]*vec4(position,1);\n"
    "}\n";

const String FsSrc =
    "#version 400 core\n"
    "\n"
    "layout(location=0) out vec4 vFragColor; //fragment shader output\n"
    "\n"
    "//input form the vertex shader\n"
    "smooth in vec4 vSmoothColor;		//interpolated colour to fragment shader\n"
    "\n"
    "void main() {\n"
    "    //set the interpolated color as the shader output\n"
    "    vFragColor = vSmoothColor;\n"
    "}\n";

//-------------------------------------------------------------------------------------------------
///	@ingroup	Test
///
///	@brief
//-------------------------------------------------------------------------------------------------
class GeoInstanceRenderTest : public AbstractRenderTest {
    static const ui32    NumInstances = 25;
    f32 m_angle;
    glm::mat4            m_mat[ NumInstances ];
    TransformMatrixBlock m_transformMatrix;

public:
    GeoInstanceRenderTest()
    : AbstractRenderTest( "rendertest/geoinstancerendertest" )
    , m_angle( 0.02f )
    , m_transformMatrix() {
        // empty
    }

    virtual ~GeoInstanceRenderTest() {
        // empty
    }

    virtual bool onCreate( RenderBackendService *rbSrv ) {
        rbSrv->sendEvent( &OnAttachViewEvent, nullptr );

        Scene::GeometryBuilder myBuilder;
        Geometry *geo = myBuilder.allocTriangles( VertexType::ColorVertex, BufferAccessType::ReadOnly );
        rbSrv->attachGeo( geo, NumInstances );

        // use a default material
        geo->m_material = AbstractRenderTest::createMaterial( VsSrc, FsSrc );
        if( nullptr != geo->m_material->m_pShader ) {
            geo->m_material->m_pShader->m_attributes.add( "position" );
            geo->m_material->m_pShader->m_attributes.add( "normal" );
            geo->m_material->m_pShader->m_attributes.add( "color0" );

            geo->m_material->m_pShader->m_parameters.add( "VP" );
            geo->m_material->m_pShader->m_parameters.add( "M" );
        }

        m_transformMatrix.m_model = glm::rotate( m_transformMatrix.m_model, 0.0f, glm::vec3( 1, 1, 0 ) );
        m_transformMatrix.update();

        glm::mat4 mat[NumInstances];
        glm::mat4 scale = glm::scale( glm::mat4( 1.0f ), glm::vec3( 0.1f ) );
		auto idx( 0 );
		auto x( -2.0f ), y( -2.0f );
		for (auto i = 0; i < 5; i++) {
			x = -2.0f;
			for ( auto j = 0; j < 5; j++ ) {
				mat[ idx ] = glm::translate( scale, glm::vec3( x, y, 0.f ) );
				x += 2.0f;
				++idx;
			}
			y += 2.0f;
		}

        rbSrv->setMatrix( "VP", m_transformMatrix.m_mvp );
        rbSrv->setMatrixArray( "M", NumInstances, mat );

        return true;
    }

    virtual bool onRender( d32 timediff, RenderBackendService *rbSrv ) {
        for ( auto i = 0; i < 25; i++ ) {
            glm::mat4 rot;
            m_mat[ i ] = glm::rotate( m_mat[ i ], m_angle, glm::vec3( 1, 1, 0 ) );
        }

        rbSrv->setMatrix( "VP", m_transformMatrix.m_mvp );
        rbSrv->setMatrixArray( "M", NumInstances, m_mat );

        return true;
    }
};

ATTACH_RENDERTEST( GeoInstanceRenderTest )

} // Namespace RenderTest
} // Namespace OSRE
<commit_msg>RenderTest: fix usage of moel matrix to rotate all instances correctly.<commit_after>/*-----------------------------------------------------------------------------------------------
The MIT License (MIT)

Copyright (c) 2015-2017 OSRE ( Open Source Render Engine ) by Kim Kulling

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.
-----------------------------------------------------------------------------------------------*/
#include "AbstractRenderTest.h"
#include "RenderTestUtils.h"

#include <osre/Common/Logger.h>
#include <osre/RenderBackend/RenderBackendService.h>
#include <osre/RenderBackend/RenderCommon.h>
#include <src/Engine/RenderBackend/OGLRenderer/OGLShader.h>
#include <osre/Scene/GeometryBuilder.h>

#include <GL/gl.h>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>

#ifdef OSRE_WINDOWS
#   include "GL/wglew.h"
#endif

namespace OSRE {
namespace RenderTest {

using namespace ::OSRE::RenderBackend;

const String VsSrc =
    "#version 400 core\n"
    "\n"
    "layout(location = 0) in vec3 position;	     // object space vertex position\n"
    "layout(location = 1) in vec3 normal;	     // object space vertex normal\n"
    "layout(location = 2) in vec3 color0;        // per-vertex colour\n"
    "\n"
    "// output from the vertex shader\n"
    "smooth out vec4 vSmoothColor;		//smooth colour to fragment shader\n"
    "\n"
    "// uniform\n"
    "uniform mat4 M[25];	// model matrix per instance\n"
    "uniform mat4 VP;	    // combined modelview projection matrix\n"
    "\n"
    "void main() {\n"
    "    //assign the per-vertex color to vSmoothColor varying\n"
    "    vSmoothColor = vec4(color0,1);\n"
    "\n"
    "    //get the clip space position by multiplying the combined MVP matrix with the object space\n"
    "    //vertex position\n"
    "    gl_Position = VP*M[ gl_InstanceID ]*vec4(position,1);\n"
    "}\n";

const String FsSrc =
    "#version 400 core\n"
    "\n"
    "layout(location=0) out vec4 vFragColor; //fragment shader output\n"
    "\n"
    "//input form the vertex shader\n"
    "smooth in vec4 vSmoothColor;		//interpolated colour to fragment shader\n"
    "\n"
    "void main() {\n"
    "    //set the interpolated color as the shader output\n"
    "    vFragColor = vSmoothColor;\n"
    "}\n";

//-------------------------------------------------------------------------------------------------
///	@ingroup	Test
///
///	@brief
//-------------------------------------------------------------------------------------------------
class GeoInstanceRenderTest : public AbstractRenderTest {
    static const ui32    NumInstances = 25;
    f32 m_angle;
    glm::mat4            m_mat[ NumInstances ];
    TransformMatrixBlock m_transformMatrix;

public:
    GeoInstanceRenderTest()
    : AbstractRenderTest( "rendertest/geoinstancerendertest" )
    , m_angle( 0.02f )
    , m_transformMatrix() {
        // empty
    }

    virtual ~GeoInstanceRenderTest() {
        // empty
    }

    bool onCreate( RenderBackendService *rbSrv ) override {
        rbSrv->sendEvent( &OnAttachViewEvent, nullptr );

        Scene::GeometryBuilder myBuilder;
        Geometry *geo = myBuilder.allocTriangles( VertexType::ColorVertex, BufferAccessType::ReadOnly );
        rbSrv->attachGeo( geo, NumInstances );

        // use a default material
        geo->m_material = AbstractRenderTest::createMaterial( VsSrc, FsSrc );
        if( nullptr != geo->m_material->m_pShader ) {
            geo->m_material->m_pShader->m_attributes.add( "position" );
            geo->m_material->m_pShader->m_attributes.add( "normal" );
            geo->m_material->m_pShader->m_attributes.add( "color0" );

            geo->m_material->m_pShader->m_parameters.add( "VP" );
            geo->m_material->m_pShader->m_parameters.add( "M" );
        }

        m_transformMatrix.m_model = glm::rotate( m_transformMatrix.m_model, 0.0f, glm::vec3( 1, 1, 0 ) );
        m_transformMatrix.update();

        glm::mat4 scale = glm::scale( glm::mat4( 1.0f ), glm::vec3( 0.1f ) );
		auto idx( 0 );
		auto x( -2.0f ), y( -2.0f );
		for (auto i = 0; i < 5; i++) {
			x = -2.0f;
			for ( auto j = 0; j < 5; j++ ) {
                m_mat[ idx ] = glm::translate( scale, glm::vec3( x, y, 0.f ) );
				x += 2.0f;
				++idx;
			}
			y += 2.0f;
		}

        rbSrv->setMatrix( "VP", m_transformMatrix.m_mvp );
        rbSrv->setMatrixArray( "M", NumInstances, m_mat);

        return true;
    }

    bool onRender( d32 timediff, RenderBackendService *rbSrv ) override {
        glm::mat4 rot( 1.0 );
        rot = glm::rotate( rot, m_angle, glm::vec3( 1, 1, 0 ) );
        for ( auto i = 0; i < NumInstances; i++ ) {
            m_mat[ i ] = m_mat[ i ] * rot;
        }

        rbSrv->setMatrix( "VP", m_transformMatrix.m_mvp );
        rbSrv->setMatrixArray( "M", NumInstances, m_mat );

        return true;
    }
};

ATTACH_RENDERTEST( GeoInstanceRenderTest )

} // Namespace RenderTest
} // Namespace OSRE
<|endoftext|>


<commit_before>/* The goal of these tests is to verify the behavior of all blob commands given
 * the current state is updateStarted.  This state is achieved as an exit from
 * updatePending.
 */
#include "firmware_handler.hpp"
#include "firmware_unittest.hpp"
#include "status.hpp"
#include "util.hpp"

#include <cstdint>
#include <string>
#include <vector>

#include <gtest/gtest.h>

namespace ipmi_flash
{
namespace
{

using ::testing::Return;
using ::testing::UnorderedElementsAreArray;

/*
 * There are the following calls (parameters may vary):
 * canHandleBlob(blob)
 * getBlobIds
 * deleteBlob(blob)
 * stat(blob)
 * stat(session)
 * open(blob)
 * close(session)
 * writemeta(session)
 * write(session)
 * read(session)
 * commit(session)
 */

class FirmwareHandlerUpdateStartedTest : public IpmiOnlyFirmwareStaticTest
{
};

/*
 * open(blob)
 */
TEST_F(FirmwareHandlerUpdateStartedTest, AttemptToOpenFilesReturnsFailure)
{
    /* In state updateStarted a file is open, which means no others can be. */
    getToUpdateStarted();

    auto blobsToOpen = handler->getBlobIds();
    for (const auto& blob : blobsToOpen)
    {
        EXPECT_FALSE(handler->open(session + 1, flags, blob));
    }
}

/* canHandleBlob(blob)
 * getBlobIds
 */
TEST_F(FirmwareHandlerUpdateStartedTest, VerifyListOfBlobs)
{
    getToUpdateStarted();

    std::vector<std::string> expected = {updateBlobId, hashBlobId,
                                         activeImageBlobId, staticLayoutBlobId};
    EXPECT_THAT(handler->getBlobIds(), UnorderedElementsAreArray(expected));
}

/*
 * TODO: deleteBlob(blob)
 */

/*
 * stat(blob)
 */
TEST_F(FirmwareHandlerUpdateStartedTest, StatOnActiveImageReturnsFailure)
{
    getToUpdateStarted();

    ASSERT_TRUE(handler->canHandleBlob(activeImageBlobId));

    blobs::BlobMeta meta;
    EXPECT_FALSE(handler->stat(activeImageBlobId, &meta));
}

TEST_F(FirmwareHandlerUpdateStartedTest, StatOnUpdateBlobReturnsFailure)
{
    getToUpdateStarted();

    ASSERT_TRUE(handler->canHandleBlob(updateBlobId));

    blobs::BlobMeta meta;
    EXPECT_FALSE(handler->stat(updateBlobId, &meta));
}

TEST_F(FirmwareHandlerUpdateStartedTest, StatOnNormalBlobsReturnsSuccess)
{
    getToUpdateStarted();

    blobs::BlobMeta expected;
    expected.blobState = FirmwareBlobHandler::UpdateFlags::ipmi;
    expected.size = 0;

    std::vector<std::string> testBlobs = {staticLayoutBlobId, hashBlobId};
    for (const auto& blob : testBlobs)
    {
        ASSERT_TRUE(handler->canHandleBlob(blob));

        blobs::BlobMeta meta = {};
        EXPECT_TRUE(handler->stat(blob, &meta));
        EXPECT_EQ(expected, meta);
    }
}

/*
 * writemeta(session)
 */
TEST_F(FirmwareHandlerUpdateStartedTest, WriteMetaToUpdateBlobReturnsFailure)
{
    getToUpdateStarted();
    EXPECT_FALSE(handler->writeMeta(session, 0, {0x01}));
}

/*
 * write(session)
 */
TEST_F(FirmwareHandlerUpdateStartedTest, WriteToUpdateBlobReturnsFailure)
{
    getToUpdateStarted();
    EXPECT_FALSE(handler->write(session, 0, {0x01}));
}

/*
 * read(session)
 */

/*
 * stat(session) - this will trigger a check, and the state may change.
 */

/*
 * TODO: close(session) - this will abort.
 */

/*
 * commit(session)
 */

} // namespace
} // namespace ipmi_flash
<commit_msg>test: firmware updateStarted: read(session)<commit_after>/* The goal of these tests is to verify the behavior of all blob commands given
 * the current state is updateStarted.  This state is achieved as an exit from
 * updatePending.
 */
#include "firmware_handler.hpp"
#include "firmware_unittest.hpp"
#include "status.hpp"
#include "util.hpp"

#include <cstdint>
#include <string>
#include <vector>

#include <gtest/gtest.h>

namespace ipmi_flash
{
namespace
{

using ::testing::IsEmpty;
using ::testing::Return;
using ::testing::UnorderedElementsAreArray;

/*
 * There are the following calls (parameters may vary):
 * canHandleBlob(blob)
 * getBlobIds
 * deleteBlob(blob)
 * stat(blob)
 * stat(session)
 * open(blob)
 * close(session)
 * writemeta(session)
 * write(session)
 * read(session)
 * commit(session)
 */

class FirmwareHandlerUpdateStartedTest : public IpmiOnlyFirmwareStaticTest
{
};

/*
 * open(blob)
 */
TEST_F(FirmwareHandlerUpdateStartedTest, AttemptToOpenFilesReturnsFailure)
{
    /* In state updateStarted a file is open, which means no others can be. */
    getToUpdateStarted();

    auto blobsToOpen = handler->getBlobIds();
    for (const auto& blob : blobsToOpen)
    {
        EXPECT_FALSE(handler->open(session + 1, flags, blob));
    }
}

/* canHandleBlob(blob)
 * getBlobIds
 */
TEST_F(FirmwareHandlerUpdateStartedTest, VerifyListOfBlobs)
{
    getToUpdateStarted();

    std::vector<std::string> expected = {updateBlobId, hashBlobId,
                                         activeImageBlobId, staticLayoutBlobId};
    EXPECT_THAT(handler->getBlobIds(), UnorderedElementsAreArray(expected));
}

/*
 * TODO: deleteBlob(blob)
 */

/*
 * stat(blob)
 */
TEST_F(FirmwareHandlerUpdateStartedTest, StatOnActiveImageReturnsFailure)
{
    getToUpdateStarted();

    ASSERT_TRUE(handler->canHandleBlob(activeImageBlobId));

    blobs::BlobMeta meta;
    EXPECT_FALSE(handler->stat(activeImageBlobId, &meta));
}

TEST_F(FirmwareHandlerUpdateStartedTest, StatOnUpdateBlobReturnsFailure)
{
    getToUpdateStarted();

    ASSERT_TRUE(handler->canHandleBlob(updateBlobId));

    blobs::BlobMeta meta;
    EXPECT_FALSE(handler->stat(updateBlobId, &meta));
}

TEST_F(FirmwareHandlerUpdateStartedTest, StatOnNormalBlobsReturnsSuccess)
{
    getToUpdateStarted();

    blobs::BlobMeta expected;
    expected.blobState = FirmwareBlobHandler::UpdateFlags::ipmi;
    expected.size = 0;

    std::vector<std::string> testBlobs = {staticLayoutBlobId, hashBlobId};
    for (const auto& blob : testBlobs)
    {
        ASSERT_TRUE(handler->canHandleBlob(blob));

        blobs::BlobMeta meta = {};
        EXPECT_TRUE(handler->stat(blob, &meta));
        EXPECT_EQ(expected, meta);
    }
}

/*
 * writemeta(session)
 */
TEST_F(FirmwareHandlerUpdateStartedTest, WriteMetaToUpdateBlobReturnsFailure)
{
    getToUpdateStarted();
    EXPECT_FALSE(handler->writeMeta(session, 0, {0x01}));
}

/*
 * write(session)
 */
TEST_F(FirmwareHandlerUpdateStartedTest, WriteToUpdateBlobReturnsFailure)
{
    getToUpdateStarted();
    EXPECT_FALSE(handler->write(session, 0, {0x01}));
}

/*
 * read(session)
 */
TEST_F(FirmwareHandlerUpdateStartedTest, ReadFromUpdateBlobReturnsEmpty)
{
    getToUpdateStarted();
    EXPECT_THAT(handler->read(session, 0, 1), IsEmpty());
}

/*
 * stat(session) - this will trigger a check, and the state may change.
 */

/*
 * TODO: close(session) - this will abort.
 */

/*
 * commit(session)
 */

} // namespace
} // namespace ipmi_flash
<|endoftext|>


<commit_before>#include <iostream>
#include <complex>
#include <vector>

#include <htool/cluster.hpp>
#include <htool/lrmat.hpp>
#include <htool/SVD.hpp>

using namespace std;
using namespace htool;

class MyMatrix: public IMatrix<double>{
	const vector<R3>& p1;
	const vector<R3>& p2;

public:
	MyMatrix(const vector<R3>& p10,const vector<R3>& p20 ):p1(p10),p2(p20) {}
	 double get_coef(const int& i, const int& j)const {return 1./(4*M_PI*norm(p1[i]-p2[j]));}
	 std::vector<double> operator*(std::vector<double> a){
		std::vector<double> result(a.size(),0);
		for (int i=0;i<p1.size();i++){
			for (int k=0;k<p2.size();k++){
				result[i]+=this->get_coef(i,k)*a[k];
			}
		}
		return result;
	 }
};

int main(){
	const int ndistance = 4;
	double distance[ndistance];
	distance[0] = 2; distance[1] = 5; distance[2] = 10; distance[3] = 20;
	SetNdofPerElt(1);

	for(int idist=0; idist<ndistance; idist++)
	{
		cout << "Distance between the clusters: " << distance[idist] << endl;

		srand (1);
		// we set a constant seed for rand because we want always the same result if we run the check many times
		// (two different initializations with the same seed will generate the same succession of results in the subsequent calls to rand)

		int nr = 100;
		int nc = 50;
		vector<int> Ir(nr); // row indices for the lrmatrix
		vector<int> Ic(nr); // column indices for the lrmatrix

		double z1 = 1;
		vector<R3>     p1(nr);
		vector<double> r1(nr);
		vector<int>  tab1(nr);
		for(int j=0; j<nr; j++){
			Ir[j] = j;
			Ic[j] = j;
			double rho = ((double) rand() / (double)(RAND_MAX)); // (double) otherwise integer division!
			double theta = ((double) rand() / (double)(RAND_MAX));
			p1[j][0] = sqrt(rho)*cos(2*M_PI*theta); p1[j][1] = sqrt(rho)*sin(2*M_PI*theta); p1[j][2] = z1;
			// sqrt(rho) otherwise the points would be concentrated in the center of the disk
			r1[j]=0.;
			tab1[j]=j;
		}
		// p2: points in a unit disk of the plane z=z2
		double z2 = 1+distance[idist];
		vectR3 p2(nc);
		vectReal r2(nc);
		vectInt tab2(nc);
		for(int j=0; j<nc; j++){
			double rho = ((double) rand() / (RAND_MAX)); // (double) otherwise integer division!
			double theta = ((double) rand() / (RAND_MAX));
			p2[j][0] = sqrt(rho)*cos(2*M_PI*theta); p2[j][1] = sqrt(rho)*sin(2*M_PI*theta); p2[j][2] = z2;
			r2[j]=0.;
			tab2[j]=j;
		}

		Cluster t(p1,r1,tab1); Cluster s(p2,r2,tab2);
		MyMatrix A(p1,p2);

		// SVD
        int reqrank_max = 10;
		SVD<double> A_SVD(Ir,Ic,t,s,reqrank_max);
		A_SVD.build(A);
		std::vector<double> SVD_errors;
		std::vector<double> SVD_errors_check(reqrank_max,0);
        std::vector<double> test(nc,1);
        cout << A_SVD*test <<endl;
		for (int k = 0 ; k < reqrank_max ; k++){
			SVD_errors.push_back(Frobenius_absolute_error(A_SVD,A,k));
			for (int l=k ; l<min(nr,nc) ; l++){
				SVD_errors_check[k]+=pow(A_SVD.get_singular_value(l),2);
			}
			SVD_errors_check[k]=sqrt(SVD_errors_check[k]);
		}

    // Testing with Eckart–Young–Mirsky theorem for Frobenius norm
		cout << SVD_errors<<endl;
		cout << SVD_errors_check << endl;

	}

}
<commit_msg>Bug fixed but now leak issue<commit_after>#include <iostream>
#include <complex>
#include <vector>

#include <htool/cluster.hpp>
#include <htool/lrmat.hpp>
#include <htool/SVD.hpp>

using namespace std;
using namespace htool;

class MyMatrix: public IMatrix<double>{
	const vector<R3>& p1;
	const vector<R3>& p2;

public:
	MyMatrix(const vector<R3>& p10,const vector<R3>& p20 ):p1(p10),p2(p20) {}
	 double get_coef(const int& i, const int& j)const {return 1./(4*M_PI*norm(p1[i]-p2[j]));}
	 std::vector<double> operator*(std::vector<double> a){
		std::vector<double> result(a.size(),0);
		for (int i=0;i<p1.size();i++){
			for (int k=0;k<p2.size();k++){
				result[i]+=this->get_coef(i,k)*a[k];
			}
		}
		return result;
	 }
};

int main(){
	const int ndistance = 4;
	double distance[ndistance];
	distance[0] = 10; distance[1] = 20; distance[2] = 30; distance[3] = 40;
	SetNdofPerElt(1);

	for(int idist=0; idist<ndistance; idist++)
	{
		cout << "Distance between the clusters: " << distance[idist] << endl;

		srand (1);
		// we set a constant seed for rand because we want always the same result if we run the check many times
		// (two different initializations with the same seed will generate the same succession of results in the subsequent calls to rand)

		int nr = 500;
		int nc = 100;
		vector<int> Ir(nr); // row indices for the lrmatrix
		vector<int> Ic(nc); // column indices for the lrmatrix

		double z1 = 1;
		vector<R3>     p1(nr);
		vector<double> r1(nr);
		vector<int>  tab1(nr);
		for(int j=0; j<nr; j++){
			Ir[j] = j;
			Ic[j] = j;
			double rho = ((double) rand() / (double)(RAND_MAX)); // (double) otherwise integer division!
			double theta = ((double) rand() / (double)(RAND_MAX));
			p1[j][0] = sqrt(rho)*cos(2*M_PI*theta); p1[j][1] = sqrt(rho)*sin(2*M_PI*theta); p1[j][2] = z1;
			// sqrt(rho) otherwise the points would be concentrated in the center of the disk
			r1[j]=0.;
			tab1[j]=j;
		}
		// p2: points in a unit disk of the plane z=z2
		double z2 = 1+distance[idist];
		vector<R3> p2(nc);
		vector<double> r2(nc);
		vector<int> tab2(nc);
		for(int j=0; j<nc; j++){
			double rho = ((double) rand() / (RAND_MAX)); // (double) otherwise integer division!
			double theta = ((double) rand() / (RAND_MAX));
			p2[j][0] = sqrt(rho)*cos(2*M_PI*theta); p2[j][1] = sqrt(rho)*sin(2*M_PI*theta); p2[j][2] = z2;
			r2[j]=0.;
			tab2[j]=j;
		}

		Cluster t(p1,r1,tab1); Cluster s(p2,r2,tab2);
		MyMatrix A(p1,p2);

		// SVD
    int reqrank_max = 10;
		SVD<double> A_SVD(Ir,Ic,t,s,reqrank_max);
		A_SVD.build(A);
		std::vector<double> SVD_errors;
		std::vector<double> SVD_errors_check(reqrank_max,0);

		for (int k = 0 ; k < reqrank_max ; k++){
			SVD_errors.push_back(Frobenius_absolute_error(A_SVD,A,k));
			for (int l=k ; l<min(nr,nc) ; l++){
				SVD_errors_check[k]+=pow(A_SVD.get_singular_value(l),2);
			}
			SVD_errors_check[k]=sqrt(SVD_errors_check[k]);
		}

    // Testing with Eckart–Young–Mirsky theorem for Frobenius norm
		cout << SVD_errors<<endl;
		cout << SVD_errors_check << endl;

	}

}
<|endoftext|>


<commit_before>#include <gtest/gtest.h>
#include <test/unit/math/rev/fun/util.hpp>
#include <stan/math/rev/core.hpp>
#include <stan/math/rev/fun/sin.hpp>
#include <vector>

TEST(AgradRev, zero_arithmetic) {
  int a = 1.0;
  double b = 2;
  std::vector<int> va(5, a);
  std::vector<double> vb(5, b);
  Eigen::VectorXd c = Eigen::VectorXd::Random(5);
  Eigen::RowVectorXd d = Eigen::RowVectorXd::Random(5);
  Eigen::MatrixXd e = Eigen::MatrixXd::Random(5, 5);
  std::vector<std::vector<int>> vva(5, va);
  std::vector<std::vector<double>> vvb(5, vb);
  std::vector<Eigen::VectorXd> vc(5, c);
  std::vector<Eigen::RowVectorXd> vd(5, d);
  std::vector<Eigen::MatrixXd> ve(5, e);

  stan::math::zero_adjoints(a);
  stan::math::zero_adjoints(b);
  stan::math::zero_adjoints(va);
  stan::math::zero_adjoints(vb);
  stan::math::zero_adjoints(c);
  stan::math::zero_adjoints(d);
  stan::math::zero_adjoints(e);
  stan::math::zero_adjoints(vva);
  stan::math::zero_adjoints(vvb);
  stan::math::zero_adjoints(vc);
  stan::math::zero_adjoints(vd);
  stan::math::zero_adjoints(ve);

  stan::math::zero_adjoints(a, b, va, vb, c, d, e,
		vva, vvb, vc, vd, ve);
}

TEST(AgradRev, zero_var) {
  using stan::math::var;
  using stan::math::vari;

  var a(5.0);
  a.vi_->adj_ = 2.0;

  stan::math::zero_adjoints(a);
  EXPECT_FLOAT_EQ(a.vi_->adj_, 0.0);

  stan::math::recover_memory();
}

TEST(AgradRev, zero_std_vector_var) {
  using stan::math::var;
  using stan::math::vari;

  std::vector<var> a(5, 0.0);
  for(size_t i = 0; i < a.size(); ++i)
    a[i].vi_->adj_ = i + 1.0;

  stan::math::zero_adjoints(a);
  for(size_t i = 0; i < a.size(); ++i)
    EXPECT_FLOAT_EQ(a[i].vi_->adj_, 0.0);

  stan::math::recover_memory();
}

TEST(AgradRev, zero_vector_var) {
  using stan::math::var;
  using stan::math::vari;

  Eigen::Matrix<var, Eigen::Dynamic, 1> a =
    Eigen::VectorXd::Zero(5).template cast<var>();
  for(size_t i = 0; i < a.size(); ++i)
    a(i).vi_->adj_ = i + 1.0;

  stan::math::zero_adjoints(a);
  for(size_t i = 0; i < a.size(); ++i)
    EXPECT_FLOAT_EQ(a(i).vi_->adj_, 0.0);

  stan::math::recover_memory();
}

TEST(AgradRev, zero_row_vector_var) {
  using stan::math::var;
  using stan::math::vari;

  Eigen::Matrix<var, 1, Eigen::Dynamic> a =
    Eigen::RowVectorXd::Zero(5).template cast<var>();
  for(size_t i = 0; i < a.size(); ++i)
    a(i).vi_->adj_ = i + 1.0;

  stan::math::zero_adjoints(a);
  for(size_t i = 0; i < a.size(); ++i)
    EXPECT_FLOAT_EQ(a(i).vi_->adj_, 0.0);

  stan::math::recover_memory();
}

TEST(AgradRev, zero_matrix_var) {
  using stan::math::var;
  using stan::math::vari;

  Eigen::Matrix<var, Eigen::Dynamic, Eigen::Dynamic> a =
    Eigen::MatrixXd::Zero(5, 5).template cast<var>();
  for(size_t i = 0; i < a.size(); ++i)
    a(i).vi_->adj_ = i + 1.0;

  stan::math::zero_adjoints(a);
  for(size_t i = 0; i < a.size(); ++i)
    EXPECT_FLOAT_EQ(a(i).vi_->adj_, 0.0);

  stan::math::recover_memory();
}

TEST(AgradRev, zero_std_vector_std_vector_var) {
  using stan::math::var;
  using stan::math::vari;

  std::vector<var> a(5, 0.0);
  std::vector<var> b(5, 1.0);
  std::vector<var> c(5, 2.0);
  std::vector<std::vector<var>> va = { a, b, c };
  for(size_t i = 0; i < va.size(); ++i)
    for(size_t j = 0; j < va[i].size(); ++j)
      va[i][j].vi_->adj_ = i + 1.0;

  stan::math::zero_adjoints(va);
  for(size_t i = 0; i < va.size(); ++i)
    for(size_t j = 0; j < va[i].size(); ++j)
      EXPECT_FLOAT_EQ(va[i][j].vi_->adj_, 0.0);

  stan::math::recover_memory();
}

TEST(AgradRev, zero_std_vector_vector_var) {
  using stan::math::var;
  using stan::math::vari;

  Eigen::Matrix<var, Eigen::Dynamic, 1> a =
    Eigen::VectorXd::Zero(3).template cast<var>();
  Eigen::Matrix<var, Eigen::Dynamic, 1> b =
    Eigen::VectorXd::Zero(4).template cast<var>();
  Eigen::Matrix<var, Eigen::Dynamic, 1> c =
    Eigen::VectorXd::Zero(5).template cast<var>();
  std::vector<Eigen::Matrix<var, Eigen::Dynamic, 1>> va = { a, b, c };
  for(size_t i = 0; i < va.size(); ++i)
    for(size_t j = 0; j < va[i].size(); ++j)
      va[i](j).vi_->adj_ = i + 1.0;

  stan::math::zero_adjoints(va);
  for(size_t i = 0; i < va.size(); ++i)
    for(size_t j = 0; j < va[i].size(); ++j)
      EXPECT_FLOAT_EQ(va[i](j).vi_->adj_, 0.0);

  stan::math::recover_memory();
}

TEST(AgradRev, zero_std_vector_row_vector_var) {
  using stan::math::var;
  using stan::math::vari;

  Eigen::Matrix<var, 1, Eigen::Dynamic> a =
    Eigen::RowVectorXd::Zero(3).template cast<var>();
  Eigen::Matrix<var, 1, Eigen::Dynamic> b =
    Eigen::RowVectorXd::Zero(4).template cast<var>();
  Eigen::Matrix<var, 1, Eigen::Dynamic> c =
    Eigen::RowVectorXd::Zero(5).template cast<var>();
  std::vector<Eigen::Matrix<var, 1, Eigen::Dynamic>> va = { a, b, c };
  for(size_t i = 0; i < va.size(); ++i)
    for(size_t j = 0; j < va[i].size(); ++j)
      va[i](j).vi_->adj_ = i + 1.0;

  stan::math::zero_adjoints(va);
  for(size_t i = 0; i < va.size(); ++i)
    for(size_t j = 0; j < va[i].size(); ++j)
      EXPECT_FLOAT_EQ(va[i](j).vi_->adj_, 0.0);

  stan::math::recover_memory();
}

TEST(AgradRev, zero_std_vector_matrix_var) {
  using stan::math::var;
  using stan::math::vari;

  Eigen::Matrix<var, Eigen::Dynamic, Eigen::Dynamic> a =
    Eigen::MatrixXd::Zero(3, 4).template cast<var>();
  Eigen::Matrix<var, Eigen::Dynamic, Eigen::Dynamic> b =
    Eigen::MatrixXd::Zero(4, 5).template cast<var>();
  Eigen::Matrix<var, Eigen::Dynamic, Eigen::Dynamic> c =
    Eigen::MatrixXd::Zero(5, 6).template cast<var>();
  std::vector<Eigen::Matrix<var, Eigen::Dynamic, Eigen::Dynamic>> va = { a, b, c };
  for(size_t i = 0; i < va.size(); ++i)
    for(size_t j = 0; j < va[i].size(); ++j)
      va[i](j).vi_->adj_ = i + 1.0;

  stan::math::zero_adjoints(va);
  for(size_t i = 0; i < va.size(); ++i)
    for(size_t j = 0; j < va[i].size(); ++j)
      EXPECT_FLOAT_EQ(va[i](j).vi_->adj_, 0.0);

  stan::math::recover_memory();
}

TEST(AgradRev, zero_multi) {
  using stan::math::var;
  using stan::math::vari;

  int a = 2;
  double b = 3;
  var c(5.0);
  c.vi_->adj_ = 2.0;
  std::vector<var> d(5, 1.0);
  for(size_t i = 0; i < d.size(); ++i)
    d[i].vi_->adj_ = i + 1.0;
  std::vector<int> e(5, 1);
  std::vector<double> f(5, 1.0);

  stan::math::zero_adjoints(a, b, c, d, e, f);
  EXPECT_FLOAT_EQ(c.vi_->adj_, 0.0);
  for(size_t i = 0; i < d.size(); ++i)
    EXPECT_FLOAT_EQ(d[i].vi_->adj_, 0.0);

  stan::math::recover_memory();
}
<commit_msg>[Jenkins] auto-formatting by clang-format version 6.0.0-1ubuntu2 (tags/RELEASE_600/final)<commit_after>#include <gtest/gtest.h>
#include <test/unit/math/rev/fun/util.hpp>
#include <stan/math/rev/core.hpp>
#include <stan/math/rev/fun/sin.hpp>
#include <vector>

TEST(AgradRev, zero_arithmetic) {
  int a = 1.0;
  double b = 2;
  std::vector<int> va(5, a);
  std::vector<double> vb(5, b);
  Eigen::VectorXd c = Eigen::VectorXd::Random(5);
  Eigen::RowVectorXd d = Eigen::RowVectorXd::Random(5);
  Eigen::MatrixXd e = Eigen::MatrixXd::Random(5, 5);
  std::vector<std::vector<int>> vva(5, va);
  std::vector<std::vector<double>> vvb(5, vb);
  std::vector<Eigen::VectorXd> vc(5, c);
  std::vector<Eigen::RowVectorXd> vd(5, d);
  std::vector<Eigen::MatrixXd> ve(5, e);

  stan::math::zero_adjoints(a);
  stan::math::zero_adjoints(b);
  stan::math::zero_adjoints(va);
  stan::math::zero_adjoints(vb);
  stan::math::zero_adjoints(c);
  stan::math::zero_adjoints(d);
  stan::math::zero_adjoints(e);
  stan::math::zero_adjoints(vva);
  stan::math::zero_adjoints(vvb);
  stan::math::zero_adjoints(vc);
  stan::math::zero_adjoints(vd);
  stan::math::zero_adjoints(ve);

  stan::math::zero_adjoints(a, b, va, vb, c, d, e, vva, vvb, vc, vd, ve);
}

TEST(AgradRev, zero_var) {
  using stan::math::var;
  using stan::math::vari;

  var a(5.0);
  a.vi_->adj_ = 2.0;

  stan::math::zero_adjoints(a);
  EXPECT_FLOAT_EQ(a.vi_->adj_, 0.0);

  stan::math::recover_memory();
}

TEST(AgradRev, zero_std_vector_var) {
  using stan::math::var;
  using stan::math::vari;

  std::vector<var> a(5, 0.0);
  for (size_t i = 0; i < a.size(); ++i)
    a[i].vi_->adj_ = i + 1.0;

  stan::math::zero_adjoints(a);
  for (size_t i = 0; i < a.size(); ++i)
    EXPECT_FLOAT_EQ(a[i].vi_->adj_, 0.0);

  stan::math::recover_memory();
}

TEST(AgradRev, zero_vector_var) {
  using stan::math::var;
  using stan::math::vari;

  Eigen::Matrix<var, Eigen::Dynamic, 1> a
      = Eigen::VectorXd::Zero(5).template cast<var>();
  for (size_t i = 0; i < a.size(); ++i)
    a(i).vi_->adj_ = i + 1.0;

  stan::math::zero_adjoints(a);
  for (size_t i = 0; i < a.size(); ++i)
    EXPECT_FLOAT_EQ(a(i).vi_->adj_, 0.0);

  stan::math::recover_memory();
}

TEST(AgradRev, zero_row_vector_var) {
  using stan::math::var;
  using stan::math::vari;

  Eigen::Matrix<var, 1, Eigen::Dynamic> a
      = Eigen::RowVectorXd::Zero(5).template cast<var>();
  for (size_t i = 0; i < a.size(); ++i)
    a(i).vi_->adj_ = i + 1.0;

  stan::math::zero_adjoints(a);
  for (size_t i = 0; i < a.size(); ++i)
    EXPECT_FLOAT_EQ(a(i).vi_->adj_, 0.0);

  stan::math::recover_memory();
}

TEST(AgradRev, zero_matrix_var) {
  using stan::math::var;
  using stan::math::vari;

  Eigen::Matrix<var, Eigen::Dynamic, Eigen::Dynamic> a
      = Eigen::MatrixXd::Zero(5, 5).template cast<var>();
  for (size_t i = 0; i < a.size(); ++i)
    a(i).vi_->adj_ = i + 1.0;

  stan::math::zero_adjoints(a);
  for (size_t i = 0; i < a.size(); ++i)
    EXPECT_FLOAT_EQ(a(i).vi_->adj_, 0.0);

  stan::math::recover_memory();
}

TEST(AgradRev, zero_std_vector_std_vector_var) {
  using stan::math::var;
  using stan::math::vari;

  std::vector<var> a(5, 0.0);
  std::vector<var> b(5, 1.0);
  std::vector<var> c(5, 2.0);
  std::vector<std::vector<var>> va = {a, b, c};
  for (size_t i = 0; i < va.size(); ++i)
    for (size_t j = 0; j < va[i].size(); ++j)
      va[i][j].vi_->adj_ = i + 1.0;

  stan::math::zero_adjoints(va);
  for (size_t i = 0; i < va.size(); ++i)
    for (size_t j = 0; j < va[i].size(); ++j)
      EXPECT_FLOAT_EQ(va[i][j].vi_->adj_, 0.0);

  stan::math::recover_memory();
}

TEST(AgradRev, zero_std_vector_vector_var) {
  using stan::math::var;
  using stan::math::vari;

  Eigen::Matrix<var, Eigen::Dynamic, 1> a
      = Eigen::VectorXd::Zero(3).template cast<var>();
  Eigen::Matrix<var, Eigen::Dynamic, 1> b
      = Eigen::VectorXd::Zero(4).template cast<var>();
  Eigen::Matrix<var, Eigen::Dynamic, 1> c
      = Eigen::VectorXd::Zero(5).template cast<var>();
  std::vector<Eigen::Matrix<var, Eigen::Dynamic, 1>> va = {a, b, c};
  for (size_t i = 0; i < va.size(); ++i)
    for (size_t j = 0; j < va[i].size(); ++j)
      va[i](j).vi_->adj_ = i + 1.0;

  stan::math::zero_adjoints(va);
  for (size_t i = 0; i < va.size(); ++i)
    for (size_t j = 0; j < va[i].size(); ++j)
      EXPECT_FLOAT_EQ(va[i](j).vi_->adj_, 0.0);

  stan::math::recover_memory();
}

TEST(AgradRev, zero_std_vector_row_vector_var) {
  using stan::math::var;
  using stan::math::vari;

  Eigen::Matrix<var, 1, Eigen::Dynamic> a
      = Eigen::RowVectorXd::Zero(3).template cast<var>();
  Eigen::Matrix<var, 1, Eigen::Dynamic> b
      = Eigen::RowVectorXd::Zero(4).template cast<var>();
  Eigen::Matrix<var, 1, Eigen::Dynamic> c
      = Eigen::RowVectorXd::Zero(5).template cast<var>();
  std::vector<Eigen::Matrix<var, 1, Eigen::Dynamic>> va = {a, b, c};
  for (size_t i = 0; i < va.size(); ++i)
    for (size_t j = 0; j < va[i].size(); ++j)
      va[i](j).vi_->adj_ = i + 1.0;

  stan::math::zero_adjoints(va);
  for (size_t i = 0; i < va.size(); ++i)
    for (size_t j = 0; j < va[i].size(); ++j)
      EXPECT_FLOAT_EQ(va[i](j).vi_->adj_, 0.0);

  stan::math::recover_memory();
}

TEST(AgradRev, zero_std_vector_matrix_var) {
  using stan::math::var;
  using stan::math::vari;

  Eigen::Matrix<var, Eigen::Dynamic, Eigen::Dynamic> a
      = Eigen::MatrixXd::Zero(3, 4).template cast<var>();
  Eigen::Matrix<var, Eigen::Dynamic, Eigen::Dynamic> b
      = Eigen::MatrixXd::Zero(4, 5).template cast<var>();
  Eigen::Matrix<var, Eigen::Dynamic, Eigen::Dynamic> c
      = Eigen::MatrixXd::Zero(5, 6).template cast<var>();
  std::vector<Eigen::Matrix<var, Eigen::Dynamic, Eigen::Dynamic>> va
      = {a, b, c};
  for (size_t i = 0; i < va.size(); ++i)
    for (size_t j = 0; j < va[i].size(); ++j)
      va[i](j).vi_->adj_ = i + 1.0;

  stan::math::zero_adjoints(va);
  for (size_t i = 0; i < va.size(); ++i)
    for (size_t j = 0; j < va[i].size(); ++j)
      EXPECT_FLOAT_EQ(va[i](j).vi_->adj_, 0.0);

  stan::math::recover_memory();
}

TEST(AgradRev, zero_multi) {
  using stan::math::var;
  using stan::math::vari;

  int a = 2;
  double b = 3;
  var c(5.0);
  c.vi_->adj_ = 2.0;
  std::vector<var> d(5, 1.0);
  for (size_t i = 0; i < d.size(); ++i)
    d[i].vi_->adj_ = i + 1.0;
  std::vector<int> e(5, 1);
  std::vector<double> f(5, 1.0);

  stan::math::zero_adjoints(a, b, c, d, e, f);
  EXPECT_FLOAT_EQ(c.vi_->adj_, 0.0);
  for (size_t i = 0; i < d.size(); ++i)
    EXPECT_FLOAT_EQ(d[i].vi_->adj_, 0.0);

  stan::math::recover_memory();
}
<|endoftext|>


<commit_before>/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 1999 The Apache Software Foundation.  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.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 THE APACHE SOFTWARE FOUNDATION OR
 * ITS 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.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 *
 * @author David N. Bertoni
 */

#include "StylesheetConstructionContextDefault.hpp"

#include <algorithm>

#include <Include/STLHelper.hpp>

#include <PlatformSupport/URISupport.hpp>

#include <XPath/XObjectFactory.hpp>
#include <XPath/XPathEnvSupport.hpp>
#include <XPath/XPathFactory.hpp>
#include <XPath/XPathProcessorImpl.hpp>

#include "ElemTemplateElement.hpp"
#include "StylesheetRoot.hpp"
#include "XSLTEngineImpl.hpp"
#include "XSLTInputSource.hpp"

StylesheetConstructionContextDefault::StylesheetConstructionContextDefault(
			XSLTEngineImpl&				processor,
			XPathFactory&				xpathFactory,
			VectorAllocatorSizeType		theAllocatorSize) :
	StylesheetConstructionContext(),
	m_processor(processor),
	m_xpathFactory(xpathFactory),
	m_xpathProcessor(new XPathProcessorImpl),
	m_stylesheets(),
	m_stringPool(),
	m_xalanDOMCharVectorAllocator(theAllocatorSize),
	m_tempBuffer()
{
}

StylesheetConstructionContextDefault::~StylesheetConstructionContextDefault()
{
	reset();
}

void
StylesheetConstructionContextDefault::error(
			const XalanDOMString&		msg,
			const XalanNode* 			sourceNode,
			const ElemTemplateElement*	styleNode) const
{
	m_processor.error(msg, sourceNode, styleNode);
}

void
StylesheetConstructionContextDefault::error(
			const XalanDOMString&	msg,
			const XalanNode* 		sourceNode,
			const Locator* 			locator) const
{
	if (locator != 0)
	{
		m_processor.error(msg, *locator, sourceNode);
	}
	else
	{
		m_processor.error(msg, sourceNode);
	}
}

void
StylesheetConstructionContextDefault::error(
			const char*					msg,
			const XalanNode* 			sourceNode,
			const ElemTemplateElement*	styleNode) const
{
	error(TranscodeFromLocalCodePage(msg), sourceNode, styleNode);
}

void
StylesheetConstructionContextDefault::error(
			const char*			msg,
			const XalanNode* 	sourceNode,
			const Locator* 		locator) const
{
	error(TranscodeFromLocalCodePage(msg), sourceNode, locator);
}

void
StylesheetConstructionContextDefault::warn(
			const XalanDOMString&		msg,
			const XalanNode* 			sourceNode,
			const ElemTemplateElement*	styleNode) const
{
	m_processor.warn(msg, sourceNode, styleNode);
}

void
StylesheetConstructionContextDefault::warn(
			const XalanDOMString&	msg,
			const XalanNode* 		sourceNode,
			const Locator* 			locator) const
{
	if (locator != 0)
	{
		m_processor.warn(msg, *locator, sourceNode);
	}
	else
	{
		m_processor.warn(msg, sourceNode);
	}
}

void
StylesheetConstructionContextDefault::warn(
			const char*					msg,
			const XalanNode* 			sourceNode,
			const ElemTemplateElement*	styleNode) const
{
	warn(TranscodeFromLocalCodePage(msg), sourceNode, styleNode);
}

void
StylesheetConstructionContextDefault::warn(
			const char*			msg,
			const XalanNode* 	sourceNode,
			const Locator* 		locator) const
{
	warn(TranscodeFromLocalCodePage(msg), sourceNode, locator);
}

void
StylesheetConstructionContextDefault::message(
			const XalanDOMString&		msg,
			const XalanNode* 			sourceNode,
			const ElemTemplateElement*	styleNode) const
{
	m_processor.message(msg, sourceNode, styleNode);
}

void
StylesheetConstructionContextDefault::message(
			const XalanDOMString&	msg,
			const XalanNode* 		sourceNode,
			const Locator* 			locator) const
{
	if (locator != 0)
	{
		m_processor.message(msg, *locator, sourceNode);
	}
	else
	{
		m_processor.message(msg, sourceNode);
	}
}

void
StylesheetConstructionContextDefault::message(
			const char*					msg,
			const XalanNode* 			sourceNode,
			const ElemTemplateElement*	styleNode) const
{
	message(TranscodeFromLocalCodePage(msg), sourceNode, styleNode);
}

void
StylesheetConstructionContextDefault::message(
			const char*			msg,
			const XalanNode* 	sourceNode,
			const Locator* 		locator) const
{
	message(TranscodeFromLocalCodePage(msg), sourceNode, locator);
}

void
StylesheetConstructionContextDefault::reset()
{
#if !defined(XALAN_NO_NAMESPACES)
	using std::for_each;
#endif

	for_each(m_stylesheets.begin(),
			 m_stylesheets.end(),
			 DeleteFunctor


<commit_before>#include "AhoCorasickAutomata.h"
#include <algorithm>
#include <cassert>
#include <iostream>
using namespace std;

#define TEST_MAX 1024

struct Test {
  string text;
  vector<string> pattern;
  unordered_map<string, vector<int>> match;
} tests[] = {
    {
        "asdfasdfasdfasdf",
        {"asdf"},
        {
            {"asdf", {0, 4, 8, 12}},
        },
    },
    {
        "helloworldgoodbyeworldthisisagoodbookformanycomputersciencestudentihop"
        "eyouenjoy",
        {"oo"},
        {
            {"oo", {11, 30, 34}},
        },
    },
    {
        "helloworldgoodbyeworldthisisagoodbookformanycomputersciencestudentihop"
        "eyouenjoy",
        {"oo", "world", "good", "i"},
        {
            {"oo", {11, 30, 34}},
            {"world", {5, 17}},
            {"good", {10, 29}},
            {"i", {24, 26, 40, 48}},
        },
    },
};

void AssertEqual(vector<int> v1, vector<int> v2) {
  sort(v1.begin(), v1.end());
  sort(v2.begin(), v2.end());
  assert(v1.size() == v2.size());
  for (int i = 0; i < v1.size(); i++) {
    assert(v1[i] == v2[i]);
  }
}

void AssertEqual(unordered_map<string, vector<int>> m1,
                 unordered_map<string, vector<int>> m2) {
  assert(m1.size() == m2.size());
  for (unordered_map<string, vector<int>>::iterator i = m1.begin();
       i != m1.end(); i++) {
    string k1 = i->first;
    vector<int> v1 = i->second;
    assert(m2.find(k1) != m2.end());
    vector<int> v2 = m2[k1];
    AssertEqual(v1, v2);
  }
}

int main() {
  for (int i = 0; i < sizeof(tests) / sizeof(Test); i++) {
    Test &t = tests[i];

    AcNode *root = AhoCorasickAutomataNew(t.pattern);
    AssertEqual(AhoCorasickAutomataMatch(root, t.text), t.match);
    AhoCorasickAutomataFree(root);
  }
  return 0;
}

<commit_msg>add test cases for ac-automata<commit_after>#include "AhoCorasickAutomata.h"
#include <algorithm>
#include <cassert>
#include <iostream>
using namespace std;

#define TEST_MAX 1024

struct Test {
  string text;
  vector<string> pattern;
  unordered_map<string, vector<int>> match;
} tests[] = {
    {
        "sting",
        {"i", "in", "tin", "sting"},
        {
            {"i", {2}},
            {"in", {2}},
            {"tin", {1}},
            {"sting", {0}},
        },
    },
    {
        "abedget",
        {"ab", "about", "at", "ate", "be", "bed", "edge", "get"},
        {
            {"ab", {0}},
            {"about", {}},
            {"at", {}},
            {"ate", {}},
            {"be", {1}},
            {"bed", {1}},
            {"edge", {2}},
            {"get", {4}},
        },
    },
    {
        "aaaaaaaa",
        {"a", "aa", "aaa", "aaaa"},
        {
            {"a", {0, 1, 2, 3, 4, 5, 6, 7}},
            {"aa", {1, 2, 3, 4, 5, 6}},
            {"aaa", {2, 3, 4, 5}},
            {"aaaa", {3, 4}},
        },
    },
    {
        "asdfasdfasdfasdf",
        {"asdf"},
        {
            {"asdf", {0, 4, 8, 12}},
        },
    },
    {
        "helloworldgoodbyeworldthisisagoodbookformanycomputersciencestudentihop"
        "eyouenjoy",
        {"oo"},
        {
            {"oo", {11, 30, 34}},
        },
    },
    {
        "helloworldgoodbyeworldthisisagoodbookformanycomputersciencestudentihop"
        "eyouenjoy",
        {"oo", "world", "good", "i"},
        {
            {"oo", {11, 30, 34}},
            {"world", {5, 17}},
            {"good", {10, 29}},
            {"i", {24, 26, 40, 48}},
        },
    },
};

void AssertEqual(vector<int> v1, vector<int> v2) {
  sort(v1.begin(), v1.end());
  sort(v2.begin(), v2.end());
  assert(v1.size() == v2.size());
  for (int i = 0; i < v1.size(); i++) {
    assert(v1[i] == v2[i]);
  }
}

void AssertEqual(unordered_map<string, vector<int>> m1,
                 unordered_map<string, vector<int>> m2) {
  assert(m1.size() == m2.size());
  for (unordered_map<string, vector<int>>::iterator i = m1.begin();
       i != m1.end(); i++) {
    string k1 = i->first;
    vector<int> v1 = i->second;
    assert(m2.find(k1) != m2.end());
    vector<int> v2 = m2[k1];
    AssertEqual(v1, v2);
  }
}

int main() {
  for (int i = 0; i < sizeof(tests) / sizeof(Test); i++) {
    Test &t = tests[i];

    AcNode *root = AhoCorasickAutomataNew(t.pattern);
    AssertEqual(AhoCorasickAutomataMatch(root, t.text), t.match);
    AhoCorasickAutomataFree(root);
  }
  return 0;
}

<|endoftext|>


<commit_before><commit_msg>fix projection matrix multiplication<commit_after><|endoftext|>


<commit_before><commit_msg>Cleanup shim logic<commit_after><|endoftext|>


<commit_before><commit_msg>inertiaGameStyle bit is redundant. Set it always now just for compatibility<commit_after><|endoftext|>


<commit_before><commit_msg>Fix calculating fovy from fovx<commit_after><|endoftext|>


<commit_before>/*
 * SessionCompilePdf.cpp
 *
 * Copyright (C) 2009-11 by RStudio, Inc.
 *
 * This program is licensed to you under the terms of version 3 of the
 * GNU Affero General Public License. This program is distributed WITHOUT
 * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
 * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
 *
 */

#include "SessionCompilePdf.hpp"

#include <core/FilePath.hpp>
#include <core/Exec.hpp>
#include <core/FileSerializer.hpp>

#include <core/tex/TexMagicComment.hpp>

#include <r/RSexp.hpp>
#include <r/RExec.hpp>
#include <r/RRoutines.hpp>

#include <session/SessionModuleContext.hpp>

#include "SessionPdfLatex.hpp"
#include "SessionTexi2Dvi.hpp"
#include "SessionRnwWeave.hpp"

// TODO: write latex_program docs and deploy to site

// TODO: emulate texi2dvi on linux to workaround debian tilde
//       escaping bug (http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=534458)

// TODO: consider ability to opt out of texi2dvi (rather than the above)

// TODO: investigate whether texlive on windows uses -file-line-error

// TODO: check spaces in path constraint on various platforms

// TODO: investigate other texi2dvi and pdflatex options
//         -- shell-escape
//         -- clean
//         -- alternative output file location

using namespace core;

namespace session {
namespace modules {
namespace tex {
namespace compile_pdf {

namespace {

void viewPdf(const FilePath& texPath)
{
   FilePath pdfPath = texPath.parent().complete(texPath.stem() + ".pdf");
   module_context::showFile(pdfPath, "_rstudio_compile_pdf");
}

void publishPdf(const FilePath& texPath)
{
   std::string aliasedPath = module_context::createAliasedPath(texPath);
   ClientEvent event(client_events::kPublishPdf, aliasedPath);
   module_context::enqueClientEvent(event);
}

void showCompilationErrors(const FilePath& texPath)
{
   std::string errors;
   Error error = r::exec::RFunction(".rs.getCompilationErrors",
                                    texPath.absolutePath()).call(&errors);
   if (error)
      LOG_ERROR(error);

   if (!errors.empty())
   {
      module_context::consoleWriteOutput(errors);
   }
   else
   {
      FilePath logPath = texPath.parent().complete(texPath.stem() + ".log");
      std::string logContents;
      Error error = core::readStringFromFile(logPath,
                                             &logContents,
                                             string_utils::LineEndingPosix);
      if (error)
         LOG_ERROR(error);

        module_context::consoleWriteOutput(logContents);
   }
}

bool compilePdf(const FilePath& targetFilePath,
                const std::string& completedAction,
                std::string* pUserErrMsg)
{
   // set the working directory for the duration of the compile
   RestoreCurrentPathScope pathScope(module_context::safeCurrentPath());
   Error error = targetFilePath.parent().makeCurrentPath();
   if (error)
   {
      *pUserErrMsg = "Error setting current path: " + error.summary();
      return false;
   }

   // ensure no spaces in path
   std::string filename = targetFilePath.filename();
   if (filename.find(' ') != std::string::npos)
   {
      *pUserErrMsg = "Invalid filename: '" + filename +
                     "' (TeX does not understand paths with spaces)";
      return false;
   }

   // parse out magic comments
   core::tex::TexMagicComments magicComments;
   error = core::tex::parseMagicComments(targetFilePath, &magicComments);
   if (error)
      LOG_ERROR(error);

   // discover and validate tex program path
   FilePath texProgramPath;
   if (!pdflatex::latexProgramForFile(magicComments,
                                      &texProgramPath,
                                      pUserErrMsg))
   {
      return false;
   }

   // see if we need to sweave
   std::string ext = targetFilePath.extensionLowerCase();
   if (ext == ".rnw" || ext == ".snw" || ext == ".nw")
   {
      // attempt to weave the rnw
      bool success = rnw_weave::runWeave(targetFilePath,
                                         magicComments,
                                         pUserErrMsg);
      if (!success)
         return false;
   }

   // configure pdflatex options
   pdflatex::PdfLatexOptions options;
   options.fileLineError = false;
   options.syncTex = true;

   // run tex compile
   FilePath texFilePath = targetFilePath.parent().complete(
                                             targetFilePath.stem() +
                                             ".tex");
   core::system::ProcessResult result;
#if defined(_WIN32) || defined(__APPLE__)
   error = tex::texi2dvi::texToPdf(texProgramPath,
                                   texFilePath,
                                   options,
                                   &result);
#else
   // workaround for tex2dvi special character bug on linux:
   //   http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=577741
  error = tex::pdflatex::texToPdf(texProgramPath,
                                  texFilePath,
                                  options,
                                  &result);
#endif

   if (error)
   {
      *pUserErrMsg = "Unable to compile pdf: " + error.summary();
      return false;
   }
   else if (result.exitStatus != EXIT_SUCCESS)
   {
      showCompilationErrors(texFilePath);
      return false;
   }
   else
   {
      if (completedAction == "view")
         viewPdf(targetFilePath);
      else if (completedAction == "publish")
         publishPdf(targetFilePath);

      return true;
   }
}

SEXP rs_compilePdf(SEXP filePathSEXP, SEXP completedActionSEXP)
{
   try
   {
      // extract parameters
      FilePath targetFilePath = module_context::resolveAliasedPath(
                                          r::sexp::asString(filePathSEXP));
      std::string completedAction = r::sexp::asString(completedActionSEXP);

      // compile pdf
      std::string userErrMsg;
      if (!compilePdf(targetFilePath, completedAction, &userErrMsg))
      {
         if (!userErrMsg.empty())
            throw r::exec::RErrorException(userErrMsg);
      }
   }
   catch(const r::exec::RErrorException& e)
   {
      r::exec::error(e.message());
   }
   CATCH_UNEXPECTED_EXCEPTION

   return R_NilValue;
}

} // anonymous namespace

Error initialize()
{
   R_CallMethodDef compilePdfMethodDef;
   compilePdfMethodDef.name = "rs_compilePdf" ;
   compilePdfMethodDef.fun = (DL_FUNC) rs_compilePdf ;
   compilePdfMethodDef.numArgs = 2;
   r::routines::addCallMethod(compilePdfMethodDef);

   using boost::bind;
   using namespace module_context;
   ExecBlock initBlock ;
   initBlock.addFunctions()
      (bind(sourceModuleRFile, "SessionCompilePdf.R"));
   return initBlock.execute();

}

} // namespace compile_pdf
} // namespace tex
} // namespace modules
} // namesapce session

<commit_msg>update todo comments<commit_after>/*
 * SessionCompilePdf.cpp
 *
 * Copyright (C) 2009-11 by RStudio, Inc.
 *
 * This program is licensed to you under the terms of version 3 of the
 * GNU Affero General Public License. This program is distributed WITHOUT
 * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
 * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
 *
 */

#include "SessionCompilePdf.hpp"

#include <core/FilePath.hpp>
#include <core/Exec.hpp>
#include <core/FileSerializer.hpp>

#include <core/tex/TexMagicComment.hpp>

#include <r/RSexp.hpp>
#include <r/RExec.hpp>
#include <r/RRoutines.hpp>

#include <session/SessionModuleContext.hpp>

#include "SessionPdfLatex.hpp"
#include "SessionTexi2Dvi.hpp"
#include "SessionRnwWeave.hpp"

// TODO: don't dump log file if there is no error output in the log
//       (can end up dumping old log file which has no errors)

// TODO: get xelatex (install + aa) and lualatex (aa) working on test

// TODO: write latex_program docs and deploy to site

// TODO: emulate texi2dvi on linux to workaround debian tilde
//       escaping bug (http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=534458)

// TODO: consider ability to opt out of texi2dvi (rather than the above)

// TODO: investigate whether texlive on windows uses -file-line-error

// TODO: check spaces in path constraint on various platforms

// TODO: investigate other texi2dvi and pdflatex options
//         -- shell-escape
//         -- clean
//         -- alternative output file location

using namespace core;

namespace session {
namespace modules {
namespace tex {
namespace compile_pdf {

namespace {

void viewPdf(const FilePath& texPath)
{
   FilePath pdfPath = texPath.parent().complete(texPath.stem() + ".pdf");
   module_context::showFile(pdfPath, "_rstudio_compile_pdf");
}

void publishPdf(const FilePath& texPath)
{
   std::string aliasedPath = module_context::createAliasedPath(texPath);
   ClientEvent event(client_events::kPublishPdf, aliasedPath);
   module_context::enqueClientEvent(event);
}

void showCompilationErrors(const FilePath& texPath)
{
   std::string errors;
   Error error = r::exec::RFunction(".rs.getCompilationErrors",
                                    texPath.absolutePath()).call(&errors);
   if (error)
      LOG_ERROR(error);

   if (!errors.empty())
   {
      module_context::consoleWriteOutput(errors);
   }
   else
   {
      FilePath logPath = texPath.parent().complete(texPath.stem() + ".log");
      std::string logContents;
      Error error = core::readStringFromFile(logPath,
                                             &logContents,
                                             string_utils::LineEndingPosix);
      if (error)
         LOG_ERROR(error);

        module_context::consoleWriteOutput(logContents);
   }
}

bool compilePdf(const FilePath& targetFilePath,
                const std::string& completedAction,
                std::string* pUserErrMsg)
{
   // set the working directory for the duration of the compile
   RestoreCurrentPathScope pathScope(module_context::safeCurrentPath());
   Error error = targetFilePath.parent().makeCurrentPath();
   if (error)
   {
      *pUserErrMsg = "Error setting current path: " + error.summary();
      return false;
   }

   // ensure no spaces in path
   std::string filename = targetFilePath.filename();
   if (filename.find(' ') != std::string::npos)
   {
      *pUserErrMsg = "Invalid filename: '" + filename +
                     "' (TeX does not understand paths with spaces)";
      return false;
   }

   // parse out magic comments
   core::tex::TexMagicComments magicComments;
   error = core::tex::parseMagicComments(targetFilePath, &magicComments);
   if (error)
      LOG_ERROR(error);

   // discover and validate tex program path
   FilePath texProgramPath;
   if (!pdflatex::latexProgramForFile(magicComments,
                                      &texProgramPath,
                                      pUserErrMsg))
   {
      return false;
   }

   // see if we need to sweave
   std::string ext = targetFilePath.extensionLowerCase();
   if (ext == ".rnw" || ext == ".snw" || ext == ".nw")
   {
      // attempt to weave the rnw
      bool success = rnw_weave::runWeave(targetFilePath,
                                         magicComments,
                                         pUserErrMsg);
      if (!success)
         return false;
   }

   // configure pdflatex options
   pdflatex::PdfLatexOptions options;
   options.fileLineError = false;
   options.syncTex = true;

   // run tex compile
   FilePath texFilePath = targetFilePath.parent().complete(
                                             targetFilePath.stem() +
                                             ".tex");
   core::system::ProcessResult result;
#if defined(_WIN32) || defined(__APPLE__)
   error = tex::texi2dvi::texToPdf(texProgramPath,
                                   texFilePath,
                                   options,
                                   &result);
#else
   // workaround for tex2dvi special character bug on linux:
   //   http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=577741
  error = tex::pdflatex::texToPdf(texProgramPath,
                                  texFilePath,
                                  options,
                                  &result);
#endif

   if (error)
   {
      *pUserErrMsg = "Unable to compile pdf: " + error.summary();
      return false;
   }
   else if (result.exitStatus != EXIT_SUCCESS)
   {
      showCompilationErrors(texFilePath);
      return false;
   }
   else
   {
      if (completedAction == "view")
         viewPdf(targetFilePath);
      else if (completedAction == "publish")
         publishPdf(targetFilePath);

      return true;
   }
}

SEXP rs_compilePdf(SEXP filePathSEXP, SEXP completedActionSEXP)
{
   try
   {
      // extract parameters
      FilePath targetFilePath = module_context::resolveAliasedPath(
                                          r::sexp::asString(filePathSEXP));
      std::string completedAction = r::sexp::asString(completedActionSEXP);

      // compile pdf
      std::string userErrMsg;
      if (!compilePdf(targetFilePath, completedAction, &userErrMsg))
      {
         if (!userErrMsg.empty())
            throw r::exec::RErrorException(userErrMsg);
      }
   }
   catch(const r::exec::RErrorException& e)
   {
      r::exec::error(e.message());
   }
   CATCH_UNEXPECTED_EXCEPTION

   return R_NilValue;
}

} // anonymous namespace

Error initialize()
{
   R_CallMethodDef compilePdfMethodDef;
   compilePdfMethodDef.name = "rs_compilePdf" ;
   compilePdfMethodDef.fun = (DL_FUNC) rs_compilePdf ;
   compilePdfMethodDef.numArgs = 2;
   r::routines::addCallMethod(compilePdfMethodDef);

   using boost::bind;
   using namespace module_context;
   ExecBlock initBlock ;
   initBlock.addFunctions()
      (bind(sourceModuleRFile, "SessionCompilePdf.R"));
   return initBlock.execute();

}

} // namespace compile_pdf
} // namespace tex
} // namespace modules
} // namesapce session

<|endoftext|>


<commit_before><commit_msg>Fixed cast to wrong type.<commit_after><|endoftext|>


<commit_before>/*
 * Copyright (C) 2016 Fondazione Istituto Italiano di Tecnologia
 * Author: Silvio Traversaro
 * email:  silvio.traversaro@iit.it
 * website: www.icub.org
 * Permission is granted to copy, distribute, and/or modify this program
 * under the terms of the GNU General Public License, version 2 or any
 * later version published by the Free Software Foundation.
 *
 * A copy of the license can be found at
 * http://www.robotcub.org/icub/license/gpl.txt
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
 * Public License for more details
*/

#include <iDynTree/Estimation/ExternalWrenchesEstimation.h>

#include <iDynTree/Model/Model.h>
#include <iDynTree/Model/SubModel.h>
#include <iDynTree/Model/LinkState.h>
#include <iDynTree/Model/ContactWrench.h>

#include <iDynTree/Sensors/Sensors.h>

namespace iDynTree
{

LinkUnknownWrenchContacts::LinkUnknownWrenchContacts(unsigned int nrOfLinks)
{
    this->resize(nrOfLinks);
}

LinkUnknownWrenchContacts::LinkUnknownWrenchContacts(const iDynTree::Model& model)
{
    this->resize(model);
}

void LinkUnknownWrenchContacts::resize(const iDynTree::Model& model)
{
    resize(model.getNrOfLinks());
}

void LinkUnknownWrenchContacts::resize(unsigned int nrOfLinks)
{
    // To avoid dynamic memory allocation at runtime
    // we make sure that the vector have at least spaces for 3 contacts
    const size_t reservedSlots = 3;
    m_linkUnknownWrenchContacts.resize(nrOfLinks);
    for(size_t l=0; l < nrOfLinks; l++)
    {
        m_linkUnknownWrenchContacts[l].resize(0);
        m_linkUnknownWrenchContacts[l].reserve(reservedSlots);
    }
}

const UnknownWrenchContact& LinkUnknownWrenchContacts::contactWrench(const LinkIndex linkIndex, const size_t contactIndex) const
{
    return m_linkUnknownWrenchContacts[linkIndex][contactIndex];
}

UnknownWrenchContact& LinkUnknownWrenchContacts::contactWrench(const LinkIndex linkIndex, const size_t contactIndex)
{
    return m_linkUnknownWrenchContacts[linkIndex][contactIndex];
}

size_t LinkUnknownWrenchContacts::getNrOfContactsForLink(const LinkIndex linkIndex) const
{
    return m_linkUnknownWrenchContacts[linkIndex].size();
}

void LinkUnknownWrenchContacts::setNrOfContactsForLink(const LinkIndex linkIndex, const size_t nrOfContacts)
{
    m_linkUnknownWrenchContacts[linkIndex].resize(nrOfContacts);
    return;
}

void estimateExternalWrenchesBuffers::resize(const SubModelDecomposition& subModels)
{
    this->resize(subModels.getNrOfSubModels());
}

void estimateExternalWrenchesBuffers::resize(const size_t nrOfSubModels)
{
    A.resize(nrOfSubModels);
    x.resize(nrOfSubModels);
    b.resize(nrOfSubModels);
}

bool estimateExternalWrenchesBuffers::isConsistent(const SubModelDecomposition& subModels) const
{
    return (subModels.getNrOfSubModels() == A.size());
}

bool estimateExternalWrenches(const Model& model,
                              const SubModelDecomposition& subModels,
                              const SensorsList& sensors,
                              const LinkUnknownWrenchContacts& unknownWrenches,
                              const LinkVelArray& linkVel,
                              const LinkAccArray& linkProperAcc,
                              const SensorsMeasurements& ftSensorsMeasurements,
                                    estimateExternalWrenchesBuffers& bufs,
                                    LinkContactWrenches& outputContactWrenches)
{

}

}

<commit_msg>[estimation] fix compilation on Windows<commit_after>/*
 * Copyright (C) 2016 Fondazione Istituto Italiano di Tecnologia
 * Author: Silvio Traversaro
 * email:  silvio.traversaro@iit.it
 * website: www.icub.org
 * Permission is granted to copy, distribute, and/or modify this program
 * under the terms of the GNU General Public License, version 2 or any
 * later version published by the Free Software Foundation.
 *
 * A copy of the license can be found at
 * http://www.robotcub.org/icub/license/gpl.txt
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
 * Public License for more details
*/

#include <iDynTree/Estimation/ExternalWrenchesEstimation.h>

#include <iDynTree/Model/Model.h>
#include <iDynTree/Model/SubModel.h>
#include <iDynTree/Model/LinkState.h>
#include <iDynTree/Model/ContactWrench.h>

#include <iDynTree/Sensors/Sensors.h>

namespace iDynTree
{

LinkUnknownWrenchContacts::LinkUnknownWrenchContacts(unsigned int nrOfLinks)
{
    this->resize(nrOfLinks);
}

LinkUnknownWrenchContacts::LinkUnknownWrenchContacts(const iDynTree::Model& model)
{
    this->resize(model);
}

void LinkUnknownWrenchContacts::resize(const iDynTree::Model& model)
{
    resize(model.getNrOfLinks());
}

void LinkUnknownWrenchContacts::resize(unsigned int nrOfLinks)
{
    // To avoid dynamic memory allocation at runtime
    // we make sure that the vector have at least spaces for 3 contacts
    const size_t reservedSlots = 3;
    m_linkUnknownWrenchContacts.resize(nrOfLinks);
    for(size_t l=0; l < nrOfLinks; l++)
    {
        m_linkUnknownWrenchContacts[l].resize(0);
        m_linkUnknownWrenchContacts[l].reserve(reservedSlots);
    }
}

const UnknownWrenchContact& LinkUnknownWrenchContacts::contactWrench(const LinkIndex linkIndex, const size_t contactIndex) const
{
    return m_linkUnknownWrenchContacts[linkIndex][contactIndex];
}

UnknownWrenchContact& LinkUnknownWrenchContacts::contactWrench(const LinkIndex linkIndex, const size_t contactIndex)
{
    return m_linkUnknownWrenchContacts[linkIndex][contactIndex];
}

size_t LinkUnknownWrenchContacts::getNrOfContactsForLink(const LinkIndex linkIndex) const
{
    return m_linkUnknownWrenchContacts[linkIndex].size();
}

void LinkUnknownWrenchContacts::setNrOfContactsForLink(const LinkIndex linkIndex, const size_t nrOfContacts)
{
    m_linkUnknownWrenchContacts[linkIndex].resize(nrOfContacts);
    return;
}

void estimateExternalWrenchesBuffers::resize(const SubModelDecomposition& subModels)
{
    this->resize(subModels.getNrOfSubModels());
}

void estimateExternalWrenchesBuffers::resize(const size_t nrOfSubModels)
{
    A.resize(nrOfSubModels);
    x.resize(nrOfSubModels);
    b.resize(nrOfSubModels);
}

bool estimateExternalWrenchesBuffers::isConsistent(const SubModelDecomposition& subModels) const
{
    return (subModels.getNrOfSubModels() == A.size());
}

bool estimateExternalWrenches(const Model& model,
                              const SubModelDecomposition& subModels,
                              const SensorsList& sensors,
                              const LinkUnknownWrenchContacts& unknownWrenches,
                              const LinkVelArray& linkVel,
                              const LinkAccArray& linkProperAcc,
                              const SensorsMeasurements& ftSensorsMeasurements,
                                    estimateExternalWrenchesBuffers& bufs,
                                    LinkContactWrenches& outputContactWrenches)
{
    return true;
}

}

<|endoftext|>