Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
// Copright (C) 1999-2013, Bernd Gaertner
// $Rev: 3581 $
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// =========================================================================
//
// This bug report example is made based on the file: https://people.inf.ethz.ch/gaertner/subdir/software/miniball/miniball_example.cpp
// See the full conversion in https://github.com/JuliaFEM/Miniball.jl/pull/18
#include <cstdlib>
#include <iostream>
#include "Miniball.hpp"
int main (int argc, char* argv[])
{
typedef double mytype; // coordinate type
int d = 2; // dimension
int n = 5; // number of points
double seed; // initialize random number generator
if (argc != 2) {
seed = 0;
} else
seed = std::atoi(argv[1]);
std::srand (seed);
double pts[5][2] = {
{0.9506930398034363,
0.31013342946109795},
{-0.740741543466292,
-0.6717901203375765},
{-0.9868853957383338,
0.1614224757535092},
{-0.3144334948107608,
0.9492795043300425},
{-0.9506930398034363,
-0.31013342946109784}};
// Insert problem coordinates in a 2-d array
// ----------------------------------------------------
mytype** ap = new mytype*[n];
for (int i=0; i<n; ++i) {
mytype* p = new mytype[d];
for (int j=0; j<d; ++j) {
p[j] = pts[i][j];
}
ap[i]=p;
}
// std::cout << pts << std::endl;
// define the types of iterators through the points and their coordinates
// ----------------------------------------------------------------------
typedef mytype* const* PointIterator;
typedef const mytype* CoordIterator;
// create an instance of Miniball
// ------------------------------
typedef Miniball::
Miniball <Miniball::CoordAccessor<PointIterator, CoordIterator> >
MB;
MB mb (d, ap, ap+n);
// output results
// --------------
// center
std::cout << "Center:\n ";
const mytype* center = mb.center();
for(int i=0; i<d; ++i, ++center)
std::cout << *center << " ";
std::cout << std::endl;
// squared radius
std::cout << "Squared radius:\n ";
std::cout << mb.squared_radius() << std::endl;
// number of support points
std::cout << "Number of support points:\n ";
std::cout << mb.nr_support_points() << std::endl;
// support points on the boundary determine the smallest enclosing ball
std::cout << "Support point indices (numbers refer to the input order):\n ";
MB::SupportPointIterator it = mb.support_points_begin();
for (; it != mb.support_points_end(); ++it) {
std::cout << (*it)-ap << " "; // 0 = first point
}
std::cout << std::endl;
// relative error: by how much does the ball fail to contain all points?
// tiny positive numbers come from roundoff and are ok
std::cout << "Relative error:\n ";
mytype suboptimality;
std::cout << mb.relative_error (suboptimality) << std::endl;
// suboptimality: by how much does the ball fail to be the smallest
// enclosing ball of its support points? should be 0
// in most cases, but tiny positive numbers are again ok
std::cout << "Suboptimality:\n ";
std::cout << suboptimality << std::endl;
// validity: the ball is considered valid if the relative error is tiny
// (<= 10 times the machine epsilon) and the suboptimality is zero
std::cout << "Validity:\n ";
std::cout << (mb.is_valid() ? "ok" : "possibly invalid") << std::endl;
// computation time
std::cout << "Computation time was "<< mb.get_time() << " seconds\n";
// clean up
for (int i=0; i<n; ++i)
delete[] ap[i];
delete[] ap;
return 0;
}
using Miniball
using ProgressMeter
function findbadsolution()
pts = Array{Float64}(5,2)
@showprogress 1 for k in 1:1e5
for i in 1:4
angle = rand()*2*pi
x = cos(angle)
y = sin(angle)
pts[i,:] = [x y]
if i == 1
pts[end,:] = [cos(angle + pi) sin(angle + pi)]
end
end
mb = miniball(pts)
if ~isapprox(mb.center,[0.0;0.0];atol=1000*eps())
println("Find interesting points k=$k")
println("$pts")
out = mb.center
println("mb.center=$out")
break
end
end
return pts
end
pts = findbadsolution()
open("badpoint.txt", "w") do f
write(f,"double pts[5][2] = {\n")
for i = 1:5
outx = pts[i,1]
outy = pts[i,2]
write(f,"{$outx,\n")
write(f,"$outy}")
if i == 5
write(f,"};\n")
else
write(f,",\n")
end
end
end
using Miniball
using ProgressMeter
function findbadsolution()
pts = Array{Float64}(5,2)
@showprogress 1 for k in 1:100000
for i in 1:4
angle = rand()*2*pi
x = cos(angle)
y = sin(angle)
pts[i,:] = [x y]
if i == 1
pts[end,:] = [cos(angle + pi) sin(angle + pi)]
end
end
mb = miniball(pts)
if ~isapprox(mb.center,[0.0;0.0];atol=10000*eps())
println("Find interesting points k=$k")
println("$pts")
out = mb.center
println("mb.center=$out")
cppname = "test_$k.cpp"
write_cpp(cppname,pts)
run(`g++ $cppname`)
run(`./a.out`)
end
end
return pts
end
function write_cpp(name,pts)
startoffile = """
#include <cstdlib>
#include <iostream>
#include "Miniball.hpp"
int main (int argc, char* argv[])
{
typedef double mytype; // coordinate type
int d = 2; // dimension
int n = 5; // number of points
"""
endoffile = """
mytype** ap = new mytype*[n];
for (int i=0; i<n; ++i) {
mytype* p = new mytype[d];
for (int j=0; j<d; ++j) {
p[j] = pts[i][j];
}
ap[i]=p;
}
typedef mytype* const* PointIterator;
typedef const mytype* CoordIterator;
typedef Miniball::
Miniball <Miniball::CoordAccessor<PointIterator, CoordIterator> >
MB;
MB mb (d, ap, ap+n);
std::cout << "Center:\\n ";
const mytype* center = mb.center();
for(int i=0; i<d; ++i, ++center)
std::cout << *center << " ";
std::cout << std::endl;
std::cout << "Squared radius:\\n ";
std::cout << mb.squared_radius() << std::endl;
std::cout << "Number of support points:\\n ";
std::cout << mb.nr_support_points() << std::endl;
std::cout << "Support point indices (numbers refer to the input order):\\n ";
MB::SupportPointIterator it = mb.support_points_begin();
for (; it != mb.support_points_end(); ++it) {
std::cout << (*it)-ap << " "; // 0 = first point
}
std::cout << std::endl;
std::cout << "Relative error:\\n ";
mytype suboptimality;
std::cout << mb.relative_error (suboptimality) << std::endl;
std::cout << "Suboptimality:\\n ";
std::cout << suboptimality << std::endl;
std::cout << "Validity:\\n ";
std::cout << (mb.is_valid() ? "ok" : "possibly invalid") << std::endl;
std::cout << "Computation time was "<< mb.get_time() << " seconds\\n";
for (int i=0; i<n; ++i)
delete[] ap[i];
delete[] ap;
return 0;
}
"""
open(name, "w") do f
write(f,startoffile)
write(f,"double pts[5][2] = {\n")
for i = 1:5
outx = pts[i,1]
outy = pts[i,2]
write(f,"{$outx,\n")
write(f,"$outy}")
if i == 5
write(f,"};\n")
else
write(f,",\n")
end
end
write(f,endoffile)
end
end
pts = findbadsolution()
write_cpp("test.cpp",pts)
// Copright (C) 1999-2013, Bernd Gaertner
// $Rev: 3581 $
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// =========================================================================
//
// This bug report example is made based on the file: https://people.inf.ethz.ch/gaertner/subdir/software/miniball/miniball_example.cpp
// See the full conversion in https://github.com/JuliaFEM/Miniball.jl/pull/18
#include <cstdlib>
#include <iostream>
#include "Miniball.hpp"
int main (int argc, char* argv[])
{
typedef double mytype; // coordinate type
int d = 2; // dimension
int n = 5; // number of points
double seed; // initialize random number generator
if (argc != 2) {
seed = 0;
} else
seed = std::atoi(argv[1]);
std::srand (seed);
double pts[5][2] = {
{-2.628921573512486897783446693210862576961517333984375000000000000000000000000000,
4.345646543473985268235537660075351595878601074218750000000000000000000000000000},
{-7.783166805400283383420401150942780077457427978515625000000000000000000000000000e-01,
-4.950583883652715400103261345066130161285400390625000000000000000000000000000000},
{-7.110427483983996488348111597588285803794860839843750000000000000000000000000000,
9.078042051418130364837111301312688738107681274414062500000000000000000000000000e-01},
{-2.781077447672829272562466940144076943397521972656250000000000000000000000000000,
-5.261543462775741808457041770452633500099182128906250000000000000000000000000000},
{-6.913805339049894804759333055699244141578674316406250000000000000000000000000000,
1.448828316446829855834721456631086766719818115234375000000000000000000000000000}
};
// Insert problem coordinates in a 2-d array
// ----------------------------------------------------
mytype** ap = new mytype*[n];
for (int i=0; i<n; ++i) {
mytype* p = new mytype[d];
for (int j=0; j<d; ++j) {
p[j] = pts[i][j];
}
ap[i]=p;
}
// std::cout << pts << std::endl;
// define the types of iterators through the points and their coordinates
// ----------------------------------------------------------------------
typedef mytype* const* PointIterator;
typedef const mytype* CoordIterator;
// create an instance of Miniball
// ------------------------------
typedef Miniball::
Miniball <Miniball::CoordAccessor<PointIterator, CoordIterator> >
MB;
MB mb (d, ap, ap+n);
// output results
// --------------
// center
std::cout << "Center:\n ";
const mytype* center = mb.center();
for(int i=0; i<d; ++i, ++center)
std::cout << *center << " ";
std::cout << std::endl;
// squared radius
std::cout << "Squared radius:\n ";
std::cout << mb.squared_radius() << std::endl;
// number of support points
std::cout << "Number of support points:\n ";
std::cout << mb.nr_support_points() << std::endl;
// support points on the boundary determine the smallest enclosing ball
std::cout << "Support point indices (numbers refer to the input order):\n ";
MB::SupportPointIterator it = mb.support_points_begin();
for (; it != mb.support_points_end(); ++it) {
std::cout << (*it)-ap << " "; // 0 = first point
}
std::cout << std::endl;
// relative error: by how much does the ball fail to contain all points?
// tiny positive numbers come from roundoff and are ok
std::cout << "Relative error:\n ";
mytype suboptimality;
std::cout << mb.relative_error (suboptimality) << std::endl;
// suboptimality: by how much does the ball fail to be the smallest
// enclosing ball of its support points? should be 0
// in most cases, but tiny positive numbers are again ok
std::cout << "Suboptimality:\n ";
std::cout << suboptimality << std::endl;
// validity: the ball is considered valid if the relative error is tiny
// (<= 10 times the machine epsilon) and the suboptimality is zero
std::cout << "Validity:\n ";
std::cout << (mb.is_valid() ? "ok" : "possibly invalid") << std::endl;
// computation time
std::cout << "Computation time was "<< mb.get_time() << " seconds\n";
// clean up
for (int i=0; i<n; ++i)
delete[] ap[i];
delete[] ap;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment