Skip to content

Commit cd40ce6

Browse files
committed
Initial and only commit :)
1 parent b585f24 commit cd40ce6

File tree

2 files changed

+159
-0
lines changed

2 files changed

+159
-0
lines changed

index.ts

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
// Calculus Bisection Class Project
2+
// Author: Nicholas Assaderaghi (FlyN Nick)
3+
// Why did I write this in TypeScript: I felt like it :)
4+
5+
/**
6+
* Bisection function.
7+
* Finds the root of a function within given range.
8+
*
9+
* Things that may cause this to be unsuccessfull/error:
10+
* #1: Root is not within given range.
11+
* #2: Function changes signs more than once within given range.
12+
* #3: The given minimum is greater than the given maximum.
13+
* #4: There are x within given range where f(x) is undefined.
14+
*
15+
* @param {(x: number) => any} func - function you want to find the root of.
16+
* @param {number} givenMin - min of given range.
17+
* @param {number} givenMax - max of given range.
18+
* @param {bool} annoyingConsoleLogs - (optional) really annoying console log ever iteration.
19+
* @param {number} maxIter - (optional) max number of iterations
20+
*/
21+
function bisection(func: (x: number) => number, givenMin: number, givenMax: number, maxIter=100, annoyingConsoleLogs=false): number | [number, number] | "ERROR"
22+
{
23+
let posSlope = true;
24+
let min = givenMin;
25+
let max = givenMax;
26+
let iter = 0;
27+
28+
console.log("---------------------------------------------------------------");
29+
30+
if (givenMin > givenMax)
31+
{
32+
console.log("You seem to have mixed the min and max...");
33+
return "ERROR";
34+
}
35+
else if (givenMin == givenMax)
36+
{
37+
console.log("The min and max given were the same...");
38+
return "ERROR";
39+
}
40+
41+
if (func(min) > func(min+max/2)) { posSlope = false; }
42+
43+
while (iter != maxIter)
44+
{
45+
iter++;
46+
let guess = (min+max)/2;
47+
48+
if ((func(guess) < 0 && posSlope) || (func(guess) > 0 && !posSlope))
49+
{
50+
if (guess == min)
51+
{
52+
console.log(`Stopped at iteration #${iter}`);
53+
console.log(`Root not found.\nRange: (${min}, ${max}).`);
54+
return [min, max];
55+
}
56+
min = guess;
57+
}
58+
else if ((func(guess) > 0 && posSlope) || (func(guess) < 0 && !posSlope))
59+
{
60+
if (guess == max)
61+
{
62+
console.log(`Stopped at iteration #${iter}`);
63+
console.log(`Root not found.\nRange: (${min}, ${max}).`);
64+
return [min, max];
65+
}
66+
max = guess;
67+
}
68+
else
69+
{
70+
console.log(`Root: ${guess}.\nIterations it took: ${iter}.`);
71+
return guess;
72+
}
73+
if (annoyingConsoleLogs)
74+
{
75+
console.log(`Iteration #${iter}:\n\tCurrent range: (${min}, ${max})`);
76+
}
77+
}
78+
79+
console.log(`Root not found (maximum iterations reached).\nRange: (${min}, ${max}).`);
80+
81+
console.log("Remember, this algorithm will only work if:\n\t#1: The root is within the range.\n\t#2: The function changes sign once within the interval.");
82+
83+
return [min, max];
84+
}
85+
86+
/**
87+
* Just testing if everything generally works.
88+
* This is not an in-depth test (does not test all error scenarios).
89+
*/
90+
function testBisectionFunction()
91+
{
92+
console.log("TESTING BISECTION FUNCTION!");
93+
/** Test linear function: (2x -19). */
94+
const linFunc = (x: number) => { return 2*x-19; }
95+
96+
/** Test polynomial function: (x^2 + x - 5). */
97+
const polyFunc = (x: number) => { return x**2+x-5; }
98+
99+
/** First test trigonometric function: sin(1/x). */
100+
const trigFuncOne = (x: number) => { return Math.sin(1/x); }
101+
102+
/** Second test trigonometric function: sin(x)/x. */
103+
const trigFuncTwo = (x: number) => { return Math.sin(x)/x; }
104+
105+
const returnedVals: (number | [number, number] | "ERROR")[] =
106+
[
107+
bisection(linFunc, 100, -100),
108+
bisection(linFunc, -100, 100),
109+
bisection(polyFunc, 0, 21),
110+
bisection(trigFuncOne, 0.212, 0.637, 100000),
111+
bisection(trigFuncTwo, 0.1, 4.25, 1000/*, true*/) // those console logs really are annoying...
112+
]
113+
114+
console.log("---------------------------------------------------------------");
115+
console.log(`\nReturned values from bisection function:\n[`);
116+
117+
// should I have just used a regular for loop: yes.
118+
let len = returnedVals.length;
119+
let i = 0;
120+
for (const returnedVal of returnedVals)
121+
{
122+
i++;
123+
let toPrint;
124+
switch (typeof returnedVal)
125+
{
126+
case 'string':
127+
toPrint = `\t"${returnedVal}"`;
128+
break;
129+
case 'number':
130+
toPrint = `\t${returnedVal}`;
131+
break;
132+
default:
133+
toPrint = `\t[${returnedVal[0]}, ${returnedVal[1]}]`;
134+
}
135+
if (i != len) { toPrint += ','; }
136+
console.log(toPrint);
137+
}
138+
139+
console.log(`]`);
140+
}
141+
142+
testBisectionFunction();

tsconfig.json

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"compilerOptions":
3+
{
4+
"target": "es6",
5+
"lib": ["esnext", "dom"],
6+
"module": "commonjs",
7+
"moduleResolution": "node",
8+
"strict": true,
9+
"jsx": "react",
10+
"allowJs": false,
11+
"sourceMap": true,
12+
"inlineSources": true,
13+
"types": ["node"],
14+
"allowSyntheticDefaultImports": true,
15+
"experimentalDecorators": true
16+
}
17+
}

0 commit comments

Comments
 (0)