mirror of
https://github.com/TheAlgorithms/C-Plus-Plus.git
synced 2026-02-09 05:27:11 +08:00
Merge branch 'master' into is_graph_bipartite
This commit is contained in:
167
.clang-format
Normal file
167
.clang-format
Normal file
@@ -0,0 +1,167 @@
|
|||||||
|
---
|
||||||
|
Language: Cpp
|
||||||
|
AccessModifierOffset: -3
|
||||||
|
AlignAfterOpenBracket: Align
|
||||||
|
AlignConsecutiveMacros: true
|
||||||
|
AlignConsecutiveAssignments: false
|
||||||
|
AlignConsecutiveDeclarations: false
|
||||||
|
AlignEscapedNewlines: Left
|
||||||
|
AlignOperands: true
|
||||||
|
AlignTrailingComments: true
|
||||||
|
AllowAllArgumentsOnNextLine: true
|
||||||
|
AllowAllConstructorInitializersOnNextLine: true
|
||||||
|
AllowAllParametersOfDeclarationOnNextLine: true
|
||||||
|
AllowShortBlocksOnASingleLine: Never
|
||||||
|
AllowShortCaseLabelsOnASingleLine: false
|
||||||
|
AllowShortFunctionsOnASingleLine: All
|
||||||
|
AllowShortLambdasOnASingleLine: All
|
||||||
|
AllowShortIfStatementsOnASingleLine: Never
|
||||||
|
AllowShortLoopsOnASingleLine: true
|
||||||
|
AlwaysBreakAfterDefinitionReturnType: None
|
||||||
|
AlwaysBreakAfterReturnType: None
|
||||||
|
AlwaysBreakBeforeMultilineStrings: true
|
||||||
|
AlwaysBreakTemplateDeclarations: Yes
|
||||||
|
BinPackArguments: true
|
||||||
|
BinPackParameters: true
|
||||||
|
BraceWrapping:
|
||||||
|
AfterCaseLabel: false
|
||||||
|
AfterClass: false
|
||||||
|
AfterControlStatement: false
|
||||||
|
AfterEnum: false
|
||||||
|
AfterFunction: false
|
||||||
|
AfterNamespace: false
|
||||||
|
AfterObjCDeclaration: false
|
||||||
|
AfterStruct: false
|
||||||
|
AfterUnion: false
|
||||||
|
AfterExternBlock: false
|
||||||
|
BeforeCatch: false
|
||||||
|
BeforeElse: false
|
||||||
|
IndentBraces: false
|
||||||
|
SplitEmptyFunction: true
|
||||||
|
SplitEmptyRecord: true
|
||||||
|
SplitEmptyNamespace: true
|
||||||
|
BreakBeforeBinaryOperators: None
|
||||||
|
BreakBeforeBraces: Attach
|
||||||
|
BreakBeforeInheritanceComma: false
|
||||||
|
BreakInheritanceList: BeforeColon
|
||||||
|
BreakBeforeTernaryOperators: true
|
||||||
|
BreakConstructorInitializersBeforeComma: false
|
||||||
|
BreakConstructorInitializers: BeforeColon
|
||||||
|
BreakAfterJavaFieldAnnotations: false
|
||||||
|
BreakStringLiterals: true
|
||||||
|
ColumnLimit: 80
|
||||||
|
CommentPragmas: '^ IWYU pragma:'
|
||||||
|
CompactNamespaces: false
|
||||||
|
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
||||||
|
ConstructorInitializerIndentWidth: 4
|
||||||
|
ContinuationIndentWidth: 4
|
||||||
|
Cpp11BracedListStyle: true
|
||||||
|
DeriveLineEnding: true
|
||||||
|
DerivePointerAlignment: true
|
||||||
|
DisableFormat: false
|
||||||
|
ExperimentalAutoDetectBinPacking: false
|
||||||
|
FixNamespaceComments: true
|
||||||
|
ForEachMacros:
|
||||||
|
- foreach
|
||||||
|
- Q_FOREACH
|
||||||
|
- BOOST_FOREACH
|
||||||
|
IncludeBlocks: Regroup
|
||||||
|
IncludeCategories:
|
||||||
|
- Regex: '^<ext/.*\.h>'
|
||||||
|
Priority: 2
|
||||||
|
SortPriority: 0
|
||||||
|
- Regex: '^<.*\.h>'
|
||||||
|
Priority: 1
|
||||||
|
SortPriority: 0
|
||||||
|
- Regex: '^<.*'
|
||||||
|
Priority: 2
|
||||||
|
SortPriority: 0
|
||||||
|
- Regex: '.*'
|
||||||
|
Priority: 3
|
||||||
|
SortPriority: 0
|
||||||
|
IncludeIsMainRegex: '([-_](test|unittest))?$'
|
||||||
|
IncludeIsMainSourceRegex: ''
|
||||||
|
IndentCaseLabels: true
|
||||||
|
IndentGotoLabels: true
|
||||||
|
IndentPPDirectives: None
|
||||||
|
IndentWidth: 4
|
||||||
|
IndentWrappedFunctionNames: false
|
||||||
|
JavaScriptQuotes: Leave
|
||||||
|
JavaScriptWrapImports: true
|
||||||
|
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||||
|
MacroBlockBegin: ''
|
||||||
|
MacroBlockEnd: ''
|
||||||
|
MaxEmptyLinesToKeep: 1
|
||||||
|
NamespaceIndentation: None
|
||||||
|
ObjCBinPackProtocolList: Never
|
||||||
|
ObjCBlockIndentWidth: 2
|
||||||
|
ObjCSpaceAfterProperty: false
|
||||||
|
ObjCSpaceBeforeProtocolList: true
|
||||||
|
PenaltyBreakAssignment: 2
|
||||||
|
PenaltyBreakBeforeFirstCallParameter: 1
|
||||||
|
PenaltyBreakComment: 300
|
||||||
|
PenaltyBreakFirstLessLess: 120
|
||||||
|
PenaltyBreakString: 1000
|
||||||
|
PenaltyBreakTemplateDeclaration: 10
|
||||||
|
PenaltyExcessCharacter: 1000000
|
||||||
|
PenaltyReturnTypeOnItsOwnLine: 200
|
||||||
|
PointerAlignment: Left
|
||||||
|
RawStringFormats:
|
||||||
|
- Language: Cpp
|
||||||
|
Delimiters:
|
||||||
|
- cc
|
||||||
|
- CC
|
||||||
|
- cpp
|
||||||
|
- Cpp
|
||||||
|
- CPP
|
||||||
|
- 'c++'
|
||||||
|
- 'C++'
|
||||||
|
CanonicalDelimiter: ''
|
||||||
|
BasedOnStyle: google
|
||||||
|
- Language: TextProto
|
||||||
|
Delimiters:
|
||||||
|
- pb
|
||||||
|
- PB
|
||||||
|
- proto
|
||||||
|
- PROTO
|
||||||
|
EnclosingFunctions:
|
||||||
|
- EqualsProto
|
||||||
|
- EquivToProto
|
||||||
|
- PARSE_PARTIAL_TEXT_PROTO
|
||||||
|
- PARSE_TEST_PROTO
|
||||||
|
- PARSE_TEXT_PROTO
|
||||||
|
- ParseTextOrDie
|
||||||
|
- ParseTextProtoOrDie
|
||||||
|
CanonicalDelimiter: ''
|
||||||
|
BasedOnStyle: google
|
||||||
|
ReflowComments: true
|
||||||
|
SortIncludes: true
|
||||||
|
SortUsingDeclarations: true
|
||||||
|
SpaceAfterCStyleCast: false
|
||||||
|
SpaceAfterLogicalNot: false
|
||||||
|
SpaceAfterTemplateKeyword: true
|
||||||
|
SpaceBeforeAssignmentOperators: true
|
||||||
|
SpaceBeforeCpp11BracedList: false
|
||||||
|
SpaceBeforeCtorInitializerColon: true
|
||||||
|
SpaceBeforeInheritanceColon: true
|
||||||
|
SpaceBeforeParens: ControlStatements
|
||||||
|
SpaceBeforeRangeBasedForLoopColon: true
|
||||||
|
SpaceInEmptyBlock: false
|
||||||
|
SpaceInEmptyParentheses: false
|
||||||
|
SpacesBeforeTrailingComments: 2
|
||||||
|
SpacesInAngles: false
|
||||||
|
SpacesInConditionalStatement: false
|
||||||
|
SpacesInContainerLiterals: true
|
||||||
|
SpacesInCStyleCastParentheses: false
|
||||||
|
SpacesInParentheses: false
|
||||||
|
SpacesInSquareBrackets: false
|
||||||
|
SpaceBeforeSquareBrackets: false
|
||||||
|
Standard: Auto
|
||||||
|
StatementMacros:
|
||||||
|
- Q_UNUSED
|
||||||
|
- QT_REQUIRE_VERSION
|
||||||
|
TabWidth: 4
|
||||||
|
UseCRLF: false
|
||||||
|
UseTab: Never
|
||||||
|
...
|
||||||
|
|
||||||
16
.github/workflows/awesome_workflow.yml
vendored
16
.github/workflows/awesome_workflow.yml
vendored
@@ -16,7 +16,7 @@ jobs:
|
|||||||
- name: requirements
|
- name: requirements
|
||||||
run: |
|
run: |
|
||||||
sudo apt -qq -y update
|
sudo apt -qq -y update
|
||||||
sudo apt -qq install clang-tidy-10
|
sudo apt -qq install clang-tidy-10 clang-format-10
|
||||||
# checks are passing with less errors when used with this version.
|
# checks are passing with less errors when used with this version.
|
||||||
# The default installs v6.0 which did not work out well in my tests
|
# The default installs v6.0 which did not work out well in my tests
|
||||||
- name: Setup Git Specs
|
- name: Setup Git Specs
|
||||||
@@ -44,7 +44,7 @@ jobs:
|
|||||||
git "mv" "${fname}" ${new_fname}
|
git "mv" "${fname}" ${new_fname}
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
git commit -am "formatting filenames $GITHUB_SHA" || true
|
git commit -am "formatting filenames ${GITHUB_SHA::8}" || true
|
||||||
|
|
||||||
- name: Update DIRECTORY.md
|
- name: Update DIRECTORY.md
|
||||||
shell: python
|
shell: python
|
||||||
@@ -124,15 +124,9 @@ jobs:
|
|||||||
|
|
||||||
subprocess.run(["clang-tidy-10", "--fix", "-p=build", "--extra-arg=-std=c++11", *cpp_files, "--"],
|
subprocess.run(["clang-tidy-10", "--fix", "-p=build", "--extra-arg=-std=c++11", *cpp_files, "--"],
|
||||||
check=True, text=True, stderr=subprocess.STDOUT)
|
check=True, text=True, stderr=subprocess.STDOUT)
|
||||||
# for cpp_file in cpp_files:
|
|
||||||
# subprocess.run(["clang-tidy-10", "--fix", "-p=build", cpp_file, "--"],
|
|
||||||
# check=True, text=True, stderr=subprocess.STDOUT)
|
|
||||||
|
|
||||||
# print("g++:")
|
subprocess.run(["clang-format-10", "-i", "-style=file", *cpp_files],
|
||||||
# compile_exts = tuple(".c .c++ .cc .cpp .cu .cxx".split())
|
check=True, text=True, stderr=subprocess.STDOUT)
|
||||||
# compile_files = [file for file in cpp_files if file.lower().endswith(compile_exts)]
|
|
||||||
# for cpp_file in cpp_files:
|
|
||||||
# subprocess.run(["g++", cpp_file], check=True, text=True)
|
|
||||||
|
|
||||||
upper_files = [file for file in cpp_files if file != file.lower()]
|
upper_files = [file for file in cpp_files if file != file.lower()]
|
||||||
if upper_files:
|
if upper_files:
|
||||||
@@ -155,7 +149,7 @@ jobs:
|
|||||||
- name: Commit and push changes
|
- name: Commit and push changes
|
||||||
run: |
|
run: |
|
||||||
git diff DIRECTORY.md
|
git diff DIRECTORY.md
|
||||||
git commit -am "clang-tidy fixes for $GITHUB_SHA" || true
|
git commit -am "clang-format and clang-tidy fixes for ${GITHUB_SHA::8}" || true
|
||||||
git push --force origin HEAD:$GITHUB_REF || true
|
git push --force origin HEAD:$GITHUB_REF || true
|
||||||
|
|
||||||
build:
|
build:
|
||||||
|
|||||||
@@ -1,50 +1,103 @@
|
|||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* @brief [Eight Queens](https://en.wikipedia.org/wiki/Eight_queens_puzzle)
|
||||||
|
* puzzle, printing all solutions
|
||||||
|
*
|
||||||
|
* @author [Himani Negi](https://github.com/Himani2000)
|
||||||
|
* @author [David Leal](https://github.com/Panquesito7)
|
||||||
|
*
|
||||||
|
*/
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#define n 4
|
#include <array>
|
||||||
|
|
||||||
void PrintSol(int Board[n][n]) {
|
/**
|
||||||
|
* @namespace backtracking
|
||||||
|
* @brief Backtracking algorithms
|
||||||
|
*/
|
||||||
|
namespace backtracking {
|
||||||
|
/**
|
||||||
|
* @namespace n_queens_all_solutions
|
||||||
|
* @brief Functions for [Eight
|
||||||
|
* Queens](https://en.wikipedia.org/wiki/Eight_queens_puzzle) puzzle with all solutions.
|
||||||
|
*/
|
||||||
|
namespace n_queens_all_solutions {
|
||||||
|
/**
|
||||||
|
* Utility function to print matrix
|
||||||
|
* @tparam n number of matrix size
|
||||||
|
* @param board matrix where numbers are saved
|
||||||
|
*/
|
||||||
|
template <size_t n>
|
||||||
|
void PrintSol(const std::array<std::array<int, n>, n>& board) {
|
||||||
for (int i = 0; i < n; i++) {
|
for (int i = 0; i < n; i++) {
|
||||||
for (int j = 0; j < n; j++) {
|
for (int j = 0; j < n; j++) {
|
||||||
std::cout << Board[i][j] << " ";
|
std::cout << board[i][j] << " ";
|
||||||
}
|
}
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
}
|
}
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CanIMove(int Board[n][n], int row, int col) {
|
/**
|
||||||
|
* Check if a queen can be placed on matrix
|
||||||
|
* @tparam n number of matrix size
|
||||||
|
* @param board matrix where numbers are saved
|
||||||
|
* @param row current index in rows
|
||||||
|
* @param col current index in columns
|
||||||
|
* @returns `true` if queen can be placed on matrix
|
||||||
|
* @returns `false` if queen can't be placed on matrix
|
||||||
|
*/
|
||||||
|
template <size_t n>
|
||||||
|
bool CanIMove(const std::array<std::array<int, n>, n>& board, int row, int col) {
|
||||||
/// check in the row
|
/// check in the row
|
||||||
for (int i = 0; i < col; i++) {
|
for (int i = 0; i < col; i++) {
|
||||||
if (Board[row][i] == 1)
|
if (board[row][i] == 1) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/// check the first diagonal
|
/// check the first diagonal
|
||||||
for (int i = row, j = col; i >= 0 && j >= 0; i--, j--) {
|
for (int i = row, j = col; i >= 0 && j >= 0; i--, j--) {
|
||||||
if (Board[i][j] == 1)
|
if (board[i][j] == 1) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/// check the second diagonal
|
/// check the second diagonal
|
||||||
for (int i = row, j = col; i <= n - 1 && j >= 0; i++, j--) {
|
for (int i = row, j = col; i <= n - 1 && j >= 0; i++, j--) {
|
||||||
if (Board[i][j] == 1)
|
if (board[i][j] == 1) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NQueenSol(int Board[n][n], int col) {
|
/**
|
||||||
|
* Solve n queens problem
|
||||||
|
* @tparam n number of matrix size
|
||||||
|
* @param board matrix where numbers are saved
|
||||||
|
* @param col current index in columns
|
||||||
|
*/
|
||||||
|
template <size_t n>
|
||||||
|
void NQueenSol(std::array<std::array<int, n>, n> board, int col) {
|
||||||
if (col >= n) {
|
if (col >= n) {
|
||||||
PrintSol(Board);
|
PrintSol(board);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < n; i++) {
|
for (int i = 0; i < n; i++) {
|
||||||
if (CanIMove(Board, i, col)) {
|
if (CanIMove(board, i, col)) {
|
||||||
Board[i][col] = 1;
|
board[i][col] = 1;
|
||||||
NQueenSol(Board, col + 1);
|
NQueenSol(board, col + 1);
|
||||||
Board[i][col] = 0;
|
board[i][col] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} // namespace n_queens_all_solutions
|
||||||
|
} // namespace backtracking
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main function
|
||||||
|
*/
|
||||||
int main() {
|
int main() {
|
||||||
int Board[n][n] = {0};
|
const int n = 4;
|
||||||
NQueenSol(Board, 0);
|
std::array<std::array<int, n>, n> board{0};
|
||||||
|
|
||||||
|
backtracking::n_queens_all_solutions::NQueenSol(board, 0);
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,20 +1,21 @@
|
|||||||
/**
|
/**
|
||||||
* @file vector_ops.hpp
|
* @file vector_ops.hpp
|
||||||
* @author [Deep Raval](https://github.com/imdeep2905)
|
* @author [Deep Raval](https://github.com/imdeep2905)
|
||||||
*
|
*
|
||||||
* @brief Various functions for vectors associated with [NeuralNetwork (aka Multilayer Perceptron)]
|
* @brief Various functions for vectors associated with [NeuralNetwork (aka
|
||||||
|
* Multilayer Perceptron)]
|
||||||
* (https://en.wikipedia.org/wiki/Multilayer_perceptron).
|
* (https://en.wikipedia.org/wiki/Multilayer_perceptron).
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#ifndef VECTOR_OPS_FOR_NN
|
#ifndef VECTOR_OPS_FOR_NN
|
||||||
#define VECTOR_OPS_FOR_NN
|
#define VECTOR_OPS_FOR_NN
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <vector>
|
|
||||||
#include <valarray>
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
#include <iostream>
|
||||||
#include <random>
|
#include <random>
|
||||||
|
#include <valarray>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @namespace machine_learning
|
* @namespace machine_learning
|
||||||
@@ -31,18 +32,18 @@ template <typename T>
|
|||||||
std::ostream &operator<<(std::ostream &out,
|
std::ostream &operator<<(std::ostream &out,
|
||||||
std::vector<std::valarray<T>> const &A) {
|
std::vector<std::valarray<T>> const &A) {
|
||||||
// Setting output precision to 4 in case of floating point numbers
|
// Setting output precision to 4 in case of floating point numbers
|
||||||
out.precision(4);
|
out.precision(4);
|
||||||
for(const auto &a : A) { // For each row in A
|
for (const auto &a : A) { // For each row in A
|
||||||
for(const auto &x : a) { // For each element in row
|
for (const auto &x : a) { // For each element in row
|
||||||
std::cerr << x << ' '; // print element
|
std::cout << x << ' '; // print element
|
||||||
}
|
}
|
||||||
std::cerr << std::endl;
|
std::cout << std::endl;
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Overloaded operator "<<" to print a pair
|
* Overloaded operator "<<" to print a pair
|
||||||
* @tparam T typename of the pair
|
* @tparam T typename of the pair
|
||||||
* @param out std::ostream to output
|
* @param out std::ostream to output
|
||||||
* @param A Pair to be printed
|
* @param A Pair to be printed
|
||||||
@@ -52,7 +53,7 @@ std::ostream &operator<<(std::ostream &out, const std::pair<T, T> &A) {
|
|||||||
// Setting output precision to 4 in case of floating point numbers
|
// Setting output precision to 4 in case of floating point numbers
|
||||||
out.precision(4);
|
out.precision(4);
|
||||||
// printing pair in the form (p, q)
|
// printing pair in the form (p, q)
|
||||||
std::cerr << "(" << A.first << ", " << A.second << ")";
|
std::cout << "(" << A.first << ", " << A.second << ")";
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,10 +67,10 @@ template <typename T>
|
|||||||
std::ostream &operator<<(std::ostream &out, const std::valarray<T> &A) {
|
std::ostream &operator<<(std::ostream &out, const std::valarray<T> &A) {
|
||||||
// Setting output precision to 4 in case of floating point numbers
|
// Setting output precision to 4 in case of floating point numbers
|
||||||
out.precision(4);
|
out.precision(4);
|
||||||
for(const auto &a : A) { // For every element in the vector.
|
for (const auto &a : A) { // For every element in the vector.
|
||||||
std::cerr << a << ' '; // Print element
|
std::cout << a << ' '; // Print element
|
||||||
}
|
}
|
||||||
std::cerr << std::endl;
|
std::cout << std::endl;
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,14 +82,14 @@ std::ostream &operator<<(std::ostream &out, const std::valarray<T> &A) {
|
|||||||
* @return new resultant vector
|
* @return new resultant vector
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::valarray<T> insert_element(const std::valarray <T> &A, const T &ele) {
|
std::valarray<T> insert_element(const std::valarray<T> &A, const T &ele) {
|
||||||
std::valarray <T> B; // New 1D vector to store resultant vector
|
std::valarray<T> B; // New 1D vector to store resultant vector
|
||||||
B.resize(A.size() + 1); // Resizing it accordingly
|
B.resize(A.size() + 1); // Resizing it accordingly
|
||||||
for(size_t i = 0; i < A.size(); i++) { // For every element in A
|
for (size_t i = 0; i < A.size(); i++) { // For every element in A
|
||||||
B[i] = A[i]; // Copy element in B
|
B[i] = A[i]; // Copy element in B
|
||||||
}
|
}
|
||||||
B[B.size() - 1] = ele; // Inserting new element in last position
|
B[B.size() - 1] = ele; // Inserting new element in last position
|
||||||
return B; // Return resultant vector
|
return B; // Return resultant vector
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -98,13 +99,14 @@ std::valarray<T> insert_element(const std::valarray <T> &A, const T &ele) {
|
|||||||
* @return new resultant vector
|
* @return new resultant vector
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::valarray <T> pop_front(const std::valarray<T> &A) {
|
std::valarray<T> pop_front(const std::valarray<T> &A) {
|
||||||
std::valarray <T> B; // New 1D vector to store resultant vector
|
std::valarray<T> B; // New 1D vector to store resultant vector
|
||||||
B.resize(A.size() - 1); // Resizing it accordingly
|
B.resize(A.size() - 1); // Resizing it accordingly
|
||||||
for(size_t i = 1; i < A.size(); i ++) { // // For every (except first) element in A
|
for (size_t i = 1; i < A.size();
|
||||||
B[i - 1] = A[i]; // Copy element in B with left shifted position
|
i++) { // // For every (except first) element in A
|
||||||
|
B[i - 1] = A[i]; // Copy element in B with left shifted position
|
||||||
}
|
}
|
||||||
return B; // Return resultant vector
|
return B; // Return resultant vector
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -114,13 +116,14 @@ std::valarray <T> pop_front(const std::valarray<T> &A) {
|
|||||||
* @return new resultant vector
|
* @return new resultant vector
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::valarray <T> pop_back(const std::valarray<T> &A) {
|
std::valarray<T> pop_back(const std::valarray<T> &A) {
|
||||||
std::valarray <T> B; // New 1D vector to store resultant vector
|
std::valarray<T> B; // New 1D vector to store resultant vector
|
||||||
B.resize(A.size() - 1); // Resizing it accordingly
|
B.resize(A.size() - 1); // Resizing it accordingly
|
||||||
for(size_t i = 0; i < A.size() - 1; i ++) { // For every (except last) element in A
|
for (size_t i = 0; i < A.size() - 1;
|
||||||
B[i] = A[i]; // Copy element in B
|
i++) { // For every (except last) element in A
|
||||||
|
B[i] = A[i]; // Copy element in B
|
||||||
}
|
}
|
||||||
return B; // Return resultant vector
|
return B; // Return resultant vector
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -130,16 +133,17 @@ std::valarray <T> pop_back(const std::valarray<T> &A) {
|
|||||||
* @param B Second 3D vector
|
* @param B Second 3D vector
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void equal_shuffle(std::vector < std::vector <std::valarray<T>> > &A,
|
void equal_shuffle(std::vector<std::vector<std::valarray<T>>> &A,
|
||||||
std::vector < std::vector <std::valarray<T>> > &B) {
|
std::vector<std::vector<std::valarray<T>>> &B) {
|
||||||
// If two vectors have different sizes
|
// If two vectors have different sizes
|
||||||
if(A.size() != B.size())
|
if (A.size() != B.size()) {
|
||||||
{
|
std::cerr << "ERROR (" << __func__ << ") : ";
|
||||||
std::cerr << "ERROR : Can not equally shuffle two vectors with different sizes: ";
|
std::cerr
|
||||||
|
<< "Can not equally shuffle two vectors with different sizes: ";
|
||||||
std::cerr << A.size() << " and " << B.size() << std::endl;
|
std::cerr << A.size() << " and " << B.size() << std::endl;
|
||||||
std::exit(EXIT_FAILURE);
|
std::exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
for(size_t i = 0; i < A.size(); i++) { // For every element in A and B
|
for (size_t i = 0; i < A.size(); i++) { // For every element in A and B
|
||||||
// Genrating random index < size of A and B
|
// Genrating random index < size of A and B
|
||||||
std::srand(std::chrono::system_clock::now().time_since_epoch().count());
|
std::srand(std::chrono::system_clock::now().time_since_epoch().count());
|
||||||
size_t random_index = std::rand() % A.size();
|
size_t random_index = std::rand() % A.size();
|
||||||
@@ -159,26 +163,26 @@ void equal_shuffle(std::vector < std::vector <std::valarray<T>> > &A,
|
|||||||
* @param high upper limit on value
|
* @param high upper limit on value
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void uniform_random_initialization(std::vector<std::valarray<T>> &A,
|
void uniform_random_initialization(std::vector<std::valarray<T>> &A,
|
||||||
const std::pair<size_t, size_t> &shape,
|
const std::pair<size_t, size_t> &shape,
|
||||||
const T &low,
|
const T &low, const T &high) {
|
||||||
const T &high) {
|
A.clear(); // Making A empty
|
||||||
A.clear(); // Making A empty
|
|
||||||
// Uniform distribution in range [low, high]
|
// Uniform distribution in range [low, high]
|
||||||
std::default_random_engine generator(std::chrono::system_clock::now().time_since_epoch().count());
|
std::default_random_engine generator(
|
||||||
std::uniform_real_distribution <T> distribution(low, high);
|
std::chrono::system_clock::now().time_since_epoch().count());
|
||||||
for(size_t i = 0; i < shape.first; i++) { // For every row
|
std::uniform_real_distribution<T> distribution(low, high);
|
||||||
std::valarray <T> row; // Making empty row which will be inserted in vector
|
for (size_t i = 0; i < shape.first; i++) { // For every row
|
||||||
|
std::valarray<T>
|
||||||
|
row; // Making empty row which will be inserted in vector
|
||||||
row.resize(shape.second);
|
row.resize(shape.second);
|
||||||
for(auto &r : row) { // For every element in row
|
for (auto &r : row) { // For every element in row
|
||||||
r = distribution(generator); // copy random number
|
r = distribution(generator); // copy random number
|
||||||
}
|
}
|
||||||
A.push_back(row); // Insert new row in vector
|
A.push_back(row); // Insert new row in vector
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function to Intialize 2D vector as unit matrix
|
* Function to Intialize 2D vector as unit matrix
|
||||||
* @tparam T typename of the vector
|
* @tparam T typename of the vector
|
||||||
@@ -186,15 +190,15 @@ void uniform_random_initialization(std::vector<std::valarray<T>> &A,
|
|||||||
* @param shape required shape
|
* @param shape required shape
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void unit_matrix_initialization(std::vector<std::valarray<T>> &A,
|
void unit_matrix_initialization(std::vector<std::valarray<T>> &A,
|
||||||
const std::pair<size_t, size_t> &shape
|
const std::pair<size_t, size_t> &shape) {
|
||||||
) {
|
A.clear(); // Making A empty
|
||||||
A.clear(); // Making A empty
|
for (size_t i = 0; i < shape.first; i++) {
|
||||||
for(size_t i = 0; i < shape.first; i++) {
|
std::valarray<T>
|
||||||
std::valarray <T> row; // Making empty row which will be inserted in vector
|
row; // Making empty row which will be inserted in vector
|
||||||
row.resize(shape.second);
|
row.resize(shape.second);
|
||||||
row[i] = T(1); // Insert 1 at ith position
|
row[i] = T(1); // Insert 1 at ith position
|
||||||
A.push_back(row); // Insert new row in vector
|
A.push_back(row); // Insert new row in vector
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -206,14 +210,14 @@ void unit_matrix_initialization(std::vector<std::valarray<T>> &A,
|
|||||||
* @param shape required shape
|
* @param shape required shape
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void zeroes_initialization(std::vector<std::valarray<T>> &A,
|
void zeroes_initialization(std::vector<std::valarray<T>> &A,
|
||||||
const std::pair<size_t, size_t> &shape
|
const std::pair<size_t, size_t> &shape) {
|
||||||
) {
|
A.clear(); // Making A empty
|
||||||
A.clear(); // Making A empty
|
for (size_t i = 0; i < shape.first; i++) {
|
||||||
for(size_t i = 0; i < shape.first; i++) {
|
std::valarray<T>
|
||||||
std::valarray <T> row; // Making empty row which will be inserted in vector
|
row; // Making empty row which will be inserted in vector
|
||||||
row.resize(shape.second); // By default all elements are zero
|
row.resize(shape.second); // By default all elements are zero
|
||||||
A.push_back(row); // Insert new row in vector
|
A.push_back(row); // Insert new row in vector
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -226,11 +230,11 @@ void zeroes_initialization(std::vector<std::valarray<T>> &A,
|
|||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename T>
|
||||||
T sum(const std::vector<std::valarray<T>> &A) {
|
T sum(const std::vector<std::valarray<T>> &A) {
|
||||||
T cur_sum = 0; // Initially sum is zero
|
T cur_sum = 0; // Initially sum is zero
|
||||||
for(const auto &a : A) { // For every row in A
|
for (const auto &a : A) { // For every row in A
|
||||||
cur_sum += a.sum(); // Add sum of that row to current sum
|
cur_sum += a.sum(); // Add sum of that row to current sum
|
||||||
}
|
}
|
||||||
return cur_sum; // Return sum
|
return cur_sum; // Return sum
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -242,52 +246,59 @@ T sum(const std::vector<std::valarray<T>> &A) {
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
std::pair<size_t, size_t> get_shape(const std::vector<std::valarray<T>> &A) {
|
std::pair<size_t, size_t> get_shape(const std::vector<std::valarray<T>> &A) {
|
||||||
const size_t sub_size = (*A.begin()).size();
|
const size_t sub_size = (*A.begin()).size();
|
||||||
for(const auto &a : A) {
|
for (const auto &a : A) {
|
||||||
// If supplied vector don't have same shape in all rows
|
// If supplied vector don't have same shape in all rows
|
||||||
if(a.size() != sub_size) {
|
if (a.size() != sub_size) {
|
||||||
std::cerr << "ERROR: (get_shape) Supplied vector is not 2D Matrix" << std::endl;
|
std::cerr << "ERROR (" << __func__ << ") : ";
|
||||||
|
std::cerr << "Supplied vector is not 2D Matrix" << std::endl;
|
||||||
std::exit(EXIT_FAILURE);
|
std::exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return std::make_pair(A.size(), sub_size); // Return shape as pair
|
return std::make_pair(A.size(), sub_size); // Return shape as pair
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function to scale given 3D vector using min-max scaler
|
* Function to scale given 3D vector using min-max scaler
|
||||||
* @tparam T typename of the vector
|
* @tparam T typename of the vector
|
||||||
* @param A 3D vector which will be scaled
|
* @param A 3D vector which will be scaled
|
||||||
* @param low new minimum value
|
* @param low new minimum value
|
||||||
* @param high new maximum value
|
* @param high new maximum value
|
||||||
* @return new scaled 3D vector
|
* @return new scaled 3D vector
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::vector<std::vector<std::valarray<T>>>
|
std::vector<std::vector<std::valarray<T>>> minmax_scaler(
|
||||||
minmax_scaler(const std::vector<std::vector<std::valarray<T>>> &A, const T &low, const T &high) {
|
const std::vector<std::vector<std::valarray<T>>> &A, const T &low,
|
||||||
std::vector<std::vector<std::valarray<T>>> B = A; // Copying into new vector B
|
const T &high) {
|
||||||
const auto shape = get_shape(B[0]); // Storing shape of B's every element
|
std::vector<std::vector<std::valarray<T>>> B =
|
||||||
// As this function is used for scaling training data vector should be of shape (1, X)
|
A; // Copying into new vector B
|
||||||
if(shape.first != 1) {
|
const auto shape = get_shape(B[0]); // Storing shape of B's every element
|
||||||
std::cerr << "ERROR: (MinMax Scaling) Supplied vector is not supported for minmax scaling, shape: ";
|
// As this function is used for scaling training data vector should be of
|
||||||
|
// shape (1, X)
|
||||||
|
if (shape.first != 1) {
|
||||||
|
std::cerr << "ERROR (" << __func__ << ") : ";
|
||||||
|
std::cerr
|
||||||
|
<< "Supplied vector is not supported for minmax scaling, shape: ";
|
||||||
std::cerr << shape << std::endl;
|
std::cerr << shape << std::endl;
|
||||||
std::exit(EXIT_FAILURE);
|
std::exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
for(size_t i = 0; i < shape.second; i++) {
|
for (size_t i = 0; i < shape.second; i++) {
|
||||||
T min = B[0][0][i], max = B[0][0][i];
|
T min = B[0][0][i], max = B[0][0][i];
|
||||||
for(size_t j = 0; j < B.size(); j++) {
|
for (size_t j = 0; j < B.size(); j++) {
|
||||||
// Updating minimum and maximum values
|
// Updating minimum and maximum values
|
||||||
min = std::min(min, B[j][0][i]);
|
min = std::min(min, B[j][0][i]);
|
||||||
max = std::max(max, B[j][0][i]);
|
max = std::max(max, B[j][0][i]);
|
||||||
}
|
}
|
||||||
for(size_t j = 0; j < B.size(); j++) {
|
for (size_t j = 0; j < B.size(); j++) {
|
||||||
// Applying min-max scaler formula
|
// Applying min-max scaler formula
|
||||||
B[j][0][i] = ((B[j][0][i] - min) / (max - min)) * (high - low) + low;
|
B[j][0][i] =
|
||||||
|
((B[j][0][i] - min) / (max - min)) * (high - low) + low;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return B; // Return new resultant 3D vector
|
return B; // Return new resultant 3D vector
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function to get index of maximum element in 2D vector
|
* Function to get index of maximum element in 2D vector
|
||||||
* @tparam T typename of the vector
|
* @tparam T typename of the vector
|
||||||
* @param A 2D vector for which maximum index is required
|
* @param A 2D vector for which maximum index is required
|
||||||
* @return index of maximum element
|
* @return index of maximum element
|
||||||
@@ -295,13 +306,16 @@ minmax_scaler(const std::vector<std::vector<std::valarray<T>>> &A, const T &low,
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
size_t argmax(const std::vector<std::valarray<T>> &A) {
|
size_t argmax(const std::vector<std::valarray<T>> &A) {
|
||||||
const auto shape = get_shape(A);
|
const auto shape = get_shape(A);
|
||||||
// As this function is used on predicted (or target) vector, shape should be (1, X)
|
// As this function is used on predicted (or target) vector, shape should be
|
||||||
if(shape.first != 1) {
|
// (1, X)
|
||||||
std::cerr << "ERROR: (argmax) Supplied vector is ineligible for argmax" << std::endl;
|
if (shape.first != 1) {
|
||||||
std::exit(EXIT_FAILURE);
|
std::cerr << "ERROR (" << __func__ << ") : ";
|
||||||
|
std::cerr << "Supplied vector is ineligible for argmax" << std::endl;
|
||||||
|
std::exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
// Return distance of max element from first element (i.e. index)
|
// Return distance of max element from first element (i.e. index)
|
||||||
return std::distance(std::begin(A[0]), std::max_element(std::begin(A[0]), std::end(A[0])));
|
return std::distance(std::begin(A[0]),
|
||||||
|
std::max_element(std::begin(A[0]), std::end(A[0])));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -311,46 +325,51 @@ size_t argmax(const std::vector<std::valarray<T>> &A) {
|
|||||||
* @param func Function to be applied
|
* @param func Function to be applied
|
||||||
* @return new resultant vector
|
* @return new resultant vector
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::vector <std::valarray <T>> apply_function(const std::vector <std::valarray <T>> &A,
|
std::vector<std::valarray<T>> apply_function(
|
||||||
T (*func) (const T &)) {
|
const std::vector<std::valarray<T>> &A, T (*func)(const T &)) {
|
||||||
std::vector<std::valarray<double>> B = A; // New vector to store resultant vector
|
std::vector<std::valarray<double>> B =
|
||||||
for(auto &b : B) { // For every row in vector
|
A; // New vector to store resultant vector
|
||||||
b = b.apply(func); // Apply function to that row
|
for (auto &b : B) { // For every row in vector
|
||||||
|
b = b.apply(func); // Apply function to that row
|
||||||
}
|
}
|
||||||
return B; // Return new resultant 2D vector
|
return B; // Return new resultant 2D vector
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Overloaded operator "*" to multiply given 2D vector with scaler
|
* Overloaded operator "*" to multiply given 2D vector with scaler
|
||||||
* @tparam T typename of both vector and the scaler
|
* @tparam T typename of both vector and the scaler
|
||||||
* @param A 2D vector to which scaler will be multiplied
|
* @param A 2D vector to which scaler will be multiplied
|
||||||
* @param val Scaler value which will be multiplied
|
* @param val Scaler value which will be multiplied
|
||||||
* @return new resultant vector
|
* @return new resultant vector
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::vector <std::valarray <T> > operator * (const std::vector<std::valarray<T>> &A, const T& val) {
|
std::vector<std::valarray<T>> operator*(const std::vector<std::valarray<T>> &A,
|
||||||
std::vector<std::valarray<double>> B = A; // New vector to store resultant vector
|
const T &val) {
|
||||||
for(auto &b : B) { // For every row in vector
|
std::vector<std::valarray<double>> B =
|
||||||
b = b * val; // Multiply row with scaler
|
A; // New vector to store resultant vector
|
||||||
|
for (auto &b : B) { // For every row in vector
|
||||||
|
b = b * val; // Multiply row with scaler
|
||||||
}
|
}
|
||||||
return B; // Return new resultant 2D vector
|
return B; // Return new resultant 2D vector
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Overloaded operator "/" to divide given 2D vector with scaler
|
* Overloaded operator "/" to divide given 2D vector with scaler
|
||||||
* @tparam T typename of the vector and the scaler
|
* @tparam T typename of the vector and the scaler
|
||||||
* @param A 2D vector to which scaler will be divided
|
* @param A 2D vector to which scaler will be divided
|
||||||
* @param val Scaler value which will be divided
|
* @param val Scaler value which will be divided
|
||||||
* @return new resultant vector
|
* @return new resultant vector
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::vector <std::valarray <T> > operator / (const std::vector<std::valarray<T>> &A, const T& val) {
|
std::vector<std::valarray<T>> operator/(const std::vector<std::valarray<T>> &A,
|
||||||
std::vector<std::valarray<double>> B = A; // New vector to store resultant vector
|
const T &val) {
|
||||||
for(auto &b : B) { // For every row in vector
|
std::vector<std::valarray<double>> B =
|
||||||
b = b / val; // Divide row with scaler
|
A; // New vector to store resultant vector
|
||||||
|
for (auto &b : B) { // For every row in vector
|
||||||
|
b = b / val; // Divide row with scaler
|
||||||
}
|
}
|
||||||
return B; // Return new resultant 2D vector
|
return B; // Return new resultant 2D vector
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -360,125 +379,136 @@ std::vector <std::valarray <T> > operator / (const std::vector<std::valarray<T>>
|
|||||||
* @return new resultant vector
|
* @return new resultant vector
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::vector <std::valarray <T>> transpose(const std::vector<std::valarray<T>> &A) {
|
std::vector<std::valarray<T>> transpose(
|
||||||
const auto shape = get_shape(A); // Current shape of vector
|
const std::vector<std::valarray<T>> &A) {
|
||||||
std::vector <std::valarray <T> > B; // New vector to store result
|
const auto shape = get_shape(A); // Current shape of vector
|
||||||
|
std::vector<std::valarray<T>> B; // New vector to store result
|
||||||
// Storing transpose values of A in B
|
// Storing transpose values of A in B
|
||||||
for(size_t j = 0; j < shape.second; j++) {
|
for (size_t j = 0; j < shape.second; j++) {
|
||||||
std::valarray <T> row;
|
std::valarray<T> row;
|
||||||
row.resize(shape.first);
|
row.resize(shape.first);
|
||||||
for(size_t i = 0; i < shape.first; i++) {
|
for (size_t i = 0; i < shape.first; i++) {
|
||||||
row[i] = A[i][j];
|
row[i] = A[i][j];
|
||||||
}
|
}
|
||||||
B.push_back(row);
|
B.push_back(row);
|
||||||
}
|
}
|
||||||
return B; // Return new resultant 2D vector
|
return B; // Return new resultant 2D vector
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Overloaded operator "+" to add two 2D vectors
|
* Overloaded operator "+" to add two 2D vectors
|
||||||
* @tparam T typename of the vector
|
* @tparam T typename of the vector
|
||||||
* @param A First 2D vector
|
* @param A First 2D vector
|
||||||
* @param B Second 2D vector
|
* @param B Second 2D vector
|
||||||
* @return new resultant vector
|
* @return new resultant vector
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::vector <std::valarray <T> > operator + (const std::vector<std::valarray<T>> &A, const std::vector<std::valarray<T>> &B) {
|
std::vector<std::valarray<T>> operator+(
|
||||||
|
const std::vector<std::valarray<T>> &A,
|
||||||
|
const std::vector<std::valarray<T>> &B) {
|
||||||
const auto shape_a = get_shape(A);
|
const auto shape_a = get_shape(A);
|
||||||
const auto shape_b = get_shape(B);
|
const auto shape_b = get_shape(B);
|
||||||
// If vectors don't have equal shape
|
// If vectors don't have equal shape
|
||||||
if(shape_a.first != shape_b.first || shape_a.second != shape_b.second) {
|
if (shape_a.first != shape_b.first || shape_a.second != shape_b.second) {
|
||||||
std::cerr << "ERROR: (vector addition) Supplied vectors have different shapes ";
|
std::cerr << "ERROR (" << __func__ << ") : ";
|
||||||
|
std::cerr << "Supplied vectors have different shapes ";
|
||||||
std::cerr << shape_a << " and " << shape_b << std::endl;
|
std::cerr << shape_a << " and " << shape_b << std::endl;
|
||||||
std::exit(EXIT_FAILURE);
|
std::exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
std::vector<std::valarray <T>> C;
|
std::vector<std::valarray<T>> C;
|
||||||
for(size_t i = 0; i < A.size(); i++) { // For every row
|
for (size_t i = 0; i < A.size(); i++) { // For every row
|
||||||
C.push_back(A[i] + B[i]); // Elementwise addition
|
C.push_back(A[i] + B[i]); // Elementwise addition
|
||||||
}
|
}
|
||||||
return C; // Return new resultant 2D vector
|
return C; // Return new resultant 2D vector
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Overloaded operator "-" to add subtract 2D vectors
|
* Overloaded operator "-" to add subtract 2D vectors
|
||||||
* @tparam T typename of the vector
|
* @tparam T typename of the vector
|
||||||
* @param A First 2D vector
|
* @param A First 2D vector
|
||||||
* @param B Second 2D vector
|
* @param B Second 2D vector
|
||||||
* @return new resultant vector
|
* @return new resultant vector
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::vector <std::valarray <T>> operator - (const std::vector<std::valarray<T>> &A, const std::vector<std::valarray<T>> &B) {
|
std::vector<std::valarray<T>> operator-(
|
||||||
|
const std::vector<std::valarray<T>> &A,
|
||||||
|
const std::vector<std::valarray<T>> &B) {
|
||||||
const auto shape_a = get_shape(A);
|
const auto shape_a = get_shape(A);
|
||||||
const auto shape_b = get_shape(B);
|
const auto shape_b = get_shape(B);
|
||||||
// If vectors don't have equal shape
|
// If vectors don't have equal shape
|
||||||
if(shape_a.first != shape_b.first || shape_a.second != shape_b.second) {
|
if (shape_a.first != shape_b.first || shape_a.second != shape_b.second) {
|
||||||
std::cerr << "ERROR: (vector subtraction) Supplied vectors have different shapes ";
|
std::cerr << "ERROR (" << __func__ << ") : ";
|
||||||
|
std::cerr << "Supplied vectors have different shapes ";
|
||||||
std::cerr << shape_a << " and " << shape_b << std::endl;
|
std::cerr << shape_a << " and " << shape_b << std::endl;
|
||||||
std::exit(EXIT_FAILURE);
|
std::exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
std::vector<std::valarray<T>> C; // Vector to store result
|
std::vector<std::valarray<T>> C; // Vector to store result
|
||||||
for(size_t i = 0; i < A.size(); i++) { // For every row
|
for (size_t i = 0; i < A.size(); i++) { // For every row
|
||||||
C.push_back(A[i] - B[i]); // Elementwise substraction
|
C.push_back(A[i] - B[i]); // Elementwise substraction
|
||||||
}
|
}
|
||||||
return C; // Return new resultant 2D vector
|
return C; // Return new resultant 2D vector
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function to multiply two 2D vectors
|
* Function to multiply two 2D vectors
|
||||||
* @tparam T typename of the vector
|
* @tparam T typename of the vector
|
||||||
* @param A First 2D vector
|
* @param A First 2D vector
|
||||||
* @param B Second 2D vector
|
* @param B Second 2D vector
|
||||||
* @return new resultant vector
|
* @return new resultant vector
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::vector <std::valarray <T>> multiply(const std::vector<std::valarray<T>> &A, const std::vector<std::valarray<T>> &B) {
|
std::vector<std::valarray<T>> multiply(const std::vector<std::valarray<T>> &A,
|
||||||
|
const std::vector<std::valarray<T>> &B) {
|
||||||
const auto shape_a = get_shape(A);
|
const auto shape_a = get_shape(A);
|
||||||
const auto shape_b = get_shape(B);
|
const auto shape_b = get_shape(B);
|
||||||
// If vectors are not eligible for multiplication
|
// If vectors are not eligible for multiplication
|
||||||
if(shape_a.second != shape_b.first ) {
|
if (shape_a.second != shape_b.first) {
|
||||||
std::cerr << "ERROR: (multiply) Supplied vectors are not eligible for multiplication ";
|
std::cerr << "ERROR (" << __func__ << ") : ";
|
||||||
|
std::cerr << "Vectors are not eligible for multiplication ";
|
||||||
std::cerr << shape_a << " and " << shape_b << std::endl;
|
std::cerr << shape_a << " and " << shape_b << std::endl;
|
||||||
std::exit(EXIT_FAILURE);
|
std::exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
std::vector<std::valarray<T>> C; // Vector to store result
|
std::vector<std::valarray<T>> C; // Vector to store result
|
||||||
// Normal matrix multiplication
|
// Normal matrix multiplication
|
||||||
for (size_t i = 0; i < shape_a.first; i++) {
|
for (size_t i = 0; i < shape_a.first; i++) {
|
||||||
std::valarray<T> row;
|
std::valarray<T> row;
|
||||||
row.resize(shape_b.second);
|
row.resize(shape_b.second);
|
||||||
for(size_t j = 0; j < shape_b.second; j++) {
|
for (size_t j = 0; j < shape_b.second; j++) {
|
||||||
for(size_t k = 0; k < shape_a.second; k++) {
|
for (size_t k = 0; k < shape_a.second; k++) {
|
||||||
row[j] += A[i][k] * B[k][j];
|
row[j] += A[i][k] * B[k][j];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
C.push_back(row);
|
C.push_back(row);
|
||||||
}
|
}
|
||||||
return C; // Return new resultant 2D vector
|
return C; // Return new resultant 2D vector
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function to get hadamard product of two 2D vectors
|
* Function to get hadamard product of two 2D vectors
|
||||||
* @tparam T typename of the vector
|
* @tparam T typename of the vector
|
||||||
* @param A First 2D vector
|
* @param A First 2D vector
|
||||||
* @param B Second 2D vector
|
* @param B Second 2D vector
|
||||||
* @return new resultant vector
|
* @return new resultant vector
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::vector <std::valarray <T>> hadamard_product(const std::vector<std::valarray<T>> &A, const std::vector<std::valarray<T>> &B) {
|
std::vector<std::valarray<T>> hadamard_product(
|
||||||
|
const std::vector<std::valarray<T>> &A,
|
||||||
|
const std::vector<std::valarray<T>> &B) {
|
||||||
const auto shape_a = get_shape(A);
|
const auto shape_a = get_shape(A);
|
||||||
const auto shape_b = get_shape(B);
|
const auto shape_b = get_shape(B);
|
||||||
// If vectors are not eligible for hadamard product
|
// If vectors are not eligible for hadamard product
|
||||||
if(shape_a.first != shape_b.first || shape_a.second != shape_b.second) {
|
if (shape_a.first != shape_b.first || shape_a.second != shape_b.second) {
|
||||||
std::cerr << "ERROR: (hadamard_product) Supplied vectors have different shapes ";
|
std::cerr << "ERROR (" << __func__ << ") : ";
|
||||||
|
std::cerr << "Vectors have different shapes ";
|
||||||
std::cerr << shape_a << " and " << shape_b << std::endl;
|
std::cerr << shape_a << " and " << shape_b << std::endl;
|
||||||
std::exit(EXIT_FAILURE);
|
std::exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
std::vector<std::valarray<T>> C; // Vector to store result
|
std::vector<std::valarray<T>> C; // Vector to store result
|
||||||
for(size_t i = 0; i < A.size(); i++) {
|
for (size_t i = 0; i < A.size(); i++) {
|
||||||
C.push_back(A[i] * B[i]); // Elementwise multiplication
|
C.push_back(A[i] * B[i]); // Elementwise multiplication
|
||||||
}
|
}
|
||||||
return C; // Return new resultant 2D vector
|
return C; // Return new resultant 2D vector
|
||||||
}
|
}
|
||||||
} // namespace machine_learning
|
} // namespace machine_learning
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user