unexpected argument pass order employing stl numeric - c++

I think I am missing something in the following code the output of the last two call iterating with only one element of container in the accumulate results in passing that one element as the second argument instead of first or I haven't get the idea of how utilizing it yet:
#include <iostream>
#include <numeric>
#include <array>
using namespace std;
int foo(int x, int y) {return 2*x+y;}
int foo2(int x, int y) {return x+2*y;}
int main() {
array<int, 2> arr {{1, 2}};
cout << accumulate(arr.begin(), arr.end(), 0)
<< endl; // 1 + 2 = 3 as expected
cout << accumulate(arr.begin(), arr.end(), 0, foo)
<< endl; // 2*1+2 = 4 as expected
cout << accumulate(arr.begin(), arr.end()-1, 0, foo)
<< endl; // not 2*1+0 but 2*0+1 => 1!
cout << accumulate(arr.begin(), arr.end()-1, 0, foo2)
<< endl; // not 1+2*0 but 0+2*1 = > 2!
return 0;
}
output:
3
4
1
2

The third argument of accumulate is the initial accumulation value. It is thus passed as the first argument of the first call to the accumulation function. You have correctly deduced the calculation of the last two values:
accumulate(arr.begin(), arr.end()-1, 0, foo)
// = foo(0, 1) = 2*0 + 1 = 1
accumulate(arr.begin(), arr.end()-1, 0, foo2)
// = foo2(0, 1) = 0 + 2*1 = 2
Hwoever, the first two values are calculated in exactly the same way:
accumulate(arr.begin(), arr.end(), 0)
// = add(add(0, 1), 2) = (0 + 1) + 2 = 3
accumulate(arr.begin(), arr.end(), 0, foo)
// = foo(foo(0, 1), 2) = 2*(2*0 + 1) + 2 = 4
It is simply by accident that calculation you (incorrectly) expected yields the same results in these two cases.

Related

Find lowest real value in complex vector

How can I find the smallest positive real number in a complex vector of size N by 1 in Eigen3? For example, in this case I'd like to find the value 3.64038.
#include <Eigen/Dense>
#include <iostream>
using namespace std;
using namespace Eigen;
int main()
{
MatrixXd m(4, 4);
m << 1, 0, 1, 1,
0, 2, 0, 1,
0, 2, 1, 0,
2, 1, 2, 1;
cout << m << endl;
cout << m.eigenvalues() << endl;
return 0;
}
Output
1 0 1 1
0 2 0 1
0 2 1 0
2 1 2 1
(3.64038,0)
(-0.444745,0)
(0.902183,1.01932)
(0.902183,-1.01932)
Vector elements that have an imaginary part not equal to 0 should be excluded.
I wrote the following function, but was wondering if there is an approach using Eigen's methods.
double findPositiveRealMin(VectorXcd v)
{
VectorXd v_imag = v.imag();
VectorXd v_real = v.real();
for (int i = 0; i < v.rows(); i++)
{
if (v_imag[i] != 0 | v_real[i] <= 0)
v_real[i] = 1.0e16;
}
return v_real.minCoeff();
}
One option is to create a logical array and then call Eigen::select on it. Inspired by https://forum.kde.org/viewtopic.php?f=74&t=91378
In this case:
Eigen::VectorXcd v = m.eigenvalues();
// minimum positive real value with zero imaginary part
Eigen::Array<bool,Eigen::Dynamic,1> cond1 = (v.imag().array() == 0);
Eigen::Array<bool,Eigen::Dynamic,1> cond2 = (v.real().array() > 0);
double some_big_value = 1e16;
std::cout << (cond1 && cond2).select(v.real(), some_big_value).minCoeff() << std::endl;
... or, as a one-liner:
std::cout << (v.imag().array() == 0 && v.real().array() > 0).select(v.real(), 1e16).minCoeff() << std::endl;
This one-liner uses the ternary operator in combination with Eigen's unaryExpr() method.
std::cout << m.eigenvalues().unaryExpr([](auto a){return a.imag() != 0 || a.real() < 0 ? 1.e16 : a;}).real().minCoeff() << std::endl;

In C++, how can I write a function that flips a 2d array at a specified position?

For my 2d array in C++, the 2d array needs to be flipped at a certain position. I have to write a function that flips the array
Foe instance,
Before:
double A[][2] = {{0,0}, {1,1}, {2,2}, {3,3}, {4,4}, {5,5}, {6,6}, {7,7}}
A B C D
call function invert(or flip): invert(A, 8, 3, 4);
after:
double A[][2] = { {0, 0}, {1, 1}, {2, 2},{6, 6}, {5, 5}, {4, 4}, {3, 3}, {7, 7}}
D C B A
Here is the attempt I have tried
#param A is the list of locations (x,y) of the cities in the current tour.
#param n is the number of cities in A.
#param start is the index of the beginning of the section to be inverted.
#param len is the length of the segment to invert(or flip).
void invert ( double A[][2], int n, int start, int len ) {
int(*tmp)[2] = new int[][2];
for(int i = 0; i >= A.length; i--){
for(int j = 0; j >= A[i].length; j--){
if( i > start)
tmp = A[i][j];
}
}
for(i = start; i < A.length; i++)
for(j = start; j < A[i].length; j++){
while (i <= end){
tmp = A[i][j];
}
}
}
The errors I have are
expressions must have class type
a value of type double cannot be assigned to an entity of type "double(*)[2]
cannot determine which instance of overload function "end" is intended
I am fully aware that most of the errors in my code are evident to find, but I needed to start somewhere.
I admit, I don't know how to do it with a 2D C-array. I can only tell you about the simple way to do it.
First, a general advice: Name your stuff. What if I had to read only your code to see that you are dealing with locations of cities, that have x and y coordinates, instead of having to read your text, wouldn't that be great?
Next, for resizable arrays, you can (/should) use std::vector instead of C-arrays. C-arrays decay to pointers when passed to functions. C-arrays have their size as part of their type, but it is inconvenient to access it (and impossible once decayed to a pointer). And manually resizing dynamic C-arrays isn't much fun either.
Eventually, the "simple way" is to use an existing algorithm. To reverse elements in a range it is std::reverse:
#include <iostream>
#include <vector>
#include <algorithm>
struct location {
int x;
int y;
};
int main() {
std::vector<location> cities{{0,0}, {1,1}, {2,2}, {3,3}, {4,4}, {5,5}, {6,6}, {7,7}};
for (const auto& loc : cities){
std::cout << loc.x << " " << loc.y << "\n";
}
std::cout << "\n";
std::reverse(cities.begin()+ 3,cities.begin() + 7);
for (const auto& loc : cities){
std::cout << loc.x << " " << loc.y << "\n";
}
}
Output:
0 0
1 1
2 2
3 3
4 4
5 5
6 6
7 7
0 0
1 1
2 2
6 6
5 5
4 4
3 3
7 7
Actually with a 1-D c-array it is almost the same. The major difference is that c-arrays do not have begin as member. This produces same output as above:
location cities2[] = {{0,0}, {1,1}, {2,2}, {3,3}, {4,4}, {5,5}, {6,6}, {7,7}};
for (const auto& loc : cities2){
std::cout << loc.x << " " << loc.y << "\n";
}
std::cout << "\n";
std::reverse(std::begin(cities2)+ 3,std::begin(cities2) + 7);
for (const auto& loc : cities2){
std::cout << loc.x << " " << loc.y << "\n";
}
And if you want to wrap it in a function you need to take care of the array decaying to a pointer:
void my_reverse(location* loc, size_t len, size_t first, size_t last){
std::reverse(loc + first, loc + last + 1);
}
(I choose last to be the last element to be reversed. Note that the algorithm takes an iterator to the element one past the last element to be reversed).
Complete example with all three variants: https://godbolt.org/z/WMdea7WP3
That's how I'd write the function if I knew it would always be used with 2 column arrays
void invert(double cities[][2], int size, int start, int len) {
if (size < 0 || len < 0)
return;
double tempCoordsX, tempCoordsY;
int endPos = start + len - 1;
for (int i = start; i < (start + len/2); i++) {
int mirroredPos = (endPos - (i - start)) % size;
tempCoordsX = cities[i][0];
tempCoordsY = cities[i][1];
cities[i][0] = cities[mirroredPos][0];
cities[i][1] = cities[mirroredPos][1];
cities[mirroredPos][0] = tempCoordsX;
cities[mirroredPos][1] = tempCoordsY;
}
}
I repeat: please name your stuff

Comparing returned vectors from recursion tree branches

Suppose I have a given sum, say sum = 4. I am also given a vector = {2,4}. There are two ways to generate the given sum from the given vector (elements may be reused).
One way is just {4} cause 4 = 4.
Second way is {2,2} cause 2 + 2 = 4.
I have to find the shortest possible combination, therefore in this particular case the answer is {4}.
Here is my approach - I go through the tree, and when on the leaf I get a 0, we hit the base case, return {} vector, and fill up the vector while traversing the tree. When I get to a node, I choose the smaller of the two (or more) vectors. This way when I reach the root node, I should get a vector of the shortest combination that can yield me the target sum.
As of yet, I do not care about time constraints as such, I know there's a lot of repetitive computing going on so I will have to memoize it once I can get the basic version correct.
I have been trying to figure why this code is not working. Any insight would be appreciated.
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
vector<int> findBestSum(int targetSum, const vector<int> &elements, vector<vector<int>> &temp) {
if (targetSum == 0)
return {};
else if (targetSum < 0)
return {-1};
else {
vector<int> small;
for (auto &i : elements) {
int remainder = targetSum - i;
vector<int> returnedVector = findBestSum(remainder, elements, temp);
if ((!returnedVector.empty() && find(returnedVector.begin(), returnedVector.end(), -1) == returnedVector.end()) || returnedVector.empty()) {
returnedVector.push_back(i);
temp.push_back(returnedVector);
}
int smallestLength = temp[0].size();
for (auto &j : temp)
if (smallestLength >= j.size())
small = j;
}
return small;
}
}
int main() {
int targetSum = 6;
const vector<int> elements{2, 3, 5}; // answer should be [3,3] however I just get a 3...
vector<vector<int>> temp;
vector<int> bestSumVector = findBestSum(targetSum, elements, temp);
for (auto i : bestSumVector)
cout << i << " ";
}
Update (14th of July, 2021):
After a few busy months I have tried to lock horns with this problem and this time my code looks like this:
#include <iostream>
#include <vector>
#include <map>
#include <numeric>
using namespace std;
bool howSum(int &targetSum, vector<int> &elementVector, vector<int> &howSumVector, vector<vector<int>> &allSums) {
static int originaltargetsum = targetSum;
if (targetSum == 0)
return true;
else if (targetSum < 0)
return false;
else {
for (auto i : elementVector) {
int remainder = targetSum - i;
bool flag = howSum(remainder, elementVector, howSumVector, allSums);
if (flag) {
howSumVector.push_back(i);
if (targetSum == originaltargetsum ||
accumulate(howSumVector.begin(), howSumVector.end(), 0) == originaltargetsum) {
allSums.push_back(howSumVector);
howSumVector.clear();
}
return true;
}
}
return false;
}
}
int main() {
int sum = 8;
vector<int> elements = {1, 4, 5};
vector<vector<int>> allSums = {};
vector<int> workingBench = {};
howSum(sum, elements, workingBench, allSums);
for (auto &i : allSums) {
for (auto &j : i) {
cout << j << " ";
}
cout << endl;
}
}
For this I have sum as 8 and elements as {1, 4, 5}.
Also I'm storing and displaying all possible solutions right now (once that is correctly done, finding shortest vector and memoization should be easy). Possible solutions in this case are:
[1, 1, 1, 1, 1, 1, 1, 1]
[4, 4]
[5, 1, 1, 1]
[4, 1, 1, 1, 1]
Currently my code only shows the first possible combination. I'm pretty sure I'm returning true and false incorrectly, please help me out here.
I took a stab at this. I do have a working solution, hopefully it is what you want:
#include <iostream>
#include <vector>
#include <algorithm>
void howSum(int targetSum, const std::vector<int> & elementVector, const std::vector<int> & howSumVector, std::vector<std::vector<int>> & allSums)
{
static int originaltargetsum = targetSum;
if (targetSum == 0)
{
allSums.push_back(howSumVector);
return;
}
else if (targetSum < 0)
{
return;
}
else
{
for (const auto i : elementVector)
{
// an element less than or equal to 0 would cause an infinite loop
if (i <= 0)
continue;
std::vector<int> newSumVector = howSumVector;
newSumVector.push_back(i);
std::vector<int> newElementVector;
std::copy_if(std::begin(elementVector), std::end(elementVector), std::back_inserter(newElementVector), [i](int element){ return element >= i; });
howSum(targetSum - i, newElementVector, newSumVector, allSums);
}
}
}
int main()
{
int sum = 8;
std::vector<int> elements = { 1, 4, 5 };
std::vector<std::vector<int>> allSums = {};
std::vector<int> workingBench = {};
howSum(sum, elements, workingBench, allSums);
for (const auto & i : allSums)
{
for (const auto & j : i)
{
std::cout << j << " ";
}
std::cout << std::endl;
}
return 0;
}
I think, in general, you were over-thinking or over-engineering the problem. Like others have mentioned, your current code is returning true too early, and nothing besides the first element/combination is tested. With recursion, it is important to take care in your return cases - really, you only want a base case or two, and otherwise you want to recur.
With the solution I have here, the main thing I have added is copying the current combination of elements for each element you need to test. That solves your main issue of not testing every combination of numbers. In addition to that, it seemed better to append to allSums when the targetSum was reached. With those changes, I was able to do away with the bool return value and simplify the code a bit. Running the code above gives these solutions:
1 1 1 1 1 1 1 1
1 1 1 1 4
1 1 1 4 1
1 1 1 5
1 1 4 1 1
1 1 5 1
1 4 1 1 1
1 5 1 1
4 1 1 1 1
4 4
5 1 1 1
This does have some duplicates (because of the order things are tested) but I felt like it is good enough since you only want the smallest solution, 4 4. To find this, you would just need to sort the allSums vector by inner vector size and then take the first entry.
I think you need to change the implementation to correctly process elements of the vector.
In your implementation it doesn't go over all vector items, just the first one.
This is one way to do it if you use vector elements as the first parameter in your function.
vector<int> findBestSum(int element, int targetSum, const vector<int>& elements,
vector<vector<int>>& temp) {
if (targetSum == 0)
return {};
else if (targetSum < 0)
return { -1 };
else {
int remainder = targetSum - element;
vector<int> returnedVector = findBestSum(element, remainder, elements, temp);
if ((!returnedVector.empty() && find(returnedVector.begin(), returnedVector.end(), -1) == returnedVector.end()) || returnedVector.empty()) {
returnedVector.push_back(element);
return returnedVector;
}
return returnedVector;
}
}
int main() {
const int targetSum = 6;
const vector<int> elements{ 2, 3, 5 }; // answer should be [3,3] however I just get a 3...
vector<vector<int>> temp;
for (auto i : elements) {
vector<int> returnedVector = findBestSum(i, targetSum, elements, temp);
if ((!returnedVector.empty() && find(returnedVector.begin(), returnedVector.end(), -1) == returnedVector.end()) || returnedVector.empty())
temp.push_back(returnedVector);
}
if (temp.size() > 0) {
vector<int> bestSum = {};
size_t small = 0;
size_t smallestLength = temp[0].size();
for (auto& j : temp)
if (smallestLength >= j.size()) {
small = j.size();
bestSum = j;
}
for (auto i : bestSum)
cout << i << " ";
}
else
cout << " sum not found" << endl;
}

How does this c++ function work?

#include <cstdlib>
#include <iostream>
using namespace std;
int myFunction(int n)
{
int x;
if (n==1 || n==2)
x = 1;
else
x = myFunction(n-2) + myFunction(n-1);
return x;
}
int main(int argc, char *argv[])
{
int n,a;
n = 7;
a = myFunction(n);
cout << "x is: " << a;
system("PAUSE");
return EXIT_SUCCESS;
}
The output to this is "x is: 13".
How do I get x = 13 when I do n = 7?
It seems that the function repeats some number of times until x=1.
I will walk you through it for a simpler example where the function is 4, but the overall concept is the same for 7 as well.
First call: myFunction(4) and inside the function n = 4.
Since n does not equal 1 or 2, we skip to the else:
x = myFunction(3) + myFunction(2);
x = myFunction(1) + myFunction(2) + 1; // If there is a 1, that means
// that we went to the if
// clause, not the else, since
// n was either 1 or 2
x = 1 + 1 + 1;
x = 3;
This concept is called recursion and can be very useful at times. Your function currently calculates the nth fibonacci number.
On a side note, you should read why using system("PAUSE"); is a bad idea.

lp_solve consecutive calls to `solve' are incorrect

I need to solve some simple linear integer programming-like problem, I took lp_solve library. The task is to obtain variables' values for some consequtive values of linear function with possible simple (linear) constraints on variables (actually I encountered a problem even without any additional constraints). E.g. I have linear function 4a + 5b. First values I'm interested in are (function value - variables values):
0 - (0, 0); 4 - (1, 0); 5 - (0, 1); 8 - (2, 0); 9 - (1, 1)
The problem is that after getting 8 - (2, 0), lp_solve returns NUMFAILURE code (5) while solving the task and resolves it to 0 - (0, 0)…
If I do not use consequtive calls to 'solve' function and just start from 9 then I got right answer (9 - (1, 1)). Would anyone please explain this? The code is following.
#include <iostream>
#include <cstdio>
#include <lpsolve/lp_lib.h>
# if defined ERROR
# undef ERROR
# endif
# define ERROR() { fprintf(stderr, "Error\n"); exit(1); }
using std::cout;
using std::endl;
void print_res(REAL * vars, int size) {
cout << "(";
for (int i = 0; i < size - 1; ++i) {
cout << round(vars[i]) << ", ";
}
cout << round(vars[size - 1]) << ")";
}
int main()
{
lprec *lp;
int majorversion, minorversion, release, build, min = 0;
lp_solve_version(&majorversion, &minorversion, &release, &build);
const int l = 5; // number of iterations
const int dim = 2; // dimension ot current task
char p_data[] = "4 5"; // objective function: p(a, b) = 4a + 5b
if ((lp=make_lp(0, dim)) == NULL)
ERROR();
set_verbose(lp, CRITICAL);
if (!str_add_constraint(lp, p_data, GE, min)) // p(a, b) >= min
ERROR();
// objective function - p
if (!str_set_obj_fn(lp, p_data))
ERROR();
// work with integer non-negative variables
set_int(lp, 1, TRUE);
set_int(lp, 2, TRUE);
set_lowbo(lp, 1, 0);
set_lowbo(lp, 2, 0);
for (int i = 0; i < l; ++i) {
cout << "Status: " << solve(lp) << endl;
REAL vars[dim];
get_variables(lp, vars);
print_res(vars, dim);
// increase minimum value for p
min = round(get_objective(lp));
cout << ", p = " << min << endl;
if (!set_rh(lp, 1, min + 1))
ERROR();
}
return 0;
}