what is the purpose of passing -1 in add function? - c++

I am currently programming a Strassen multiplication program in CPP using vectors. I just want to know why at some function add -1 are passed and at some add function call, -1 is not passed. what is the use purpose of passing -1 in function? if I remove that -1 from the calls I got a different incorrect output.
// Strassen’s Matrix Multiplication
#include <bits/stdc++.h>
using namespace std;
// Size of two matrices
#define ROW_1 4
#define COL_1 4
#define ROW_2 4
#define COL_2 4
// print the matrix
void print(vector<vector<int> > matrix) {
for(int i = 0; i < matrix.size(); i++){
for(int j = 0; j < matrix[i].size(); j++){
cout << matrix[i][j] << ' ';
}
cout << endl;
}
}
// Add two matrices and return the result
vector<vector<int>> add(vector<vector<int> > A, vector<vector<int> > B, int split_index, int multiplier = 1) {
for (auto i = 0; i < split_index; i++)
for (auto j = 0; j < split_index; j++)
A[i][j] = A[i][j] + (multiplier * B[i][j]);
return A;
}
vector<vector<int>> strassen_multiplication(vector<vector<int> > A, vector<vector<int> > B) {
// calculating the size of matrix
int row_1 = A.size();
int col_1 = A[0].size();
int row_2 = B.size();
int col_2 = B[0].size();
// checking if multiplication is possible or not
// between the input matrices
if (col_1 != row_2) {
cout << "The Two Matrices cannot be multiplied";
return {};
}
// creating an empty matrix to store the result
vector<int> result_row(col_2, 0);
vector<vector<int> > result(row_1, result_row);
// Base case
// if size of matrix is 1
if (col_1 == 1)
result[0][0]
= A[0][0] * B[0][0];
else {
// split index
int split_index = col_1 / 2;
vector<int> row_vector(split_index, 0);
// Splitting the matrices in sub matrices
vector<vector<int> > a00(split_index, row_vector);
vector<vector<int> > a01(split_index, row_vector);
vector<vector<int> > a10(split_index, row_vector);
vector<vector<int> > a11(split_index, row_vector);
vector<vector<int> > b00(split_index, row_vector);
vector<vector<int> > b01(split_index, row_vector);
vector<vector<int> > b10(split_index, row_vector);
vector<vector<int> > b11(split_index, row_vector);
// calculating and storing the result
// inside our quadrants
for (auto i = 0; i < split_index; i++)
for (auto j = 0; j < split_index; j++) {
a00[i][j] = A[i][j];
a01[i][j] = A[i][j + split_index];
a10[i][j] = A[split_index + i][j];
a11[i][j] = A[i + split_index]
[j + split_index];
b00[i][j] = B[i][j];
b01[i][j] = B[i][j + split_index];
b10[i][j] = B[split_index + i][j];
b11[i][j] = B[i + split_index]
[j + split_index];
}
// Calculating the multiplication using the formula
// given by strassent algorithm
vector<vector<int>> p1(strassen_multiplication(a00, add(b01, b11, split_index, -1)));
vector<vector<int>> p2(strassen_multiplication(add(a00, a01, split_index), b11));
vector<vector<int>> p3(strassen_multiplication(add(a10, a11, split_index), b00));
vector<vector<int>> p4(strassen_multiplication(a11, add(b10, b00, split_index, -1)));
vector<vector<int>> p5(strassen_multiplication(add(a00, a11, split_index),add(b00, b11, split_index)));
vector<vector<int>> p6(strassen_multiplication(add(a01, a11, split_index, -1),add(b10, b11, split_index)));
vector<vector<int>> p7(strassen_multiplication(add(a00, a10, split_index, -1),add(b00, b01, split_index)));
// calculating the result
vector<vector<int> > result_00(add(add(add(p5, p4, split_index), p6, split_index), p2, split_index, -1));
vector<vector<int> > result_01(add(p1, p2, split_index));
vector<vector<int> > result_10(add(p3, p4, split_index));
vector<vector<int> > result_11(add(add(add(p5, p1, split_index), p3, split_index, -1), p7, split_index, -1));
// calulating and storing the result
// inside matrix
for (auto i = 0; i < split_index; i++){
for (auto j = 0; j < split_index; j++) {
result[i][j] = result_00[i][j];
result[i][j + split_index] = result_01[i][j];
result[split_index + i][j] = result_10[i][j];
result[i + split_index][j + split_index] = result_11[i][j];
}
}
// clearing all the arrays
a00.clear(); a01.clear(); a10.clear(); a11.clear();
b00.clear(); b01.clear(); b10.clear(); b11.clear();
p1.clear(); p2.clear(); p3.clear(); p4.clear(); p5.clear(); p6.clear(); p7.clear();
result_00.clear(); result_01.clear(); result_10.clear(); result_11.clear();
}
return result;
}
int main()
{
// Input Matrix A
vector<vector<int>> A = {{1, 1, 1, 1, 1, 1, 1, 1},{1, 1, 1, 1, 1, 1, 1, 1},{1, 1, 1, 1, 1, 1, 1, 1}, {1, 1, 1, 1, 1, 1, 1, 1},{1, 1, 1, 1, 1, 1, 1, 1},{1, 1, 1, 1, 1, 1, 1, 1},{1, 1, 1, 1, 1, 1, 1, 1}, {1, 1, 1, 1, 1, 1, 1, 1}};
// Input Matrix B
vector<vector<int>> B = {{1, 1, 1, 1, 1, 1, 1, 1},{1, 1, 1, 1, 1, 1, 1, 1},{1, 1, 1, 1, 1, 1, 1, 1}, {1, 1, 1, 1, 1, 1, 1, 1},{1, 1, 1, 1, 1, 1, 1, 1},{1, 1, 1, 1, 1, 1, 1, 1},{1, 1, 1, 1, 1, 1, 1, 1}, {1, 1, 1, 1, 1, 1, 1, 1}};
// Getting the result
vector<vector<int> > result(strassen_multiplication(A, B));
// Printing the result
print(result);
}

If you take a moment to read the add function, you will discover the fourth parameter is named multiplier and has a default value of 1. It is a good name for a variable, because it describes clearly what it will be used for.
Continuing to read the function, you will see that multiplier is used to scale B during addition. Logically, that means if you pass -1 as a multiplier, then the operation becomes a subtraction instead of an addition.
What seems strange to me is that you say you are programming this. One would expect that means the code is yours. So you should understand what it does and why. I guess the code is not yours.
You could make the code a bit clearer if you do this:
// Add two matrices and return the result
vector<vector<int>> add_scaled(
vector<vector<int>> A,
const vector<vector<int>>& B,
int split_index,
int multiplier)
{
for (auto i = 0; i < split_index; i++)
for (auto j = 0; j < split_index; j++)
A[i][j] = A[i][j] + (multiplier * B[i][j]);
return A;
}
vector<vector<int>> add(
vector<vector<int>> A,
const vector<vector<int>>& B,
int split_index)
{
return add_scaled(A, B, split_index, 1);
}
vector<vector<int>> subtract(
vector<vector<int>> A,
const vector<vector<int>>& B,
int split_index)
{
return add_scaled(A, B, split_index, -1);
}
This turns your original add function into add_scaled, and creates two simpler functions add and subtract which do not do any scaling. Then you have:
vector<vector<int>> p1(strassen_multiplication(a00, subtract(b01, b11, split_index)));
vector<vector<int>> p2(strassen_multiplication(add(a00, a01, split_index), b11));
vector<vector<int>> p3(strassen_multiplication(add(a10, a11, split_index), b00));
vector<vector<int>> p4(strassen_multiplication(a11, subtract(b10, b00, split_index)));
// etc...

Related

LeetCode 417 solution in C++. I'm getting a heap buffer overflow error

I'm working through this problem: https://leetcode.com/problems/pacific-atlantic-water-flow/
After battling through my own solution for several hours, I ended up not being able to fully solve it, so I'm tracing through how others did it. My new code is based on this: https://leetcode.com/problems/pacific-atlantic-water-flow/discuss/608490/C%2B%2B-Implementation-(DFS)
It's basically the same, except I made it more verbose, and I added some comments for clarity. Even though the code is virtually the same, I'm getting a heap overflow error for very large inputs. I'm not sure what's causing it, but I'm guessing that I'm not correctly passing references to vectors and end up making copies in memory. Can someone please help me figure out the inefficiency?
#include <vector>
#include <assert.h>
using namespace std;
bool isOutOfBounds(int row, int col, vector<vector<int>>& matrix) {
bool rowOutOfBound = row < 0 || row == matrix.size();
bool colOutOfBound = col < 0 || col == matrix[0].size();
return rowOutOfBound || colOutOfBound;
}
void explore(vector<vector<int>>& matrix, int i, int j, int prevHeight, vector<vector<bool>>& explored) {
// if we are out of bounds, or our height is greater, or if this cell was already explored
if (isOutOfBounds(i, j, matrix) || matrix[i][j] < prevHeight || explored[i][j]) return;
int height = matrix[i][j];
explored[i][j] = true;
explore(matrix, i - 1, j, height, explored); // flow up
explore(matrix, i, j + 1, height, explored); // flow right
explore(matrix, i + 1, j, height, explored); // flow down
explore(matrix, i, j - 1, height, explored); // flow left
}
vector<vector<int>> pacificAtlantic(vector<vector<int>>& matrix) {
vector<vector<int>> result;
if (matrix.size() == 0) return result;
// create boolean grids of explored paths, one for pacific, one for atlantic
vector<vector<bool>> pacific(matrix.size(), vector<bool>(matrix[0].size(), false));
vector<vector<bool>> atlantic(pacific);
for (int i = 0; i < matrix.size(); i++) {
explore(matrix, i, 0, INT_MIN, pacific); // explore first column
explore(matrix, i, matrix.size() - 1, INT_MIN, atlantic); // explore last column
}
for (int j = 0; j < matrix[0].size(); j++) {
explore(matrix, 0, j, INT_MIN, pacific); // explore first row
explore(matrix, matrix[j].size() - 1, j, INT_MIN, atlantic); // explore last row
}
// for every column of each row
for (int i = 0; i < matrix.size(); i++) {
for (int j = 0; j < matrix[i].size(); j++) {
if (pacific[i][j] && atlantic[i][j]) {
result.push_back({ i, j });
}
}
}
return result;
}
void main() {
vector<vector<int>> matrix {
{ 1, 2, 2, 3, 5 },
{ 3, 2, 3, 4, 4 },
{ 2, 4, 5, 3, 1 },
{ 6, 7, 1, 4, 5 },
{ 5, 1, 1, 2, 4 }
};
vector<vector<int>> expected{ {0, 4}, {1, 3}, {1, 4}, {2, 2}, {3, 0}, {3, 1}, {4, 0} };
vector<vector<int>> result = pacificAtlantic(matrix);
assert(result == expected);
}
I had an error when exploring last column, and last row, so was accessing invalid vector indexes.
when I fixed
for (int i = 0; i < matrix.size(); i++) {
explore(matrix, i, 0, INT_MIN, pacific); // explore first column
explore(matrix, i, matrix.size() - 1, INT_MIN, atlantic); // explore last column
}
for (int j = 0; j < matrix[0].size(); j++) {
explore(matrix, 0, j, INT_MIN, pacific); // explore first row
explore(matrix, matrix[j].size() - 1, j, INT_MIN, atlantic); // explore last row
}
the solution worked.
The code should have read as:
for (int i = 0; i < matrix.size(); i++) {
explore(matrix, i, 0, INT_MIN, pacific); // explore first column
explore(matrix, i, matrix[0].size() - 1, INT_MIN, atlantic); // explore last column
}
for (int j = 0; j < matrix[0].size(); j++) {
explore(matrix, 0, j, INT_MIN, pacific); // explore first row
explore(matrix, matrix.size() - 1, j, INT_MIN, atlantic); // explore last row
}

Dijkstra's Algorithm w/ Adjacency List Map c++

Currently trying to implement dijkstra's algorithm in C++ by the use of an adjacency list in a text file read into a map object. The map is initialized as:
map<int, vector<pair<int, int>>> = adjList;
Sample text file input:
1 2,1 8,2
2 1,1 3,1
3 2,1 4,1
4 3,1 5,1
5 4,1 6,1
6 5,1 7,1
7 6,1 8,1
8 7,1 1,2
Where the key is a vertex, and the x values of the pairs in the vector are connected to the key vertex. The y values are the path distances. I pass that map into my dijkstra function, where I initialize a vector for shortest distances and a vector for storing visited vertices. My loop is where things start going wrong, as I get outputs of zeroes and very large numbers. Here's my code:
//checks if vertex has been visited or not
bool booler(int vertex, vector<int> visited){
bool booly;
if(find(visited.begin(), visited.end(), vertex) != visited.end()){
booly = true;
}
else{
booly = false;
}
return booly;
}
//checks vector for the shortest distance vertex
int minDist(vector<int> distances, vector<int> visited){
int minDist = 1000000;
int index;
for(int v = 0; v < distances.size(); v++){
if(booler(v, visited) == false && distances[v] < minDist){
minDist = distances[v];
index = v;
}
}
return index;
}
void dijkstra(int source, map<int, vector<pair<int, int>>> adjList, int vSize){
vector<int> distances(vSize, 1000000);
vector<int> visited = {};
distances[source] = 0;
for(int c = 0; c < distances.size(); c++){
int u = minDist(distances, visited);
visited.push_back(u);
for(int v = 1; v < distances.size(); v++){
for(int s = 0; s < adjList[u].size(); s++){
//updates distances based on v connection to u
if(booler(v, visited) == false && distances[u] < 1000000 && adjList[u][s].second + distances[u] < distances[v]){
distances[v] = distances[u] + adjList[u][v].second;
}
}
}
}
//prints out shortest path
for(int x = 0; x < distances.size(); x++){
cout << distances[x] << " " << endl;
}
}
I haven't been able to fix this error, any help would be greatly appreciated!
Here is an implement how to use dijkstra.
https://www.quora.com/What-is-the-most-simple-efficient-C++-code-for-Dijkstras-shortest-path-algorithm
It is my solution for your problem:
#include "bits/stdc++.h"
using namespace std;
map<int, vector<pair<int, int> > > mp;
void addEdge(int u, int v, int dist) {
mp[u].push_back(make_pair(v, dist));
}
void startDijkstra(int u) {
vector<int> dist(1e2 + 1, 1e9);
set<pair<int, int> > st;
st.insert(make_pair(0, u));
dist[u] = 0;
while (!st.empty()) {
pair<int, int> now = *st.begin();
st.erase(st.begin());
int v = now.second;
int w = now.first;
const vector<pair<int, int> > &edges = mp[v];
for (const pair<int, int> &to : edges) {
if (w + to.second < dist[to.first]) {
st.erase(make_pair(dist[to.first], to.first));
dist[to.first] = w + to.second;
st.insert(make_pair(dist[to.first], to.first));
}
}
}
for (int i = 1; i <= 8; i++) {
cout << i << ' ' << dist[i] << endl;
}
}
int main() {
addEdge(1, 2, 1);
addEdge(1, 8, 2);
addEdge(2, 1, 1);
addEdge(2, 3, 1);
addEdge(3, 2, 1);
addEdge(3, 4, 1);
addEdge(4, 3, 1);
addEdge(4, 5, 1);
addEdge(5, 4, 1);
addEdge(5, 6, 1);
addEdge(6, 5, 1);
addEdge(6, 7, 1);
addEdge(7, 6, 1);
addEdge(7, 8, 1);
addEdge(8, 9, 1);
addEdge(8, 1, 2);
startDijkstra(1);
return 0;
}

Optimizing the number of calls to expensive function

I have an mainFun that takes four parameters x, a, b, and c, all vector-valued and possibly of varying length. This function calls expensiveFun that is computationally expensive so I'd like to reduce the number of calls to expensiveFun. This function needs to be called for each value in x[i], a[i], b[i], c[i] and if a, b, or c are of shorter length, then they need to be "wrapped" (their index is in modulo a[i % a.size()]). It would be the best to precompute the expensiveFun for each possible distinct value of x (i.e. all integers 0,...,max(x)) and then just fill-in the output out by out[i] = precomputedValues[x[i]]. This can be easily achieved if a, b, and c have the same length (example below), but it gets ugly if they are not. Is there any way to make it more efficient for case when the lengths of parameter vectors differ?
Below I provide a reproducible example. It's a simplified code, written just to serve as example.
std::vector<int> expensiveFun(int x, int a, int b, int c) {
std::vector<int> out(x+1);
out[0] = a+b*c;
for (int i = 1; i <= x; i++)
out[i] = out[i-1] * i + a * (b+c);
return out;
}
std::vector<int> mainFun(
std::vector<int> x,
std::vector<int> a,
std::vector<int> b,
std::vector<int> c
) {
int n = x.size();
int a_size = a.size();
int b_size = b.size();
int c_size = c.size();
std::vector<int> out(n);
// easy
if (a_size == b_size && b_size == a_size) {
int max_x = 0;
for (int j = 0; j < n; j++)
if (x[j] > max_x)
max_x = x[j];
for (int i = 0; i < a_size; i++) {
int max_x = 0;
for (int j = 0; j < n; j += a_size) {
if (x[j] > max_x)
max_x = x[j];
}
std::vector<int> precomputedValues = expensiveFun(max_x, a[i], b[i], c[i]);
for (int j = i; j < n; j += a_size) {
out[j] = precomputedValues[x[j]];
}
}
// otherwise give up
} else {
for (int j = 0; j < n; j++) {
out[j] = expensiveFun(x[j], a[j % a_size], c[j % c_size], c[j % c_size]).back();
}
}
return out;
}
Example input:
x = {0, 1, 5, 3, 2, 1, 0, 4, 4, 2, 3, 4, 1}
a = {1, 2, 3}
b = {1, 2}
c = {3, 4, 5, 6}
Parameters should be folded so that they become:
x = {0, 1, 5, 3, 2, 1, 0, 4, 4, 2, 3, 4, 1}
a = {1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1}
b = {1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1}
c = {3, 4, 5, 6, 3, 4, 5, 6, 3, 4, 5, 6, 3}
The output is not important at the moment since the main issue in here is about efficiently dealing with varying-size parameter vectors.
Memoize your function.
Once you compute a vector for a combination of a, b, and c, store it in an std::unordered_map. The next time you see the same combination, you retrieve the vector that you have already computed - the classic approach of paying with computer memory for computation speed-up.
std::map<std::tuple<int,int,int>,std::vector<int>> memo;
int expensiveFunMemo(int x, int xMax, int a, int b, int c) {
assert(x <= xMax);
std::vector<int>& out = memo[std::make_tuple(a, b, c)];
if (!out.size()) {
out.push_back(a+b*c);
for (int i = 1; i <= xMax; i++)
out.push_back(out[i-1] * i + a * (b+c));
}
assert(out.size == xMax+1);
return out[x];
}
This way you would never compute expensiveFunMemo for any combination of {a, b, c} more than once.
Your mainFun becomes simpler, too:
std::vector<int> mainFun(
const std::vector<int>& x,
const std::vector<int>& a,
const std::vector<int>& b,
const std::vector<int>& c
) {
size_t n = x.size();
size_t a_size = a.size();
size_t b_size = b.size();
size_t c_size = c.size();
std::vector<int> out(n);
int xMax = *std::max_element(x.begin(), x.end());
for (size_t j = 0 ; j < n ; j++) {
out[j] = expensiveFunMemo(x[j], xMax, a[j % a_size], c[j % c_size], c[j % c_size]);
}
return out;
}
Note: this solution uses std::map<K,V> instead of std::unordered_map<K,V> because std::tuple<...> lacks a generic hash function. This Q&A offers a solution to fix this problem.

Inserting multiple elements into a 2D block

I am attempting to calculate the energy of a series of elements inside a vector of vectors. As soon as the particular element has the right energy, it is then pushed into another vector of vectors. Here is an example because it is hard to explain:
bool energy(const std::vector<double> &vals)
{
float sum = 0.0;
for(unsigned i=0; (i < vals.size()); i++)
{
sum += (vals[i]*vals[i]);
}
//cout << sum << endl;
return (sum >= 5);
}
int main(int argc, char *argv[]) {
std::vector<vector<double> > vals {
{0, 0, 0, 0, 0}, // This has an energy of "0" -> does not count
{1, 1, 1, 1, 1}, // This has an energy of "5" -> push_back to vector[0]
{1, 1, 1, 1, 1}, // This has an energy of "5" -> push_back to vector[0]
{1, 1, 1, 1, 1}, // This has an energy of "5" -> push_back to vector[0]
{1, 2, 1, 1, 1}, //This has an energy of "5" -> push_back to vector[0]
{0, 0, 0, 0, 0}, // This has an energy of "0" -> does not count && start a new
// vector
{1, 2, 3, 4, 5}, // This has an energy of "55" -> push_back to vector[1]
{1, 2, 3, 4, 5}, // This has an energy of "55" -> push_back to vector[1]
{1, 2, 3, 4, 5}, // This has an energy of "55" -> push_back to vector[1]
{1, 2, 3, 4, 5} // This has an energy of "55" -> push_back to vector[1]
};
std::vector<vector<double> > clusters;
std::vector<vector<double> > tmp;
//std::for_each(vals.begin(), vals.end(), energy);
int j = 0;
for(unsigned i=0; (i < vals.size()); i++)
{
if(energy(vals[i]))
{
clusters.resize(j + 1);
clusters[j] = vals[i];
}else if(!energy(vals[i]) && energy(vals[i+1]))
{
j++;
}
}
for(unsigned i=0; (i < clusters.size()); i++)
{
for(unsigned j=0; (j < clusters[i].size()); j++)
{
cout << clusters[i][j] << ' ';
}
cout << endl;
}
}
What should happen
There should be 2 elements of the vector of vectors named clusters each containing the values of:
clusters[0] = {
1, 1, 1, 1, 1,
1, 1, 1, 1, 1,
1, 1, 1, 1, 1,
1, 2, 1, 1, 1
};
`clusters[1] = 1, 2, 3, 4, 5,
1, 2, 3, 4, 5,
1, 2, 3, 4, 5,
1, 2, 3, 4, 5}`
What is happening?
The vector of vectors seem to be over-riding the blocks that get inserted into them. So instead of the above, I just get the last element that it found so:
`cluster[0] = {1 2 1 1 1}
cluster[1] = {1 2 3 4 5}`
What I was thinking and attempting was to store each of the "blocks" inside a vector of vectors that contain the sufficient energy and then push all these values inside a vector<double> and then insert this vector inside the block of clusters..
Is there an alternative way, a much simpler solution to this problem?
Corrected code:
#include<vector>
#include<iostream>
using namespace std;
bool energy(const std::vector<double> &vals)
{
float sum = 0.0;
for(unsigned i=0; (i < vals.size()); i++)
{
sum += (vals[i]*vals[i]);
}
//cout << sum << endl;
return (sum >= 5);
}
int main(int argc, char *argv[]) {
std::vector<vector<double> > vals {
{0, 0, 0, 0, 0}, // This has an energy of "0" -> does not count
{1, 1, 1, 1, 1}, // This has an energy of "5" -> push_back to vector[0]
{1, 1, 1, 1, 1}, // This has an energy of "5" -> push_back to vector[0]
{1, 1, 1, 1, 1}, // This has an energy of "5" -> push_back to vector[0]
{1, 2, 1, 1, 1}, //This has an energy of "5" -> push_back to vector[0]
{0, 0, 0, 0, 0}, // This has an energy of "0" -> does not count && start a new
// vector
{1, 2, 3, 4, 5}, // This has an energy of "55" -> push_back to vector[1]
{1, 2, 3, 4, 5}, // This has an energy of "55" -> push_back to vector[1]
{1, 2, 3, 4, 5}, // This has an energy of "55" -> push_back to vector[1]
{1, 2, 3, 4, 5} // This has an energy of "55" -> push_back to vector[1]
};
std::vector<vector<double> > tmp(vals.size());
std::vector<vector<double> > clusters(vals.size());
int j = 0;
for(unsigned i=0; (i < vals.size()); i++)
{
if(energy(vals[i]))
{
clusters[j].insert(clusters[j].end(), vals[i].begin(), vals[i].end());
}else if(!energy(vals[i]) && energy(vals[i+1]))
{
j++;
}
}
for(unsigned i=0; (i < clusters.size()); i++)
{
for(unsigned j=0; (j < clusters[i].size()); j++)
{
cout << clusters[i][j] << ' ';
}
cout << endl;
}
}
The output is:
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1
1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5
Your problem is here:
for(unsigned i=0; (i < vals.size()); i++)
{
if(energy(vals[i]))
{
clusters.resize(j + 1);
clusters[j] = vals[i];
}
else if(!energy(vals[i]) && energy(vals[i+1]))
{
j++;
}
}
First of all, your energy function returns an int, so when the return value is non-zero, it will evaluate the condition to true, and when it is 0, it will be false.
Second, you are effectively doing a push_back in the if branch, but you are only pushing the current vector (you aren't appending it to an existing vector).
To fix this, I would recommend using a map<int, vector<int>> so you can quickly reference each cluster (e.g. the ones with energy of 5 would have a key of 5, so you would either create a new vector and insert those values, or append to the one that already exists there). If you need it in a vector of vectors, you can always iterate through the map after you have them sorted and swap them into the vector of vectors.
you could simplify a lot your code, so it would be much more easy to read and understand, for example take you energy function, you could write it in a single line using algorithms:
return std::inner_product(vals.begin(), vals.end(), vals.begin(), 0.) >= 5;
I changed a piece of code make it works
int j = 0;
for(unsigned i=0; (i < vals.size()); i++)
{
if(energy(vals[i])) {
clusters[j].insert(clusters[j].end, vals[i].begin(), vals[i].end());
}
if(!energy(vals[i]) && energy(vals[i+1])) {
clusters.push_back( tmp );
++j;
}
}
Don't use resize. You can just push_back an empty vector into your clusters.
And for each operation to append a vector, just using insert by range
void insert (iterator position, InputIterator first, InputIterator last);
Ref: http://en.cppreference.com/w/cpp/container/vector/insert

Matlab to OpenCV conversion - optimization?

I am converting Matlab code to OpenCV "C/cpp" code. And I have some doubts as below.
A = [ 2; 10; 7; 1; 3; 6; 10; 10; 2; 10];
ind = [10; 5; 9; 2];
B is a submatrix of A ; Elements of matrix B are elements of A at locations specified in ind.
B = [10 3; 2; 10];
In Matlab, I just use
B = A(ind);
In C using OpenCV,
for ( int i = 0; i < ind.rows; i++) {
B.at<int>(i,0) = A.at<int>(ind.at<int>(i,0), 0);
}
Is there a way to do it without using for loop?
If you are looking for an tidy way of copying. I would suggest you define a function
Here is a STL-like implementation of copy at given position
#include<vector>
#include<cstdio>
using namespace std;
/**
* Copies the elements all elements of B to A at given positions.
* indexing array ranges [ind_first, ind_lat)
* e.g
* int A[]= {0, 2, 10, 7, 1, 3, 6, 10, 10, 2, 10};
* int B[] = {-1, -1, -1, -1};
* int ind[] = {10, 5, 9, 2};
* copyat(B, A, &ind[0], &ind[3]);
* // results: A:[0,2,10,7,1,-1,6,10,10,-1,-1]
*/
template<class InputIterator, class OutputIterator, class IndexIterator>
OutputIterator copyat (InputIterator src_first,
OutputIterator dest_first,
IndexIterator ind_first,
IndexIterator ind_last)
{
while(ind_first!=ind_last) {
*(dest_first + *ind_first) = *(src_first);
++ind_first;
}
return (dest_first+*ind_first);
}
int main()
{
int A[]= {0, 2, 10, 7, 1, 3, 6, 10, 10, 2, 10};
int B[] = {-1, -1, -1, -1};
int ind[] = {10, 5, 9, 2};
copyat(B, A, &ind[0], &ind[3]);
printf("A:[");
for(int i=0; i<10; i++)
printf("%d,", A[i]);
printf("%d]\n",A[10]);
}