#! /usr/bin/env python3
# -*- coding: UTF-8 -*- 
# Øving 3: Numerisk bestemmelse av
# vinkler for fire like masser som henger med jevne
# mellomrom paa ei snor.

# Importerer numpy
import numpy as np

# L = snoras lengde
L = 1.0
# D = lengden mellom festepunktene
D = 0.9
# Vi har utledet en ligning for x = cos(alpha):
# (L/5)*(1+2x+4x/sqrt(1+3x^2))=D.
# Denne ligningeni vil vi lose numerisk.
# En mulighet (det finnes flere!) er da aa omforme ligningen til
# formen x = f(x), sette inn en startverdi
# x0 paa hoyre side, regne ut f(x0) og sette x1 = f(x0), deretter
# regne ut f(x1) og sette x2 = f(x1) osv. Hvis dette iterative
# skjemaet konvergerer, vil vi etter N iterasjoner med god tilnermelse
# ha xN = x(N-1), som er losningen.
# Her er flere varianter aktuelle. Vi innforer gamma=(5D/L-1)/2 og har:
# 1: x = gamma/(1+2/sqrt(1+3x^2))
# 2: x = gamma - 2x/sqrt(1+3x^2)
# 3: x = sqrt(1+3x^2)(gamma-x)/2
gamma = (5*D/L - 1)/2;
# Setter startverdi for x: x0 = 0.5;
x0=0.5
# Setter max tillatt feil i x lik 1e-6
# og max antall iterasjoner lik 100
max_error=1e-6
max_iter=100
# Løser x=f(x) numerisk
# Setter startverdi for feilen lik 1.0 
# slik at while-lokken garantert starter
error = 1.0
j = 0
while error > max_error and j < max_iter:
	x1=gamma/(1+2/np.sqrt(1+3*x0*x0))
	error = np.abs(x1-x0)
	x0 = x1
	j = j+1
    
# Gi beskjed dersom vi har brukt opp max antall iterasjoner
# uten at feilen har blitt mindre enn max_error
if j == max_iter:
	print('Max antall iterasjoner brukt opp.\n')
else:
	print('Løsning funnet: x=',x0,'etter',j,'iterasjoner')

alpha = np.arccos(x0)
print('Vinkelen alpha er %3.2f grader' % (alpha*180/np.pi))

# Vi kan naa bestemme vinkelen beta, samt de 3 snordragene i enheter av mg:
beta = np.arctan(np.tan(alpha)/2)
S1 = 2/np.sqrt(1-x0*x0)
S2 = np.sqrt((1+3*x0*x0)/(1-x0*x0))
S3 = 2*x0/np.sqrt(1-x0*x0)
print('Vinkelen beta er %3.2f grader' % (beta*180/np.pi))
print('Snordragene er')
print('S1 = %3.2f mg' % (S1))
print('S2 = %3.2f mg' % (S2))
print('S3 = %3.2f mg' % (S3))

