#include <math.h>
#include <iostream>
using namespace std;
void graph(){
int x=140;
int y=20;
double convert = 3.141592/180;
cout<<"amplitude, frequency\n";
double amp,freq;
cin>>amp>>freq;
for(int i=0; i<y; i++){
for(int j=0; j<x; j++){
if(i==nearbyint(3*amp*cos(5*freq*j*convert))+10){
cout<<"*";
}
else if(i==y/2){
cout<<"-";
}
else if(j==x/2){
cout<<"|";
}
else{
cout<<" ";
}
}
cout<<endl;
}
}
int main(){
graph();
return 0;
}
when the code is run, the graph will do fine until you start inputting numbers above 4, where then the line will start having large spaces in between the *'s in the y axis.
What is the simplest way I can fill in the gaps between the *s
The equation is multiplied with 3 and 5 for formatting purposes.
I can think of some ways to do this.
The easiest way is just to check against the interval (j-0.5,j+0.5) by replacing the test
if(i==nearbyint(3*amp*cos(5*freq*j*convert))+10){
cout<<"*";
}
with
void graph( double amp, double freq ){
int x=140;
int y=20;
double convert = 3.141592/180;
for(int i=0; i<y; i++){
for(int j=0; j<x; j++){
double jx = j;
double v1 = 3*amp*cos(5*freq*(jx-0.5)*convert)+10;
double v2 = 3*amp*cos(5*freq*(jx+0.5)*convert)+10;
if( ((i>=v1)&&(i<=v2)) || ((i<=v1)&&(i>=v2))){
cout<<"*";
}
else if(i==y/2){
cout<<"-";
}
else if(j==x/2){
cout<<"|";
}
else{
cout<<" ";
}
}
cout<<endl;
}
}
Godbolt Link: https://godbolt.org/z/G47WjqafP
This results in
Program stdout
|
|
* * * * * * * * * * | * * * * * * * * * *
* * * * * * * * * * | * * * * * * * * * *
* * * * * * * * * * | * * * * * * * * * *
* * * * * * * * * * | * * * * * * * * * *
* * * * * * * * * * | * * * * * * * * * *
* * * * * * * * * * | * * * * * * * * *
* * * * * * * * * * | * * * * * * * * *
* * * * * * * * * * | * * * * * * * * *
----*------*------*------*------*-------*------*------*------*------*-------*------*------*------*------*-------*------*------*------*------
* * * * * * * * * *| * * * * * * * * *
* * * * * * * * * *| * * * * * * * * *
* * * * * * * * * *| * * * * * * * * *
* * * * * * * * * *| * * * * * * * * *
* * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * *
* * * * * * * * * |* * * * * * * * * *
|
But the coolest I could find for a 10 minute Blitz code project is an approach where you can use something like the Bresenham line algorithm. Bresenham will guarantee that the space between two adjacent point while drawing a line is maximum one pixel, which is exactly what you are asking.
I could apply Bresenham straight to your algorithm but why not extend this to make it more generic? I'm already wasted so here we go...
First you need to define a viewport for your graph that will map between fictitious coordinates to screen coordinates.
struct Extents {
double x[2];
double y[2];
};
Second you will need a class to hold a virtual screen with a character buffer inside and some way to clear it up.
This map will contain characters that will be printed out later.
template< int WIDTH, int HEIGHT >
struct Graph {
Extents ext;
char map[WIDTH][HEIGHT];
void clear() {
memset( map, ' ', WIDTH*HEIGHT );
}
void print() {
for ( int i=0; i<HEIGHT; ++i ) {
for ( int j=0; j<WIDTH; ++j ) {
std::cout << map[j][HEIGHT-i-1];
}
std::cout << std::endl;
}
}
};
Then you need some methods to convert from viewport to screen and vice versa
double from_screen_x( int j ) {
return ext.x[0] + (j*(ext.x[1]-ext.x[0]))/WIDTH;
}
int from_viewport_x( double x ) {
return (x-ext.x[0])/(ext.x[1]-ext.x[0])*WIDTH;
}
int from_viewport_y( double y ) {
return HEIGHT*((y-ext.y[0])/(ext.y[1]-ext.y[0]));
}
Then once we have a way to convert from (x,y) to (i,j) screen coordinates, we can easily 'plot' a single point with a given character.
void point( int x, int y, char ch ) {
if ( (x>=0) && (x<WIDTH) ) {
if ( (y>=0) && (y<HEIGHT) ) {
map[x][y] = ch;
}
}
}
Now the workhorse of the entire class - the Bresenham algorithm which you can find on Wikipedia
void line( int x0, int y0, int x1, int y1, char ch ) {
int dx = abs(x1 - x0);
int sx = x0 < x1 ? 1 : -1;
int dy = - int( abs(y1 - y0) );
int sy = y0 < y1 ? 1 : -1;
int error = dx + dy;
while( true ) {
point(x0, y0, ch);
if ( (x0 == x1) && (y0 == y1) ) break;
int e2 = 2 * error;
if ( e2 >= dy ) {
if (x0 == x1) break;
error = error + dy;
x0 = x0 + sx;
}
if (e2 <= dx) {
if (y0 == y1) break;
error = error + dx;
y0 = y0 + sy;
}
}
}
Then we need the high level functions: one to draw the axis and another to plot the chart.
The axis is easy - just find the screen coordinates of the origin (0,0) and plot it on our 'map'.
void axis() {
int i = from_viewport_y(0);
for ( int j=0; j<WIDTH; ++j ) {
point(j,i,'-');
}
int j = from_viewport_x(0);
for ( int i=0; i<HEIGHT; ++i ) {
point(j,i,'|');
}
}
For the chart algorithm I decided to go fancy and using a templated function that will allow us to externalize the actual computation.
This algorithm will sweep the x axis in screen space, map into the viewport, compute the point in virtual coordinates and bring them back to the actual (i,j) screen coordinates. Once we have obtained the first point we can from the 2nd point call the line algorithm between the old and the new point and keep iterating until the end.
template< typename Fn >
void chart( char ch, Fn&& fn ) {
int lasti = 0;
for ( int j=0; j<WIDTH; ++j ) {
double x = from_screen_x( j );
int i = from_viewport_y( fn(x) );
if ( j>0 ) {
line( j-1,lasti, j, i, ch );
}
lasti = i;
}
}
Now we are left with just the business logic. Let's create a cosine functor that will give us a cosine function with a given amplitude and frequency.
struct CosFn {
double amp;
double freq;
double operator()( double x ) {
return amp*cos( freq*x );
}
};
Now we just need to put everything together and plot it all
int main() {
Extents ext{{-1,1},{-1,1}};
Graph<120,20> g{ext};
g.clear();
g.axis();
g.chart( '.', CosFn{1,2} );
g.chart( '^', CosFn{0.75,4} );
g.chart( '*', CosFn{0.5,8} );
g.print();
}
This will produce:
Program stdout
.............|.............
...... | ......
.... ^^^^^^^^^^^ ....
.... ^^^^ | ^^^^ ....
.... ^^^ * ^^^ ....
********* ... ^^^ ****|**** ^^^ ... *********
*** ** ... ^^ ** | ** ^^ ... ** ***
* .**. ^^ ** | ** ^^ .**. *
** ... ** ^^ ** | ** ^^ ** ... **
--*----------...--------*------------^^----------*----------|----------*----------^^------------*--------...----------*-
** ... ** ^^ ** | ** ^^ ** ... *
... * ^^ * | * ^^ * ...
... ** ^^ ** | ** ^^ ** ...
... ^** ** | ** **^ ...
^ ^^^ ********** | ********** ^^^
^^^ ^^^ | ^^^ ^^^
^^^^ ^^^^ | ^^^^ ^^^^
^^^^^^^^^^^ | ^^^^^^^^^^^
|
|
Godbolt link: https://godbolt.org/z/P3Wx1vE7s
the problem I am solving:
I would like to implement a library and use it in pyhon.
the issue I am facing:
After compiling the code and trying to import the module in python, I get an ImportError, mentioning undefined symbol. The exact text is saying the following:
``
Python 3.10.6 (main, Nov 2 2022, 18:53:38) [GCC 11.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
import RPA
Traceback (most recent call last):
File "", line 1, in
ImportError: /home/blub/RecursivePartitioningAlgorithm/RPA.cpython-310-x86_64-linux-gnu.so: undefined symbol: Z18standardPositionB5PiS_S_S
``
**the command line I use to compile my module:
**
c++ -O3 -Wall -shared -std=c++11 -fPIC $(python3.10 -m pybind11 --includes) RecPartAlgorithm.cpp -o RPA$(python3.10-config --extension-suffix)
**below is the code that I am trying to compile.
**
`
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <map>
#include <sys/resource.h>
#include <sys/time.h>
#include <sys/times.h>
#include <iostream>
#include <pybind11/pybind11.h>
#include "bd.h"
#include "sets.h"
#include "draw.h"
#include "graphics.h"
#include "util.h"
#define STRINGIFY(x) #x
#define MACRO_STRINGIFY(x) STRINGIFY(x)
namespace py = pybind11;
/******************************************************************
******************************************************************/
int solve(int L, int *q);
/* Lower and upper bounds of each rectangular subproblem. */
int **lowerBound, **upperBound;
/* Arrays of indices for indexing the matrices that store information
* about rectangular subproblems (L,W), where (L,W) belongs to X' x Y'
* and X' and Y' are the raster points sets associated to (L,l,w) and
* (W,l,w), respectively. */
int *indexX, *indexY;
/* Set of integer conic combinations of l and w:
* X = {x | x = rl + sw, with r,w in Z and r,w >= 0} */
Set normalSetX;
/* Array that stores the normalized values of each integer between 0 and
* L (dimension of the problem):
* normalize[x] = max {r in X' | r <= x} */
int *normalize;
/* Store the solutions of the subproblems. */
std::map<int, int> *solutionMap;
int *solution;
/* Store the division points in the rectangular and in the L-shaped
* pieces associated to the solutions found. */
std::map<int, int> *divisionPointMap;
int *divisionPoint;
/* Dimensions of the boxes to be packed. */
int l, w;
/* Type of the structure used to store the solutions. */
int memory_type;
/* Store the points that determine the divisions of the rectangles. */
CutPoint **cutPoints;
int *indexRasterX, *indexRasterY;
int numRasterX, numRasterY;
/******************************************************************
******************************************************************/
inline int roundToNearest(double a) {
return (int) floor(a + 0.5);
}
/******************************************************************
******************************************************************/
/**
* Calculate the upper bound of a given rectangle R(x,y) (degenerated L).
*
* Parameters:
* x - Length of the rectangle.
*
* y - Width of the rectangle.
*
* Return:
* The computed upper bound.
*/
inline int R_UpperBound(int x, int y) {
/* A(R) / lw */
x = normalize[x];
y = normalize[y];
return upperBound[indexX[x]][indexY[y]];
}
/******************************************************************
******************************************************************/
/**
* Calculate the upper bound of a given L.
*
* Parameters:
* q - The L-piece.
*
* Return:
* The computed upper bound for this L-piece.
*/
inline int L_UpperBound(int *q) {
/* Area(L) / lw */
return (q[0] * q[1] - (q[0] - q[2]) * (q[1] - q[3])) / (l * w);
}
/******************************************************************
******************************************************************/
/**
* Calculate the lower bound of a given rectangle R(x,y) (degenerated L).
*
* Parameters:
* x - Length of the rectangle.
*
* y - Width of the rectangle.
*
* Return:
* The computed lower bound.
*/
inline int R_LowerBound(int x, int y) {
x = normalize[x];
y = normalize[y];
return lowerBound[indexX[x]][indexY[y]];
}
/******************************************************************
******************************************************************/
/**
* Calculate the lower bound of a given L. It divides the L in two
* rectangles and calculates their lower bounds to compose the lower
* bound of the L-piece.
*
* +-----+ +-----+ +-----+
* | | | | | |
* | | | | | |
* | +----+ --> +-----+----+ or | +----+
* | | | | | | |
* | | | | | | |
* +----------+ +----------+ +-----+----+
* (a) (b)
*
* Parameters:
* q - The L-piece.
*
* Return:
* The computed lower bound.
*/
inline int L_LowerBound(int *q, bool *horizontalCut) {
int a = lowerBound[indexX[normalize[q[2] ]]]
[indexY[normalize[q[1] - q[3]]]]
+
lowerBound[indexX[normalize[q[0]]]]
[indexY[normalize[q[3]]]];
int b = lowerBound[indexX[normalize[q[2]]]]
[indexY[normalize[q[1]]]]
+
lowerBound[indexX[normalize[q[0] - q[2]]]]
[indexY[normalize[q[3] ]]];
if(a > b) {
*horizontalCut = true;
return a;
}
else {
*horizontalCut = false;
return b;
}
}
/******************************************************************
******************************************************************/
/**
* Divide an L-piece in two new L-pieces, according to the specified
* subdivision, and normalize the two ones.
*
* Parameters:
* i - Point that determines the division int the L-piece.
*
* q - The L-piece to be divided.
*
* q1 - It will store a new L-piece.
*
* q2 - It will store the other new L-piece.
*
* standardPosition - Pointer to the function that will divide the L-piece.
*/
void divide(int *i, int *q, int *q1, int *q2,
void (*standardPosition)(int*, int*, int*, int*)) {
/* Divide the L-piece in two new ones. */
(*standardPosition)(i, q, q1, q2);
/* Normalize the new L-pieces. */
normalizePiece(q1);
normalizePiece(q2);
}
/******************************************************************
******************************************************************/
/**
* Return the solution of the L-piece related to the index L.
*
* Parameters:
* L - Index of the L-piece.
*
* key - Key for this L-piece.
*
* Return:
* The current solution of the specified L-piece.
*/
inline int getSolution(int L, int key) {
if(memory_type == MEM_TYPE_4) {
return solution[L] & nRet;
}
else {
return solutionMap[L][key] & nRet;
}
}
/******************************************************************
******************************************************************/
/**
* Return the solution of the L-piece related to the index L.
*
* Parameters:
* L - Index of the L-piece.
*
* q - The L-piece.
*
* Returns:
* The current solution of the specified L-piece.
*/
inline int getSolution(int L, int *q) {
if(memory_type == MEM_TYPE_4) {
return solution[L] & nRet;
}
else {
int key = getKey(q[0], q[1], q[2], q[3], memory_type);
return solutionMap[L][key] & nRet;
}
}
/******************************************************************
******************************************************************/
/**
* Return the solution of the L-piece related to the index L.
*
* Parameters:
* L - Index of the L-piece.
*
* q - The L-piece.
*
* key - Key for this L-piece.
*
* Return:
* The current solution of the specified L-piece.
*/
inline int getSolution(int L, int *q, int *key) {
if(memory_type == MEM_TYPE_4) {
return solution[L];
}
else {
*key = getKey(q[0], q[1], q[2], q[3], memory_type);
return solutionMap[L][*key];
}
}
/******************************************************************
******************************************************************/
/**
* Store the solution of an L-piece.
*
* Parameters:
* L - Index of the L-piece.
*
* key - Key for this L-piece.
*
* LSolution - Solution to be stored.
*
*/
inline void storeSolution(int L, int key, int LSolution) {
if(memory_type == MEM_TYPE_4) {
solution[L] = LSolution;
}
else {
solutionMap[L][key] = LSolution;
}
}
/******************************************************************
******************************************************************/
/**
* Store the point where the division in the L-piece was made.
*
* Parameters:
* L - Index of the L-piece.
*
* key - Key for this L-piece.
*
* point - Representation of the point where the division was made.
*
*/
inline void storeDivisionPoint(int L, int key, int point) {
if(memory_type == MEM_TYPE_4) {
divisionPoint[L] = point;
}
else {
divisionPointMap[L][key] = point;
}
}
/******************************************************************
******************************************************************/
/**
* Verify whether the solution is optimal.
*
* Parameters:
* L - Index of the L-piece.
*
* key - Key for this L-piece.
*
* upperBound - Upper bound for the L-piece.
*
* Return:
* Return whether the current solution for the L-piece is optimal.
*/
inline bool optimal(int L, int key, int upperBound) {
int Lsolution = getSolution(L, key);
if((Lsolution & nRet) == upperBound) {
return true;
}
return false;
}
/******************************************************************
******************************************************************/
/**
* Divide the L-piece in every possible way, according to the specified
* subdivision B.
*
* Parameters:
* L - Index of the L-piece.
*
* q - The L-piece.
*
* constraints - Constraints that determine the interval of x' and y'.
*
* B - The subdivision.
*
* standardPosition - Pointer to the function that divides the L-piece
* according to the subdivision B.
*
* X - Set of raster points.
*
* startX - Index to start the divisions on the set X.
*
* Y - Set of raster points.
*
* startY - Index to start the divisions on the set Y.
*/
int divideL(int L, int *q, int *constraints, int B,
void (*standardPosition)(int*, int*, int*, int*),
Set X, int startX, Set Y, int startY) {
/* i_k[0] <- x'
* i_k[1] <- y'
*/
int i_k[2];
int i_x, i_y;
int q1[4], q2[4];
int key = 0;
int LSolution = getSolution(L, q, &key);
int upperBound = L_UpperBound(q);
for(i_x = startX; i_x < X.size; i_x++) {
i_k[0] = X.points[i_x];
if(i_k[0] > constraints[1]) {
break;
}
for(i_y = startY; i_y < Y.size; i_y++) {
i_k[1] = Y.points[i_y];
if(i_k[1] > constraints[3]) {
break;
}
divide(i_k, q, q1, q2, (*standardPosition));
if(q1[0] < 0 || q2[0] < 0) {
continue;
}
if(L_UpperBound(q1) + L_UpperBound(q2) > (LSolution & nRet)) {
/* It is possible that this division gets a better solution. */
int L1 = LIndex(q1[0], q1[1], q1[2], q1[3], memory_type);
int L2 = LIndex(q2[0], q2[1], q2[2], q2[3], memory_type);
int L1Solution = solve(L1, q1);
int L2Solution = solve(L2, q2);
if((L1Solution & nRet) + (L2Solution & nRet) > (LSolution & nRet)) {
/* A better solution was found. */
LSolution = ((L1Solution & nRet) + (L2Solution & nRet))
| (B << descSol);
storeSolution(L, key, LSolution);
storeDivisionPoint(L, key, i_k[0] | (i_k[1] << descPtoDiv2));
if((LSolution & nRet) == upperBound) {
return LSolution;
}
}
}
}
}
return LSolution;
}
/******************************************************************
******************************************************************/
/**
* Divide the L-piece in every possible way, according to the B6
* subdivision.
*
* +-------------+--------+
* | | |
* | (x',y') | L2 |
* | o------o |
* | | (x'',y') |
* | L1 | |
* | | |
* +------+---------------+
*
* Parameters:
* L - Index of the L-piece.
*
* q - The L-piece.
*
* X - Set of raster points.
*
* Y - Set of raster points.
*/
int divideB6(int L, int *q, Set X, Set Y) {
/* i_k[0] <- x'
* i_k[1] <- y'
* i_k[2] <- x''
*/
int i_k[3];
int q1[4], q2[4];
int key = 0;
int LSolution = getSolution(L, q, &key);
int upperBound = R_UpperBound(q[0], q[1]);
int i = 0;
for(i_k[0] = X.points[i]; i < X.size; i++) {
i_k[0] = X.points[i];
int j = i;
for(i_k[2] = X.points[j]; j < X.size; j++) {
i_k[2] = X.points[j];
if(i_k[0] == 0 && i_k[2] == 0) {
continue;
}
int k = 0;
for(i_k[1] = Y.points[k]; k < Y.size; k++) {
i_k[1] = Y.points[k];
divide(i_k, q, q1, q2, standardPositionB6);
if(q1[0] < 0 || q2[0] < 0) {
continue;
}
if(L_UpperBound(q1) + L_UpperBound(q2) > (LSolution & nRet)) {
/* It is possible that this division gets a better solution. */
int L1 = LIndex(q1[0], q1[1], q1[2], q1[3], memory_type);
int L2 = LIndex(q2[0], q2[1], q2[2], q2[3], memory_type);
int L1Solution = solve(L1, q1);
int L2Solution = solve(L2, q2);
if((L1Solution & nRet) + (L2Solution & nRet) > (LSolution & nRet)) {
/* A better solution was found. */
LSolution = ((L1Solution & nRet) + (L2Solution & nRet))
| (B6 << descSol);
storeSolution(L, key, LSolution);
storeDivisionPoint(L, key, i_k[0] | (i_k[1] << descPtoDiv2) |
(i_k[2] << descPtoDiv3));
if((LSolution & nRet) == upperBound) {
return LSolution;
}
}
}
}
}
}
return LSolution;
}
/******************************************************************
******************************************************************/
/**
* Divide the L-piece in every possible way, according to the B7
* subdivision.
*
* +-------------+
* | |
* | (x',y'') |
* | o------+
* | | |
* | L1 | L2 |
* | | |
* +------o |
* | (x',y') |
* | |
* | |
* +-------------+
*
* Parameters:
* L - Index of the L-piece.
*
* q - The L-piece.
*
* X - Set of raster points.
*
* Y - Set of raster points.
*/
int divideB7(int L, int *q, Set X, Set Y) {
/* i_k[0] <- x'
* i_k[1] <- y'
* i_k[2] <- y''
*/
int i_k[3];
int q1[4], q2[4];
int key = 0;
int LSolution = getSolution(L, q, &key);
int upperBound = R_UpperBound(q[0], q[1]);
int j = 0;
for(i_k[1] = Y.points[j]; j < Y.size; j++) {
i_k[1] = Y.points[j];
int k = j;
for(i_k[2] = Y.points[k]; k < Y.size; k++) {
i_k[2] = Y.points[k];
if(i_k[1] == 0 && i_k[2] == 0) {
continue;
}
int i = 0;
for(i_k[0] = X.points[i]; i < X.size; i++) {
i_k[0] = X.points[i];
divide(i_k, q, q1, q2, standardPositionB7);
if(q1[0] < 0 || q2[0] < 0) {
continue;
}
if(L_UpperBound(q1) + L_UpperBound(q2) > (LSolution & nRet)) {
/* It is possible that this division gets a better solution. */
int L1 = LIndex(q1[0], q1[1], q1[2], q1[3], memory_type);
int L2 = LIndex(q2[0], q2[1], q2[2], q2[3], memory_type);
int L1Solution = solve(L1, q1);
int L2Solution = solve(L2, q2);
if(((L1Solution & nRet) + (L2Solution & nRet)) > (LSolution & nRet)) {
/* A better solution was found. */
LSolution = ((L1Solution & nRet) + (L2Solution & nRet))
| (B7 << descSol);
storeSolution(L, key, LSolution);
storeDivisionPoint(L, key, i_k[0] | (i_k[1] << descPtoDiv2) |
(i_k[2] << descPtoDiv3));
if((LSolution & nRet) == upperBound) {
return LSolution;
}
}
}
}
}
}
return LSolution;
}
/******************************************************************
******************************************************************/
/**
* Solve the problem of packing rectangular (l,w)-boxes into the
* specified L-shaped piece.
*
* Parameters:
* L - Index of the L-piece.
*
* q - The L-piece. q = {X, Y, x, y}.
*/
int solve(int L, int *q) {
int key = 0;
if(memory_type == MEM_TYPE_4) {
if(solution[L] != -1) {
/* This problem has already been solved. */
return solution[L];
}
}
else {
key = getKey(q[0], q[1], q[2], q[3], memory_type);
if(solutionMap[L].count(key) > 0) {
/* This problem has already been solved. */
return solutionMap[L][key];
}
}
if(q[0] != q[2]) {
bool horizontalCut;
int lowerBound = L_LowerBound(q, &horizontalCut);
int upperBound = L_UpperBound(q);
int LSolution = lowerBound | (B1 << descSol);
if(horizontalCut)
storeDivisionPoint(L, key, 0 | (q[3] << descPtoDiv2));
else
storeDivisionPoint(L, key, q[2] | (0 << descPtoDiv2));
storeSolution(L, key, LSolution);
/* Try to solve this problem with homogeneous packing (or other
* better solution already computed). */
if((LSolution & nRet) != upperBound) {
/* It was not possible to solve this problem with homogeneous
* packing. */
int constraints[4];
int startX = 0;
int startY = 0;
/* Construct the raster points sets X and Y. */
Set X, Y;
constructRasterPoints(q[0], q[1], &X, &Y, normalSetX);
for(startX = 0; X.points[startX] < q[2]; startX++);
for(startY = 0; Y.points[startY] < q[3]; startY++);
/***********************************
* 0 <= x' <= x and 0 <= y' <= y *
***********************************/
constraints[0] = 0; constraints[1] = q[2];
constraints[2] = 0; constraints[3] = q[3];
/CODE IS MISSING DUE TO CHARACTER LIMITATION/
/******************************************************************
******************************************************************/
void makeIndices(int L, int W) {
Set X, Y, raster;
constructRasterPoints(L, W, &X, &Y, normalSetX);
int j = 0;
int k = 0;
int i = 0;
raster = newSet(L + 2);
while(i < X.size && X.points[i] <= L &&
j < Y.size && Y.points[j] <= W) {
if(X.points[i] == Y.points[j]) {
raster.points[k++] = X.points[i++];
raster.size++;
j++;
}
else if(X.points[i] < Y.points[j]) {
raster.points[k++] = X.points[i++];
raster.size++;
}
else {
raster.points[k++] = Y.points[j++];
raster.size++;
}
}
while(i < X.size && X.points[i] <= L) {
if(X.points[i] > raster.points[k-1]) {
raster.points[k++] = X.points[i];
raster.size++;
}
i++;
}
if(k > 0 && raster.points[k-1] < L) {
raster.points[k++] = L;
raster.size++;
}
raster.points[k] = L + 1;
raster.size++;
try {
indexRasterX = new int[L + 2];
indexRasterY = new int[W + 2];
}
catch (std::exception& e) {
std::cout << "Error allocating memory." << std::endl;
exit(0);
}
j = 0;
numRasterX = 0;
for(int i = 0; i <= L; i++) {
if(raster.points[j] == i) {
indexRasterX[i] = numRasterX++;
j++;
}
else {
indexRasterX[i] = indexRasterX[i - 1];
}
}
indexRasterX[L + 1] = indexRasterX[L] + 1;
j = 0;
numRasterY = 0;
for(int i = 0; i <= W; i++) {
if(raster.points[j] == i) {
indexRasterY[i] = numRasterY++;
j++;
}
else {
indexRasterY[i] = indexRasterY[i - 1];
}
}
indexRasterY[W + 1] = indexRasterY[W] + 1;
free(raster.points);
free(X.points);
free(Y.points);
}
/******************************************************************
******************************************************************/
void freeMemory() {
if(memory_type == MEM_TYPE_4) {
delete[] solution;
delete[] divisionPoint;
}
else {
delete[] solutionMap;
delete[] divisionPointMap;
}
delete[] indexRasterX;
delete[] indexRasterY;
}
/******************************************************************
******************************************************************/
bool tryAllocateMemory(int size) {
try {
solutionMap = new std::map<int, int>[size];
}
catch (std::exception& e) {
if(size == 0) {
std::cout << "Error allocating memory." << std::endl;
exit(0);
}
return false;
}
try {
divisionPointMap = new std::map<int, int>[size];
}
catch (std::exception& e) {
delete [] solutionMap;
delete [] divisionPointMap;
if(size == 0) {
std::cout << "Error allocating memory." << std::endl;
exit(0);
}
return false;
}
return true;
}
/******************************************************************
******************************************************************/
void allocateMemory() {
memory_type = MEM_TYPE_4;
int nL = roundToNearest((pow((double)numRasterX,
ceil((double)memory_type / 2.0)) *
pow((double)numRasterY,
floor((double)memory_type / 2.0))));
memory_type--;
if(nL >= 0) {
try {
solution = new int[nL];
try {
divisionPoint = new int[nL];
for(int i = 0; i < nL; i++)
solution[i] = -1;
}
catch (std::exception& e) {
delete[] solution;
do {
nL = roundToNearest((pow((double)numRasterX,
ceil((double)memory_type/ 2.0)) *
pow((double)numRasterY,
floor((double)memory_type / 2.0))));
memory_type--;
if(nL >= 0 && tryAllocateMemory(nL)) {
break;
}
} while(memory_type >= 0);
}
}
catch (std::exception& e) {
do {
nL = roundToNearest((pow((double)numRasterX,
ceil((double)memory_type / 2.0)) *
pow((double)numRasterY,
floor((double)memory_type / 2.0))));
memory_type--;
if(nL >= 0 && tryAllocateMemory(nL)) {
break;
}
} while(memory_type >= 0);
}
}
else {
do {
nL = roundToNearest((pow((double)numRasterX,
ceil((double)memory_type / 2.0)) *
pow((double)numRasterY,
floor((double)memory_type / 2.0))));
memory_type--;
if(nL >= 0 && tryAllocateMemory(nL)) {
break;
}
} while(memory_type >= 0);
}
memory_type++;
}
/******************************************************************
******************************************************************/
int calculate_boxes(int L, int W, int l, int w) {
int q[4];
int BD_solution, L_solution;
int INDEX;
double BD_time, L_time;
struct rusage usage, prev_usage;
int L_n, W_n;
/* Read L, W, l and w from standard input. */
if(L < W) {
std::swap(L, W);
}
memory_type = 5;
/* Try to solve the problem with Algorithm 1. */
getrusage(RUSAGE_SELF, &prev_usage);
BD_solution = solve_BD(L, W, l, w, 0);
getrusage(RUSAGE_SELF, &usage);
BD_time =
(((double) usage.ru_utime.tv_sec +
((double) usage.ru_utime.tv_usec / 1e06)) -
((double) prev_usage.ru_utime.tv_sec +
((double) prev_usage.ru_utime.tv_usec / 1e06)));
printf("\nPhase 1 (Five-block Algorithm)\n");
printf(" - solution found: %d box", BD_solution);
if(BD_solution >= 2) {
printf("es");
}
printf(".\n");
printf(" - runtime: %.2f second", BD_time);
if(BD_time >= 2.0) {
printf("s");
}
printf("\n");
L_solution = -1;
L_time = 0.0;
L_n = normalize[L];
W_n = normalize[W];
if(BD_solution != upperBound[indexX[L_n]][indexY[W_n]]) {
/* The solution obtained by Algorithm 1 is not known to be
* optimal. Then it will try to solve the problem with
* L-Algorithm. */
getrusage(RUSAGE_SELF, &prev_usage);
makeIndices(L_n, W_n);
allocateMemory();
q[0] = q[2] = L_n;
q[1] = q[3] = W_n;
INDEX = LIndex(q[0], q[1], q[2], q[3], memory_type);
solve(INDEX, q);
L_solution = getSolution(INDEX, q);
draw(L, W, INDEX, q, L_solution & nRet, true);
freeMemory();
getrusage(RUSAGE_SELF, &usage);
L_time = (((double) usage.ru_utime.tv_sec +
((double) usage.ru_utime.tv_usec / 1e06)) -
((double) prev_usage.ru_utime.tv_sec +
((double) prev_usage.ru_utime.tv_usec / 1e06)));
printf("\nPhase 2 (L-Algorithm)\n");
printf(" - solution found: %d box", L_solution);
if(L_solution >= 2) {
printf("es");
}
printf(".\n");
printf(" - runtime: %.2f second", L_time);
if(L_time >= 2.0) {
printf("s");
}
printf("\n");
}
else {
q[0] = q[2] = L_n;
q[1] = q[3] = W_n;
draw(L, W, 0, q, BD_solution, false);
}
int n = std::max(BD_solution, L_solution);
printf("\nSolution found: %d box", n);
if(n >= 2) {
printf("es");
}
printf(".\n");
int upper = upperBound[indexX[L_n]][indexY[W_n]];
printf("\nComputed upper bound: %d box", upper);
if(upper >= 2) {
printf("es");
}
printf(".\n");
if(upper == n) {
printf("Proven optimal solution.\n");
}
double time = BD_time + L_time;
printf("Runtime: %.2f second", time);
if(time >= 2.0) {
printf("s");
}
printf(".\n");
for(int i = 0; i < normalSetX.size; i++) {
free(lowerBound[i]);
free(upperBound[i]);
free(cutPoints[i]);
}
delete[] lowerBound;
delete[] upperBound;
delete[] cutPoints;
delete[] indexX;
delete[] indexY;
delete[] normalize;
delete[] normalSetX.points;
return n;
}
PYBIND11_MODULE(RecPartAlgorithm, m) {
m.doc() = R"pbdoc(
Pybind11 example plugin
-----------------------
.. currentmodule:: RecPartAlgorithm
.. autosummary::
:toctree: _generate
add
subtract
)pbdoc";
m.def("calculate_boxes", &calculate_boxes, R"pbdoc(
calculates boxes
Some other explanation about the add function.
)pbdoc");
#ifdef VERSION_INFO
m.attr("__version__") = MACRO_STRINGIFY(VERSION_INFO);
#else
m.attr("__version__") = "dev";
#endif
}
`
I tried to make sure that the python and cpython version match. tried to use different python versions and also tried to use conda and python virtualenvironments. Tried to use a make file instead of the g++ command line tool. Any help/idea/input would help a lot!
The issue happened during compilation. As mentioned in command above. I have now used cmake and included all the files in the repository via pybind11_add_module inside the CMakeLists.txt file instead of using the compilr from the command line. This solved the issue.