Here's the problem I'm working on: a user gives me an unspecified number of points on a standard x,y coordinate plane, where 0 < x^2 + y^2 <= 1. (x squared plus y squared, just for clarity).
Here is an example of the input:
0.2 0.38
0.6516 -0.1
-0.3 0.41
-0.38 0.2
From there, I calculate the distance of those points from the origin, (0, 0). Here is the function I use to find the distance and push it into a vector of doubles, B.
void findDistance(double x = 0, double y = 0) {
double x2 = pow(x, 2);
double y2 = pow(y, 2);
double z = x2 + y2;
double final = sqrt(z);
B.push_back(final);
}
Then, I want to bucket sort vector B, where there are n buckets for n points. Here is my current build of the bucketSort:
void bucketSort(double arr[], int n)
{
vector<double> b[n];
for (int i=0; i<n; i++)
{
int bi = n*arr[i];
b[bi].push_back(arr[i]);
}
for (int i=0; i<n; i++)
sort(b[i].begin(), b[i].end());
int index = 0;
for (int i = 0; i < n; i++)
for (int j = 0; j < b[i].size(); j++)
arr[index++] = b[i][j];
}
My problem is I can't get bucketSort to work without crashing. I get a windows message saying the program has stopped working. Now, I know the function works, but only when I initialize the vector and fill it at the same time. This is an example of a call that works:
double arr[] = {0.707107, 0.565685, 0.989949, 0.848528 };
int n = sizeof(arr)/sizeof(arr[0]);
bucketSort(arr, n);
So far, I've yet to find any other format for calling and initializing the vector that the function will accept and run. I need to find a way to take the points, computer the distances, and sort the distances. Current main that I'm plugging in and getting as a backfire:
int main(){
int number;
while (cin >> number){
A.push_back(number); }
int q = 0; double r = 0; double d = 0;
while (q < (A.size() - 1)){
findDistance(A[q], A[q+1]);
q += 2;
}
double arr[B.size()]; copy(B.begin(), B.end(), arr);
int n = (sizeof(B) + sizeof(B[0])) / sizeof(B[0]);
bucketSort(arr, n);
int w = 0;
while (w < y){ cout << arr[w] << endl; w++; }
The arr copy was created in some strange debugging attempt: sorry if unclear. Results of distance function stored in B, copied into arr, and arr is what's attempted to be sorted. The user inputs are given through the command prompt, using the syntax listed in the beginning. Output should be something like:
0.42941
0.49241
0.50804
0.65923
If anyone can offer suggestions of edits to either of functions that would make it work, the assistance would be greatly appreciated.
Here are a few issues to work on:
Your input loop will stop when it reads a non-integer. Change number to double
Your size calculation
int n = (sizeof(B) + sizeof(B[0])) / sizeof(B[0]);
I am not sure what you are trying to do here, but sizeof on a vector is not what you want. I think replacing this with:
int n = B.size();
is what you want.
I am not sure why you needed to convert the vector to an array to do the bucket sort - much easier to just pass the vector through to the bucket sort, then the size comes with the vector.
Change the bucketSort function to take a reference to a vector:
void bucketSort(vector<double> &arr)
{
int n = B.size();
...
and just pass B into the function. The rest of the code should be the same.
Also a portability note: not every compiler supports variable sized arrays, you are better off sticking with vector wherever possible.
Related
I am trying to create models that involve looping through large multidimensional arrays (ex: dimensions = 20 x 1000 x 60), which run very slow the way I code them in R. I downloaded Rcpp and have been trying to implement such a model, since C++ handles loops very well. Normally, I would write such a function in R as:
fun <- function(x,y,z){
f <- array(0, dim = c(18,50,10));
for (i in 1:18){
for (j in 1:50){
for (l in 1:10){
f[i,j,l] <- (i*j/10) + l;
}
}
}
return(f[x,y,z])
}
and as expected the function yields:
> fun(10,20,5)
[1] 25
This is what I thought the equivalent code in Rcpp should look like:
cppFunction('
double fun(int x, int y, int z){
int f[18][50][10] = {0};
for (int i = 1; i > 18; i++){
for (int j = 1; j > 50; j++){
for (int l = 1; l > 10; l++){
f[i][j][l] = (i * j/10) + l;
}
}
}
return f[x][y][z];
}
')
but I am getting 0's anytime I go to use the function.
> fun(10,20,5)
[1] 0
The actual models I'll be implementing use backward iteration, so I do need the arrays as part of the function. Alternatively, returning the array itself would also work for my purposes, but I haven't had luck with that either.
Any help would be sincerely appreciated.
Thanks
Remember that C++ is 0 indexed. You need to start your indexing at 0 rather than 1 as in R. You also need to make sure that your loops only continue while the value of i, j, and l are less than the dimensions of the array (so switch > for <. And your array needs to be an array of double, not int:
Rcpp::cppFunction('
double fun(int x, int y, int z){
double f[18][50][10] = {0};
for (int i = 0; i < 18; i++){
for (int j = 0; j < 50; j++){
for (int l = 0; l < 10; l++){
f[i][j][l] = (i * j/10) + l;
}
}
}
return f[x][y][z];
}
')
Testing gives:
fun(10, 20, 5)
#> [1] 25
Task
Given n gold bars, find the maximum weight of gold that fits into bag of capacity W
Input
first line contains the capacity W of the knapsack and the number n of bars of gold. The next line contains n integers
Output
The max weight of gold that fits into a knapsack of capacity W.
Constraints
1 <= W <= 10000; 1<= n <= 300; 0 <= w0, w1, w2, ... , w(n-1) <= 100000
Code
#include <iostream>
#include <vector>
using std::vector;
int optimal_weight(int W, vector<int> w) {
int n = w.size() + 1;
int wt = W + 1;
int array [n][wt];
int val = 0;
for(int i = 0; i < wt; i++) array [0][i] = 0;
for(int i = 0; i < n; i++) array [i][0] = 0;
for(int i = 1; i< n; i++) {
for(int j = 1; j < wt; j++ ){
array[i][j] = array [i-1][j];
if (w[i-1] <= j) {
val = array[i-1][j - w[i-1]] + w[i-1];
if(array[i][j] < val) array[i][j] = val;
}
}
}
//printing the grid
// for(int i=0; i < n; i++) {
// for(int j=0; j < wt; j++) {
// cout<<array[i][j]<<" ";
// }
// cout<<endl;
// }
// cout<<endl;
return array [n-1][wt-1];
}
int main() {
int n, W;
std::cin >> W >> n;
vector<int> w(n);
for (int i = 0; i < n; i++) {
std::cin >> w[i];
}
std::cout << optimal_weight(W, w) << '\n';
}
The above code works fine for smaller inputs, but gives an unknown signal 11 error on the platform I wish to submit to. My best guess is of a possible segmentation fault, but I have been unable to debug it since quite some time now. Any help is much appreciated!
First note that your code doesn't work. That is, it doesn't compile when you adhere strictly to the C++ language standard, as C++ does not support variable-length arrays. (as noted by #Evg in a comment; some compilers offer this as an extension.)
The main reason for excluding those from C++ is probably why you're experiencing issues for larger problem sizes: the danger of stack overflows, the namesake of this website (as noted by #huseyinturgulbuyukisik in a comment). Variable-length arrays are allocated on the stack, whose size is limited. When you exceed it, you might attempt to write to a segment of memory that is not allocated to your process, triggering Linux signal 11, also known as SIGSEGV - the segmentation violation signal.
Instead of stack-based allocation, you should allocate your memory on the heap. A straightforward way to do so would be using the std::vector container (whose default allocator does indeed allocate on the heap). Thus, you would write:
std::vector<int> vec(n * wt);
and instead of array[i][j] you'd use vec[i * wt + j].
Now, this is not as convenient as using array[x][y]; for the extra convenience you can, for example, write a helper lambda, to access individual elements, e.g.
auto array_element = [&vec, wt](int x, int y) { return vec[x * wt + y]; }
with this lambda function available, you can now write statements such as array_element(i,j) = array_element(i-1,j);
or use a multi-dimensional container (std::vector<std::vector<int>> would work but it's ugly and wasteful IMHO; unfortunately, the standard library doesn't have a single-allocation multi-dimensional equivalent of that).
Other suggestions, not regarding a solution to your signal 11 issue:
Use more descriptive variable names, e.g. weight instead of wt and capacity instead of W. I'd also considersub_solutions_table or solutions_table instead of array, and might also rename i and j according to the semantics of the dynamic solution table.
You never actually need more than 2 rows of the solutions table; why not just allocate one row for the current iteration and one row for the previous iteration, and have appropriate pointers switch between them?
Replace
vector< vector< int> > k(n + 1,vector< int>(W + 1));
with
int array[n][w];
So I have a vector of vectors type double. I basically need to be able to set 360 numbers to cosY, and then put those 360 numbers into cosineY[0], then get another 360 numbers that are calculated with a different a now, and put them into cosineY[1].Technically my vector is going to be cosineYa I then need to be able to take out just cosY for a that I specify...
My code is saying this:
for (int a = 0; a < 8; a++)
{
for int n=0; n <= 360; n++
{
cosY[n] = cos(a*vectorOfY[n]);
}
cosineY.push_back(cosY);
}
which I hope is the correct way of actually setting it.
But then I need to take cosY for a that I specify, and calculate another another 360 vector, which will be stored in another vector again as a vector of vectors.
Right now I've got:
for (int a = 0; a < 8; a++
{
for (int n = 0; n <= 360; n++)
{
cosProductPt[n] = (VectorOfY[n]*cosY[n]);
}
CosProductY.push_back(cosProductPt);
}
The VectorOfY is besically the amplitude of an input wave. What I am doing is trying to create a cosine wave with different frequencies (a). I am then calculation the product of the input and cosine wave at each frequency. I need to be able to access these 360 points for each frequency later on in the program, and right now also I need to calculate the addition of all elements in cosProductPt, for every frequency (stored in cosProductY), and store it in a vector dotProductCos[a].
I've been trying to work it out but I don't know how to access all the elements in a vector of vectors to add them. I've been trying to do this for the whole day without any results. Right now I know so little that I don't even know how I would display or access a vector inside a vector, but I need to use that access point for the addition.
Thank you for your help.
for (int a = 0; a < 8; a++)
{
for int n=0; n < 360; n++) // note traded in <= for <. I think you had an off by one
// error here.
{
cosY[n] = cos(a*vectorOfY[n]);
}
cosineY.push_back(cosY);
}
Is sound so long as cosY has been pre-allocated to contain at least 360 elements. You could
std::vector<std::vector<double>> cosineY;
std::vector<double> cosY(360); // strongly consider replacing the 360 with a well-named
// constant
for (int a = 0; a < 8; a++) // same with that 8
{
for int n=0; n < 360; n++)
{
cosY[n] = cos(a*vectorOfY[n]);
}
cosineY.push_back(cosY);
}
for example, but this hangs on to cosY longer than you need to and could cause problems later, so I'd probably scope cosY by throwing the above code into a function.
std::vector<std::vector<double>> buildStageOne(std::vector<double> &vectorOfY)
{
std::vector<std::vector<double>> cosineY;
std::vector<double> cosY(NumDegrees);
for (int a = 0; a < NumVectors; a++)
{
for int n=0; n < NumDegrees; n++)
{
cosY[n] = cos(a*vectorOfY[n]); // take radians into account if needed.
}
cosineY.push_back(cosY);
}
return cosineY;
}
This looks horrible, returning the vector by value, but the vast majority of compilers will take advantage of Copy Elision or some other sneaky optimization to eliminate the copying.
Then I'd do almost the exact same thing for the second step.
std::vector<std::vector<double>> buildStageTwo(std::vector<double> &vectorOfY,
std::vector<std::vector<double>> &cosineY)
{
std::vector<std::vector<double>> CosProductY;
for (int a = 0; a < numVectors; a++)
{
for (int n = 0; n < NumDegrees; n++)
{
cosProductPt[n] = (VectorOfY[n]*cosineY[a][n]);
}
CosProductY.push_back(cosProductPt);
}
return CosProductY;
}
But we can make a couple optimizations
std::vector<std::vector<double>> buildStageTwo(std::vector<double> &vectorOfY,
std::vector<std::vector<double>> &cosineY)
{
std::vector<std::vector<double>> CosProductY;
for (int a = 0; a < numVectors; a++)
{
// why risk constantly looking up cosineY[a]? grab it once and cache it
std::vector<double> & cosY = cosineY[a]; // note the reference
for (int n = 0; n < numDegrees; n++)
{
cosProductPt[n] = (VectorOfY[n]*cosY[n]);
}
CosProductY.push_back(cosProductPt);
}
return CosProductY;
}
And the next is kind of an extension of the first:
std::vector<std::vector<double>> buildStageTwo(std::vector<double> &vectorOfY,
std::vector<std::vector<double>> &cosineY)
{
std::vector<std::vector<double>> CosProductY;
std::vector<double> cosProductPt(360);
for (std::vector<double> & cosY: cosineY) // range based for. Gets rid of
{
for (int n = 0; n < NumDegrees; n++)
{
cosProductPt[n] = (VectorOfY[n]*cosY[n]);
}
CosProductY.push_back(cosProductPt);
}
return CosProductY;
}
We could do the same range-based for trick for the for (int n = 0; n < NumDegrees; n++), but since we are iterating multiple arrays here it's not all that helpful.
I am consider new to c++ and I have facing some doubt on merging three set of arrays.
For example:
x = 2,3,1,4,5
y = 1,3,5,7,9
z = 3,5,4,6,1
I would like to merge them into:
w = 2,1,3,3,3,5,1,5,4,4,7,6,5,9,1
I have been searching through Google. However what I get is how to merge the arrays and put them in an ascending orders.
What I actually needed:
1st from x, 1st from y, 1st from z, 2nd from x, 2nd from y, 2nd from z ............ 5th from z
Thank you very much!
It's just a matter of making a loop with i from 0 to 4 and mapping every i to the corresponding element of the array w.
Here's the skeleton of the algorithm:
std::array<int, 5> x, y, z;
std::array<int, 15> w;
for (int i = 0; i < 5; i++) {
w[i*3] = x[i];
w[i*3+1] = y[i];
w[i*3+2] = z[i];
}
And here's the working example.
If you are using std::vector, then the algorithm gets a little bit trickier. You'll need to find the maximum size, using std::max for example, and perform a loop based on that value. Then whenever a vector is empty, you'll need to skip it. Here's the skeleton again:
std::vector<int> x, y, z;
std::vector<int> w;
std::size_t max = std::max({x.size(), y.size(), z.size()});
for (std::size_t i = 0; i < max; i++) {
if (x.size() > i) w.push_back(x[i]);
if (y.size() > i) w.push_back(y[i]);
if (z.size() > i) w.push_back(z[i]);
}
As long as you know the size of x, y, z, and w, this is a fairly straightforward solution.
In C++, unlike other higher-level programming languages, most array-based operations are not handled by special functions. Instead, the user is required to write a loop to do this task themselves.
In your case, assuming that x, y, z, and w are all declared and defined properly, the most straightforward way is probably using a for loop, as follows:
int i;
for(i=0; i<(size_of_x); i++){
w[i*3] = x[i];
w[i*3+1] = y[i];
w[i*3+2] = z[i];
}
Notice that the variable size_of_x will need to be defined for this to work.
You might also want to consider the fact that the lengths of the arrays may differ.
int *resArray;
int totalLength = sizeof(x) + sizeof(y) + sizeof(z);
int maxLength = max(sizeof(x), max(sizeof(y), sizeof(x));
resArray = new int[totalLength];
int j = 0;
for (int i = 0; i < maxLength; i++)
{
if (i < sizeof(x))
{
resArray[j] = x[i];
j++
}
if (i < sizeof(y))
{
resArray[j] = y[i];
j++
}
if (i < sizeof(z))
{
resArray[j] = z[i];
j++
}
}
It'll not be the fastest solution, but it can handle arrays of different lengths.
Edit:
Do not forget to free the memory you've allocated using new.
And you can consider the use of std::vector
How about some C++11?
#include <vector>
int main()
{
std::vector<int> x {2,3,1,4,5}, y {1,3,5,7,9}, z {3,5,4,6,1};
std::vector<int> w;
for (int i {}; i < x.size(); ++i)
{
w.insert(v.end(),{x[i], y[i], z[i]});
}
}
I want to create a function that calculates neural network output. The elements of my NN
is a 19D input vector and a 19D output vector. I choose one hidden layer with 50 neurons. My code is the following but i am not quite sure if it works properly.
double *BuildPlanner::neural_tactics(){
norm(); //normalize input vector
ReadFromFile(); // load weights W1 W2 b1
double hiddenLayer [50][1];
for(int h=0; h<50; h++){
hiddenLayer[h][0] =0;
for(int f = 0; f < 19; f++){
hiddenLayer[h][0] = hiddenLayer[h][0] + W1[h][f]*input1[f][0];
}
}
double HiddenLayer[50][1];
for(int h=0; h<50; h++){
HiddenLayer[h][0] = tanh(hiddenLayer[h][0] + b1[h][0]);
}
double outputLayer[50][1];
for(int h=0; h<19; h++){
for(int k=0; k<50; k++){
outputLayer[h][0] = outputLayer[h][0] + W2[h][k]*HiddenLayer[k][0];
}
}
double Output[19];
for(int h=0; h<19; h++){
Output[h] = tanh(outputLayer[h][0]);
}
return Output;
}
Actually I not quite sure about the matrices multiplication. W1*input+b1 where the size
of the matrices are 50x19 * 19x1 + 50x1 and W2*outHiddenLayer 19x50*50x1!
Your matrix multiplication looks ok to me, but there are other problems--`outputLayer is 50x1 but a) you only iterate through the first 19 elements, and b) you have it on the RHS of your equation
outputLayer[h][0] = outputLayer[h][0] + W2[h][k]...
before that element has ever been defined. That could be causing all your problems. Also, although I assume you're making outputLayer 2-dimensional to make them look matrix-like, it's completely gratuitous and slows things down when the second dimension has size 1--just declare it and the others as
double outputLayer[50];
since it's a vector and those are always one dimensional so it will actually make your code clearer.