Combination of point coordinates from limit values

Dec 26, 2020 at 2:02pm
Hello
I have an lower and upper limit values of n dimension coordinate system, like
[2,5,8]- lower and [6,12,16] - upper for 3 dim. I want to get points from those limit values like [2,5,8],[6,5,8],[6,12,8],[6,5,16] ... and goes on in total there must be 2^n points.
How should do with recursion in C++??

Thnks:)
Dec 26, 2020 at 3:30pm
why recursion?

A point is 'inside' the limits if all the values in the random point are between the upper and lower for the same position, right?
so you need [{2..6}, {5..12}, {8..16} ] (inclusive) in your example.

you can randomly generate these, using <random>, or you can divide it up evenly and iterate a 'grid' of points, or something like that. Being iteration, you *could* make it recursive if you wanted to do so, but recursion does not appreciably shorten the code or bring anything to the table except an extra layer of convolution.

so something like..
- make a little struct of <random> bits, one for each dimension, packed into a vector..
then, in pseudocode:
for(all the points you need)
for(each coordinate)
{
point[which][coordinate] = random_vec[coordinate].distribution(generator);
}

or with recursion (still pseudocodeish) the simple way (you can probably make this cute and small and hard to follow if you want to, and eliminate some parameters with statics, if you only call the function once)

void wtf(point, random_vec, which, int count, const int n)
{
if(count == n) return;
for(each coordinate)
{
point[which][coordinate] = random_vec[coordinate].distribution(generator);
}
wtf(point, random_vec, which+1, count+1, n);
}

you don't 'have' to make a generator for each dimension, but that save a lot of tracking the upper and lower bounds for each one and adjusting a random value to fit between them for each one etc. Its easier to let the generator do that work for you for each one.
** I treated n as if it were already expanded to 2^n, if you want to put the power computation inside the logic here you can.
Last edited on Dec 26, 2020 at 3:37pm
Dec 26, 2020 at 3:44pm
actually this is also good, I was not looking for between values , just the coordinates of limit points. So, limits have big difference (bettwen up and low) in my code and I do not want to generate random numbers between.them because the code will run lot of times and speed is important
Dec 26, 2020 at 3:44pm
I think he just wants to enumerate the corner points of the bounding (hyper-)cube. That's why there's 2^n of them. Also, recursion makes more sense with this interpretation.
Dec 26, 2020 at 3:55pm
This is pretty basic, but perhaps something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>
#include <iomanip>
#include <vector>
using namespace std;

// pre: a.size() == b.size()
void ff(const vector<int>& a, const vector<int>& b, vector<int>& c) {
    if (c.size() == a.size()) {
        for (int x: c) cout << setw(4) << x << ' ';
        cout << '\n';
    }
    else {
        c.push_back(a[c.size()]);  ff(a, b, c);  c.pop_back();
        c.push_back(b[c.size()]);  ff(a, b, c);  c.pop_back();
    }
}

void f(const vector<int>& a, const vector<int>& b) {
    vector<int> c;
    ff(a, b, c);
}

int main() {
    vector<int> a{1, 2, 3, 4}, b{10, 20, 30, 40};
    f(a, b);
}

Dec 26, 2020 at 4:22pm
If it's only ever going to be the ends of the interval then each dimension will be isomorphic to {0,1}, so you might as well just count upwards and map the relevant bits to the ends of their interval.
Dec 26, 2020 at 4:51pm
@dutch Oh nice, I could not say that I totally understood, how it works after first pop.back ??
Last edited on Dec 26, 2020 at 5:10pm
Dec 27, 2020 at 3:32am
How does it works??
Dec 27, 2020 at 6:16pm
Forget about the stack frame. It's uninteresting in this code since we pass the exact same references for the arguments every time.

Focus instead on the contents of c for each call to ff. Suppose main was

1
2
    vector<int> a{1, 2, 3}, b{10, 20, 30};
    f(a, b);

Then the calls to ff would be (with indentation level showing the recursion level):

ff(a, b, {})
    ff(a, b, {1})
        ff(a, b, {1,2})
            ff(a, b, {1,2,3})
                <print>
            ff(a, b, {1,2,30})
                <print>
        ff(a, b, {1,20})
            ff(a, b, {1,20,3})
                <print>
            ff(a, b, {1,20,30})
                <print>
    ff(a, b, {10})
        ff(a, b, {10,2})
            ff(a, b, {10,2,3})
                <print>
            ff(a, b, {10,2,30})
                <print>
        ff(a, b, {10,20})
            ff(a, b, {10,20,3})
                <print>
            ff(a, b, {10,20,30})
                <print>
Dec 28, 2020 at 7:22am
thanks
Dec 28, 2020 at 9:01am
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <iomanip>
#include <vector>
using namespace std;

int main()
{
   vector<int> first{ 1, 2, 3, 4 }, last{ 10, 20, 30, 40 };
   int N = first.size();
   for ( int i = 0; i < ( 1 << N ); i++ )
   {
      for ( int j = 0; j < N; j++ ) cout << setw( 4 ) << ( ( 1 << j ) & i ? last[j] : first[j] );
      cout << '\n';
   }
}
Dec 28, 2020 at 7:04pm
The OP question has two n-dimensional points and seems to assume that they are "opposing" vertices of cuboid* (in 3D), rectangle (in 2D), etc that have their edges are parallel to axes of the frame of reference. The task seems to be to list all vertices of said shape.


* https://en.wikipedia.org/wiki/Cuboid
Dec 28, 2020 at 9:57pm

It looks like half then half then half . . . either way.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62

#include<vector>
#include<iostream>
#include<cmath>
#include <iomanip>

using namespace std;

using MATRIX =	vector<vector<double>>;

MATRIX create(vector<double> a,vector<double> b)
{
MATRIX answer;
int p=pow(2,a.size()),tog;
answer.resize(p,vector<double>(a.size()));
int g=p;
for(int m=0;m<a.size();m++)
{
	tog=-1;
	g=(int)g/2;//keep halfing
	for(int n=0;n<p;n++)
	{
		if((n % g)==0) tog=-tog;
		if(tog==1)  answer[n][m]=a[m];
		else        answer[n][m]=b[m];
	}
}
return answer;
}


void print (MATRIX M)
{
	for (int n=0;n<M.size();n++)
	{
	for(int m=0;m<M[0].size();m++)
	{
		cout<<setw(4)<<M[n][m];
	}
	cout<<endl;
}
cout<<endl;
}

int main()
{
vector<double> a={1,2,3};
vector<double> b={10,20,30};
MATRIX result=create(a,b);
print(result);

a.clear();
b.clear();
result.clear();
a={1, 2, 3, 4};
b={10, 20, 30, 40};
 result=create(a,b);
print(result);
system("pause");

}
 

Last edited on Dec 28, 2020 at 10:15pm
Topic archived. No new replies allowed.