I am trying to sample random numbers from different distributions based on conditional logic and I am having trouble finding a nice way to go about it.
I have a struct representing some distribution:
struct Distribution {
std::string name;
double args[2];
}
The standard normal distribution would thus be represented by:
Distribution normal = {"normal", {0, 1}}
My goal is to; given an array of Distributions, create a few thousand samples from each distribution. This would not be a problem would it not have been for the fact that the different distributions in std::random are of different type. Due to the different type of the distributions I am having trouble with initializing the distribution before sampling from it.
What I would like to write is something that initializes the distribution outside the sampling loop, e.g.:
struct Distribution {
std::string name;
double args[2];
}
int main(void) {
Distribution distrs[2] = {
{"uniform", {0, 1}},
{"normal", {0, 1}}
};
int n_samples = 100;
double samples[200];
std::random_device rd;
std::mt19937 mt(rd());
for (int ix = 0; ix < 2; ix++) {
// Selects distribution to sample from depending on content of distrs[ix]
some_common_type_for_distr sampler; // This does obv. not compile
std::string distr_name = distrs[ix].name;
double args[2] = distrs[ix].args;
if (distr_name == "uniform") {
sampler = std::uniform_real_distribution<double>(args[0], args[1]);
} else if (distr_name == "normal") {
sampler = std::normal_distribution<double>(args[0], args[1]);
}
// Samples from the above initialized distribution
for (int jx = 0; jx < n_samples; ix++) { // Sampling loop
// Shifts by ix*n_samples to place samples from second
// distribution after samples from first distribution
samples[jx + ix*n_samples] = sampler(mt);
}
}
// Do something with samples.
}
However, as mentioned above, I run into problems when trying to somehow save the different initialized distributions to the same variable (in above case sampler). This results in me needing to re-initialize the distribution inside the sampling loop, e.g.:
struct Distribution {
std::string name;
double args[2];
}
int main(void) {
Distribution distrs[2] = {
{"uniform", {0, 1}},
{"normal", {0, 1}}
};
int n_samples = 100;
double samples[200];
std::random_device rd;
std::mt19937 mt(rd());
for (int ix = 0; ix < 2; ix++) {
// Initializes and samples in one go, resulting in re-initialization
// on every iteration
for (int jx = 0; jx < n_samples; ix++) { // Sampling loop
std::string distr_name = distrs[ix].name;
double args[2] = distrs[ix].args;
if (distr_name == "uniform") {
std::uniform_real_distribution<double> sampler(args[0], args[1]);
samples[jx + ix*n_samples] = sampler(mt);
} else if (distr_name == "normal") {
std::normal_distribution<double> sampler(args[0], args[1]);
samples[jx + ix*n_samples] = sampler(mt);
}
}
}
// Do something with samples.
}
So my question is basically; is there any way to write the program in such a way that the distributions are initialized outside the sampling loop, as in the first main function above?
you can erase the type, for example, use std::function
std::function<double()> GetSampler(const Distribution& d, std::mt19937& mt){
if (d.name == "uniform") {
std::uniform_real_distribution<double> sampler(d.args[0], d.args[1]);
return [sampler,&mt]()mutable{return sampler(mt);};
} else if (d.name == "normal") {
std::normal_distribution<double> sampler(d.args[0], d.args[1]);
return [sampler,&mt]()mutable{return sampler(mt);};
}
// handle other case
return []{return 4;};
}
use
std::function<double()> samplers[2] = {
GetSampler(distrs[0],mt),
GetSampler(distrs[1],mt)
};
// Sampling loop
for (int ix = 0; ix < 2; ix++)
for (int jx = 0; jx < n_samples; jx++) {
auto& sampler = samplers[ix];
samples[jx + ix*n_samples] = sampler();
}
https://godbolt.org/z/KGsaTTKnr
Related
I'm calling a function in C++ main function, for some reason it's taking long to call the function.
#include <iostream>
#include <opencv2/opencv.hpp>
#include "Eigen/Dense"
int inRo(float val){
return (int)round(val);}
std::pair<int,int> inRo(std::pair<float,float> pt){
return std::make_pair(inRo(pt.first),inRo(pt.second));}
// Gives the boundary points of Obstacles (in this case, the boundary points of white region in img)
std::vector<std::pair<int,int>> getBoundPts(cv::Mat img){
std::vector<std::pair<int,int>> bound_pts;
cv::Mat img_dilate;
cv::dilate(img.clone(),img_dilate,cv::Mat(),cv::Point(-1,-1),1,1,1);
cv::Mat img_bound = img_dilate - img;
std::vector<cv::Point> bound_pts_cv;
cv::findNonZero(img_bound,bound_pts_cv);
for(int i = 0;i < bound_pts_cv.size();i++){
std::pair<int,int> pt = std::make_pair(bound_pts_cv[i].x,bound_pts_cv[i].y);
bound_pts.push_back(pt);
}
return bound_pts;
}
void getNeighPts(std::pair<float,float> pt,Eigen::MatrixXf potentials_map,std::vector<std::pair<int,int>>& list_pts_bound,std::vector<float>& list_vals_bound,std::vector<std::pair<int,int>>& list_pts_empty){
//this function tries divides the neighbourhood points of a point 'pt'
//into two categories, empty (or list_pts_empty, are the ones with zero
//potential value, which can be obtained from map_potential) and non-zero ones
//(list_pts_bound, which are the ones with a non-zero potential value which
//can also be obtained from map_potential and list_val_bound is the corresponding
//potential values of the list_pts_bound).
//I'M SURE THE FUNCTION CAN BE WRITTEN IN SIMPLER WAYS BUT THE ONE I
//NEED IS MORE GENERIC AND COULD ABLE TO MODIFIED FOR VARIOUS TYPES OF
//NEIGHBOURHOODS AROUND A POINT.
clock_t ct1,ct2;
ct1 = clock();
list_pts_empty.clear();
list_vals_bound.clear();
list_pts_bound.clear();
std::pair<int,int> ind;
float pot_val_ind;
std::vector<std::pair<int,int>> neighs_perp;
neighs_perp.push_back(std::make_pair(0,1));
neighs_perp.push_back(std::make_pair(0,-1));
neighs_perp.push_back(std::make_pair(1,0));
neighs_perp.push_back(std::make_pair(-1,0));
int i,j;
for(int k = 0;k < neighs_perp.size();k++)
{
i = neighs_perp[k].first;
j = neighs_perp[k].second;
ind = std::make_pair(pt.first+i,pt.second+j);
if(ind.first >= 0 && ind.second >= 0 && ind.first < potentials_map.cols() && ind.second < potentials_map.rows())
{
pot_val_ind = potentials_map(ind.second,ind.first);
if(pot_val_ind > 0)
{
list_pts_bound.push_back(ind);
list_vals_bound.push_back(potentials_map(ind.second,ind.first) + 1);
}
else if(inRo(pot_val_ind) == 0)
{
list_pts_empty.push_back(ind);
}
}
}
ct2 = clock();
std::cout<<"Inside : "<<float(ct2-ct0)/CLOCKS_PER_SEC<<std::endl;
}
int main(){
clock_t t1,t2;
cv::Mat img = cv::Mat::zeros(500,500,CV_8UC1);
cv::Mat img_win = img(cv::Rect(125,125,250,250));
img_win.setTo(255);
std::vector<std::pair<int,int>> brush_que = getBoundPts(img);
Eigen::MatrixXf mat_potential(500,500);
Eigen::MatrixXf mat_block = Eigen::MatrixXf::Ones(250,250);
mat_potential.block(125,125,250,250) = -255*mat_block;
for(int i = 0;i < brush_que.size();i++){
std::pair<float,float> pt = brush_que[i];
mat_potential(pt.second,pt.first) = 1;
}
std::vector<std::pair<int,int>> neighs_empty;
std::vector<std::pair<int,int>> neighs_pts;
std::vector<float> neighs_val;
std::pair<int,int> pt_ex = brush_que[0];
t1 = clock();
getNeighPts(pt_ex,mat_potential,neighs_pts,neighs_val,neighs_empty);
t2 = clock();
std::cout<<"Outside : "<<float(t2-t1)/CLOCKS_PER_SEC<<std::endl;
}
the t2-t1 >>> ct2-ct1.
This is the trimmed version of my main code, and here I'm getting,
Inside : 1e-05
Outside : 0.002574
and in the main code, the difference is going way higher depending on the type of 'img'. Any suggesions on the problem would be appreciated.
Thanks in advance :)
For a project that I am working on I need to generate a vector of random numbers within a function. The problem is that I end up generating the same vector of numbers each time. I have this example that reproduces my problem:
#include <iostream>
#include <random>
std::vector<double> generate(std::default_random_engine generator, double mean, double sigma, int n)
{
std::vector<double> generated(n,0);
std::normal_distribution<double> distribution(mean,sigma);
for (int i = 0;i<n;i++)
generated[i] = distribution(generator);
return generated;
}
std::vector<double> generate(double mean, double sigma, int n)
{
std::vector<double> generated(n,0);
std::default_random_engine generator;
std::normal_distribution<double> distribution(mean,sigma);
for (int i = 0;i<n;i++)
generated[i] = distribution(generator);
return generated;
}
int main(int argc, char** argv)
{
// Read inputs
int nrolls = 20; // number of experiments
int ntimes = 50;
double mean = 100;
double sigma = 4;
bool useFunction(false);
if (argc>1)
useFunction=true;
// crates series
std::vector< std::vector<double> > results(ntimes,std::vector<double>());
std::default_random_engine generator;
for (int i = 0;i<ntimes/4;i++){
std::vector<double> generated(nrolls,0);
std::normal_distribution<double> distribution(mean,sigma);
for (int i = 0;i<nrolls;i++)
generated[i] = distribution(generator);
results[i] = generated;
}
for (int i = ntimes/4;i<ntimes/2;i++)
results[i] = generate(generator,mean,sigma,nrolls);
for (int i = ntimes/2;i<3*ntimes/4;i++){
std::vector<double> generated(nrolls,0);
std::normal_distribution<double> distribution(mean,sigma);
for (int i = 0;i<nrolls;i++)
generated[i] = distribution(generator);
results[i] = generated;
}
for (int i = 3*ntimes/4;i<ntimes;i++)
results[i] = generate(mean,sigma,nrolls);
//
// Display all random numbers
for (int i = 0;i<ntimes;i++){
std::cout<<i;
for (int j = 0;j<nrolls;j++)
std::cout<<" "<<results[i][j];
std::cout<<std::endl;
}
// Check number of equal results
int n_equal(0);
int n_total(0);
for (int i=0;i<ntimes;i++){
for (int k = 0;k<nrolls;k++){
for (int j=i+1;j<ntimes;j++){
n_total++;
if (results[i][k] == results[j][k])
n_equal++;
}
}
}
std::cout<<n_equal<<"/"<<n_total<<std::endl;
// Exit
return 0;
}
I have tried to solve it by passing the generator to the function where the array of random numbers is generated but apparently, it does not work either. Can somebody give me a hint on how should I do it to get different arrays each time i call the generate function?
Thank you very much.
You have two problems here. First
std::vector<double> generate(std::default_random_engine generator, double mean, double sigma, int n)
Takes the PRNG by value, which means it makes a copy. That means every time you call the function your going to be starting from the same sequence since you never modify the generator from the call site.
The second issue is with
std::vector<double> generate(double mean, double sigma, int n)
You recreate the same generator every time you call the function. This is not going to work as it is going to create the same sequence each time.
Typically you have two options. You can pass the PRNG to the function by reference, or you declare a static PRNG in the function so it persists between function calls.
After playing a bit with them, I found it best to use global variables for the new C++ random generators. And you should have one per random number suite, so you're (statistically almost :) 100% sure to get the distribution specified.
Pseudo-random generators are static beasts by nature, since they keep numbers generated in the last computation to generate the next.
I'm creating a wxWidget application with C++ where at the start of the program I want the application window to contain pixels with random colors like this:
In the above application there are 3600 pixels (60 x 60) and I have given each pixel a random RGB color by using uniform_int_distribution
The colours for the pixels in the image above are generated at the moment using the following function in my code:
void random_colors(int ctable[][3], int n)
{
// construct a trivial random generator engine from a time-based seed:
unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
std::default_random_engine generator (seed);
std::uniform_int_distribution<int> distribution(0,255);
for(int i=0; i<n; i++)
{
for(int j=0; j<3; j++)
{
ctable[i][j] = distribution(generator);
}
}
}
I do this by giving this function a table with dimensions 3600 x 3 and this function will fill in the values for the colours.
This way however is not what I want. What I want is to create a class called somNode where each somNode-object represents a pixel in the picture (with RGB values as a member array attribute). In this somNode-class I have a member function using uniform_int_distribution to give when constructed each somNode its own random RGB colour. This is the function which creates the random colour for each somNode:
void rand_node_colour(int nodeWeights[])
{
// construct a trivial random generator engine from a time-based seed:
unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
std::default_random_engine generator (seed);
std::uniform_int_distribution<int> distribution(0,255);
for(int i=0; i<3; i++)
{
nodeWeights[i] = distribution(generator);
}
}
the nodeWeights member array represents the RGB-value of the somNode. Now when I create this "som-grid" what I have in the image above (the 3600 pixels corresponding to 3600 somNodes) I use the following code (take a look at the som-constructor):
#include "somNode.h"
#include <vector>
class som
{
public:
double learning_rate;
std::vector<somNode> somGrid;
public:
som(double lrate);
void epoch();
void trainOnce();
};
/*
* Initialize the som grid
*/
som::som(double lrate)
{
learning_rate = lrate;
// Create the som grid
for(int i=0; i<60; i++)
{
for(int j=0; j<60; j++)
{
int xL = j*10;
int xR = (j+1)*10;
int yT = i*10;
int yB = (i+1)*10;
somGrid.push_back(somNode(xL, xR, yB, yT));
}
}
}
// Train som by one epoch
void som::epoch()
{
}
// Train som by one color
void som::trainOnce()
{
}
So I have a vector<somNode> somGrid where I push all these 3600 somNodes when I construct them. When each node is constructed the somNode member function rand_node_colour is called which creates the RGB-value.
When however I implement this code instead of the one I used at first I get this result:
You can see that there is a clear pattern so something is going wrong here. My question is: What is happening in the random number generation when somNodes are created? Why it doesn't produce the same result as the code I used above?
P.S. here is the somNode.cpp:
#include <random>
#include <iostream>
#include <chrono>
#include<cmath>
void rand_node_colour(int nodeWeights[]);
/*
* This class represent a node in the som-grid
*/
class somNode
{
public:
// Weight of the node representing the color
int nodeWeights[3];
// Position in the grid
double X, Y;
// corner coorinates for drawing the node on the grid
int x_Left, x_Right, y_Bottom, y_Top;
public:
// Constructor
somNode(int xL, int xR, int yB, int yT);
void editWeights(int r, int g, int b);
double getDistance(int r, int g, int b);
};
somNode::somNode(int xL, int xR, int yB, int yT)
{
// Set the corner points
x_Left = xL;
x_Right = xR;
y_Bottom = yB;
y_Top = yT;
// Initialize random weights for node
rand_node_colour(nodeWeights);
// Calculate the node's position (center coordinate)
X = x_Left + (double)((x_Right - x_Left)/double(2));
Y = y_Bottom + (double)((y_Top - y_Bottom)/double(2));
}
void somNode::editWeights(int r, int g, int b)
{
nodeWeights[0] = r;
nodeWeights[1] = g;
nodeWeights[2] = b;
}
double somNode::getDistance(int r, int g, int b)
{
return sqrt(pow(nodeWeights[0]-r, 2) + pow(nodeWeights[1]-g, 2) + pow(nodeWeights[2]-b, 2));
}
void rand_node_colour(int nodeWeights[])
{
// construct a trivial random generator engine from a time-based seed:
unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
std::default_random_engine generator (seed);
std::uniform_int_distribution<int> distribution(0,255);
for(int i=0; i<3; i++)
{
nodeWeights[i] = distribution(generator);
}
}
The issue here is that you constantly recreate and seed the random number generator in rand_node_colour. You call it in a tight loop so you can get the same time which means the seed will be the same and that means the random numbers generated will be the same.
What you need to do is seed the generator once and then keep using its random output. An easy way to fix you code would be to make it static in the function sos it is only initialized once and each subsequent call to the function will continue on instead of start the generator all over. If we do that the code becomes
void rand_node_colour(int nodeWeights[])
{
// construct a trivial random generator engine from a time-based seed:
static std::default_random_engine generator (std::chrono::system_clock::now().time_since_epoch().count());
std::uniform_int_distribution<int> distribution(0,255);
for(int i=0; i<3; i++)
{
nodeWeights[i] = distribution(generator);
}
}
I'm attempting to build a genetic algorithm that can take a certain amount of variables (say 4), and use these in a way so that you could have 2a + 3b + c*c + d = 16. I realise there are more efficient ways to calculate this, but I want to try and build a genetic algorithm to expand later.
I'm starting by trying to create "organisms" that can compete later. What I've done is this:
#include "stdafx.h"
#include <iostream>
#include <vector>
#include <random>
// Set population size
const int population_size = 10;
const int number_of_variables = 4;
int main()
{
// Generate random number
std::random_device rd;
std::mt19937 rng(rd()); // random-number engine (Mersenne-Twister in this case)
std::uniform_int_distribution<int> uni(-10, 10);
// Set gene values.
std::vector<int>chromosome;
std::vector<int>variables;
for (int i = 0; i < number_of_variables; ++i)
{
double rand_num = uni(rng);
variables.push_back (rand_num);
std::cout << variables[i] << "\n";
}
return 0;
}
What happens is it will fill up the number_of_variables vector, and output these just because that makes it clear for me that it's actually doing what I intend for it to do. What I want it to do however is to fill up each "chromosome" with one variables vector, so that for example chromosome 0 would have the values {1, 5, -5, 9} etc.
The following code obviously isn't working, but this is what I'd like it to do:
for (int j = 0; j < population_size; ++j)
{
for (int i = 0; i < number_of_variables; ++i)
{
double rand_num = uni(rng);
variables.push_back(rand_num);
}
chromosome.push_back(variables[j]);
std::cout << chromosome[j] << "\n";
}
Meaning it'd fill up the variables randomly, then chromosome1 would take those 4 values that "variables" took, and repeat. What actually happens is that (I think) it only takes the first value from "variables" and copies that into "chromosome" rather than all 4.
If anyone could help it'd be very much appreciated, I realise this might be simply a rookie mistake that is laughably simply in the eyes of someone more experienced with vectors (which would probably be 99% of the people on this website, hah).
Anyway, thanks :)
#include <iostream>
#include <vector>
#include <random>
// Set population size
const int population_size = 10;
const int number_of_variables = 4;
int main()
{
// Generate random number
std::random_device rd;
std::mt19937 rng(rd()); // random-number engine (Mersenne-Twister in this case)
std::uniform_int_distribution<int> uni(-10, 10);
// Set gene values.
std::vector< std::vector<int>>chromosome;
for( int kp = 0; kp < population_size; kp++ )
{
std::vector<int>variables;
for (int i = 0; i < number_of_variables; ++i)
{
double rand_num = uni(rng);
variables.push_back (rand_num);
}
chromosome.push_back( variables );
}
// display entire population
for( auto c : chromosome )
{
for( auto v : c )
{
std::cout << v << " ";
}
std::cout << "\n";
}
// display 4th member of population
for( auto v : chromosone[ 3 ] )
{
std::cout << v << " ";
}
std::cout << "\n";
return 0;
}
http://ideone.com/2jastJ
You can place a vector inside a vector with the syntax:
std::vector<std::vector<int>>
but you will need to make the outer vector large enough for num_variables.
#include <vector>
#include <cstdlib>
using Individual = std::vector<int>;
using Population = std::vector<Individual>;
// short for std::vector<std::vector<int>>;
const size_t number_of_variables = 8;
int main() {
Population population(10);
for (auto& individual : population) {
individual.resize(number_of_variables);
for (size_t j = 0; j < number_of_variables; ++j) {
individual[j] = j; // replace with random number
}
}
}
Live demo: http://ideone.com/pfufGt
I am looking at the k-means++ initialization algorithm. The following two steps of the algorithm give rise to non-uniform probabilities:
For each data point x, compute D(x), the distance between x and the
nearest center that has already been chosen.
Choose one new data point at random as a new center, using a weighted
probability distribution where a point x is chosen with probability
proportional to D(x)^2.
How can I select with this stated weighted probability distribution in C++?
Discrete distributions is a lot easier to do in C++11 with the random header and using std::discrete_distribution. This is example:
#include <iostream>
#include <map>
#include <random>
int main()
{
std::random_device rd;
std::mt19937 gen(rd());
std::discrete_distribution<> d({20,30,40,10});
std::map<int, int> m;
for(int n=0; n<10000; ++n) {
++m[d(gen)];
}
for(auto p : m) {
std::cout << p.first << " generated " << p.second << " times\n";
}
}
and this is a sample of the output:
0 generated 2003 times
1 generated 3014 times
2 generated 4021 times
3 generated 962 times
With a finite set of individual data points X, this calls for a discrete probability distribution.
The easiest way to do this is to enumerate the points X in order, and calculate an array representing their cumulative probability distribution function: (pseudocode follows)
/*
* xset is an array of points X,
* cdf is a preallocated array of the same size
*/
function prepare_cdf(X[] xset, float[] cdf)
{
float S = 0;
int N = sizeof(xset);
for i = 0:N-1
{
float weight = /* calculate D(xset[i])^2 here */
// create cumulative sums and write to the element in cdf array
S += weight;
cdf[i] = S;
}
// now normalize so the CDF runs from 0 to 1
for i = 0:N-1
{
cdf[i] /= S;
}
}
function select_point(X[] xset, float[] cdf, Randomizer r)
{
// generate a random floating point number from a
// uniform distribution from 0 to 1
float p = r.nextFloatUniformPDF();
int i = binarySearch(cdf, p);
// find the lowest index i such that p < cdf[i]
return xset[i];
}
You call prepare_cdf once, and then call select_point as many times as you need to generate random points.
I'd take the following approach:
iterate over the data-points, storing their D-squared's in a double distance_squareds[] or std::vector<double> distance_squareds or whatnot, and storing the sum of their D-squared's in a double sum_distance_squareds.
use the drand48 function to choose a random number in [0.0, 1.0), and multiply it by sum_distance_squareds; store the result in random_number.
iterate over distance_squareds, adding together the values (again), and as soon as the running total meets or exceeds random_number, return the data-point corresponding to the D-squared that you'd just added.
due to round-off error, it's remotely possible that you'll finish the loop without having returned; if so, just return the first data-point, or the last one, or whatever. (But don't worry, this should be a very rare edge case.)
Here you have something that may help you,
using (numbers..) array with given probability distribution (prob..) it will generate for you (numbers) with those probabilities (here it will count them).
#include <iostream>
#include <cmath>
#include <time.h>
#include <stdlib.h>
#include <map>
#include <vector>
using namespace std;
#define ARRAY_SIZE(array) (sizeof(array)/sizeof(array[0]))
int checkDistribution(double random, const map<double, vector<int> > &distribution_map)
{
int index = 0;
map<double, vector<int> >::const_iterator it = distribution_map.begin();
for (; it!=distribution_map.end(); ++it)
{
if (random < (*it).first)
{
int randomInternal = 0;
if ((*it).second.size() > 1)
randomInternal = rand() % ((*it).second.size());
index = (*it).second.at(randomInternal);
break;
}
}
return index;
}
void nextNum(int* results, const map<double, vector<int> > &distribution_map)
{
double random = (double) rand()/RAND_MAX;
int index = checkDistribution(random,distribution_map);
results[index]+=1;
}
int main() {
srand (time(NULL));
int results [] = {0,0,0,0,0};
int numbers [] = {-1,0,1,2,3};
double prob [] = {0.01, 0.3, 0.58, 0.1, 0.01};
int size = ARRAY_SIZE(numbers);
// Building Distribution
map<double, vector<int> > distribution_map;
map<double, vector<int> >::iterator it;
for (int i = 0; i < size; i++)
{
it = distribution_map.find(prob[i]);
if (it!=distribution_map.end())
it->second.push_back(i);
else
{
vector<int> vec;
vec.push_back(i);
distribution_map[prob[i]] = vec;
}
}
// PDF to CDF transform
map<double, vector<int> > cumulative_distribution_map;
map<double, vector<int> >::iterator iter_cumulative;
double cumulative_distribution = 0.0;
for (it=distribution_map.begin();it!=distribution_map.end();++it)
{
cumulative_distribution += ((*it).second.size() * (*it).first);
cumulative_distribution_map[cumulative_distribution] = (*it).second;
}
for (int i = 0; i<100; i++)
{
nextNum(results, cumulative_distribution_map);
}
for (int j = 0; j<size; j++)
cout<<" "<<results[j]<<" ";
return 0;
}