// Intern Rente
// Et program til udregning af den interne rente for et investeringsprojekt
// Lavet af hold A fra datalogi-kurset p MK 1. r
// februar 2002

#include <iostream.h>
#include <iomanip.h>
#include <fstream.h>
#include <math.h>
#include <conio.h>

const int MAXANTTERM = 40;
const int MAXGRAD = MAXANTTERM;

void IntroducerInternRente();
void IndlaesProjekt(int &antterm, double bet[MAXANTTERM+1]);
void IndtastProjekt(int &antterm, double bet[MAXANTTERM+1]);
void IndlaesProjektFraFil(char *filnavn, int &antterm, double bet[MAXANTTERM+1]);
void UdskrivProjekt(int antterm, double bet[MAXANTTERM+1]);
double FindInternRente(int antterm, double bet[MAXANTTERM+1], int &fundet);
double FindRod(double x0, double eps, int maxiter, int n, double a[MAXGRAD+1], int &succes);
void Horner (int n, double a[MAXGRAD+1], double x, double &f, double &df);
void UdskrivInternRente(double r, int fundet);

//// Hovedprogram

int main()
{
	int antterm; // antal terminer i betalingsrkken
	double bet[MAXANTTERM+1]; // de enkelte betalinger i betalingsrkken
						   // (starter i tidspunkt 0, slutter ved tidspunkt antterm)
	double r; // den fundne interne rente, udtrykt som kommatal
	int fundet; // angiver om en intern rente blev fundet (sandt/falsk variabel)

	IntroducerInternRente();
	IndlaesProjekt(antterm, bet);
	UdskrivProjekt(antterm, bet);
	r=FindInternRente(antterm, bet, fundet);
	UdskrivInternRente(r, fundet);

	getch();
	return 0;
}

//// Funktioner

void IntroducerInternRente()
{
	cout<<"Velkommen til programmet, der beregner den interne rente";
	cout<<"i et projekt lbende over n r, med i terminer.";
}

void IndlaesProjekt(int &antterm, double bet[MAXANTTERM+1])
{
 char svar;
 clrscr();
 cout<<"\n Her skal der vlges mellem manuel indtastning og indlsning fra fil.";
 cout<<"\n Tast M for manuel eller F for fil: ";
 cin>>svar;
 if(svar=='M'||svar=='m')
	 IndtastProjekt(antterm,bet);
 if(svar=='F'||svar=='f')
	 IndlaesProjektFraFil("c:\\projekt.dat",antterm,bet);
}

void IndtastProjekt(int &antterm, double bet[MAXANTTERM+1])
{
 int i;
 clrscr();
 cout<<"\n Indtast antallet af terminer: ";
 cin>>antterm;
 for (i=0; i<=antterm; i++)
	{
	 cout<<"\n Betaling nr.: "<<i<<" ";
	 cout<<"\n Indtast vrdien af betalingen: ";
	 cin>>bet[i];
	}
}

void IndlaesProjektFraFil(char *filnavn, int &antterm, double bet[MAXANTTERM+1])
{
 int i;
 ifstream old_file;
 old_file.open(filnavn);

 old_file>>antterm;

 for(i=0; i<=antterm; i++)
 {
	old_file>>bet[i];
 }
}

void UdskrivProjekt(int antterm, double bet[MAXANTTERM+1])
{
 int i;

 for(i=0; i<=antterm; i++)
 {
	cout<<"\n Belb termin "<<(i)<<"	 "<<bet[i];
 }
}

double FindInternRente(int antterm, double bet[MAXANTTERM+1], int &fundet)
{
	double gaet, r, rod, x0, eps;
	int maxiter;

	cout <<"\n Indtast et gt p den interne rente i procent:";
	cin >>gaet;
	x0=1+(gaet/100.);

	cout <<"\n Indtast epsilon-vrdi, der angiver hvor tt roden skal vre p 0:";
	cin >>eps;
	cout <<"\n Indtast max antal interationer, der m bruges i forsg p at finde en rod:";
	cin >>maxiter;

	rod=FindRod(x0,eps, maxiter, antterm, bet, fundet);
	r=rod-1;

	return r;
}

double FindRod(double x0, double eps, int maxiter, int n, double a[MAXGRAD+1], int &succes)
{
 double xny, xgl, f, fm;
 int taeller=0;

 succes=0;
 xny=x0;

 do
 {
	xgl=xny;
	Horner(n,a,xgl,f,fm);
	xny=xgl-(f/fm);
	taeller++;
 }
 while((fabs(xny-xgl)>eps)&&(taeller<maxiter));

 if(taeller<maxiter)
		succes=1;

 return xny;

}

void Horner (int n, double a[MAXGRAD+1], double x, double &f, double &df)
{
	double b[MAXGRAD+1], c[MAXGRAD];
	int k;

	b[0]=a[0];

	for (k=1; k<=n; k++)
		b[k]=a[k]+x*b[k-1];

	c[0]=b[0];

	for (k=1; k<=n; k++)
		c[k]=b[k]+x*c[k-1];

	f=b[n];
	df=c[n-1];
}

void UdskrivInternRente(double r, int fundet)
{
	if(fundet==1)
	{
			cout.setf(ios::fixed);
			cout.setf(ios::showpoint);
			cout<<"Renten er " << setw(5) << setprecision(2) <<r*100<<"%";
	}
}


