Skip to content

Commit

Permalink
Add vsum command
Browse files Browse the repository at this point in the history
  • Loading branch information
taka19 committed Mar 20, 2018
1 parent 84dd012 commit 38aa401
Showing 1 changed file with 214 additions and 0 deletions.
214 changes: 214 additions & 0 deletions src/main/vsum.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
// ----------------------------------------------------------------- //
// The Speech Signal Processing Toolkit (SPTK) //
// developed by SPTK Working Group //
// http://sp-tk.sourceforge.net/ //
// ----------------------------------------------------------------- //
// //
// Copyright (c) 1984-2007 Tokyo Institute of Technology //
// Interdisciplinary Graduate School of //
// Science and Engineering //
// //
// 1996-2018 Nagoya Institute of Technology //
// Department of Computer Science //
// //
// All rights reserved. //
// //
// Redistribution and use in source and binary forms, with or //
// without modification, are permitted provided that the following //
// conditions are met: //
// //
// - Redistributions of source code must retain the above copyright //
// notice, this list of conditions and the following disclaimer. //
// - 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. //
// - Neither the name of the SPTK working group nor the names of its //
// contributors may be used to endorse or promote products derived //
// from this software without specific prior written permission. //
// //
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND //
// CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, //
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF //
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE //
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS //
// BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, //
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED //
// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, //
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON //
// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, //
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY //
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE //
// POSSIBILITY OF SUCH DAMAGE. //
// ----------------------------------------------------------------- //

#include <getopt.h>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <vector>

#include "SPTK/math/statistics_accumulator.h"
#include "SPTK/utils/sptk_utils.h"

namespace {

const int kMagicNumberForEndOfFile(-1);
const int kDefaultVectorLength(1);

void PrintUsage(std::ostream* stream) {
// clang-format off
*stream << std::endl;
*stream << " vsum - summation of vectors" << std::endl;
*stream << std::endl;
*stream << " usage:" << std::endl;
*stream << " vsum [ options ] [ infile ] > stdout" << std::endl;
*stream << " options:" << std::endl;
*stream << " -l l : length of vector ( int)[" << std::setw(5) << std::right << kDefaultVectorLength << "][ 1 <= l <= ]" << std::endl; // NOLINT
*stream << " -m m : order of vector ( int)[" << std::setw(5) << std::right << "l-1" << "][ 0 <= m <= ]" << std::endl; // NOLINT
*stream << " -t t : number of vector ( int)[" << std::setw(5) << std::right << "N/A" << "][ 1 <= t <= ]" << std::endl; // NOLINT
*stream << " -h : print this message" << std::endl;
*stream << " infile:" << std::endl;
*stream << " vectors (double)[stdin]" << std::endl;
*stream << " stdout:" << std::endl;
*stream << " summation of vectors (double)" << std::endl;
*stream << std::endl;
*stream << " SPTK: version " << sptk::kVersion << std::endl;
*stream << std::endl;
// clang-format on
}

} // namespace

int main(int argc, char* argv[]) {
int vector_length(kDefaultVectorLength);
int num_vector(kMagicNumberForEndOfFile);

for (;;) {
const int option_char(getopt_long(argc, argv, "l:m:t:h", NULL, NULL));
if (-1 == option_char) break;

switch (option_char) {
case 'l': {
if (!sptk::ConvertStringToInteger(optarg, &vector_length) ||
vector_length <= 0) {
std::ostringstream error_message;
error_message
<< "The argument for the -l option must be a positive integer";
sptk::PrintErrorMessage("vsum", error_message);
return 1;
}
break;
}
case 'm': {
if (!sptk::ConvertStringToInteger(optarg, &vector_length) ||
vector_length < 0) {
std::ostringstream error_message;
error_message << "The argument for the -m option must be a "
<< "non-negative integer";
sptk::PrintErrorMessage("vsum", error_message);
return 1;
}
++vector_length;
break;
}
case 't': {
if (!sptk::ConvertStringToInteger(optarg, &num_vector) ||
num_vector <= 0) {
std::ostringstream error_message;
error_message
<< "The argument for the -t option must be a positive integer";
sptk::PrintErrorMessage("vsum", error_message);
return 1;
}
break;
}
case 'h': {
PrintUsage(&std::cout);
return 0;
}
default: {
PrintUsage(&std::cerr);
return 1;
}
}
}

// get input file
const int num_rest_args(argc - optind);
if (1 < num_rest_args) {
std::ostringstream error_message;
error_message << "Too many input files";
sptk::PrintErrorMessage("vsum", error_message);
return 1;
}
const char* input_file(0 == num_rest_args ? NULL : argv[optind]);

// open stream
std::ifstream ifs;
ifs.open(input_file, std::ios::in | std::ios::binary);
if (ifs.fail() && NULL != input_file) {
std::ostringstream error_message;
error_message << "Cannot open file " << input_file;
sptk::PrintErrorMessage("vsum", error_message);
return 1;
}
std::istream& input_stream(ifs.fail() ? std::cin : ifs);

sptk::StatisticsAccumulator accumulator(vector_length - 1, 1);
sptk::StatisticsAccumulator::Buffer buffer;
if (!accumulator.IsValid()) {
std::ostringstream error_message;
error_message << "Failed to set condition for accumulation";
sptk::PrintErrorMessage("vsum", error_message);
return 1;
}

std::vector<double> data(vector_length);
std::vector<double> sum(vector_length);
for (int vector_index(1);
sptk::ReadStream(false, 0, 0, vector_length, &data, &input_stream, NULL);
++vector_index) {
if (!accumulator.Run(data, &buffer)) {
std::ostringstream error_message;
error_message << "Failed to accumulate statistics";
sptk::PrintErrorMessage("vsum", error_message);
return 1;
}

if (kMagicNumberForEndOfFile != num_vector &&
vector_index % num_vector == 0) {
if (!accumulator.GetSum(buffer, &sum)) {
std::ostringstream error_message;
error_message << "Failed to accumulate statistics";
sptk::PrintErrorMessage("vsum", error_message);
return 1;
}
if (!sptk::WriteStream(0, vector_length, sum, &std::cout, NULL)) {
std::ostringstream error_message;
error_message << "Failed to write statistics";
sptk::PrintErrorMessage("vsum", error_message);
return 1;
}
accumulator.Clear(&buffer);
}
}

if (kMagicNumberForEndOfFile == num_vector) {
if (!accumulator.GetSum(buffer, &sum)) {
std::ostringstream error_message;
error_message << "Failed to accumulate statistics";
sptk::PrintErrorMessage("vsum", error_message);
return 1;
}
if (!sptk::WriteStream(0, vector_length, sum, &std::cout, NULL)) {
std::ostringstream error_message;
error_message << "Failed to write statistics";
sptk::PrintErrorMessage("vsum", error_message);
return 1;
}
}

return 0;
}

0 comments on commit 38aa401

Please sign in to comment.