A Pen by Jaegyeom Kim on CodePen.
Created
August 15, 2021 10:33
-
-
Save CMaybe/d4fedc5e28ad07656f44ce84f3eefd14 to your computer and use it in GitHub Desktop.
Curve Fitting
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let theta = 0.0; // Start angle at 0 | |
let dx=0.0001; // Value for incrementing x | |
let noise = []; | |
let t= []; | |
let y = []; | |
let weight = []; | |
let regulated_weight = []; | |
let target = []; | |
let diff = []; | |
let N = 0; // size of point | |
let M = 0; // size of weight | |
let C = 0; // const of eq | |
let error = 0; | |
let lambda = 0; | |
function setup() { | |
createCanvas(600, 500); | |
noiseSlider = createSlider(1, 100,50,1); | |
noiseSlider.position(0,height+10); | |
noiseSlider.input(ChangeNoise); | |
noiseButton = createButton('make noise'); | |
noiseButton.mousePressed(MakeNoise); | |
noiseButton.position(noiseSlider.x + noiseSlider.width,noiseSlider.y) | |
noiseDisplayer = createP() | |
noiseDisplayer.position(noiseSlider.x,noiseSlider.y); | |
N = noiseSlider.value(); | |
noiseDisplayer.html('N = '+noiseSlider.value()); | |
fittingSlider = createSlider(1, 10,5,1); | |
fittingSlider.input(ChangeFitting); | |
M = fittingSlider.value(); | |
fittingSlider.position(noiseButton.x + noiseButton.width,noiseButton.y); | |
fittingButton = createButton('Fitting'); | |
fittingButton.position(fittingSlider.x + fittingSlider.width,fittingSlider.y) | |
fittingButton.mousePressed(Fitting); | |
fittingDisplayer = createP(); | |
fittingDisplayer.position(fittingSlider.x,fittingSlider.y); | |
fittingDisplayer.html('M = '+fittingSlider.value()); | |
regularizationSlider = createSlider(-30, 0,-15,1); | |
regularizationSlider.input(ChangeLambda); | |
lambda = regularizationSlider.value(); | |
regularizationSlider.position(fittingButton.x + fittingButton.width,fittingButton.y); | |
regularizationButton = createButton('regularization'); | |
regularizationButton.position(regularizationSlider.x +regularizationSlider.width,regularizationSlider.y) | |
regularizationButton.mousePressed(RegularizationFitting); | |
regularizationDisplayer = createP(); | |
regularizationDisplayer.position(regularizationSlider.x,regularizationSlider.y); | |
regularizationDisplayer.html('ln(Lambda) = '+regularizationSlider.value()); | |
} | |
function draw() { | |
background(0); | |
translate(50,height/2); | |
calcWave(); | |
drawNoise(); | |
drawFitting(); | |
drawRegulatedFitting(); | |
} | |
function drawNoise(){ | |
strokeWeight(3); | |
stroke(0,120,0); | |
noFill(); | |
for (let v of noise) { | |
ellipse(v.x * 500,v.y * 150,10); | |
} | |
} | |
function drawFitting(){ | |
let x = 0; | |
strokeWeight(3); | |
stroke(255,0,0); | |
beginShape(); | |
noFill(); | |
while (x<=1) { | |
let y = 0; | |
for(let i =0;i<=M;i++){ | |
y+= weight[i]*pow(x,i); | |
} | |
vertex(x*500, 150*y); | |
x += dx; | |
} | |
endShape(); | |
} | |
function drawRegulatedFitting(){ | |
let x = 0; | |
strokeWeight(3); | |
stroke(255,100,100); | |
beginShape(); | |
noFill(); | |
while (x<=1) { | |
let y = 0; | |
for(let i =0;i<=M;i++){ | |
y+= regulated_weight[i]*pow(x,i); | |
} | |
vertex(x*500, 150*y); | |
x += dx; | |
} | |
endShape(); | |
} | |
function calcWave() { | |
let x = 0; | |
strokeWeight(3); | |
stroke(255); | |
beginShape(); | |
noFill(); | |
while (x<=1) { | |
vertex(x*500, 150*sin(2*PI*x)); | |
x += dx; | |
} | |
endShape(); | |
} | |
function MakeNoise() { | |
noise = []; | |
target=[]; | |
N = noiseSlider.value(); | |
for(let i =0;i<=N;i++){ | |
x = i/N; | |
let t = createVector(x,sin(2*PI*x) + random(-0.4,0.4)); | |
noise.push(t); | |
target.push(t.y); | |
} | |
} | |
function Fitting() { | |
M = fittingSlider.value() | |
error=0; | |
let X=[]; | |
for(let i =0;i<=N;i++){ | |
x = i/N; | |
let temp = []; | |
for(let j = 0;j<=M;j++){ | |
temp.push(pow(x,j)); | |
} | |
X.push(temp); | |
} | |
weight = math.multiply(math.multiply(math.inv(math.multiply(math.transpose(X),X)),math.transpose(X)),target) | |
} | |
function RegularizationFitting() { | |
M = fittingSlider.value() | |
lambda = Math.pow(Math.E,regularizationSlider.value()) | |
let X=[]; | |
for(let i =0;i<=N;i++){ | |
x = i/N; | |
let temp = []; | |
for(let j = 0;j<=M;j++){ | |
temp.push(pow(x,j)); | |
} | |
X.push(temp); | |
} | |
Lambda = math.multiply(math.identity(M+1),lambda); | |
regulated_weight = math.multiply(math.multiply(math.inv(math.add(math.multiply(math.transpose(X),X),Lambda)),math.transpose(X)),target)["_data"]; | |
} | |
function ChangeFitting(){ | |
fittingDisplayer.html('M = '+fittingSlider.value()); | |
} | |
function ChangeNoise(){ | |
noiseDisplayer.html('N = '+noiseSlider.value()); | |
} | |
function ChangeLambda(){ | |
regularizationDisplayer.html('ln(Lambda) = '+regularizationSlider.value()); | |
} | |
function normalDistribution(x,simga,mu){ | |
let result = 1/math.sqrt(2*math.PI*(sigma*sigma))* | |
math.pow(math.E,(-1/(2*sigma*sigma)*(x-mu)*(x-mu))) | |
return result; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjs/9.4.4/math.js"></script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment