I am implementing an algorithm to generate basis function for bsplines using the following link: http://www.cs.mtu.edu/~shene/COURSES/cs3621/NOTES/spline/B-spline/bspline-curve-coef.html
I should get a tridiagonal system on solving the system of linear equations
however I get a lower triangular matrix.
I would be glad if someone could tell me what am I am doing wrong? Thank you.
I have written computingCoefficients (b_spline_interpolation.cpp) function and I tried another function basis to compute the coeffiicents. However neither gives a tridiagonal matrix. Please help.
Here is my code
b_spline_interpolation.cpp
#include "mymain.h"
vector<double> generateParameters(int &nplus1)
{
cout<<"generating parameters.."<<endl;
size_t i= 0;//unsigned i
double n = nplus1-1;
vector<double> t(nplus1);
t[0]=0.0;
t[n]=1.0;
for(i=1;i<=n-1;i++)
t[i]=i/n;
cout<<"the parameters are:"<<endl;
for(i=0;i<t.size();i++)//print parameters
cout<<t[i]<<endl;
return t;
}
void generateKnotsUsingDeBoorFormula(int &nplus1 , int °ree_p , int &mplus1 , vector< double > &knots_u)
{
int i,j,jj,p=degree_p,n=nplus1-1,m=mplus1-1;
vector <double> t(nplus1);
t= generateParameters( nplus1 );
for( i=0;i<=p;i++)
knots_u[i]=0;
for( j= 1;j <= n-p;j++)
{
for(i = j; i<=j+p-1 ; i++)
knots_u[ j+p ]+=t[i]/p;
}
for ( jj=0;jj<=p;jj++)
knots_u[m-p+jj]=1;
cout<<"generating knots using DeBoor Formula..."<<endl;
cout<<"the knots are:"<<endl;
for(i=0;i<=m;i++)//print knots
cout<<knots_u[i]<<endl;
}
void generateUniformKnots(int nplus1 , int degree_p , int mplus1 , vector< double > &knots_u)
{ cout<<"generating knots with uniform knot spacing..."<<endl;
int i,j,jj,p=degree_p,n=nplus1-1,m=mplus1-1;
for( i=0;i<=p;i++)
knots_u[i]=0;
for( j= 1;j <= n-p;j++)
knots_u[ j+p ]=((double)j)/(n-p+1);
for ( jj=0;jj<=p;jj++)
knots_u[m-p+jj]=1;
cout<<"the knots are:"<<endl;
for(i=0;i<=m;i++)//print knots
cout<<knots_u[i]<<endl;
}
double calcDist(double x1 , double y1 , double x2 , double y2)
{double d=sqrt( pow( x1 - x2 , 2 ) +pow( y1 - y2 , 2 ));
return d;}
void generateKnotsUsingCentripetalMethod(int nplus1 , int degree_p , int mplus1 , vector< double > &knots_u,MatrixXd temp_matrix)
{ cout<<"generating knots with centripetal method..."<<endl;
int i , p = degree_p , n=nplus1-1,m=mplus1-1;
vector <double> t(nplus1);
t[ 0 ]= 0;
t[ n ]= 1;
double l = 0 ;
for(i=1;i<=n;i++) //calculating the value of L
{
l=l+calcDist(temp_matrix(i,0),temp_matrix(i,1),temp_matrix(i-1,0),temp_matrix(i-1,1) );
}
for(i=1;i<=n-1;i++)
{
t [i] = ( calcDist(temp_matrix(i,0),temp_matrix(i,1),temp_matrix(i-1,0),temp_matrix(i-1,1) ) )/l;
}
for(i=0;i<=m;i++)//print knots
cout<<knots_u[i]<<endl;
}
void computingCoefficients( int nplus1 ,int degree_p , int mplus1 , double u , vector < double > &knots_u ,vector <double> &N )//nplus1 is the number of control points of bspline curve
{
int m = mplus1 -1;
int n = nplus1 -1;
if ( u == knots_u [ 0 ]) // rule out special cases
N[0] = 1.0;
if (u == knots_u [ m ])
N[n] = 1.0 ;
if(u != knots_u[0] && u!=knots_u[m])
{
int i =0, j =0, ktemp , k =0;
for ( ktemp = 0;ktemp < m;ktemp ++ )//finding k
{
bool b1 = (u >= knots_u [ ktemp ]);
bool b2 = (u < knots_u [ ktemp+1 ]) ;
if (b1&& b2 )
k=ktemp;
}
N[k] = 1.0; // degree 0 coefficient
int degree_d = 0 ;
for (degree_d =1 ;degree_d<=degree_p;degree_d++) // degree d goes from 1 to p ,outer loop
{
if((k-degree_d>=0)&&(k-degree_d+1>=0))
N[k- degree_d ] = ( ( knots_u[ k + 1 ]-u )/( knots_u[ k + 1 ]-knots_u[ k - degree_d + 1] ) )* N[(k-degree_d)+1]; // right (south-west corner) term only
for ( i = k - degree_d + 1 ; i <= k-1 ; i++) // compute internal terms
if( ( i >= 0 )&&( i + degree_d + 1< N.size())&&( (i+1)<N.size() ) )//negative subcripts of vector give out of range vector
N[ i ] =( ( u - knots_u [ i ] )/( knots_u [ i + degree_d ] -knots_u [ i ] ) ) * N [ i ] + ( ( knots_u[ i + degree_d + 1 ]- u )/( knots_u[ i + degree_d + 1 ] - knots_u[ i + 1 ] ) ) * N[ i + 1 ];
N[ k ] = ( ( u - knots_u [ k ])/(knots_u[ k + degree_d ]-knots_u[ k ]) )* N[k]; // let (north-west corner) term only
}
}// end for this if(u != knots_u[0] && u!=knots_u[m])
cout<<"Computing Coefficients.."<<endl;
cout<<"The basis functions are:"<<endl;
for(int i=0; i<nplus1 ; i++)
cout<<N[i]<<endl;
}
void knot( int n,int c, vector<double> &x)
{cout<<"in Knot function:";
int nplusc,nplus2,i;
nplusc = n + c;
nplus2 = n + 2;
x[1] = 0;
for (i = 2; i <= nplusc; i++)
{
if ( (i > c) && (i < nplus2) )
x[i] = x[i-1] + 1;
else
x[i] = x[i-1];
}
printf("The knot vector is ");
for (i = 1; i <= nplusc; i++){
cout<<x[i]<<" ";
}
printf("\n");
}
void basis(int c , double t , int npts , vector < double > &x , vector < double > &n )
{
int nplusc;
int i,k;
double d,e;
vector <double> temp(36);
nplusc = npts + c;
printf("knot vector is \n");
for (i = 1; i <= nplusc; i++){
cout<<" "<<x[i]<<endl;
}
printf("t is %f \n", t);
/* calculate the first order basis functions n[i][1] */
for (i = 1; i<= nplusc-1; i++){
if (( t >= x[i]) && (t < x[i+1]))
temp[i] = 1;
else
temp[i] = 0;
}
/* calculate the higher order basis functions */
for (k = 2; k <= c; k++){
for (i = 1; i <= nplusc-k; i++){
if (temp[i] != 0) /* if the lower order basis function is zero skip the calculation */
d = ((t-x[i])*temp[i])/(x[i+k-1]-x[i]);
else
d = 0;
if (temp[i+1] != 0) /* if the lower order basis function is zero skip the calculation */
e = ((x[i+k]-t)*temp[i+1])/(x[i+k]-x[i+1]);
else
e = 0;
temp[i] = d + e;
}
}
if (t == (double )x[nplusc]){ /* pick up last point */
temp[npts] = 1;
}
/* put in n array */
for (i = 1; i < npts; i++) {
n[i] = temp[i];
}
}
MatrixXd getDataPoints( int &nplus1,MatrixXd &temp_matrix)//the second argument is required for centripetal spacing
{
int n=nplus1-1;
cout<<"Getting Data Points...."<<endl;
MatrixXd D=MatrixXd :: Zero( nplus1 , 2);//second argument is 2 for x,y annd 3 for x,y,z .currently in 2D
int i=0 ,j=0,k=0;
cout<< "Enter the data points:"<<endl;
for (i=0;i<=n;i++)
{ double temp[2] = {0};
for (j=0;j<1;j++)
{
cout<<"x:";
cin>>temp[j];
cout<<"y:";
cin>>temp[j+1];
cout<<endl;
D(i,j)=temp[j];
D(i,j+1)=temp[j+1];
}
}
temp_matrix =D ;//copy the matrix D into a temporary global matrix.Use this matrix in calculating knots for centripetal method
return D;
}
MatrixXd solveLinearEquation(MatrixXd &N,MatrixXd &D)
{
cout<<"solving System of Linear Equations using LU decomposition..."<<endl;
MatrixXd A =N;
MatrixXd B =D ;
MatrixXd X;
cout << "Here is the matrix A:\n" << A << endl;
cout << "Here is the right hand side b:\n" << B << endl;
X = A.ldlt().solve(B);
cout << "The solution is:\n" << X << endl;
cout << "Here is the matrix A:" << endl << A << endl;
cout << "Here is the matrix B:" << endl << B << endl;
X = A.fullPivLu().solve(B);
if((A*X).isApprox(B))
{
cout << "Here is a solution X to the equation AX = B:" << endl << X << endl;
}
else
cout << "The equation AX = B does not have any solution." << endl;
return X;
}
void computeControlPoints( int nplus1 ,int degree_p , int mplus1 , vector< double > &knots_u , int counter ,vector < double > &N ,MatrixXd &N_matrix , MatrixXd &D )
{
int n= nplus1 - 1;
//Input: n+1 n data points D0, ..... Dn and a degree p
//Output: A B-spline curve of degree p that contains all data points in the given order
int i=0,j=0,k=0;
{
for( j = 0 ; j< N_matrix.cols(); j++ )
{if (counter<N_matrix.rows())
N_matrix(counter, j ) = N[j];
}
}
if(counter==n)
{
cout << "Basis Matrix is :" << endl <<N_matrix << endl;
cout<<"Computing Control Points..."<<endl;
MatrixXd P = solveLinearEquation( N_matrix, D);
}
//Evaluate Nj,p(ti) into row i and column j of matrix N;
/* matrix N is available */
//for (i = 0 ; i< = n ; i++ )
//Place data point Di on row i of matrix D;
/* matrix D is constructed */
//Use a linear system solver to solve for P from D = N.P
//Row i of P is control point Pi;
//Control points P0, ..., Pn, knot vector U, and degree p determine an
interpolating B-spline curve;
}
mymain.h
#include <iostream>
#include<GL/glut.h>
#include<Eigen/Dense>
#include <vector>
#include<cmath>
using namespace std; // for iostream library
using namespace Eigen; // for Eigen Libary
//Function declarations
double calcDist(double x1 , double y1 , double x2 , double y2);
void knot( int n,int c, vector<double> &x);
void computeControlPoints( int nplus1 ,int degree_p , int mplus1 , vector< double > &knots_u , int counter ,vector < double > &N ,MatrixXd &N_matrix , MatrixXd &D );
void computingCoefficients( int nplus1 ,int degree_p , int mplus1 ,double u, vector < double > &knots_u ,vector <double> &N );
void drawBsplineCurve(int nplus1,int mplus1 ,MatrixXd P , vector <double> knots_u );
void generateKnotsUsingCentripetalMethod(int nplus1 , int degree_p , int mplus1 , vector< double > &knots_u,MatrixXd temp_matrix);
MatrixXd getDataPoints( int &nplus1,MatrixXd &temp_matrix);
MatrixXd solveLinearEquation(MatrixXd &N,MatrixXd &D) ;
void generateKnotsUsingDeBoorFormula(int &nplus1 , int °ree_p , int &mplus1 , vector< double > &knots_u);
vector<double> generateParameters(int &nplus1);
void generateUniformKnots(int nplus1 , int degree_p , int mplus1 , vector< double > &knots_u);
void generateKnotsUsingDeBoorFormula(int &nplus1 , int °ree_p , int &mplus1 , vector< double > &knots_u);
void basis(int c,double t,int npts,vector<double> &x,vector<double> &n);
//cubic_spline_interpolation
int spline (int n, int end1, int end2, double slope1, double slope2,
double x[], double y[], double b[], double c[], double d[],
int *iflag );
double seval (int n, double u,
double x[], double y[],
double b[], double c[], double d[],
int *last);
double sinteg (int n, double u,
double x[], double y[],
double b[], double c[], double d[],
int *last);
double deriv (int n, double u,
double x[],
double b[], double c[], double d[],
int *last);
//Display
void DisplayText(double positionx,double positiony ,int choice );
void Draw2DOrigin( double xorigin ,double yorigin );
void Draw3DOrigin(double xorigin ,double yorigin ,double zorigin);
void SelectObject(int choice);
//linear_interpolation file
void linearInterpolation(double theta1,double tx1,double ty1,double theta2,double tx2,double ty2 ,double timeparameter);
//optimization calcuation
double optimization(int choice, double a,double b , VectorXd weightsi ,VectorXd weightsj, MatrixXd A ,VectorXd q);
I am sorry for the long post. Eagerly awaiting reply!
PS: I am using Visual Studio 2008 Express Edition.
I am using Eigen Library for matrices: http://eigen.tuxfamily.org/dox/
Related
Alright so this program is meant to simulate a solar system by semi-randomly generating a star, semi-randomly generating planets around the star, simulating the passing of time (using MPI to spread out the computational load), and determining habitability of resulting planets. I should have it commented for readability.
I am however having a problem with getting MPI working. As far as I can tell I'm doing something wrong that prevents it from initializing properly. Here's the errors I get.
OrbitPlus.cpp:323:50: error: invalid conversion from ‘char’ to ‘char**’ [-fpermissive]
system1 = Time( system, n , dt , argc, **argv);
^
OrbitPlus.cpp:191:33: error: initializing argument 5 of ‘std::vector<std::vector<float> > Time(std::vector<std::vector<float> >, int, float, int, char**)’ [-fpermissive]
std::vector<std::vector<float>> Time( std::vector<std::vector<float>> system , int n, float dt, int argc, char **argv){
^
I do find it interesting that both errors are considered fpermissive errors if when I compile it with -
mpic++ -std=c++11 -o OrbitPlus OrbitPlus.cpp
So it seems if I was feeling adventurous I could just run the code with -fpermissive option and roll the dice, but I don't feel like being so brave. Clearly the errors are related to each other.
Here's my code.
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <tuple>
#include <vector>
#include <stdio.h>
#include <math.h>
#include <complex>
#include <stdint.h>
#include <time.h>
#include <string.h>
#include <algorithm>
#include "mpi.h"
double MyRandom(){
//////////////////////////
//Random Number Generator
//Returns number between 0-99
//////////////////////////
double y = 0;
unsigned seed = time(0);
std::srand(seed);
uint64_t x = std::rand();
x ^= x << 13;
x ^= x >> 7;
x ^= x << 17;
x = (1070739 * x) % 2199023255530;
y = x / 21990232555.31 ;
return y;
}
////////////////////////
///////////////////////
std::tuple< char , float , float , float , int > Star(){
////////////////////////////
//Star will generate a Star
//Randomly or User Selected
//Class, Luminosity, Probability, Radius, Mass, Temperature
//Stars always take up 99% of the mass of the system.
///////////////////////////
char Class;
int choice = 8;
float L, R, M, T;
double y = 4;
std::tuple< char , float , float , float , float > star( Class , L , R , M , T) ;
std::cout << "Select Star Class (OBAFGKM) or Select 8 for Random" << std::endl;
std::cout << "1 = O, 2 = B, 3 = A, 4 = F, 5 = G, 6 = K, 7 = M : ";
std::cin >> choice;
if ( choice == 8 ) {
y = MyRandom();
if (y <= 0.003) choice = 1;
if ((y > 0.003) && (y <= 0.133)) choice = 2;
if ((y > 0.133) && (y <= 0.733)) choice = 3;
if ((y > 0.733) && (y <= 3.733)) choice = 4;
if ((y > 3.733) && (y <= 11.333)) choice = 5;
if ((y > 11.333) && (y <= 23.433)) choice = 6;
else choice = 7;
}
if (choice == 1) {
Class = 'O';
L = 30000;
R = 0.0307;
M = 16;
T = 30000;
}
if (choice == 2) {
Class = 'B';
L = 15000;
R = 0.0195;
M = 9;
T = 20000;
}
if (choice == 3) {
Class = 'A';
L = 15;
R = 0.00744;
M = 1.7;
T = 8700;
}
if (choice == 4) {
Class = 'F';
L = 3.25;
R = 0.00488;
M = 1.2;
T = 6750;
}
if (choice == 5) {
Class = 'G';
L = 1;
R = 0.00465;
M = 1;
T = 5700;
}
if (choice == 6) {
Class = 'K';
L = 0.34;
R = 0.00356;
M = 0.62;
T = 4450;
}
if (choice == 7) {
Class = 'M';
L = 0.08;
R = 0.00326;
M = 0.26;
T = 3000;
}
return star;
}
////////////
///////////
std::vector< std::vector<float> > Planet( float L, float R, float M, int T, int n){
///////////////////////////
//Planet generates the Planets
//Random 1 - 10, Random distribution 0.06 - 6 JAU unless specified by User
//Frost line Calculated, First Planet after Frost line is the Jupiter
//The Jupiter will have the most mass of all Jovian worlds
//Otherwise divided into Jovian and Terrestrial Worlds, Random Masses within groups
//Also calculates if a planet is in the Habitable Zone
////////////////////////////
float frostline, innerCHZ, outerCHZ;
float a = 0.06; // a - albedo
float m = M / 100; //Mass of the Jupiter always 1/100th mass of the Star.
std::vector<float> sys;
std::vector<std::vector <float>> system;
for (int i = 0 ; i < n ; i++){
sys.push_back( MyRandom()/10 * 3 ) ; //Distances in terms of Sol AU
}
sort(sys.begin(), sys.end() );
for (int i = 0 ; i < n ; i++){
system[i].push_back(sys[i]);
system[i].push_back(0); //system[i][0] is x, system[i][1] is y
}
frostline = (0.6 * T / 150) * (0.6 * T/150) * R / sqrt(1 - a);
innerCHZ = sqrt(L / 1.1);
outerCHZ = sqrt(L / 0.53);
for (int i = 0 ; i < n ; i++){
if (system[i][0] <= frostline) {
float tmass = m * 0.0003 * MyRandom();
system[i].push_back(tmass) ; //system[i][2] is mass, [3] is marker for the Jupiter
system[i].push_back(0) ;
}
if ((system[i][0] >= frostline) && (system[i-1][0] < frostline)){
system[i].push_back(m) ;
float J = 1;
system[i].push_back(J) ;
}
if ((system[i][0] >= frostline) && (system[i-1][0] >= frostline)) {
float jmass = m * 0.01 * MyRandom();
system[i].push_back(jmass) ;
system[i].push_back(0) ;
}
if ((system[i][0] >= innerCHZ) && (system[i][0] <= outerCHZ)){
float H = 1;
system[i].push_back(H);
}
else system[i].push_back(0); //[4] is habitable marker
}
return system;
}
////////////
////////////
std::vector<std::vector<float>> Time( std::vector<std::vector<float>> system , int n, float dt, int argc, char **argv){
#define ASIZE 3 //Setup
int MPI_Init(int *argc, char ***argv);
int rank, numtasks = n, namelen, rc;
char processor_name[MPI_MAX_PROCESSOR_NAME];
MPI_Status status;
MPI_Init( &argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &numtasks);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Get_processor_name(processor_name, &namelen);
rc = MPI_Bcast(&system, ASIZE, MPI_DOUBLE, 0, MPI_COMM_WORLD); //Master
// Broadcast computed initial values to all other processes
if (rc != MPI_SUCCESS) {
fprintf(stderr, "Oops! An error occurred in MPI_Bcast()\n");
MPI_Abort(MPI_COMM_WORLD, rc);
}
//Slaves
const float pi = 4 * atan(1.0);
const float G = 6.67 * pow(10,-11);
float a_x, a_y;
for (int i = 0 ; i < n; i++) {
if (rank != i){
a_x = G * system[i][2] * (system[i][0]-system[rank][0]) / ((system[i][0]-system[rank][0]) * (system[i][0]-system[rank][0]));
a_y = G * system[i][2] * (system[i][1]-system[rank][1]) / ((system[i][1]-system[rank][1]) * (system[i][1]-system[rank][1]));
}
if (rank == i){
a_x = G * system[i][2] * 100 * system[i][0] / (system[i][0] * system[i][0]);
a_y = G * system[i][2] * 100 * system[i][1] / (system[i][1] * system[i][1]);
}
a_x += a_x;
a_y += a_y;
}
for (int i=0; i < n; i++){
system[i][0] += system[i][5] * dt + 0.5 * a_x * dt * dt;
system[i][1] += system[i][6] * dt + 0.5 * a_y * dt * dt;
system[i][5] += a_x * dt;
system[i][6] += a_y * dt;
}
for(int i=0 ; i<n ; i++){
for(int j=0 ; j<i ; j++){
if (system[j][0] == 0 && system[j][1] == 0){
system.erase(system.begin() + j);
} // crash into star
if (system[j][0] == system[i][0] && system[j][1] == system[i][1]){
system[i][2] += system[j][2];
system.erase(system.begin() + j);
} // planet crash
} //check co-ordinates
} // planet destroy loop
for(int i = 0 ; i < n ; i++){
if (sqrt(system[i][0]*system[i][0] + system[i][1]*system[i][1]) >= 60) system.erase(system.begin() + i);
}
//Send results back to the first process
if (rank != 0){// All processes except the one of rank 0
MPI_Send(&system, 1, MPI_DOUBLE, 0, 1, MPI_COMM_WORLD);
}
else {
for (int j = 1; j < numtasks; j++) {
MPI_Recv(&system, 1, MPI_DOUBLE, MPI_ANY_SOURCE, 1,
MPI_COMM_WORLD, &status);
}
}
MPI_Finalize();
///////////////////////////
//Time advances the solar system.
//Plots the Orbits
//Uses MPI to spread it's calculations.
///////////////////////////
return system;
}
////////////
////////////
std::vector<bool> FinalCheck( std::vector<std::vector<float>> system, std::vector<bool> Water, int n){
///////////////////////////
//Final Checks
//Reports if a Planet spent the whole Time in the Habitable Zone
///////////////////////////
for (int i = 0 ; i < n ; i++){
if (system[i][4] == 1.0) Water.push_back(true);
else Water.push_back(false);
}
return Water;
}
////////////
////////////
int main(int argc, char** argv){
char Class;
float L, R, M, T;
std::tuple< char , float , float , float , float > star( Class , L , R , M , T );
star = Star();
int n = MyRandom()/10 + 1;
std::vector<std::vector <float>> system ;
std::vector<std::vector <float>> system1 ;
system = Planet( L , R , M, T, n);
float G = 6.67 * pow(10,-11), pi = 4 * atan(1.0), dt;
for (int i = 0; i < n; i++){
if (system[i][3] == 1){
dt = 2 * pi * .01 * pow(system[i][0] * 1.5 * pow(10,8), 1.5) / sqrt(G * M * 2 * pow(10,30));
}
system[i].push_back(0.0); //system[i][5] is speed in x-axis
system[i].push_back( sqrt(6.67 * pow(10,-11) * 2 * pow(10,30) * M / system[i][0])); //system[i][6] is speed in y-axis
}
std::ofstream Finder;
std::ofstream Report;
Finder.open("plotdata.dat");
Report.open("report.txt");
Finder << "# Plot Co-ordinates" << std::endl;
for (int i = 0 ; i < 1000 ; i++) {
system1 = Time( system, n , dt , argc, argv);
for (int j=0 ; j<n ; j++){
Finder << "[color " << j << "] " << system[j][0] << " " << system[j][1] << std::endl;
if((system[j][4] == 1.0) && ( (sqrt(system[j][0] * system[j][0] + system[j][1] * system[j][1]) < sqrt(L / 1.1) ) || ((sqrt(system[j][0] * system[j][0] + system[j][1] * system[j][1]) > sqrt(L / 0.53)) ))) system[j][4] = 0.0;
}
system = system1;
}
Finder.close();
int m;
m = system.size()/system[0].size();
std::vector<bool> Water;
Water = FinalCheck( system, Water, n);
//Report
for (int i = 0 ; i < n ; i++){
Report << "Planet " << i << "ends up at" << system[i][0] << " and " << system[i][1] << "has mass " << system[i][2] ;
if (system[i][3] == 1) Report << ", which is the 'Jupiter' of the system." ;
if (system[i][4] == 1) Report << ", which can have liquid water on the surface." ;
}
Report.close();
///////////////////////////
//Report cleans everything up and gives the results
//Shows the plot, lists the Planets
//Reports the Positions and Masses of all Planets
//Reports which was the Jupiter and which if any were Habitable
//////////////////////////
return 0;
}
Any thoughts the gurus here have would be appreciated, especially with getting rid of those -fpermissive errors.
EDIT 1 - Code as presented will now completely compile - but will return a Segmentation fault during the Star routine. After the user inputs the star type but before it actually makes a star as far as I can tell.
The following error message was received after running my code located at the end of the message:
terminate called after throwing an instance of 'std::out_of_range'
what(): vector::_M_range_check: __n (which is 0) >= this->size() (which is 0)
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
I'm sorry for the length of the code. It appears that the error is coming from when I am calling the numerov function within the f function. If you are able to determine what the error is would you please let me know? Thank you!
#include <iostream>
#include <cmath>
#include <fstream>
#include <vector>
using namespace std;
int nx = 500, m = 10, ni = 10;
double x1 = 0, x2 = 1, h = (x2 - x1)/nx;
int nr, nl;
vector<double> ul, q, u;
//Method to achieve the evenly spaced Simpson rule
double simpson(vector <double> y, double h)
{
int n = y.size() - 1;
double s0 = 0, s1 = 0, s2 = 0;
for (int i = 1; i < n; i += 2)
{
s0 += y.at(i);
s1 += y.at(i-1);
s2 += y.at(i+1);
}
double s = (s1 + 4*s0 + s2)/3;
//Add the last slice separately for an even n+1
if ((n+1)%2 == 0)
return h*(s + (5*y.at(n) + 8*y.at(n-1) - y.at(n-2))/12);
else
return h*2;
}
//Method to perform the Numerov integration
vector <double> numerov(int m, double h, double u0, double u1, double q)
{
vector<double> u;
u.push_back(u0);
u.push_back(u1);
double g = h*h/12;
for (int i = 1; i < m+1; i++)
{
double c0 = 1 + g*q;
double c1 = 2 - 10*g*q;
double c2 = 1 + g*q;
double d = g*(0);
u.push_back((c1*u.at(i) - c0*u.at(i-1) + d)/c2);
}
return u;
}
//Method to provide the function for the root search
double f(double x)
{
vector<double> w;
vector<double> j = numerov(nx + 1, h, 0.0, 0.001, x);
for (int i = 0; i < 0; i++)
{
w.push_back(j.at(i));
}
return w.at(0);
}
//Method to carry out the secant search
double secant(int n, double del, double x, double dx)
{
int k = 0;
double x1 = x + dx;
while ((abs(dx) > del) && (k < n))
{
double d = f(x1) - f(x);
double x2 = x1 - f(x1)*(x1 - x)/d;
x = x1;
x1 = x2;
dx = x1 - x;
k++;
}
if (k == n)
cout << "Convergence not found after " << n << " iterations." << endl;
return x1;
}
int main()
{
double del = 1e-6, e = 0, de = 0.1;
//Find the eigenvalue via the secant method
e = secant (ni, del, e, de);
//Find the solution u(x)
u = numerov(nx + 1, h, 0.0, 0.01, e);
//Output the wavefunction to a file
ofstream myfile ("Problem 2.txt");
if (myfile.is_open())
{
myfile << "Input" << "\t" << "u(x)" << endl;
double x = x1;
double mh = m*h;
for (int i = 0; i <= nx; i += m)
{
myfile << x << "\t" << u.at(i) << endl;
x += mh;
}
myfile.close();
}
return 0;
}
vector<double> w;
for (int i = 0; i < 0; i++)
{
w.push_back(j.at(i));
}
return w.at(0);
w will have nothing in it, since that loop will run 0 times. Thus, w.at(0) will throw the out of range error.
Why do you think the problem is in the numerov function?
I see an error in the function f?
vector<double> w;
vector<double> j = numerov(nx + 1, h, 0.0, 0.001, x);
for (int i = 0; i < 0; i++)
{
w.push_back(j.at(i));
}
return w.at(0);
There is nothing on vector w and you try to access element 0.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I'm trying to check how much time passes with each 3 solutions for a problem, but sometimes I get a runtime error and can't see the passed time for 3rd solution, but sometimes it works. I think the solutions.h file is correct but i put it here anyway.
#include <iostream>
#include <cstdlib>
#include <ctime>
#include "solutions.h"
using namespace std;
int main()
{
cout << "Hello world!" << endl;
int* input1 = new int[10000];
int* input2 = new int[20000];
int* input3 = new int[40000];
int* input4 = new int[80000];
int* input5 = new int[100000];
for(int i = 0; i<100000; i++)
{
input1[i]= rand();
input2[i]= rand();
input3[i]= rand();
input4[i]= rand();
input5[i]= rand();
}
int* output1= new int[1000];
double duration;
clock_t startTime1 = clock();
solution1(input1,10000,1000,output1);
duration = 1000 * double( clock() - startTime1 ) / CLOCKS_PER_SEC;
cout << "Solution 1 with 10000 inputs took " << duration << " milliseconds." << endl;
startTime1 = clock();
solution2(input1,10000,1000,output1);
duration = 1000 * double( clock() - startTime1 ) / CLOCKS_PER_SEC;
cout << "Solution 2 with 10000 inputs took " << duration<< " milliseconds." << endl;
startTime1 = clock();
solution3(input1,10000,1000,output1);
duration = 1000 * double( clock() - startTime1 ) / CLOCKS_PER_SEC;
cout << "Solution 3 with 10000 inputs took " << duration << " milliseconds." << endl<<endl<<endl;
return 0;
}
And the solutions.h is
#ifndef SOLUTIONS_H_INCLUDED
#define SOLUTIONS_H_INCLUDED
#include <cmath>
void solution1( int input[], const int n, const int k, int output[] );
void solution2( int input[], const int n, const int k, int output[] );
void solution3( int input[], const int n, const int k, int output[] );
void swap( int &n1, int &n2 ) {
int temp = n1;
n1 = n2;
n2 = temp;
}
void solution1( int input[], const int n, const int k, int output[] ) {
int maxIndex, maxValue;
for( int i = 0; i < k; i++ ) {
maxIndex = i;
maxValue = input[i];
for( int j = i+1; j < n; j++ ) {
if( input[j] >= maxValue ) {
maxIndex = j;
maxValue = input[ j ];
}
}
swap( input[i], input[maxIndex] );
output[i] = input[i];
}
}
int partition( int input[], int p, int r ) {
int x = input[ r ], i = p - 1;
for( int j = p; j < r; j++ ) {
if( input[ j ] >= x ) {
i = i + 1;
swap( input[i], input[j] );
}
}
swap( input[i+1], input[r] );
return i + 1;
}
void quickSort( int input[], int p, int r ) {
int q;
if( p < r ) {
q = partition( input, p, r );
quickSort( input, p, q - 1 );
quickSort( input, q + 1, r );
}
}
void solution2( int input[], const int n, const int k, int output[] ) {
quickSort( input, 0, n - 1 );
for( int i = 0; i < k; i++ ) {
output[i] = input[i];
}
}
int partition2( int input[], int a, int p, int r ) {
int x = a, i = p - 1;
for( int j = p; j < r; j++ ) {
if( input[ j ] == x ) {
swap( input[ j ], input[ r ] );
}
if( input[ j ] >= x ) {
i = i + 1;
swap( input[i], input[j] );
}
}
swap( input[ i + 1 ], input[ r ] );
return i + 1;
}
void quickSort2( int input[], int p, int r ) {
int q;
if( p < r ) {
q = partition2( input, input[ r ], p, r );
quickSort2( input, p, q - 1 );
quickSort2( input, q + 1, r );
}
}
int findMin( int n1, int n2 ) {
if( n1 <= n2 )
return n1;
else
return n2;
}
int select( int input[], int n, int k, int start, int end, int flag ) {
if( n <= 5 ) {
quickSort2( input, start, end );
return input[ start + k - 1 ];
}
int i = start, numGroups = (int) ceil( ( double ) n / 5 ), numElements, j = 0;
int *medians = new int[numGroups];
while( i <= end ) {
numElements = findMin( 5, end - i + 1 );
medians[( i - start ) / 5] = select( input, numElements, (int) ceil( ( double ) numElements / 2 ), i, i + numElements - 1, 1 );
i = i + 5;
}
int M = select( medians, numGroups, (int) ceil( ( double ) numGroups / 2 ), 0, numGroups - 1, 1 );
delete[] medians;
if( flag == 1 )
return M;
int q = partition2( input, M, start, end );
int m = q - start + 1;
if( k == m )
return M;
else if( k < m )
return select( input, m - 1, k, start, q - 1, 0 );
else
return select( input, end - q, k - m, q + 1, end, 0 );
}
void solution3( int input[], const int n, const int k, int output[] ) {
select( input, n, k, 0, n - 1, 0 );
for( int i = 0; i < k; i++ )
output[i] = input[i];
}
#endif // SOLUTIONS_H_INCLUDED
Building your program with address sanitizer (clang++ clock.cxx -std=c++11 -O1 -g -fsanitize=address -fno-omit-frame-pointer) reveals the problem:
$ ./a.out
Hello world!
=================================================================
==8175==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x62e00000a040 at pc 0x000104dbd912 bp 0x7fff5ae43970 sp 0x7fff5ae43968
WRITE of size 4 at 0x62e00000a040 thread T0
#0 0x104dbd911 in main clock.cxx:18
#1 0x7fff88cd85fc in start (libdyld.dylib+0x35fc)
#2 0x0 (<unknown module>)
0x62e00000a040 is located 0 bytes to the right of 40000-byte region [0x62e000000400,0x62e00000a040)
And there is your code:
int* input1 = new int[10000];
int* input2 = new int[20000];
int* input3 = new int[40000];
int* input4 = new int[80000];
int* input5 = new int[100000];
for(int i = 0; i<100000; i++)
{
input1[i]= rand();
input2[i]= rand();
input3[i]= rand();
input4[i]= rand();
input5[i]= rand();
}
As you can see, size of input1, input2, ..., input4 is 10K, 20K, 40K, 80K elements, but in the loop we are accessing to elements out of this array so this can lead to the heap corruption.
Process returned -1073741819 (0xC0000005)
This means "memory access violation" or SEGFAULT.
Hope this will help.
I've tried to implement Newton's method for polynomials. Like:
double xn=x0;
double gxn=g(w, n, xn);
int i=0;
while(abs(gxn)>e && i<100){
xn=xn-(gxn/dg(w, n, xn));
gxn=g(w, n, xn);
i++;
}
where g(w, n, xn) computes the value of the function and dg(w, n, xn) computes the derivative.
As x0 I use starting point M which I found using Sturm's theorem.
My problem is that this method is divergent for some polynomials like x^4+2x^3+2x^2+2x+1. Maybe it's not regular, but I noticed that it happens when the solution of the equation is a negative number. Where can I look for an explanation?
Edit:
dg
double result=0;
for(int i=0; i<n+1; i++)
result+=w[i]*(n-i)*pow(x, n-i-1);
where n is the degree of polynomial
I'm not sure why would you say it's divergent.
I implemented Newton's method similarly to yours:
double g(int w[], int n, double x) {
double result = 0;
for (int i = 0; i < n + 1; i++)
result += w[i] * pow(x, n - i);
return result;
}
double dg_dx(int w[], int n, double x) {
double result = 0;
for (int i = 0; i < n ; i++)
result += w[i] * (n - i) * pow(x, n - i - 1);
return result;
}
int main() {
double xn = 0; // Choose initial value. I chose 0.
double gx;
double dg_dx_x;
int w[] = { 1, 2, 2, 2, 1 };
int i = 0;
int n = 4;
do {
gx = g(w, n, xn);
dg_dx_x = dg_dx(w, n, xn);
xn = xn - (gx / dg_dx_x);
i++;
} while (abs(gx) > 10e-5 && i < 100);
std::cout << xn << '\n';
}
And it yields -0.997576, which is close to the solution -1.
I have this equation
and
then find the polynomial from
I am trying to implement it like this:
for (int n=0;n<order;n++){
df[n][0]=y[n];
for (int i=0;i<N;i++){ //N number of points
df[n][i]+=factorial(n,i)*y[i+n-1];
}
}
for (int i=0;i<N;i++){
term=factorial(s,i);
result*=df[0][i]*term;
sum+=result;
}
return sum;
1) I am not sure how to implement the sign of every argument in the function.As you can see it goes 'positive' , 'negative', 'positive' ...
2) I am not sure for any mistakes...
Thanks!
----------------------factorial-----------------------------
int fact(int n){
//3!=1*2*3
if (n==0) return 1;
else
return n*fact(n-1);
}
double factorial(double s,int n){
//(s 3)=s*(s-1)*(s-2)/6
if ((n==0) &&(s==0)) return 1;
else
return fact(s)/fact(n);
}
The simplest solution is probably to just keep the sign in
a variable, and multiply it in each time through the loop.
Something like:
sign = 1.0;
for ( int i = 0; i < N; ++ i ) {
term = factorial( s, i );
result *= df[0][i] * term;
sum += sign * result;
sign = - sign;
}
You cannot do pow( -1, m ).
You can write your own:
inline int minusOnePower( unsigned int m )
{
return (m & 1) ? -1 : 1;
}
You may want to build up some tables of calculated values.
Well, I understand you want to approximately calculate the value f(x) for a given x=X, using Newton Interpolation polynomial with equidistant points (more specifically Newton-Gregory forward difference interpolation polynomial).
Assuming s=(X-x0)/h, where x0 is the first x, and h the step to obtain the rest of the x for which you know the exact value of f :
Considere:
double coef (double s, int k)
{
double c(1);
for (int i=1; i<=k ; ++i)
c *= (s-i+1)/i ;
return c;
}
double P_interp_value(double s, int Num_of_intervals , double f[] /* values of f in these points */) // P_n_s
{
int N=Num_of_intervals ;
double *df0= new double[N+1]; // calculing df only for point 0
for (int n=0 ; n<=N ; ++n) // n here is the order
{
df0[n]=0;
for (int k=0, sig=-1; k<=n; ++k, sig=-sig) // k here is the "x point"
{
df0[n] += sig * coef(n,k) * f[n-k];
}
}
double P_n_s = 0;
for (int k=0; k<=N ; ++k ) // here k is the order
{
P_n_s += coef(s,k)* df0[k];
}
delete []df0;
return P_n_s;
}
int main()
{
double s=0.415, f[]={0.0 , 1.0986 , 1.6094 , 1.9459 , 2.1972 };
int n=1; // Num of interval to use during aproximacion. Max = 4 in these example
while (true)
{
std::cin >> n;
std::cout << std::endl << "P(n=" << n <<", s=" << s << ")= " << P_interp_value(s, n, f) << std::endl ;
}
}
it print:
1
P(n=1, s=0.415)= 0.455919
2
P(n=2, s=0.415)= 0.527271
3
P(n=3, s=0.415)= 0.55379
4
P(n=4, s=0.415)= 0.567235
compare with:
http://ecourses.vtu.ac.in/nptel/courses/Webcourse-contents/IIT-KANPUR/Numerical%20Analysis/numerical-analysis/Rathish-kumar/rathish-oct31/fratnode8.html
It works. Now we can start to optimize these code.
just for the sign ;-)
inline signed int minusOnePower( unsigned int m )
{
return 1-( (m & 1)<<1 );
}