How to check if two n-sized vectors are linearly dependant on C++? [closed] - c++

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
A program should be made which finds if the two vectors a = (a0, a1, ..., an-1) and b = (b0, b1, ..., bn-1) (1 ≤ n ≤ 20) are linearly dependant. The input should be n, and the coordinates of the two vectors and the output should be 1 if the vectors are linearly dependant, else - 0.
I've been struggling for hours over this now and I've got absolutely nothing. I know only basic C++ stuff and my geometry sucks way too much. I'd be really thankful if someone would write me a solution or at least give me some hint. Thanks in advance !
#include <iostream>
using namespace std;
int main()
{
int n;
double a[20], b[20];
cin >> n;
int counter = n;
bool flag = false;
for (int i = 0; i < n; i++)
{
cin >> a[i];
cin >> b[i];
}
double k;
for (int i = 0; i < n; i++)
{
for (k = 0; k < 1000; k = k + 0.01)
{
if (a[i] == b[i])
{
counter--;
}
}
}
if (counter == 0 && k != 0)
flag = true;
cout << flag;
return 0;
}
Apparently that was all I could possibly come up with. The "for" cycle is wrong on so many levels but I don't know how to fix it. I'm open to suggestions.

There are 4 parts to the problem:
1. Math and algorithms
Vectors a and b are linearly depndent if ∃k. a = k b. That is expanded to ∃k. ∑i=1..n ai = k ai and that is a set of equations any of which can be solved for k.
So you calculate k as b0 / a0 and check that the same k works for the other dimensions.
Don't forget to handle a0 = 0 (or small, see below). I'd probably swap the vectors so the larger absolute value is denominator.
2. Limited precision numeric calculations
Since the precision is limited, calculations involve rounding error. You need to check for approximate equality, not exact, because most likely you won't get exact results even when you expect them.
Approximate equality comes in two forms, absolute (|x - y| < ε) and relative (1 - ε < |x / y| < 1 + ε). Obviously the relative makes more sense here (you want to ignore the last significant digit only), but again you have to handle the case where the values are too small.
3. C++
Don't use plain arrays, use std::vector. That way you won't have arbitrary limits.
Iterate with iterator, not indices. Iterators work for all container types, indices only work for the few with continuous integral indices and random access. Which is basically just vector and plain array. And note that iterators are designed so that pointer is iterator, so you can iterate with iterator over plain arrays too.
4. Plain old bugs
You have the loop over k, but you don't use the value inside the loop.
The logic with counter does not seem to make any sense. I don't even see what you wanted to achieve with that.

You're right, that code bears no reationship to the problem at all.
It's easier than you think (at least conceptually). Divide each element in the vector by the corressponding element in the other vector. If all those division result in the same number then the vectors are linearly dependendent. So { 1, 2, 4 } and { 3, 6, 12 } are linear because 1/3 == 2/6 == 4/12.
However there are two technical problems. First you have to consider what happens when your elements are zero, you don't want to divide by zero.
Secondly because you are dealing with floating point numbers it's not sufficient to test if two numbers are equal. Because of rounding errors they often won't be. So you have to come up with some test to see if two numbers are nearly equal.
I'll leave you to think about both those problems.

Related

How to find the power of the array elements? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
I need to check if A[0] ^ A[1] ^ A[2] ... ^ A[N] is even or odd.
Is this code right??
#include <bits/stdc++.h>
#include <cmath>
using namespace std;
int main(){
long long n;
cin >> n;
int a[n];
long int mp;
for(int i = 0; i < n; i++){
cin >> a[i];
mp = pow(a[i], a[i+1]);
}
if (mp % 2 == 0){
cout << "YES";
}
else cout<<"NO";
}
Do the maths first.
Consider that
odd * odd * odd * odd .... * odd == odd
You can multiply any odd factors and the result is always odd. Whether a number is odd or even is equivalent to: It has a prime factor 2. Some integer raised to some other integer cannot remove a prime factor, it can also not add a prime factor when it wasn't present before. You start with some x and then
x * x * x * x * x .... * x = y
has the same prime factors as x, just with different powers. The only exceptions is to get an odd number from an even one when you raise a number to power 0, because x^0 = 1.
Ergo, you are on the wrong track. Instead of brute force raising numbers to some power you merely need to consider ...
is A[0] odd or even
is any of the other elements 0 (remember that (a^b)^c) is just a^(b*c))
Thats it.
I will not write the code for you to not spoil the exercise. But I should tell you whats wrong with your code: pow is not made to be used with integers. There are many Q&As here about pow returning a "wrong" result, which is most often just due to wrong expectations. Here is one of them: Why does pow(n,2) return 24 when n=5, with my compiler and OS?. Moreover, you are accessing the array out of bounds in the last iteration of the loop. Hence all your code has undefined behavior. Output could be "maybe" or something else entirely. Also, your code merely calculates a[i] ^ a[i+1] and after the loop you only consider the very last result. Thats not what the task you describe asks for. Last but not least, Why aren't variable-length arrays part of the C++ standard?. Use std::vector for dynamically sized arrays.

How to make this code faster (learning best practices)? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I have this little loop here, and I was wondering if I do some big mistake, perf wise.
For example, is there a way to rewrite parts of it differently, to make vectorization possible (assuming GCC4.8.1 and all vecotrization friendly flags enabled)?
Is this the best way to pass a list a number (const float name_of_var[])?
The idea of the code is to take a vector (in the mathematical sense, not necesserly a std::vector) of (unsorted numbers) y and two bound values (ox[0]<=ox[1]) and to store in a vector of integers rdx the index i of the entry of y satisfying ox[0]<=y[i]<=ox[1].
rdx can contain m elements and y has capacity n and n>m. If there are more than m
values of y[i] satisfying ox[0]<=y[i]<=ox[1] then the code should return the first m
Thanks in advance,
void foo(const int n,const int m,const float y[],const float ox[],int rdx[]){
int d0,j=0,i=0;
for(;;){
i++;
d0=((y[i]>=ox[0])+(y[i]<=ox[1]))/2;
if(d0==1){
rdx[j]=i;
j++;
}
if(j==m) break;
if(i==n-1) break;
}
}
d0=((y[i]>=ox[0])+(y[i]<=ox[1]))/2;
if(d0==1)
I believe the use of an intermediary variable is useless, and take a few more cycles
This is the most optimized version I could think of, but it's totally unreadable...
void foo(int n, int m, float y[],const float ox[],int rdx[])
{
for(int i = 0; i < n && m != 0; i++)
{
if(*y >= *ox && *y <= ox[1])
{
*rdx=i;
rdx++;
m--;
}
y++;
}
}
I think the following version with a decent optimisation flag should do the job
void foo(int n, int m,const float y[],const float ox[],int rdx[])
{
for(int j = 0, i = 0; j < m && i < n; i++) //Reorder to put the condition with the highest probability to fail first
{
if(y[i] >= ox[0] && y[i] <= ox[1])
{
rdx[j++] = i;
}
}
}
Just to make sure I'm correct: you're trying to find the first m+1 (if it's actually m, do j == m-1) values that are in the range of [ ox[0], ox[1] ]?
If so, wouldn't it be better to do:
for (int i=0, j=0;;++i) {
if (y[i] < ox[0]) continue;
if (y[i] > ox[1]) continue;
rdx[j] = i;
j++;
if (j == m || i == n-1) break;
}
If y[i] is indeed in the range you must perform both comparisons as we both do.
If y[i] is under ox[0], no need to perform the second comparison.
I avoid the use of division.
A. Yes, passing the float array as float[] is not only efficient, it is the only way (and is identical to a float * argument).
A1. But in C++ you can use better types without performance loss. Accessing a vector or array (the standard library container) should not be slower than accessing a plain C style array. I would strongly advise you to use those. In modern C++ there is also the possibility to use iterators and functors; I am no expert there but if you can express the independence of operations on different elements by being more abstract you may give the compiler the chance to generate code that is more suitable for vectorization.
B. You should replace the division by a logical AND, operator&&. The first advantage is that the second condition is not evaluated at all if the first one is false -- this could be your most important performance gain here. The second advantage is expressiveness and thus readability.
C. The intermediate variable d0 will probably disappear when you compile with -O3, but it's unnecessary nonetheless.
The rest is ok performancewise. Idiomatically there is room for improvement as has been shown already.
D. I am not sure about a chance for vectorization with the code as presented here. The compiler will probably do some loop unrolling at -O3; try to let it emit SSE code (cf. http://gcc.gnu.org/onlinedocs/, specifically http://gcc.gnu.org/onlinedocs/gcc-4.8.2/gcc/i386-and-x86-64-Options.html#i386-and-x86-64-Options). Who knows.
Oh, I just realized that your original code passes the constant interval boundaries as an array with 2 elements, ox[]. Since array access is an unnecessary indirection and as such may carry an overhead, using two normal float parameters would be preferred here. Keep them const like your array. You could also name them nicely.

C++ sieve of Eratosthenes with array [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I'd like to code the famous Sieve of Eratosthenes in C++ using just array as it would be a set where I can delete some elements on the way to find out primes numbers.
I don't want to use STL (vector, set)... Just array! How can I realize it?
I try to explain why I don't want to use STL set operator: I'm learning C++ from the very beginning and I think STL is of course useful for programmers but built on standard library, so I'd like to use former operators and commands. I know that everything could be easier with STL.
The key to the sieve of Eratosthenes's efficiency is that it does not, repeat not, delete ⁄ remove ⁄ throw away ⁄ etc. the composites as it enumerates them, but instead just marks them as such.
Keeping all the numbers preserves our ability to use a number's value as its address in this array and thus directly address it: array[n]. This is what makes the sieve's enumeration and marking off of each prime's multiples efficient, when implemented on modern random-access memory computers (just as with the integer sorting algorithms).
To make that array simulate a set, we give each entry two possible values, flags: on and off, prime or composite, 1 or 0. Yes, we actually only need one bit, not byte, to represent each number in the sieve array, provided we do not remove any of them while working on it.
And btw, vector<bool> is automatically packed, representing bools by bits. Very convenient.
From Algorithms and Data Structures
#include<iostream>
#include<cmath>
#include<cstring>
using namespace std;
void runEratosthenesSieve(int upperBound) {
int upperBoundSquareRoot = (int)sqrt((double)upperBound);
bool *isComposite = new bool[upperBound + 1];
memset(isComposite, 0, sizeof(bool) * (upperBound + 1));
for (int m = 2; m <= upperBoundSquareRoot; m++) {
if (!isComposite[m]) {
cout << m << " ";
for (int k = m * m; k <= upperBound; k += m)
isComposite[k] = true;
}
}
for (int m = upperBoundSquareRoot; m <= upperBound; m++)
if (!isComposite[m])
cout << m << " ";
delete [] isComposite;
}
int main()
{
runEratosthenesSieve(1000);
}
You don't want to use STL, but that's not a good idea
STL makes life much simpler.
Still consider this implementation using std::map
int max = 100;
S sieve;
for(int it=2;it < max;++it)
sieve.insert(it);
for(S::iterator it = sieve.begin();it != sieve.end();++it)
{
int prime = *it;
S::iterator x = it;
++x;
while(x != sieve.end())
if (((*x) % prime) == 0)
sieve.erase(x++);
else
++x;
}
for(S::iterator it = sieve.begin();it != sieve.end();++it)
std::cout<<*it<<std::endl;

C++ Adding big numbers together with operator overload

I am new to C++ and attempting to create a "BigInt" class. I decided to base most of the implementation on reading the numbers into vectors.
So far I have only written the copy constructor for an input string.
Largenum::Largenum(std::string input)
{
for (std::string::const_iterator it = input.begin(); it!=input.end(); ++it)
{
number.push_back(*it- '0');
}
}
The problem I am having is with the addition function. I have created a function which seems to work after I tested it a few times, but as you can see its highly inefficient. I have 2 different vectors such as:
std::vector<int> x = {1,3,4,5,9,1};
std::vector<int> y = {2,4,5,6};
The way I thought to solve this problem was to add 0s before the shorter, in this case y vector to make both vectors have the same size such as:
x = {1,3,4,5,9,1};
y = {0,0,2,4,5,6};
Then to add them using elementary style addition.
I don't want to add 0s infront of vector Y as it would be slow with a large number. My current solution is to reverse the vector, then push_back the appropriate amount of 0s, then reverse it back. This may be slower then simply inserting at the front it seems, I have not tested yet.
The problem is that after I do all of the addition on the vectors and push_back the result. I am left with a backward vector and I need to use reverse yet again! There has got to be a much better way then my method but I am stuck on finding it. Ideally I would make A const as well. Here is the code of the function:
Largenum Largenum::operator+(Largenum &A)
{
bool carry = 0;
Largenum sum;
std::vector<int>::size_type max = std::max(A.number.size(), this->number.size());
std::vector<int>::size_type diff = std::abs (A.number.size()-this->number.size());
if (A.number.size()>this->number.size())
{
std::reverse(this->number.begin(), this->number.end());
for (std::vector<int>::size_type i = 0; i<(max-diff); ++i) this->number.push_back(0);
std::reverse(this->number.begin(), this->number.end());
}
else if (this->number.size() > A.number.size())
{
std::reverse(A.number.begin(), A.number.end());
for (std::vector<int>::size_type i = 0; i<(max-diff); ++i) A.number.push_back(0);
std::reverse(A.number.begin(), A.number.end());
}
for (std::vector<int>::size_type i = max; i!=0; --i)
{
int num = (A.number[i-1] + this->number[i-1] + carry)%10;
sum.number.push_back(num);
(A.number[i-1] + this->number[i-1] + carry >= 10) ? carry = 1 : carry = 0;
}
if (carry) sum.number.push_back(1);
reverse(sum.number.begin(), sum.number.end());
return sum;
}
If anyone has any input that would be great, this is my first program using classes in C++ and its fairly overwhelming.
I think your function is quite close to the most optimal one I have seen. Still here are few suggestions how to improve it:
Decimal numeric system is quite inefficient, you have a lot of digits for big numbers. Better use a higher base to reduce the number of digits you have to add. Reading and writing such numbers in human readable representation will be a bit harder, but you will optimize the operations several times, because you will have less digits.
When implementing big integers I represent them in reverse order, thus I have the least significant digit at position with index 0, and the most significant one at the end of the array. This way when carry forces you to add a new digit you only perform a push_back, not a whole reverse.
One issue: integer modulus is pretty slow on modern processors, even compared to branch misprediction. Rather than doing an explicit %10, try this for your third for-loop:
int num = A.number[i-1] + this->number[i-1] + carry;
if(num >= 10)
{
carry = 1;
num -= 10;
}
else
{
carry = 0;
}
sum.number.push_back(num);

Long array performance issue

I have an array of char pointers of length 175,000. Each pointer points to a c-string array of length 100, each character is either 1 or 0. I need to compare the difference between the strings.
char* arr[175000];
So far, I have two for loops where I compare every string with every other string. The comparison functions basically take two c-strings and returns an integer which is the number of differences of the arrays.
This is taking really long on my 4-core machine. Last time I left it to run for 45min and it never finished executing. Please advise of a faster solution or some optimizations.
Example:
000010
000001
have a difference of 2 since the last two bits do not match.
After i calculate the difference i store the value in another array
int holder;
for(int x = 0;x < UsedTableSpace; x++){
int min = 10000000;
for(int y = 0; y < UsedTableSpace; y++){
if(x != y){
//compr calculates difference between two c-string arrays
int tempDiff =compr(similarity[x]->matrix, similarity[y]->matrix);
if(tempDiff < min){
min = tempDiff;
holder = y;
}
}
}
similarity[holder]->inbound++;
}
With more information, we could probably give you better advice, but based on what I understand of the question, here are some ideas:
Since you're using each character to represent a 1 or a 0, you're using several times more memory than you need to use, which creates a big performance impact when it comes to caching and such. Instead, represent your data using numeric values that you can think of in terms of a series of bits.
Once you've implemented #1, you can grab an entire integer or long at a time and do a bitwise XOR operation to end up with a number that has a 1 in every place where the two numbers didn't have the same values. Then you can use some of the tricks mentioned here to count these bits speedily.
Work on "unrolling" your loops somewhat to avoid the number of jumps necessary. For example, the following code:
total = total + array[i];
total = total + array[i + 1];
total = total + array[i + 2];
... will work faster than just looping over total = total + array[i] three times. Jumps are expensive, and interfere with the processor's pipelining. Update: I should mention that your compiler may be doing some of this for you already--you can check the compiled code to see.
Break your overall data set into chunks that will allow you to take full advantage of caching. Think of your problem as a "square" with the i index on one axis and the j axis on the other. If you start with one i and iterate across all 175000 j values, the first j values you visit will be gone from the cache by the time you get to the end of the line. On the other hand, if you take the top left corner and go from j=0 to 256, most of the values on the j axis will still be in a low-level cache as you loop around to compare them with i=0, 1, 2, etc.
Lastly, although this should go without saying, I guess it's worth mentioning: Make sure your compiler is set to optimize!
One simple optimization is to compare the strings only once. If the difference between A and B is 12, the difference between B and A is also 12. Your running time is going to drop almost half.
In code:
int compr(const char* a, const char* b) {
int d = 0, i;
for (i=0; i < 100; ++i)
if (a[i] != b[i]) ++d;
return d;
}
void main_function(...) {
for(int x = 0;x < UsedTableSpace; x++){
int min = 10000000;
for(int y = x + 1; y < UsedTableSpace; y++){
//compr calculates difference between two c-string arrays
int tempDiff = compr(similarity[x]->matrix, similarity[y]->matrix);
if(tempDiff < min){
min = tempDiff;
holder = y;
}
}
similarity[holder]->inbound++;
}
}
Notice the second-th for loop, I've changed the start index.
Some other optimizations is running the run method on separate threads to take advantage of your 4 cores.
What is your goal, i.e. what do you want to do with the Hamming Distances (which is what they are) after you've got them? For example, if you are looking for the closest pair, or most distant pair, you probably can get an O(n ln n) algorithm instead of the O(n^2) methods suggested so far. (At n=175000, n^2 is 15000 times larger than n ln n.)
For example, you could characterize each 100-bit number m by 8 4-bit numbers, being the number of bits set in 8 segments of m, and sort the resulting 32-bit signatures into ascending order. Signatures of the closest pair are likely to be nearby in the sorted list. It is easy to lower-bound the distance between two numbers if their signatures differ, giving an effective branch-and-bound process as less-distant numbers are found.