Find lowest real value in complex vector - c++

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;

Related

unexpected argument pass order employing stl numeric

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.

How to find indexes from vector1 in vector2 in c++

i was envolving about a week with this issue, i have two vector for example vec1 and vec2, i want after search and find values from vec1 in vec2 return their indexes where only found for example:
vector<int>vec2 = { 1, 2, 2, 4 };
vector<int>vec1 = { 1, 2, 4 };
i want somthing like this pseudo code and this result:
pseudo code:
for i = 0 to vec2.size() do
return vec1 indexes in vec2;
end
result:
pass1:
1 0 0 0
pass2:
0 1 1 0
pass3:
0 0 0 1
final resault:
0 0 0 1
My code (it does not compile):
My code:
#include <vector>
#include <iostream>
using namespace std;
vector<int> find_index(vector<int>vec2, vector<int>vec1)
{
std::vector<double> tmp;
for (int i = 0; i<vec2.size(); i++)
{
for (int j = 0; j<vec2.size(); j++)
{
if (vec2[i] == vec1[j])
{
tmp.push_back(i);
}
}
}
return tmp;
}
int main()
{
vector<int>vec2 = { 1, 2, 2, 4 };
vector<int>vec1 = { 1, 2, 4 };
cout << find_index(vec2, vec1);
getchar();
return 0;
}
The code you have fails to compile for two reasons:
Using double item type for the tmp vector. A vector<double> does not convert implicitly to the required function result type vector<int>.
The standard library does not define output of vectors, so the cout << a vector in main doesn't compile.
To output the vector you can define function like this:
void write_to( ostream& stream, vector<int> const& v )
{
for( int i = 0; i < int( v.size() ); ++i )
{
stream << (i > 0? " " : "") << v[i];
}
}
and call it like this:
write_to( cout, find_index(vec2, vec1) );
cout << "\n";
It's also possible to write a little glue code that would enable the cout << notation, i.e. that would make it use the write_to function, but that is maybe just complication now.
With these changes your code compiles and outputs
0 1 2 3

Solving Subset algorithm using a recursive way gives wrong answer

I have tried to solve the following problem but I still get wrong answer, however the two test cases in the problem are correct answer for me.
Problem Statement: Subsets Sum, or "SS" (double S) for shortcut, is a classical problem in computer science.
We are given a set of positive integer numbers; we have to know if there is a non-empty subset of this set that the sum of its elements is equal to a given number.
Ex: suppose the set is [3, 4, 7, 9, 10] and the target number is 20 The sum of elements of the subset [3, 7, 10] is equal to 20.
Input Format: The input consists of many test cases, each test case is composed of two lines. On the first line of the input file there is a number indicates the number of test cases. The first line of each test case has two integer numbers (k, n): k is the target number, n <= 10 is the number of elements of the set. On the second line there are n integer numbers, each of these numbers is less than one hundred.
Output Format: for each test case print "YES" without quotes if there is a subset that satisfies the condition above, "NO" otherwise.
Sample Input:
2
1 5
45 26 36 4 8
49 8
49 9 5 37 0 42 15 19
Sample Output:
NO
YES
You can test the submission here: http://www.a2oj.com/p.jsp?ID=151
My Code:
#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <cstdio>
#include <vector>
#include <cstdlib>
#include <numeric>
#include <sstream>
#include <iostream>
#include <algorithm>
using namespace std;
bool check = false;
void get(vector<int> arr, long total, int i, int k)
{
int length = arr.size() - 1;
if (i == length*length || i == length)
return;
if (total == k)
{
check = true;
return;
}
if (total >= k && i <= 1)
{
check = false;
return;
}
get(arr, total + arr[i], i + 1, k);
get(arr, total, i + 1, k);
}
int main(void) {
int t;
cin >> t;
vector<int> arr;
while (t--)
{
arr.clear();
int n, k;
cin >> n >> k;
for (int i = 0; i < k; i++)
{
int n;
cin >> n;
arr.push_back(n);
}
get(arr, 0, 0, n);
// arr = { 49,9,5,37,0,42,15,19 };
// get(arr, 0, 0, 49);
if (check)
cout << "YES" << endl;
else
cout << "NO" << endl;
check = false;
}
return 0;
}
I would do that way:
bool SS(const std::vector<int>& v, int total)
{
std::set<int> sums;
for (auto e : v) {
std::set<int> r = sums;
r.insert(e);
for (auto s : sums) {
r.insert(s + e);
}
sums.swap(r);
}
return sums.count(total);
}
where the std::set sums content is all the possible sums from the given vector.
Live example
In the last line of your get function, you are overwriting the value computed by the previous recursive call.
get(arr, total + arr[i], i + 1, k);
get(arr, total, i + 1, k);
So if the first call sets check to true and the second one sets it to false, you will lose first one. This is one of the reasons using global variables is considered harmful, specially in recursive functions.
Instead of defining a global variable, you should change your get function to return a boolean value, and then you can have your recursive like this:
return get(arr, total + arr[i], i + 1, k) || get(arr, total, i + 1, k);
Also try to use more meaningful variable/function names. For example your recursive function can have the following prototype:
bool addsUp(vector<int> array, int total, int from, int length);
As for your k and n variables in the main function, I think you should swap their names to comply with the problem statement (k is the desired total, n is the count of numbers).
And finally your boundary conditions seem to be not quite right. This is the recursive function that got accepted for me:
bool addsUp(vector<int> arr, long soFar, int from, int total) {
if (total == 0)
return false;
if (soFar == total)
return true;
if (soFar > total)
return false;
if (from >= arr.size())
return false;
return addsUp(arr, soFar + arr[from], from + 1, total) || addsUp(arr, soFar, from + 1, total);
}
I have a recursive code which you could have a try,
#include <iostream>
#include <vector>
bool find_subset(const std::vector<int>& input_data, int N, int target_value)
{
if (N == 1)
return input_data[0] == target_value;
bool result = false;
for (int i = 0; i < N; ++i)
{
std::vector<int> copy = input_data;
copy.erase(copy.begin() + i);
if (input_data[i] == target_value || find_subset(copy, N - 1, target_value - input_data[i]))
{
result = true;
break;
}
}
return result;
}
int main()
{
std::vector<int> test_1{45, 26, 36, 4, 8}; int target_1 = 1;
std::vector<int> test_2{49, 9, 5, 37, 0, 42, 15, 19}; int target_2 = 49;
std::vector<int> test_3{ 1, 3, 5, 7 }; int target_3 = 13;
std::vector<int> test_4{ 1, 3, 5, 7 }; int target_4 = 14;
std::cout << (find_subset(test_1, test_1.size(), target_1) ? "Yes" : "No") << std::endl;
std::cout << (find_subset(test_2, test_2.size(), target_2) ? "Yes" : "No") << std::endl;
std::cout << (find_subset(test_3, test_3.size(), target_3) ? "Yes" : "No") << std::endl;
std::cout << (find_subset(test_4, test_4.size(), target_4) ? "Yes" : "No") << std::endl;
return 0;
}
The output are:
No
Yes
Yes
No

c++ Algorithm to convert an integer into an array of bool

I'm trying to code an algorithm that will save to file as binary strings every integer in a range. Eg, for the range 0 to 7:
0 0 0
0 0 1
0 1 0
0 1 1
1 0 0
1 0 1
1 1 0
1 1 1
Note that the leading zeros and spaces between digits are essential.
What I cant figure out how to do in a simple way is to convert the integers to binary numbers represented by bool []s (or some alternate approach).
EDIT
As requested, my solution so far is:
const int NUM_INPUTS = 6;
bool digits[NUM_INPUTS] = {0};
int NUM_PATTERNS = pow(2, NUM_INPUTS);
for(int q = 0; q < NUM_PATTERNS; q++)
{
for(int w = NUM_INPUTS -1 ; w > -1 ; w--)
{
if( ! ((q+1) % ( (int) pow(2, w))) )
digits[w] = !digits[w];
outf << digits[w] << " ";
}
outf << "\n";
}
Unfortunately, this is a bit screwy as the first pattern it gives me is 000001 instead of 000000.
This is not homework. I'm just coding a simple algorithm to give me an input file for training a neural network.
Don't use pow. Just use binary math:
const int NUM_INPUTS = 6;
int NUM_PATTERNS = 1 << NUM_INPUTS;
for(int q = 0; q < NUM_PATTERNS; q++)
{
for(int w = NUM_INPUTS -1 ; w > -1; w--)
{
outf << ((q>>w) & 1) << " ";
}
outf << "\n";
}
Note: I'm not providing code, but merely a hint because the question sounds like homework
This is quite easy. See this example:
number = 23
binary representation = 10111
first digit = (number )&1 = 1
second digit = (number>>1)&1 = 1
third digit = (number>>2)&1 = 1
fourth digit = (number>>3)&1 = 1
fifth digit = (number>>4)&1 = 1
Alternatively written:
temp = number
for i from 0 to digits_count
digit i = temp&1
temp >>= 1
Note that the order of digits taken by this algorithm is the reverse of what you want to print.
The lazy way would be to use std::bitset.
Example:
#include <bitset>
#include <iostream>
int main()
{
for (unsigned int i = 0; i != 8; ++i){
std::bitset<3> b(i);
std::cout << b << std::endl;
}
}
If you want to output the bits individually, space-separated, replace std::cout << b << std::endl; with a call to something like Write(b), with Write defined as:
template<std::size_t S>
void Write(const std::bitset<S>& B)
{
for (int i = S - 1; i >= 0; --i){
std::cout << std::noboolalpha << B[i] << " ";
}
std::cout << std::endl;
}

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;
}