├── .gitignore ├── Makefile ├── README.md ├── notebook └── scipy.optimize.ipynb ├── package.json ├── public ├── assets │ ├── data │ │ ├── Sigma.json │ │ ├── U.json │ │ ├── Urosen.json │ │ ├── Uval.json │ │ └── matrix.json │ ├── eigenfeatures.js │ ├── eigensum.js │ ├── flow.js │ ├── graph.js │ ├── images │ │ ├── levelsets1.png │ │ └── levelsets2.png │ ├── index.html │ ├── iterates.js │ ├── lib │ │ ├── auto-render.min.js │ │ ├── bfgs.js │ │ ├── contour_plot.js │ │ ├── contrib │ │ │ └── auto-render.min.js │ │ ├── d3-ring-note.js │ │ ├── fonts │ │ │ ├── KaTeX_AMS-Regular.eot │ │ │ ├── KaTeX_AMS-Regular.ttf │ │ │ ├── KaTeX_AMS-Regular.woff │ │ │ ├── KaTeX_AMS-Regular.woff2 │ │ │ ├── KaTeX_Caligraphic-Bold.eot │ │ │ ├── KaTeX_Caligraphic-Bold.ttf │ │ │ ├── KaTeX_Caligraphic-Bold.woff │ │ │ ├── KaTeX_Caligraphic-Bold.woff2 │ │ │ ├── KaTeX_Caligraphic-Regular.eot │ │ │ ├── KaTeX_Caligraphic-Regular.ttf │ │ │ ├── KaTeX_Caligraphic-Regular.woff │ │ │ ├── KaTeX_Caligraphic-Regular.woff2 │ │ │ ├── KaTeX_Fraktur-Bold.eot │ │ │ ├── KaTeX_Fraktur-Bold.ttf │ │ │ ├── KaTeX_Fraktur-Bold.woff │ │ │ ├── KaTeX_Fraktur-Bold.woff2 │ │ │ ├── KaTeX_Fraktur-Regular.eot │ │ │ ├── KaTeX_Fraktur-Regular.ttf │ │ │ ├── KaTeX_Fraktur-Regular.woff │ │ │ ├── KaTeX_Fraktur-Regular.woff2 │ │ │ ├── KaTeX_Main-Bold.eot │ │ │ ├── KaTeX_Main-Bold.ttf │ │ │ ├── KaTeX_Main-Bold.woff │ │ │ ├── KaTeX_Main-Bold.woff2 │ │ │ ├── KaTeX_Main-Italic.eot │ │ │ ├── KaTeX_Main-Italic.ttf │ │ │ ├── KaTeX_Main-Italic.woff │ │ │ ├── KaTeX_Main-Italic.woff2 │ │ │ ├── KaTeX_Main-Regular.eot │ │ │ ├── KaTeX_Main-Regular.ttf │ │ │ ├── KaTeX_Main-Regular.woff │ │ │ ├── KaTeX_Main-Regular.woff2 │ │ │ ├── KaTeX_Math-BoldItalic.eot │ │ │ ├── KaTeX_Math-BoldItalic.ttf │ │ │ ├── KaTeX_Math-BoldItalic.woff │ │ │ ├── KaTeX_Math-BoldItalic.woff2 │ │ │ ├── KaTeX_Math-Italic.eot │ │ │ ├── KaTeX_Math-Italic.ttf │ │ │ ├── KaTeX_Math-Italic.woff │ │ │ ├── KaTeX_Math-Italic.woff2 │ │ │ ├── KaTeX_Math-Regular.eot │ │ │ ├── KaTeX_Math-Regular.ttf │ │ │ ├── KaTeX_Math-Regular.woff │ │ │ ├── KaTeX_Math-Regular.woff2 │ │ │ ├── KaTeX_SansSerif-Bold.eot │ │ │ ├── KaTeX_SansSerif-Bold.ttf │ │ │ ├── KaTeX_SansSerif-Bold.woff │ │ │ ├── KaTeX_SansSerif-Bold.woff2 │ │ │ ├── KaTeX_SansSerif-Italic.eot │ │ │ ├── KaTeX_SansSerif-Italic.ttf │ │ │ ├── KaTeX_SansSerif-Italic.woff │ │ │ ├── KaTeX_SansSerif-Italic.woff2 │ │ │ ├── KaTeX_SansSerif-Regular.eot │ │ │ ├── KaTeX_SansSerif-Regular.ttf │ │ │ ├── KaTeX_SansSerif-Regular.woff │ │ │ ├── KaTeX_SansSerif-Regular.woff2 │ │ │ ├── KaTeX_Script-Regular.eot │ │ │ ├── KaTeX_Script-Regular.ttf │ │ │ ├── KaTeX_Script-Regular.woff │ │ │ ├── KaTeX_Script-Regular.woff2 │ │ │ ├── KaTeX_Size1-Regular.eot │ │ │ ├── KaTeX_Size1-Regular.ttf │ │ │ ├── KaTeX_Size1-Regular.woff │ │ │ ├── KaTeX_Size1-Regular.woff2 │ │ │ ├── KaTeX_Size2-Regular.eot │ │ │ ├── KaTeX_Size2-Regular.ttf │ │ │ ├── KaTeX_Size2-Regular.woff │ │ │ ├── KaTeX_Size2-Regular.woff2 │ │ │ ├── KaTeX_Size3-Regular.eot │ │ │ ├── KaTeX_Size3-Regular.ttf │ │ │ ├── KaTeX_Size3-Regular.woff │ │ │ ├── KaTeX_Size3-Regular.woff2 │ │ │ ├── KaTeX_Size4-Regular.eot │ │ │ ├── KaTeX_Size4-Regular.ttf │ │ │ ├── KaTeX_Size4-Regular.woff │ │ │ ├── KaTeX_Size4-Regular.woff2 │ │ │ ├── KaTeX_Typewriter-Regular.eot │ │ │ ├── KaTeX_Typewriter-Regular.ttf │ │ │ ├── KaTeX_Typewriter-Regular.woff │ │ │ └── KaTeX_Typewriter-Regular.woff2 │ │ ├── katex.css │ │ ├── katex.js │ │ ├── katex.min.css │ │ ├── katex.min.js │ │ ├── lib.js │ │ └── template.v1.js │ ├── milestones.js │ ├── momentum.js │ ├── numjs.js │ ├── phasediagram.js │ ├── phasediagram_description.js │ ├── poly.js │ ├── stochastic_milestones.js │ ├── utils.js │ └── widgets.css ├── gradient_descent.html ├── index.html ├── introduction.html ├── newton.html ├── quasi_newton.html ├── scipy.optimize.html ├── stochastic_gradient.html └── surrogate.html └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.log -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | 2 | 3 | s3_upload: 4 | aws s3 sync --region eu-west-1 --acl public-read public s3://fa.bianp.net/teaching/2018/eecs227at/ 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Overview of optimization algorithms 2 | 3 | http://fa.bianp.net/teaching/2018/eecs227at/ 4 | 5 | run `npm install` to install dependencies. 6 | 7 | run `npm run build` to concat those dependencies into a lib file. 8 | 9 | `npm run serve` will run a server so you can preview the ajax calls. 10 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "scripts": { 3 | "build": "cat node_modules/d3/build/d3.min.js node_modules/numeric/numeric-1.2.6.min.js node_modules/d3-swoopy-drag/swoopy-drag.js node_modules/d3-tip/index.js > public/assets/lib/lib.js", 4 | "serve": "python3 -m http.server 8001", 5 | "cache-template": "curl http://distill.pub/template.v1.js > public/assets/lib/template.v1.js" 6 | }, 7 | "dependencies": { 8 | "d3": "^4.7.1", 9 | "d3-swoopy-drag": "^0.0.3", 10 | "d3-tip": "^0.7.1", 11 | "distill-template": "^1.0.1", 12 | "numeric": "^1.2.6" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /public/assets/data/Sigma.json: -------------------------------------------------------------------------------- 1 | [5.1092745973688506e-5,0.00042845503744989096,0.0010105650129318066,0.0014680502962768332,0.021102816317430294,0.023620693472746652,0.026948729512678436,0.03851785759575888,0.03853250419531349,0.03860694006453175,0.03860694006468644,0.038687205706877344,0.04140947207865848,0.04552175217820313,0.04880418604478542,0.07703382297102701,0.07706256243856262,0.07720835555162749,0.07720835555199344,0.09887604117513601,0.1026948844914457,0.10689212957099727,0.1522409349774262,0.15224093497742677,0.15224093497742716,0.15224093497742777,0.15260424411385212,0.15615327549604915,0.16342851172717826,0.1726993269477357,0.1841806074455186,0.19083600421875027,0.1908638876299017,0.19100146964629874,0.19100146964689638,0.1939227490347833,0.20321293131835208,0.20999798526917268,0.2514393050792103,0.2593154572333739,0.267990744563858,0.3094963514226793,0.3138373757817931,0.32363751730489604,0.3331668802771941,0.3374838632663561,0.337770385989691,0.33790553662353273,0.3385312443107496,0.3385312443163762,0.35328277825507454,0.3554772799512604,0.35670165035846163,0.37549021458844833,0.37549021458844856,0.3754902145884486,0.37549021458844933,0.37712031168332427,0.37739386913702905,0.3787198576063582,0.3787198576218005,0.439058332677571,0.44735487336127255,0.4586613457831825,0.4907088291492569,0.4909514437626649,0.4921025615748709,0.49210256159995996,0.500765557632366,0.5064994227965264,0.5215998924838611,0.5343907966292943,0.5857864376269034,0.5857864376269047,0.585786437626906,0.5857864376269061,0.5861722584190509,0.590468444764028,0.5986511896588259,0.608309221494794,0.6183301860577991,0.6243504498002237,0.624376515970503,0.6244931207159342,0.6244931207212939,0.6301018521608721,0.643173677592987,0.6572175955584028,0.6753950987094531,0.6756252795609305,0.6766577819064032,0.6766577819723264,0.6873887543116216,0.7077604745231686,0.7332560954395942,0.7380273726043314,0.7380273726043315,0.7380273726043323,0.7380273726043325,0.772766220561986,0.7908522794813367,0.8228830201707171,0.8526582589167938,0.889128861006339,0.8904007062260878,0.8907502234015025,0.8920543602902318,0.8920543605940385,0.8946465089572883,0.8967473130506038,0.8972959062686872,0.9175811154736325,0.9234423338349309,0.9238751422431225,0.9252326000646816,0.9252326003963469,0.9272889731543336,0.9272889731543341,0.927288973154335,0.9272889731543357,0.9299479030560198,0.9314788674149754,0.9319365457980867,0.9344197778066098,0.9344197788133801,0.9473141548015536,0.95836559701548,1.00904397532488,1.01429057818481,1.025276893823247,1.0444772276192678,1.0451283204248976,1.0478741330866757,1.0478741353522585,1.0644167928689492,1.0749585120567333,1.1044503694502097,1.129746247304068,1.1793560429291652,1.1842618728393972,1.191462000130946,1.1948959933333632,1.2259203093557034,1.2259203093557043,1.2259203093557045,1.2259203093557052,1.2298512450303516,1.2306570759848314,1.2337605850414142,1.2337605963783165,1.2346331352698197,1.2346331352698199,1.2346331352698203,1.2346331352698205,1.2349566509141696,1.2391057744900738,1.2486312052789066,1.2608145690374846,1.2675095555104197,1.2731652181964364,1.2731819999005698,1.2732508247623213,1.273250825142681,1.2860332912059607,1.29770296659939,1.3088303323599835,1.3411181752068755,1.356658716994277,1.3771820291536572,1.3868740702472466,1.3868740702472475,1.386874070247248,1.3868740702472486,1.4286530459400766,1.4354485997669204,1.4700326893679252,1.4770005686253076,1.4775493395676553,1.4792937072646977,1.4792937727503266,1.4853857654118394,1.4913823560553345,1.5155646486569867,1.5220128235986423,1.5378450113653668,1.5723290893817332,1.5725007135983375,1.5729712135857434,1.5729712629003674,1.577661197723883,1.5882552851652993,1.5943041017850168,1.5957674474366947,1.6100209395622178,1.611938033705024,1.6126839969429347,1.6146748609616057,1.6146752150548884,1.6176374074446545,1.6376873585723004,1.6482487951612825,1.648248795161283,1.6482487951612836,1.648248795161285,1.653000802311688,1.6540768023158026,1.655832191708458,1.6572087768311117,1.6572098626811385,1.7259399248346303,1.7272623251627965,1.7280303701020152,1.765611250245197,1.767014501440868,1.7701527070343506,1.7701584387545404,1.7780624470928508,1.7799878438195118,1.7802691097268835,1.7812311860751873,1.781234176169022,1.7823068394270232,1.8154027570508833,1.8204195728967243,1.8204195728967252,1.8204195728967258,1.8204195728967265,1.8386966506548006,1.8602444088464711,1.8892772117051293,1.9040767847266,1.9129445653344364,1.9468801313626525,1.9468801313626534,1.9468801313626538,1.946880131362654,1.9493231080653617,1.9505693766993495,1.951604322151037,1.9518370622887948,1.9999999999999993,2.0000000000000004,2.0000000000000013,2.0000000000000018,2.0002411720000177,2.0035716280487703,2.012085314068996,2.024618546576087,2.0300545063209916,2.0312346996960815,2.032224933184192,2.03249178159006,2.0384327253393937,2.038494876977998,2.038596871450004,2.0386666874007506,2.0500953218007845,2.0577831223412613,2.06198111501648,2.093819383359219,2.096208609127018,2.0993805863242607,2.1078215529859174,2.1121063051218942,2.118061739029673,2.1243209197014705,2.1292915204982497,2.1326726467369057,2.133397296079361,2.1344875274730017,2.136548936747832,2.152240934977425,2.152240934977426,2.1522409349774265,2.1522409349774283,2.154267391201858,2.161714864615217,2.181122296206846,2.184200544922955,2.191956706013691,2.195105133956426,2.199791547786336,2.2039064409573483,2.2237239027028783,2.2284013113337413,2.231498222337411,2.2657245766907783,2.2705027610157096,2.274845054563588,2.276076517276884,2.283764593737386,2.296087739465777,2.337084503218554,2.3373814562997377,2.3380502163796972,2.338778333522534,2.345436677622608,2.353133105788483,2.365545138597086,2.370792169736657,2.385467394671433,2.3876985027936612,2.3903076440726028,2.391864635412639,2.3935646835189117,2.39782609416918,2.4056366470995587,2.411113187075662,2.4221394375712477,2.4263751502486204,2.428610083225795,2.428610083225796,2.428610083225796,2.428610083225798,2.4332621220716546,2.4404295147376636,2.4505959494042315,2.4695497274183986,2.4697792920735027,2.470048939189045,2.4703003772204553,2.4850276050518647,2.4951694322710827,2.4986788899285375,2.4986788899285384,2.498678889928539,2.4986788899285406,2.5048302468645147,2.508085821710054,2.511268568103075,2.5173916485191716,2.5198093529101855,2.5228756152030334,2.5335873044141706,2.5471172988994444,2.555902546876282,2.5585691435188265,2.5607806673550604,2.5718503174567244,2.579597800408132,2.5857864376268997,2.585786437626903,2.5857864376269037,2.585786437626905,2.589572806022223,2.6097176674974816,2.6345773971521993,2.6591244011569453,2.680321995148641,2.6930437174944464,2.6938867242628715,2.7021837695357145,2.7164569841965727,2.727241419427163,2.7272414194271652,2.7272414194271657,2.727241419427168,2.7408498638753995,2.7546760231135567,2.7653668647301792,2.7653668647301792,2.7653668647301806,2.765366864730182,2.765524050447629,2.7680350961733065,2.7754823510081605,2.775742854405896,2.7887091454767354,2.793673943379943,2.7964251212377262,2.8038370325276842,2.8039424977904477,2.8039599104006867,2.803963477690072,2.8138954756592764,2.8153040592396965,2.8156720524635683,2.827711716200323,2.8382325909601853,2.8468292841079226,2.8496489436148686,2.852784813433434,2.8544193556892643,2.857170392411228,2.862950372234442,2.869112710382204,2.8708412408457504,2.871468035503805,2.888929997823039,2.8901175074229983,2.892509419385317,2.8945429122933475,2.9011497009984617,2.904119333088131,2.917607799707604,2.9176077997076058,2.9176077997076066,2.9176077997076075,2.932698789628368,2.940312393690019,2.955302192223339,2.9572800617592776,2.9600449346024384,2.967294695516258,2.9793765124766676,2.9841815562541196,2.992295471729006,2.9970175105963293,3.006908335750046,3.020958849384216,3.03432774014087,3.0434833767132834,3.0452301526635606,3.047116001510474,3.048101887260143,3.1026699195051526,3.102706976842689,3.102826406306491,3.102895656928137,3.104127968533318,3.107245967085906,3.108474148361632,3.1086804096039993,3.1112166751488615,3.115948020773003,3.116528115071774,3.118399579661089,3.126538011905335,3.135120238967006,3.1365511575979776,3.149569905232741,3.1495699052327426,3.1495699052327435,3.149569905232748,3.1598296533772405,3.162808874413154,3.1652593140348637,3.174047248672015,3.1791333903895604,3.1805937498775516,3.209541006065686,3.220600156396794,3.221874408476921,3.2254170565234292,3.2260689366842867,3.229753886694249,3.23463313526982,3.2346331352698203,3.234633135269822,3.234633135269826,3.255330328384785,3.2570272200871044,3.2578296170925163,3.2616750208092515,3.267108417656038,3.274142201686546,3.277071632565163,3.279040177993051,3.279040177993052,3.279040177993054,3.279040177993055,3.2826254102565415,3.2863127681212982,3.291777591966026,3.302642990012206,3.306310325389802,3.3087249808835555,3.3105809417683445,3.3150467952227753,3.3328469948661166,3.3511533023570834,3.3511533023570856,3.351153302357087,3.3511533023570887,3.3736988493639335,3.3779933207113104,3.38372381425796,3.3844919446728534,3.393263150780544,3.396293846427974,3.4000468142355587,3.4142135623730936,3.414213562373096,3.4142135623730985,3.414213562373102,3.4143036926804315,3.417685867720631,3.429741490995779,3.444459779908849,3.4467843070954585,3.4482012414341088,3.4482012414341137,3.448201241434114,3.448201241434116,3.452632112375997,3.4526513028370194,3.452694842683425,3.452729632424849,3.465583234611795,3.4697579206079583,3.4729795101399135,3.47626268917304,3.4838608375682467,3.4893761678244375,3.5059062704152253,3.5067793300287287,3.5168071887221375,3.523178073493411,3.566454497350518,3.566454497350519,3.5664544973505206,3.566454497350523,3.5786252269588252,3.5812402320716425,3.6099302389320123,3.611057599777946,3.6121623704218675,3.612634704003484,3.6137563957284087,3.6155963739285233,3.6157896283006887,3.6167340310829497,3.6191111302203653,3.6230173590345967,3.6263491592247905,3.6310832202221177,3.6312138814488826,3.6341969104922187,3.6361136859106167,3.6416623359527427,3.642676681718375,3.647805013600926,3.6502975657417727,3.6526229957886,3.6546050505842915,3.6550511195334003,3.656330923099721,3.6571528302796708,3.6573722951691914,3.661434999061722,3.661796399586571,3.661828208418727,3.661988390770088,3.6629724095737637,3.67245536020594,3.675311622290963,3.6799549472644784,3.6820643566204794,3.683689265470823,3.683885122875622,3.683925268941622,3.6900320366461714,3.6988254786455386,3.701368663798625,3.7013686637986254,3.701368663798629,3.7013686637986303,3.703829841103989,3.705650631970268,3.727038583036773,3.734583239818677,3.7352183604721594,3.736875029818916,3.739597188354314,3.740646343402732,3.7413232722111474,3.7445679331365826,3.750331741707456,3.7512048498412747,3.751862547704211,3.752184589213833,3.766297102848727,3.7722442160425462,3.781006646325294,3.786579289024283,3.789644662726383,3.8009624362017176,3.803485230427637,3.8241127345688195,3.825733335610649,3.840105762142252,3.8405935870758743,3.8448122913900886,3.8466435100572927,3.847759065022572,3.8477590650225726,3.847759065022574,3.847759065022579,3.847787997860114,3.8541125973423176,3.8575467071219323,3.8686206874060374,3.86883794831308,3.8749137337260797,3.8795862961033447,3.8807125457805345,3.8844283437609635,3.886196500428559,3.8861992827717557,3.8862297686191813,3.886700306569959,3.894555752530102,3.895660309833761,3.941427251934513,3.952919159329166,3.961572981790942,3.9616073396622014,3.961750219883238,3.962453861282883,3.9635473972700677,3.964737703220327,3.967308458946766,3.9723444265876693,3.9826598722388473,3.99266059031374,3.997925055313101,3.9999999999999907,3.999999999999991,3.999999999999992,3.9999999999999947,3.999999999999995,3.999999999999995,3.999999999999996,3.999999999999997,3.999999999999997,3.9999999999999973,3.9999999999999973,3.999999999999998,3.999999999999998,3.9999999999999987,3.9999999999999987,3.999999999999999,3.999999999999999,3.999999999999999,3.999999999999999,3.999999999999999,3.9999999999999996,3.9999999999999996,3.9999999999999996,3.9999999999999996,4.0,4.0,4.0,4.0,4.0,4.0,4.0,4.000000000000001,4.000000000000001,4.000000000000001,4.000000000000001,4.000000000000001,4.000000000000001,4.000000000000001,4.000000000000001,4.000000000000002,4.000000000000002,4.000000000000002,4.000000000000002,4.000000000000002,4.000000000000002,4.000000000000003,4.0000000000000036,4.000000000000004,4.000000000000005,4.000000000000005,4.000000000000005,4.000000000000006,4.001146755279631,4.026309972250407,4.053125406877162,4.086549164806044,4.09283278866238,4.108424663702197,4.10938310816454,4.115827462064289,4.115832612165395,4.127259725896701,4.128802817067982,4.155775793719407,4.15796368170977,4.159048343340735,4.1838713061357735,4.184667236245215,4.184935634089127,4.185027808397086,4.18977540257893,4.189777683986853,4.190455113196096,4.190507066092326,4.1905173471841115,4.198720914055915,4.210027334215417,4.21626308277052,4.216330096086353,4.255542937813145,4.255554254623679,4.256347434929313,4.256348392618572,4.265886161188622,4.2687207971099275,4.283077781001367,4.291023350483904,4.298631336201366,4.298631336201368,4.29863133620137,4.298631336201371,4.302902542782346,4.303321457387401,4.304688077784849,4.306052726560006,4.310986345142569,4.311030615090402,4.3124915646984405,4.312491974892225,4.320230477378649,4.323706483630491,4.339395976814695,4.349676162932122,4.353980857392538,4.354044249278762,4.354225273111101,4.355450259783386,4.355450420850032,4.367456357609939,4.36923856339447,4.373392707421158,4.376096911507799,4.381761679460227,4.3820047528408725,4.382044955570956,4.382351382445996,4.382684698969514,4.382684738444394,4.384966213685538,4.3904137937985395,4.421353145566253,4.422581186062072,4.4228430776619545,4.4335455026494754,4.433545502649479,4.433545502649481,4.4335455026494826,4.441142419875306,4.4472483267874,4.447248705372408,4.4551282190007875,4.461288828738311,4.461780532118279,4.496246023987594,4.499573058987688,4.501108121372629,4.501109694772713,4.501979850799055,4.548354578913563,4.548424634304511,4.549745582960597,4.55179875856588,4.5517987585658854,4.551798758565887,4.5517987585658926,4.552222548491558,4.552222680358013,4.554955350161118,4.603485828211576,4.610968996618181,4.623763495719387,4.648846697642913,4.648846697642914,4.648846697642915,4.648846697642917,4.6494847284258,4.6660676564227,4.666373837463469,4.6744190310211,4.674419078416317,4.674463615912293,4.702783765347471,4.720959822006944,4.7209598220069475,4.720959822006949,4.720959822006951,4.730857851714661,4.735603712444384,4.736542734988181,4.736732267173744,4.736791895483509,4.738174907614364,4.738376796467692,4.742577261046455,4.742577272422044,4.74997960596166,4.754156063489584,4.755453400138305,4.7653668647301775,4.7653668647301775,4.765366864730179,4.765366864730181,4.778542500860738,4.78572274303522,4.796489745923113,4.797837684288099,4.798968046735827,4.802129494619787,4.825964527164404,4.830652582404736,4.832182101804276,4.832182160584097,4.83980318134973,4.850430094767256,4.850430094767256,4.850430094767256,4.8504300947672565,4.87930762952478,4.884256618709575,4.90351429415646,4.90359403929012,4.906341573456081,4.906341577080933,4.953776458381384,4.95838455047661,4.966907440044499,4.999771810844948,5.016803382923014,5.025224587751226,5.0271890082387785,5.030443805318355,5.030655452349666,5.0352241848543775,5.035224186431651,5.036509354026931,5.043569145495655,5.0647116405050765,5.0823922002923885,5.082392200292389,5.082392200292395,5.082392200292397,5.085671566980964,5.085947025086998,5.0917215135935985,5.091721514899855,5.11137144334125,5.119651658820683,5.119806676485098,5.1229535140235,5.123449589661316,5.123449590414702,5.130230698055743,5.1323231549848565,5.148348874333285,5.154965435432221,5.163224594966772,5.166004281302907,5.168372562389871,5.168898422647709,5.174069170275883,5.177624524499497,5.182179660102096,5.18217966199495,5.18910267690424,5.197054458257686,5.197109382321388,5.199789868976136,5.199789869653924,5.2421164267128795,5.246671676872988,5.272758580572832,5.272758580572833,5.272758580572834,5.272758580572837,5.319585671782597,5.322043261060471,5.323511066207491,5.376414701910258,5.391336272650865,5.412571330917056,5.414213562373092,5.414213562373095,5.414213562373096,5.414213562373099,5.424203989826462,5.424630846080281,5.4331947119625035,5.433194712214822,5.456218350316131,5.456313622963416,5.456334803041362,5.459530493344062,5.459583491611428,5.459830707150803,5.460975581715541,5.46097558176171,5.463438548245974,5.488483922249765,5.501321110071455,5.50132111007146,5.501321110071461,5.501321110071464,5.512932615088581,5.527339555060685,5.534477907992983,5.535227881418489,5.535439914295797,5.538013530569761,5.538367678960724,5.54626003858765,5.546260038729923,5.571389916774199,5.571389916774204,5.571389916774207,5.57138991677421,5.612939417105189,5.61649144368849,5.644388841072317,5.658079344882134,5.663155625435423,5.665889455854483,5.666001174994955,5.668326281086029,5.668326281107318,5.733732207028532,5.738845066955055,5.749389798752064,5.765380861387947,5.785882988095971,5.804313057167245,5.807939966886105,5.808126113077744,5.811405770301005,5.811405770313711,5.812177803130223,5.820439001162925,5.821013858964124,5.8233122049464665,5.847759065022571,5.847759065022572,5.847759065022573,5.847759065022577,5.850076759298707,5.850216679525735,5.852783471771329,5.852783471779767,5.859137890774689,5.869752298911381,5.881571422842196,5.881778489467804,5.884035682986483,5.886285850218052,5.886285850232995,5.901546840540367,5.903538019667945,5.907578938603218,5.909055864794503,5.961604867371894,5.961899891192753,5.961917653407891,5.962278031185359,5.962278031186162,5.963129809475606,5.965943618883343,6.007632095506816,6.010904754066514,6.053119868637345,6.053119868637346,6.0531198686373475,6.053119868637353,6.125923246266052,6.126005325519488,6.126985357774944,6.12698734653491,6.129812339040711,6.130038492358636,6.17958042710327,6.179580427103273,6.179580427103273,6.179580427103279,6.18496889161597,6.185265908296038,6.190480062352646,6.190480062356394,6.23447870959905,6.23486023832997,6.238937290180354,6.2389773142121046,6.239753300038704,6.2397533000392045,6.244760405402927,6.244763339207707,6.248448793214927,6.248488423483406,6.253079651125132,6.25308519137893,6.351751204838711,6.351751204838715,6.351751204838718,6.351751204838719,6.383033361944482,6.385431432987422,6.4297857581338205,6.429865626250292,6.431201197669278,6.431201197669624,6.458303193796733,6.458305619221877,6.468330304269243,6.468341573944297,6.470523655757692,6.470524173056726,6.527193782745554,6.527303318535823,6.529123300318984,6.529123300319306,6.543579959555116,6.543859488513636,6.555682155935752,6.555682455214924,6.6131259297527505,6.613125929752751,6.613125929752753,6.613125929752759,6.614458848362748,6.614530428890439,6.615724755091229,6.6157247550913825,6.7270999949590085,6.727109630094256,6.7272648293879405,6.7272648293879564,6.744088327185263,6.745850030453501,6.77407969064429,6.774079690644294,6.774079690644294,6.7740796906442995,6.7903120038432405,6.790312079187987,6.813053126623431,6.813185610939153,6.823290831720974,6.823290874042478,6.829580595928171,6.829649698160004,6.830740981444102,6.830740981444162,6.959345584794544,6.959372026960457,6.959781428782669,6.9597814287826845,6.961479786036254,6.961586962080857,6.9643420292302105,6.964342031063403,7.0727110268456626,7.0727110268456626,7.072711026845665,7.07271102684567,7.075368983534183,7.076497600702606,7.077792498106825,7.077832166837388,7.0784355204184966,7.078435520418511,7.101857390568633,7.101857393837108,7.107205399686157,7.107244603354998,7.11314629425194,7.113146298983108,7.261972627395665,7.261972627395668,7.2619726273956715,7.261972627395677,7.262535605527016,7.262571082500508,7.263096497606454,7.263096497606458,7.331098518879747,7.331465318963141,7.339298907009198,7.339298907420172,7.375854312312909,7.37585876633777,7.37592390970383,7.3759239097038325,7.388692883594684,7.389042701314886,7.398484700335615,7.398484700779698,7.510855316470907,7.510865540812093,7.511012243499108,7.51101224349911,7.513495409601994,7.513631491455263,7.516867868214559,7.516867868287587,7.624509785411543,7.624509785411547,7.624509785411551,7.624509785411552,7.631592983873221,7.6318750772246515,7.638262623524698,7.638262623598168,7.6955875715786295,7.695592184972215,7.695656963513606,7.695656963513607,7.809346953377027,7.809348117371073,7.809364269141147,7.809364269141148,7.812012533235054,7.812131065726284,7.814618285067252,7.814618285078553,7.923794261513252,7.92382422385282,7.924430650386926,7.924430650388526] -------------------------------------------------------------------------------- /public/assets/data/matrix.json: -------------------------------------------------------------------------------- 1 | [[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0],[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0],[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0],[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0],[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0],[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0],[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0],[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0],[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0],[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0],[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0],[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0],[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0],[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0],[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0],[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0]] -------------------------------------------------------------------------------- /public/assets/eigensum.js: -------------------------------------------------------------------------------- 1 | 2 | function renderEigenPanel(eigensum, U, x, b, wi, refit, hat, renderStars) { 3 | var mathdiv = eigensum.append("div") 4 | 5 | var xrange = d3.scaleLinear().domain([-10,10]).range([-1,1]) 6 | var startpoint = 0 7 | var witemp = 0 8 | 9 | var equations = []; 10 | 11 | function renderEquation(hat, value, number) { 12 | var html = hat ? MathCache("phat") : MathCache("p"); 13 | html = html.replace('0', value); 14 | html = html.replace('1', number); 15 | return html; 16 | } 17 | 18 | if (!(renderStars === undefined)) { 19 | for (var i = 0; i < 7; i++) { 20 | 21 | mathdiv 22 | .append("span") 23 | .style("text-align","center") 24 | .style("display","inline-block") 25 | .style("width", "110px") 26 | .style("height", "25px") 27 | .style("font-size", "16px") 28 | .html(MathCache("star")); 29 | 30 | 31 | // Add pluses and equal signs 32 | if (i < 5) { 33 | mathdiv.append("span").style("text-align","center") 34 | .style("display","inline-block") 35 | .style("width", "25px") 36 | .style("height", "25px") 37 | .style("opacity", 0) 38 | .html(".") 39 | } else{ 40 | if (i == 5) { 41 | mathdiv.append("span").style("text-align","center") 42 | .style("display","inline-block") 43 | .style("width", "26px") 44 | .style("height", "25px") 45 | .style("opacity", 0) 46 | .html(".") 47 | } 48 | } 49 | 50 | } 51 | } 52 | 53 | 54 | 55 | // Render Equations 56 | for (var i =0; i < 7; i++) { 57 | 58 | var html = MathCache("model"); 59 | if (i != 6) { 60 | html = renderEquation(hat, wi[i].toPrecision(3), i+1); 61 | } 62 | 63 | if (i != 6) { 64 | var equation = mathdiv 65 | .append("span") 66 | .attr("class", "draggable-number") 67 | .style("text-align","center") 68 | .style("display","inline-block") 69 | .style("width", "110px") 70 | .style("height", "50px") 71 | .style("font-size", "16px") 72 | .style("cursor", "ew-resize") 73 | .html(html) 74 | .call( 75 | d3.drag() 76 | .on("start", function() { startpoint = d3.mouse(this)[0] } ) 77 | .on("drag", (function(i) { return function() { 78 | var xi = xrange(d3.mouse(this)[0] - startpoint) + wi[i] 79 | witemp = wi.slice(0); witemp[i] = xi 80 | var str = renderEquation(hat, (witemp[i]).toPrecision(3), i+1); 81 | d3.select(this).html(str) 82 | 83 | var w = zeros(6); w[i] = xi 84 | updates[i](numeric.dot(numeric.transpose(U),w)) 85 | updatesum(numeric.dot(numeric.transpose(U),witemp)) 86 | }} )(i) ) 87 | .on("end", function() { wi = witemp }) 88 | ) 89 | } else { 90 | var equation = mathdiv 91 | .append("span") 92 | .style("text-align","center") 93 | .style("display","inline-block") 94 | .style("width", "110px") 95 | .style("height", "50px") 96 | .style("font-size", "16px") 97 | .html(html) 98 | } 99 | 100 | equations.push(equation) 101 | 102 | // Add pluses and equal signs 103 | if (i < 5) { 104 | var html = MathCache("plus"); 105 | mathdiv.append("span").style("text-align","center") 106 | .style("display","inline-block") 107 | .style("width", "25px") 108 | .style("height", "50px") 109 | .style("font-size", "16px") 110 | .html(html) 111 | } else{ 112 | if (i == 5) { 113 | var html = MathCache("equals"); 114 | mathdiv.append("span").style("text-align","center") 115 | .style("display","inline-block") 116 | .style("width", "26px") 117 | .style("height", "50px") 118 | .style("font-size", "16px") 119 | .html(html) 120 | } 121 | } 122 | 123 | } 124 | 125 | var div = eigensum 126 | .style("display", "block") 127 | .style("margin-left","auto") 128 | .style("margin-right","auto") 129 | .style("width", 940+"px") 130 | .style("position", "relative") 131 | .append("div") 132 | 133 | // Render Polynomials 134 | var updates = [] 135 | for (var i = 0; i < 6; i++ ){ 136 | var w = zeros(6) 137 | w[i] = 2 138 | var update = renderEigenSum(div.append("svg"), x, undefined, function() {}, ["hsl(24, 100%, 50%)", "hsl(24, 100%, 50%)"]) 139 | updates.push(update.poly) 140 | if (i != 5) { 141 | div.append("span").html("+").style("position", "relative").style("top", "-54px").style("display","inline-block") 142 | .style("width", "7px").style("left", "-5px") 143 | } 144 | } 145 | 146 | div.append("span").html("=").style("position", "relative").style("top", "-54px").style("position", "relative").style("width", "7px").style("left", "-1px") 147 | 148 | var updatesum = renderEigenSum(div.append("svg"),x, b, 149 | refit, 150 | ["black", "black"]).poly 151 | 152 | function updateweights(win) { 153 | wi = win 154 | for (var i = 0; i < 6; i++ ){ 155 | var html = renderEquation(hat, win[i].toPrecision(3), i + 1); 156 | equations[i].html(html) 157 | var w = zeros(6); w[i] = win[i] 158 | updates[i](numeric.dot(w,U)) 159 | } 160 | updatesum(numeric.dot(win,U)) 161 | 162 | } 163 | 164 | updateweights(wi) 165 | 166 | return {updates:updates, updatesum:updatesum, updateweights:updateweights} 167 | } 168 | 169 | /* 170 | 171 | Render the Polynomial fitting widget 172 | 173 | */ 174 | function renderEigenSum(svg, xv, b, dragCallback, colors) { 175 | 176 | /* 177 | Data on eigenvectors 178 | 179 | xv - x values (\xi in paper) 180 | U - eigenvectors 181 | Lambda - eigenvalues 182 | */ 183 | 184 | // Linear regression - minimize ||Ax - b||^2. Notation is different in article. 185 | var A = vandermonde(xv, 25) 186 | var w = zeros(xv.length) 187 | /************************************************************************** 188 | START VISUALIZATION 189 | ***************************************************************************/ 190 | 191 | var width = 110 192 | var height = 110 193 | 194 | var x = d3.scaleLinear().domain([-1.5,1.5]).range([0, width]); 195 | var y = d3.scaleLinear().domain([-3,3]).range([height, 0]); 196 | 197 | var valueline = d3.line() 198 | .x(function(d) { return x(d[0]); }) 199 | .y(function(d) { return y(d[1]); }); 200 | 201 | var display_poly = function (weights) { 202 | 203 | w = weights 204 | 205 | eigenpath 206 | .attr("d", valueline(evalPoly(w) )) 207 | .style("opacity",1) 208 | 209 | var pd = polyC.selectAll("circle").data(xv).merge(polyC) 210 | 211 | pd.attr("cy", function (d) { 212 | return y(poly(w, d)) 213 | }) 214 | 215 | if (!(datalines === undefined)) { 216 | datalines 217 | .attr("x1", function(d,i) { return x(d[0]) }) 218 | .attr("y1", function(d,i) { return y(d[1]) }) 219 | .attr("x2", function(d,i) { return x(d[0]) }) 220 | .attr("y2", function(d,i) { return y(poly(w, d[0])) }) 221 | } 222 | } 223 | 224 | /* 225 | * Add eigenvalue plot at the bottom. 226 | * Some copy and pasted code here, but its only a 1-time thing. 227 | */ 228 | 229 | svg.attr("width", width) 230 | .attr("height", height) 231 | .style("padding", "6px") 232 | 233 | 234 | var eigensvg = svg.append("svg") 235 | .attr("width", width) 236 | .attr("height", height) 237 | 238 | var eigenpath = eigensvg.append("path") 239 | .style("stroke-width", "2px") 240 | .style("stroke", colors[1]) 241 | .style("fill","none") 242 | 243 | var polyC = svg.append("g").selectAll("circle").data(xv) 244 | .enter() 245 | .append("circle") 246 | .attr("cx", function(d,i) { return x(d) }) 247 | .attr("cy", function(d,i) { return y(1) }) 248 | .attr("r", 2) 249 | .style("stroke-width", "1px") 250 | .style("stroke", colors[1]) 251 | .style("fill", "white") 252 | 253 | if (!(b === undefined)) { 254 | 255 | var voronoi = d3.voronoi() 256 | .x(function(d) { return x(d[0]); }) 257 | .y(function(d) { return y(d[1]); }) 258 | .extent([[0, 0], [110, 110]]); 259 | 260 | var data = svg.append("g") 261 | 262 | data.selectAll("circle").data(d3.zip(xv,b)) 263 | .enter() 264 | .append("circle") 265 | .attr("cx", function(d,i) { return x(d[0]) }) 266 | .attr("cy", function(d,i) { return y(d[1]) }) 267 | .attr("r", 2) 268 | .style("stroke-width", "8px") 269 | .style("stroke", "rgba(255,255,255,0.1)") 270 | .style("fill", colors[0]) 271 | .call(d3.drag() 272 | .on("drag", function(d,i) { 273 | var ypos = d3.event.y 274 | var yval = y.invert(ypos) 275 | this.setAttribute("cy", ypos) 276 | b[i] = yval 277 | dragCallback(b) 278 | datalines.data(d3.zip(xv,b)).merge(datalines) 279 | .attr("x1", function(d,i) { return x(d[0]) }) 280 | .attr("y1", function(d,i) { return y(d[1]) }) 281 | .attr("x2", function(d,i) { return x(d[0]) }) 282 | .attr("y2", function(d,i) { return y(poly(w, d[0])) }) 283 | }) 284 | ) 285 | 286 | var vongroup = svg.append("g") 287 | 288 | var dragging = false 289 | vongroup.selectAll("path") 290 | .data(voronoi.polygons(d3.zip(xv,b))) 291 | .enter().append("path") 292 | .attr("d", function(d, i) { return "M" + d.join("L") + "Z"; }) 293 | .datum(function(d, i) { return d.point; }) 294 | .style("stroke", "#2074A0") //I use this to look at how the cells are dispersed as a check 295 | .style("fill", "white") 296 | .style("opacity", 0.001) 297 | // .style("pointer-events", "all") 298 | .on("mouseover", function(d,i) { 299 | if (!dragging){ 300 | d3.select(datalinessvg.selectAll("line").nodes()[i]).style("stroke-width", "1px"); 301 | d3.select(data.selectAll("circle").nodes()[i]).style("fill", "red"); 302 | } 303 | }) 304 | .on("mouseout", function(d,i) { 305 | if (!dragging) { 306 | d3.select(datalinessvg.selectAll("line").nodes()[i]).style("stroke-width", "0px"); 307 | d3.select(data.selectAll("circle").nodes()[i]).style("fill", "black"); 308 | } 309 | }) 310 | // .on("mouseout", removeTooltip); 311 | .call(d3.drag() 312 | .on("drag", function(d,i) { 313 | dragging = true 314 | d3.select(datalinessvg.selectAll("line").nodes()[i]).style("stroke-width", "2px"); 315 | d3.select(data.selectAll("circle").nodes()[i]).style("fill", "pink"); 316 | 317 | var ypos = d3.event.y 318 | var yval = y.invert(ypos) 319 | if (ypos < 0 || ypos > 110) { 320 | return 321 | } 322 | var thisvar = data.selectAll("circle").nodes()[i] 323 | thisvar.setAttribute("cy", ypos) 324 | b[i] = yval 325 | dragCallback(b) 326 | datalines.data(d3.zip(xv,b)).merge(datalines) 327 | .attr("x1", function(d,i) { return x(d[0]) }) 328 | .attr("y1", function(d,i) { return y(d[1]) }) 329 | .attr("x2", function(d,i) { return x(d[0]) }) 330 | .attr("y2", function(d,i) { return y(poly(w, d[0])) }) 331 | vongroup.selectAll("path") 332 | .data(voronoi.polygons(d3.zip(xv,b))) 333 | .merge(vongroup) 334 | .attr("d", function(d, i) { return "M" + d.join("L") + "Z"; }) 335 | }) 336 | .on("end", function(d,i) { 337 | dragging = false 338 | d3.select(datalinessvg.selectAll("line").nodes()[i]).style("stroke-width", "0px"); 339 | d3.select(data.selectAll("circle").nodes()[i]).style("fill", "black"); 340 | }) 341 | ) 342 | 343 | var datalinessvg = svg.append("g") 344 | 345 | var datalines = datalinessvg.selectAll("line").data(d3.zip(xv,b)) 346 | .enter() 347 | .append("line") 348 | .attr("x1", function(d,i) { return x(d[0]) }) 349 | .attr("y1", function(d,i) { return y(d[1])+2 }) 350 | .attr("x2", function(d,i) { return x(d[0]) }) 351 | .attr("y2", function(d,i) { return y(0) }) 352 | .style("stroke-width", "0px") 353 | .style("stroke", "red") 354 | 355 | } 356 | 357 | eigensvg.append("g") 358 | .attr("class", "grid") 359 | .attr("transform", "translate(0," + (height/2) + ")") 360 | .call(d3.axisBottom(x) 361 | .ticks(1) 362 | .tickSize(2)) 363 | 364 | // Start at some nice looking defaults. 365 | display_poly(w) 366 | 367 | return {poly:display_poly}; 368 | } 369 | 370 | -------------------------------------------------------------------------------- /public/assets/flow.js: -------------------------------------------------------------------------------- 1 | function renderFlowWidget(divin, FlowSigma, M, FlowU) { 2 | 3 | var jetc = d3.scaleLinear().domain([-100,1.5,2,3,4,5,10,60,200,500]).range(colorbrewer.RdYlBu[10]); 4 | 5 | var colorBar = divin.append("div").style("position", "absolute").style("left","490px").style("top", "5px").style("height","45px") 6 | 7 | colorMap( colorBar, 8 | 180, 9 | jetc, 10 | d3.scaleLinear().domain([0,100]).range([0, 180]) ) 11 | 12 | divin.append("figcaption") 13 | .style("position", "absolute") 14 | .style("left", "500px") 15 | .style("width", "300px") 16 | .style("top", "70px") 17 | .html("Each square represents a node, colored by its weight. Edges connect each square to the four neighboring squares.") 18 | 19 | divin.append("figcaption") 20 | .style("position", "absolute") 21 | .style("left", "500px") 22 | .style("width", "100px") 23 | .style("top", "0px") 24 | .attr("class", "figtext") 25 | .html("Weights") 26 | 27 | // sliderGen([320, 130]) 28 | // .ticks([0,2/FlowSigma[1119]]) 29 | // .cRadius(5) 30 | // .startxval(4) 31 | // .shifty(10) 32 | // .change(changeStep)(divin.append("div").style("position","relative").style("left", "100px")) 33 | 34 | var slider = divin.append("div").style("position","relative").style("left", "112px") 35 | /* 36 | Generate coordinates for 2D Laplacian based on input matrix 37 | V[i] = (x,y) coordinate of node in 2D space. 38 | */ 39 | var V = [] 40 | for (var i = 0; i < 16; i++) { for (var j = 0; j < 112; j++) { 41 | if (M[i][j] == 0){ V.push([j,i]) } 42 | }} 43 | 44 | /* Generate b in optimization problem x'Ax - b'x */ 45 | var b = zeros(FlowU[0].length); b[448] = 10; b[560] = 10 46 | var step = 1.9/(FlowSigma[1119]) 47 | //var iter = geniter(FlowU, FlowSigma, b, step) 48 | var Ub = numeric.dot(FlowU, b) 49 | 50 | // We can also run this on momentum. 51 | var iterf = geniterMomentum(FlowU, FlowSigma, b, step, 0.999).iter 52 | var iter = function(k) { return iterf(k)[1] } 53 | 54 | /************************************************************************** 55 | START VISUALIZATION 56 | ***************************************************************************/ 57 | divin.style("position", "relative") 58 | 59 | /* Render the 2D grid of pixels, given a div as input 60 | * (appends an svg inside the div) 61 | * Returns a function which allows you to update it */ 62 | function renderGrid(s, transition) { 63 | 64 | var sampleSVG = s.style("display", "block") 65 | .style("margin-left","auto") 66 | .style("margin-right","auto") 67 | .style("width", "920px") 68 | .append("svg") 69 | .attr("width", 920) 70 | .attr("height", 150) 71 | 72 | /* Render discretization of 2D Laplacian*/ 73 | sampleSVG.selectAll("rect") 74 | .data(V) 75 | .enter().append("rect") 76 | .style("fill", function(d,i) { return "white" }) 77 | .attr("height", 7.7) 78 | .attr("width", 7.7) 79 | .attr("x", function(d, i){return d[0]*8+ 10}) 80 | .attr("y", function(d, i){return d[1]*8 + 10}) 81 | 82 | /* display a function on the laplacian using colormap map*/ 83 | var display = function (x, map) { 84 | if (transition === undefined){ 85 | sampleSVG.selectAll("rect").style("fill", function(d,i) { return map(x[i]) }) 86 | } else { 87 | sampleSVG.transition() 88 | .duration(transition) 89 | .selectAll("rect") 90 | .style("fill", function(d,i) { return map(x[i]) }) 91 | } 92 | } 93 | 94 | return display 95 | 96 | } 97 | 98 | var display = renderGrid(divin) 99 | /* Render Control Slider */ 100 | 101 | // Callbacks 102 | var showEigen = function (d,i) { 103 | display(FlowU[i], divergent) 104 | } 105 | 106 | var cacheval = -1 107 | var cacheiter = null 108 | var onDragSlider = function (i) { 109 | var i = Math.floor(Math.exp(i-1)) 110 | if (cacheval != i) { 111 | cacheiter = iter(i) 112 | cacheval = i 113 | } 114 | display(cacheiter, jetc) 115 | } 116 | 117 | display(iter(100), jetc) // Set it up to a nice looking default 118 | 119 | var barLengths = getStepsConvergence(FlowSigma,step) 120 | .map( function(i) {return Math.abs(Math.log(i+1)) } ).filter( function(d,i) { return (i < 50) || i%20 == 0 } ) 121 | 122 | var slideControl = sliderBarGen(barLengths, function(x) { return Math.exp(x-1)} ) 123 | .height(281) 124 | .linewidth(1.3) 125 | .maxX(13.3) 126 | .mouseover( function(d,i) { display(FlowU[i], divergent) }) 127 | .labelFunc(function (d,i) { 128 | if (i < 50) { 129 | return ((i == 0) ? "Eigenvalue 1" : "") + (( (i+1) % 25 == 0 ) ? (i + 1) : "") 130 | } else { 131 | return (( (i+1) % 25 == 0 ) ? 20*(i + 1) : "") 132 | } 133 | }) 134 | .update(onDragSlider)(divin) 135 | 136 | slideControl.slidera.init() 137 | 138 | function changeStep(alpha, beta) { 139 | var iteration = geniterMomentum(FlowU, FlowSigma, b, Math.max(alpha/FlowSigma[1119],0.00000001), Math.min(beta,0.999999)) 140 | iterf = iteration.iter 141 | var barLengths = getStepsConvergence(iteration.maxLambda.map(function(i) { return 1- i}), 1) 142 | .map( function(i) {return Math.log(Math.max(i,1))} ) 143 | .filter( function(d,i) { return (i < 50) || i%20 == 0 } ) 144 | slideControl.update(barLengths) 145 | iter = function(k) { return iterf(k)[1] } 146 | cacheval = -1 147 | slideControl.slidera.init() 148 | } 149 | var reset = slider2D(slider, changeStep, FlowSigma[0], FlowSigma[1119], [1.9,0.00001]) 150 | 151 | slider.append("div") 152 | .attr("class","figtext") 153 | .style("left", "155px") 154 | .style("top", "0px") 155 | .style("position","absolute") 156 | .style("pointer-events", "none") 157 | .html("Step-size α =") 158 | 159 | slider.append("div") 160 | .attr("class","figtext") 161 | .style("left", "-87px") 162 | .style("top", "20px") 163 | .style("position","absolute") 164 | .style("pointer-events", "none") 165 | .html("Momentum β = ") 166 | 167 | return reset 168 | } 169 | 170 | //
Step-size α =
171 | //
Momentum β =
172 | -------------------------------------------------------------------------------- /public/assets/graph.js: -------------------------------------------------------------------------------- 1 | var seed = 17; 2 | function random() { 3 | var x = Math.sin(seed++) * 10000; 4 | return x - Math.floor(x); 5 | } 6 | 7 | function generateGraph(svg, graph, linklength, strength) { 8 | 9 | var width = 300; 10 | var height = 200; 11 | 12 | var simulation = d3.forceSimulation() 13 | .force("link", d3.forceLink().id(function(d) { return d.id; }) 14 | .strength(2) 15 | .distance(function() {return linklength})) 16 | .force("charge", d3.forceManyBody().strength(-110)) 17 | .force("center", d3.forceCenter(width / 2, height / 2)) 18 | .force("x",d3.forceX(1000).strength(strength)) 19 | .force("y",d3.forceY(1000).strength(strength)) 20 | .stop() 21 | var link = svg.append("g") 22 | .attr("class", "links") 23 | .selectAll("line") 24 | .data(graph.links) 25 | .enter().append("line") 26 | .attr("stroke-width", 1) 27 | .attr("stroke","black") 28 | 29 | var node = svg.append("g") 30 | .attr("class", "nodes") 31 | 32 | 33 | var nodedata = node 34 | .selectAll("circle") 35 | .data(graph.nodes) 36 | .enter().append("circle") 37 | .attr("r", 3) 38 | .attr("fill", "black") 39 | 40 | nodedata.append("title") 41 | .text(function(d) { return d.id; }); 42 | 43 | simulation 44 | .nodes(graph.nodes) 45 | .on("tick", ticked); 46 | 47 | simulation.force("link") 48 | .links(graph.links); 49 | 50 | for (var i = 0; i < 200; ++i) { 51 | simulation.tick(); 52 | } 53 | 54 | function ticked() { 55 | link.attr("x1", function(d) { return d.source.x; }) 56 | .attr("y1", function(d) { return d.source.y; }) 57 | .attr("x2", function(d) { return d.target.x; }) 58 | .attr("y2", function(d) { return d.target.y; }); 59 | 60 | nodedata.attr("cx", function(d) { return d.x; }) 61 | .attr("cy", function(d) { return d.y; }); 62 | } 63 | 64 | var updateColors = function (update) { 65 | node.selectAll("circle") 66 | .data(update) 67 | .attr("fill", function(d,i) { return d}) 68 | } 69 | 70 | ticked() 71 | 72 | return updateColors 73 | }; 74 | 75 | 76 | function genGrid(svg) { 77 | 78 | var data = {"nodes": [],"links": []} 79 | var id = {} 80 | 81 | var n = 6 82 | var c = 0 83 | for (var i = 0; i < n; i ++) { 84 | for (var j = 0; j < n; j ++) { 85 | data.nodes.push({"id": i + "," + j}) 86 | id[i + "," + j] = c 87 | c++ 88 | } 89 | } 90 | 91 | var L = zeros2D(c,c) 92 | 93 | for (var i = 0; i < n; i++) { 94 | for (var j = 0; j < n; j++){ 95 | if (j < (n-1)) { 96 | data.links.push({"source":i + "," + j, "target": i + "," + (j + 1)}) 97 | L[id[i + "," + j]][id[i + "," + (j+1)]] = -1 98 | L[id[i + "," + (j+1)]][id[i + "," + j]] = -1 99 | } 100 | if (i < (n-1)) { 101 | data.links.push({"source":i + "," + j, "target": (i + 1) + "," + j}) 102 | L[id[i + "," + j]][id[(i+1) + "," + j]] = -1 103 | L[id[(i+1) + "," + j]][id[i + "," + j]] = -1 104 | } 105 | } 106 | } 107 | 108 | for (var i = 0; i < c; i++) { 109 | L[i][i] = -numeric.sum(L[i]) + ((i == 0) ? 1 : 0) 110 | } 111 | 112 | colorbrewer.Spectral[3] 113 | var divergent = d3.scaleLinear().domain([-0.1,0,0.1]).range(["#fc8d59", "#e6e600", "#99d594"]); 114 | 115 | var E = eigSym(L) 116 | 117 | var update = generateGraph(svg, data,2,0.2) 118 | 119 | var colors = [] 120 | for (var i = 0; i < c; i++) { 121 | colors.push(divergent(E.U[34][i])) 122 | } 123 | update(colors) 124 | 125 | 126 | } 127 | 128 | 129 | function genPath(svg) { 130 | var data = {"nodes": [], "links": []} 131 | 132 | var n = 36 133 | var L = zeros2D(n,n) 134 | for (var i = 0; i < n; i ++) { 135 | data.nodes.push({"id": i}) 136 | if (i < (n-1)){ 137 | data.links.push({"source":i, "target": i+1}) 138 | L[i][i+1] = -1 139 | L[i+1][i] = -1 140 | } 141 | } 142 | 143 | for (var i = 0; i < 3; i++){ 144 | var s = Math.floor(random()*36) 145 | var t = Math.floor(random()*36) 146 | data.links.push({"source":s, "target": t}) 147 | L[s][t] = -1 148 | L[t][s] = -1 149 | } 150 | 151 | for (var i = 0; i < n; i++) { 152 | L[i][i] = -numeric.sum(L[i]) + ((i == 0) ? 1 : 0) 153 | } 154 | 155 | var divergent = d3.scaleLinear().domain([-0.1,0,0.1]).range(["#fc8d59", "#e6e600", "#99d594"]); 156 | 157 | var E = eigSym(L) 158 | 159 | var update = generateGraph(svg, data, 3, 0.43) 160 | var colors = [] 161 | for (var i = 0; i < n; i++) { 162 | colors.push(divergent(E.U[34][i])) 163 | } 164 | update(colors) 165 | 166 | 167 | } 168 | 169 | 170 | function genExpander(svg) { 171 | var data = {"nodes": [], "links": []} 172 | var n = 36 173 | var L = zeros2D(n,n) 174 | 175 | for (var i = 0; i < n; i ++) { 176 | data.nodes.push({"id": i}) 177 | } 178 | 179 | for (var i = 0; i < 80; i++){ 180 | var s = Math.floor(random()*36); 181 | var t = Math.floor(random()*36) 182 | data.links.push({"source":s, "target": t}) 183 | L[s][t] = -1 184 | L[t][s] = -1 185 | } 186 | 187 | for (var i = 0; i < n; i++) { 188 | L[i][i] = -numeric.sum(L[i]) + ((i == 0) ? 1 : 0) 189 | } 190 | var divergent = d3.scaleLinear().domain([-0.1,0,0.1]).range(["#fc8d59", "#e6e600", "#99d594"]); 191 | 192 | var E = eigSym(L) 193 | var update = generateGraph(svg, data, 20, 0.2) 194 | var colors = [] 195 | for (var i = 0; i < n; i++) { 196 | colors.push(divergent(E.U[34][i])) 197 | } 198 | update(colors) 199 | } 200 | 201 | -------------------------------------------------------------------------------- /public/assets/images/levelsets1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/images/levelsets1.png -------------------------------------------------------------------------------- /public/assets/images/levelsets2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/images/levelsets2.png -------------------------------------------------------------------------------- /public/assets/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 17 | 18 | 19 |

Hello World

20 |

A description of the article

21 | 22 |

This is the first paragraph of the article.

23 |

We can also cite external publications.

24 |
25 | 26 | -------------------------------------------------------------------------------- /public/assets/iterates.js: -------------------------------------------------------------------------------- 1 | /* 2 | Make a standard "path of descent" plot which shows iterates 3 | on a 2D optimization landscape 4 | 5 | Takes in : f, the objective function 6 | Name of div where the graphic is rendered 7 | update, which gets passed in the objective 8 | values at every iteration 9 | 10 | Returns : callback `changeParams` to change alpha, beta 11 | */ 12 | function genIterDiagram(f, xstar, axis, optMethod, showSolution, showStartingPoint, totalIters) { 13 | 14 | /* 15 | Configurable Parameters 16 | */ 17 | var w = 984 18 | var h = 300 19 | var state_beta = 0.0 20 | var state_alpha = 0.001 21 | var num_contours = 15 22 | var onDrag = function() {} 23 | var w0 =[-1.21, 0.853] 24 | var strokeColor = "#ff6600" 25 | var showOptimum = true 26 | var pathWidth = 1.5 27 | var circleRadius = 2 28 | var pointerScale = 1 29 | 30 | function renderIterates(div) { 31 | 32 | // Render the other stuff 33 | var intDiv = div.style("width", w + "px") 34 | .style("height", h + "px") 35 | 36 | // Render Contours 37 | var plotCon = contour_plot.ContourPlot(w,h) 38 | .f(function(x,y) { return f([x,y])[0] }) 39 | .drawAxis(false) 40 | .xDomain(axis[0]) 41 | .yDomain(axis[1]) 42 | .contourCount(num_contours) 43 | .minima([{x:xstar[0], y:xstar[1]}]); 44 | 45 | var elements = plotCon(intDiv); 46 | 47 | var svg = intDiv.append("div") 48 | .append("svg") 49 | .style("position", 'absolute') 50 | .style("left", 0) 51 | .style("top", 0) 52 | .style("width", w + "px") 53 | .style("height", h + "px") 54 | .style("z-index", 2) 55 | 56 | var X = d3.scaleLinear().domain(axis[0]).range([0, w]) 57 | var Y = d3.scaleLinear().domain(axis[1]).range([0, h]) 58 | 59 | // Rendeer Draggable dot 60 | var circ = svg.append("g") //use xlink:href="cafe-18.svg#svg4619"> 61 | .attr("transform", "translate(" + X(w0[0]) + "," + Y(w0[1]) + ")") 62 | .call(d3.drag().on("drag", function() { 63 | var pt = d3.mouse(svg.node()) 64 | var x = X.invert(pt[0]) 65 | var y = Y.invert(pt[1]) 66 | this.setAttribute("transform","translate(" + pt[0] + "," + pt[1] + ")") 67 | w0 = [x,y] 68 | onDrag(w0) 69 | iter(state_alpha, state_beta, w0); 70 | })) 71 | 72 | if (showStartingPoint) { 73 | circ.append("use") 74 | .style("cursor", "pointer") 75 | .attr("xlink:href", "#pointerThingy") 76 | .attr("transform", "scale(" + pointerScale + ")") 77 | 78 | circ.append("text") 79 | .style("cursor", "pointer") 80 | .attr("class", "figtext") 81 | .attr("transform", "translate(20,3)") 82 | .html("Starting Point") 83 | } 84 | 85 | var iterColor = d3.scaleLinear().domain([0, totalIters]).range([strokeColor, strokeColor]) 86 | 87 | var update2D = plot2dGen(X, Y, iterColor) 88 | .stroke(strokeColor) 89 | .pathWidth(pathWidth) 90 | .circleRadius(circleRadius)(svg) 91 | 92 | 93 | if (showOptimum) { 94 | // Append x^s var showSolution = falsetar 95 | var pxstar = ringPathGen(7,50,14)([X(xstar[0]), Y(xstar[1])], 96 | [X(xstar[0]), Y(xstar[1]) - 15]) 97 | svg.append("circle").attr("cx", X(xstar[0])).attr("cy", Y(xstar[1])).attr("r", 7).attr("stroke","#3f5b75").attr("stroke-width",1).attr("fill","none") 98 | svg.append("path").attr("d", pxstar.d).attr("stroke","#3f5b75").attr("stroke-width",1).attr("fill","none") 99 | svg.append("text") 100 | .attr("class","figtext") 101 | .attr("transform", "translate(" + pxstar.label[0] + "," + (pxstar.label[1]) + ")" ) 102 | .html("Optimum") 103 | } 104 | 105 | 106 | if (showSolution) { 107 | var pxsol = ringPathGen(7,43.36,14)([X(0), Y(0)], 108 | [X(0), Y(0) + 20]) 109 | var solcirc = svg.append("circle").attr("cx", X(0)).attr("cy", Y(0)).attr("r", 7).attr("stroke",strokeColor).attr("stroke-width",1).attr("fill","none") 110 | var solpath = svg.append("path").attr("d", pxsol.d).attr("stroke",strokeColor).attr("stroke-width",1).attr("fill","none") 111 | var sollabel = svg.append("text") 112 | .attr("class","figtext") 113 | .attr("transform", "translate(" + pxsol.label[0] + "," + (pxsol.label[1]) + ")" ) 114 | .html("Solution") 115 | } 116 | function updateSol(x,y) { 117 | if (showSolution) { 118 | var pxsol = ringPathGen(7,50,14)([X(x), Y(y)], [X(x), Y(y) + 15]) 119 | solcirc.attr("cx", X(x)).attr("cy", Y(y)) 120 | solpath.attr("d", pxsol.d) 121 | sollabel.attr("transform", "translate(" + pxsol.label[0] + "," + (pxsol.label[1]) + ")" ) 122 | } 123 | } 124 | 125 | // svg.append("rect") 126 | // .attr("width", 50) 127 | // .attr("height",14) 128 | // .attr("x", pxstar.label[0] ) 129 | // .attr("y", pxstar.label[1]) 130 | 131 | function iter(alpha, beta, w0) { 132 | 133 | // Update Internal state of alpha and beta 134 | state_alpha = alpha 135 | state_beta = beta 136 | 137 | // Generate iterates 138 | if (optMethod != null) { 139 | var OW = optMethod(f, w0, alpha, totalIters) 140 | var W = OW[1] 141 | 142 | update2D(W) 143 | 144 | updateSol(OW[1][OW[1].length - 1][0], OW[1][OW[1].length - 1][1]) 145 | circ.attr("transform", "translate(" + X(w0[0]) + "," + Y(w0[1]) + ")" ) 146 | circ.moveToFront() 147 | } 148 | 149 | } 150 | 151 | if (optMethod != null) { 152 | iter(state_alpha, state_beta, w0); 153 | } 154 | 155 | return { control:iter, 156 | w0:function() { return w0 }, 157 | alpha:function() { return state_alpha }, 158 | beta:function() {return state_beta} } 159 | 160 | } 161 | 162 | renderIterates.showStartingPoint = function(_) { 163 | showStartingPoint = _; return renderIterates; 164 | } 165 | 166 | renderIterates.pointerScale = function(_) { 167 | pointerScale = _; return renderIterates; 168 | } 169 | 170 | renderIterates.circleRadius = function(_) { 171 | circleRadius = _; return renderIterates; 172 | } 173 | 174 | renderIterates.pathWidth = function(_) { 175 | pathWidth = _; return renderIterates; 176 | } 177 | 178 | renderIterates.showSolution = function(_) { 179 | showSolution = _; return renderIterates; 180 | } 181 | 182 | renderIterates.showOptimum = function(_) { 183 | showOptimum = _; return renderIterates; 184 | } 185 | 186 | renderIterates.strokeColor = function(_) { 187 | strokeColor = _; return renderIterates; 188 | } 189 | 190 | renderIterates.width = function (_) { 191 | w = _; return renderIterates; 192 | } 193 | 194 | renderIterates.height = function (_) { 195 | h = _; return renderIterates; 196 | } 197 | 198 | renderIterates.iters = function (_) { 199 | totalIters = _; return renderIterates; 200 | } 201 | 202 | renderIterates.drag = function (_) { 203 | onDrag = _; return renderIterates; 204 | } 205 | 206 | renderIterates.init = function (_) { 207 | w0 = _; return renderIterates; 208 | } 209 | 210 | renderIterates.alpha = function (_) { 211 | state_alpha = _; return renderIterates; 212 | } 213 | 214 | renderIterates.beta = function (_) { 215 | state_beta = _; return renderIterates; 216 | } 217 | 218 | return renderIterates 219 | 220 | } 221 | -------------------------------------------------------------------------------- /public/assets/lib/auto-render.min.js: -------------------------------------------------------------------------------- 1 | (function(e){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=e()}else if(typeof define==="function"&&define.amd){define([],e)}else{var t;if(typeof window!=="undefined"){t=window}else if(typeof global!=="undefined"){t=global}else if(typeof self!=="undefined"){t=self}else{t=this}t.renderMathInElement=e()}})(function(){var e,t,r;return function n(e,t,r){function a(o,l){if(!t[o]){if(!e[o]){var f=typeof require=="function"&&require;if(!l&&f)return f(o,!0);if(i)return i(o,!0);var d=new Error("Cannot find module '"+o+"'");throw d.code="MODULE_NOT_FOUND",d}var s=t[o]={exports:{}};e[o][0].call(s.exports,function(t){var r=e[o][1][t];return a(r?r:t)},s,s.exports,n,e,t,r)}return t[o].exports}var i=typeof require=="function"&&require;for(var o=0;o 0) return; 36 | if(abs(dp0) < epsMin) return v; 37 | var n = opt.maxTry || 25; 38 | function zoom(low,high){ 39 | if(low.f === undefined) low.f = f(low.x); 40 | if(high.f === undefined) high.f = f(high.x); 41 | while(true){ 42 | var nv = {}; 43 | var a = nv.a = 0.5*(low.a+high.a); 44 | nv.s = mul(nv.a,d); 45 | nv.x = add(v.x,nv.s); 46 | var p = nv.f = f(nv.x); 47 | if(!n--) return lineSearchSimple(v,d); 48 | if(p > p0+c1*a*dp0 || p >= low.f){ 49 | high = nv; 50 | }else{ 51 | nv.df = df(nv.x); 52 | var dp = nv.dp = sum(mul(nv.df,d)); 53 | if(abs(dp) <= -c2*dp0) return nv; 54 | if(dp*(high.a-low.a) >= 0) high = low; 55 | low = nv; 56 | } 57 | } 58 | } 59 | var nv = {a:1}; 60 | var ov = {x:v.x,a:0}; 61 | var op; 62 | while(true){ 63 | nv.s = mul(nv.a,d); 64 | nv.x = add(v.x,nv.s); 65 | var a = nv.a; 66 | var p = nv.f = f(nv.x); 67 | if(p > p0+c1*a*dp0 || (op !== undefined && p > op)) return zoom(ov,nv); 68 | nv.df = df(nv.x); 69 | var dp = nv.dp = sum(mul(nv.df,d)); 70 | if(abs(dp) <= -c2*dp0) return nv; 71 | if(dp >= 0) return zoom(nv,ov); 72 | ov.x = nv.x; 73 | ov.a = nv.a; 74 | ov.f = nv.f; 75 | ov.df = nv.df; 76 | ov.s = nv.s; 77 | op = p; 78 | nv.a = 0.5*(a+max); 79 | if(!n--) return lineSearchSimple(v,d); 80 | } 81 | } 82 | function lineSearchSimple(v,d){ 83 | var p0 = v.f; 84 | var dp0 = sum(mul(v.df,d)); 85 | if(abs(dp0) < epsMin) return v; 86 | var n = opt.maxTry || 25; 87 | var nv = {a:dp0>0?-1:1}; 88 | while(true){ 89 | nv.s = mul(nv.a,d); 90 | nv.x = add(v.x,nv.s); 91 | var a = nv.a; 92 | var p = nv.f = f(nv.x); 93 | if(p < p0+c1*a*dp0){ 94 | nv.df = df(nv.x); 95 | return nv; 96 | } 97 | nv.a *= 0.5; 98 | if(!n--) throw "too much step, during line search"; 99 | } 100 | } 101 | 102 | for(var i=0;i opt.maxNormDir) d = mul(d,opt.maxNormDir/normDir); 107 | } 108 | 109 | W.push(v.x); Obj.push(v.f); 110 | var og = v.df; 111 | var nv = lineSearch(v,d); // compute step length 112 | if(nv === undefined){ // SemiPositiveness lost 113 | B = numeric.identity(guess.length); 114 | continue; 115 | } 116 | if(nv == v) return [Obj, W]; // max precision 117 | v = nv; 118 | if(norm2(v.df) < eps) return [Obj, W]; 119 | /* start: refresh Jacobian */ 120 | var y = sub(v.df,og); 121 | var vs = trsp([v.s]); 122 | var ts = [v.s]; 123 | var vy = trsp([y]); 124 | var ty = [y]; 125 | subeq(B,mul(1/dot(ts,dot(B,vs)),dot(B,dot(vs,dot(ts,B))))); 126 | addeq(B,mul(1/dot(ty,vs),dot(vy,ty))); 127 | /* end: refresh Jacobian */ 128 | } 129 | debugger; 130 | return [Obj, W] 131 | 132 | } 133 | 134 | function runBFGS2(func, w0, alpha, totalIters) { 135 | function f1(w){ 136 | return func(w)[0] 137 | } 138 | function df1(w) { 139 | return func(w)[1] 140 | } 141 | return _bfgs(w0, {f:f1, df: df1}, totalIters, 10e-16) 142 | } 143 | // 144 | // 145 | // globalScope.bfgs = bfgs; 146 | // globalScobe.runBFGS2 = runBFGS2; 147 | // }).call(this); 148 | -------------------------------------------------------------------------------- /public/assets/lib/contour_plot.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : 3 | typeof define === 'function' && define.amd ? define('contour_plot', ['exports'], factory) : 4 | factory((global.contour_plot = {})); 5 | }(this, function (exports) { 'use strict'; 6 | 7 | /** finds the zeros of a function, given two starting points (which must 8 | * have opposite signs */ 9 | function bisect(f, a, b, parameters) { 10 | parameters = parameters || {}; 11 | var maxIterations = parameters.maxIterations || 100, 12 | tolerance = parameters.tolerance || 1e-10, 13 | fA = f(a), 14 | fB = f(b), 15 | delta = b - a; 16 | 17 | if (fA * fB > 0) { 18 | throw "Initial bisect points must have opposite signs"; 19 | } 20 | 21 | if (fA === 0) return a; 22 | if (fB === 0) return b; 23 | 24 | for (var i = 0; i < maxIterations; ++i) { 25 | delta /= 2; 26 | var mid = a + delta, 27 | fMid = f(mid); 28 | 29 | if (fMid * fA >= 0) { 30 | a = mid; 31 | } 32 | 33 | if ((Math.abs(delta) < tolerance) || (fMid === 0)) { 34 | return mid; 35 | } 36 | } 37 | return a + delta; 38 | } 39 | 40 | // This file is modified from the d3.geom.contour 41 | // plugin found here https://github.com/d3/d3-plugins/tree/master/geom/contour 42 | 43 | /* 44 | Copyright (c) 2012-2015, Michael Bostock 45 | All rights reserved. 46 | 47 | Redistribution and use in source and binary forms, with or without 48 | modification, are permitted provided that the following conditions are met: 49 | 50 | * Redistributions of source code must retain the above copyright notice, this 51 | list of conditions and the following disclaimer. 52 | 53 | * Redistributions in binary form must reproduce the above copyright notice, 54 | this list of conditions and the following disclaimer in the documentation 55 | and/or other materials provided with the distribution. 56 | 57 | * The name Michael Bostock may not be used to endorse or promote products 58 | derived from this software without specific prior written permission. 59 | 60 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 61 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 62 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 63 | DISCLAIMED. IN NO EVENT SHALL MICHAEL BOSTOCK BE LIABLE FOR ANY DIRECT, 64 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 65 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 66 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 67 | OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 68 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 69 | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 70 | */ 71 | 72 | function d3_contour(grid, start) { 73 | var s = start || d3_geom_contourStart(grid), // starting point 74 | c = [], // contour polygon 75 | x = s[0], // current x position 76 | y = s[1], // current y position 77 | dx = 0, // next x direction 78 | dy = 0, // next y direction 79 | pdx = NaN, // previous x direction 80 | pdy = NaN, // previous y direction 81 | i = 0; 82 | 83 | do { 84 | // determine marching squares index 85 | i = 0; 86 | if (grid(x-1, y-1)) i += 1; 87 | if (grid(x, y-1)) i += 2; 88 | if (grid(x-1, y )) i += 4; 89 | if (grid(x, y )) i += 8; 90 | 91 | // determine next direction 92 | if (i === 6) { 93 | dx = pdy === -1 ? -1 : 1; 94 | dy = 0; 95 | } else if (i === 9) { 96 | dx = 0; 97 | dy = pdx === 1 ? -1 : 1; 98 | } else { 99 | dx = d3_geom_contourDx[i]; 100 | dy = d3_geom_contourDy[i]; 101 | } 102 | 103 | // update contour polygon 104 | if (dx != pdx && dy != pdy) { 105 | c.push([x, y]); 106 | pdx = dx; 107 | pdy = dy; 108 | } else { 109 | c.push([x, y]); 110 | } 111 | 112 | x += dx; 113 | y += dy; 114 | } while (s[0] != x || s[1] != y); 115 | 116 | return c; 117 | } 118 | 119 | // lookup tables for marching directions 120 | var d3_geom_contourDx = [1, 0, 1, 1,-1, 0,-1, 1,0, 0,0,0,-1, 0,-1,NaN]; 121 | var d3_geom_contourDy = [0,-1, 0, 0, 0,-1, 0, 0,1,-1,1,1, 0,-1, 0,NaN]; 122 | function d3_geom_contourStart(grid) { 123 | var x = 0, 124 | y = 0; 125 | 126 | // search for a starting point; begin at origin 127 | // and proceed along outward-expanding diagonals 128 | while (true) { 129 | if (grid(x,y)) { 130 | return [x,y]; 131 | } 132 | if (x === 0) { 133 | x = y + 1; 134 | y = 0; 135 | } else { 136 | x = x - 1; 137 | y = y + 1; 138 | } 139 | } 140 | } 141 | 142 | function isoline(f, value, xScale, yScale) { 143 | var xRange = xScale.range(), yRange = yScale.range(); 144 | return function(x, y) { 145 | if ((x < xRange[0]) || (x > xRange[1]) || 146 | (y < yRange[0]) || (y > yRange[1])) return false; 147 | return f(xScale.invert(x), yScale.invert(y)) < value; 148 | }; 149 | } 150 | 151 | function smoothPoints(f, points, level, xScale, yScale) { 152 | var xRange = xScale.range(), yRange = yScale.range(); 153 | var ySmooth = function(y) { 154 | return f(xScale.invert(x), yScale.invert(y)) - level; 155 | }; 156 | var xSmooth = function(x) { 157 | return f(xScale.invert(x), yScale.invert(y)) - level; 158 | }; 159 | for (var k = 0; k < points.length; ++k) { 160 | var point = points[k], 161 | x = point[0], y = point[1]; 162 | 163 | if ((x <= xRange[0]) || (x >= xRange[1]) || 164 | (y <= yRange[0]) || (y >= yRange[1])) continue; 165 | 166 | var currentSmooth = ySmooth(y); 167 | 168 | var p = {'maxIterations' : 9}; 169 | for (var delta = 0.5; delta <= 3; delta += 0.5) { 170 | if (ySmooth(y - delta) * currentSmooth < 0) { 171 | y = bisect(ySmooth, y, y - delta, p); 172 | } else if (xSmooth(x - delta) * currentSmooth < 0) { 173 | x = bisect(xSmooth, x, x - delta, p); 174 | } else if (ySmooth(y + delta) * currentSmooth < 0) { 175 | y = bisect(ySmooth, y, y + delta, p); 176 | } else if (xSmooth(x + delta) * currentSmooth < 0) { 177 | x = bisect(xSmooth, x, x + delta, p); 178 | } else { 179 | continue; 180 | } 181 | break; 182 | } 183 | 184 | point[0] = x; 185 | point[1] = y; 186 | } 187 | } 188 | 189 | function getLogLevels(f, xScale, yScale, count) { 190 | var xRange = xScale.range(), yRange = yScale.range(); 191 | 192 | // figure out min/max values by sampling pointson a grid 193 | var maxValue, minValue, value; 194 | maxValue = minValue = f(xScale.invert(xRange[0]), yScale.invert(yRange[0])); 195 | for (var y = yRange[0]; y < yRange[1]+1; ++y) { 196 | for (var x = xRange[0]; x < xRange[1]+1; ++x) { 197 | value = f(xScale.invert(x),yScale.invert(y)); 198 | minValue = Math.min(value, minValue); 199 | maxValue = Math.max(value, maxValue); 200 | } 201 | } 202 | 203 | // lets get contour lines on a log scale, keeping 204 | // values on an integer scale (if possible) 205 | var levels = []; 206 | var logRange = Math.log(maxValue - Math.floor(minValue)); 207 | var base = Math.ceil(Math.exp(logRange / (count))), 208 | upper = Math.pow(base, Math.ceil(logRange / Math.log(base))); 209 | 210 | for (var i = 0; i < count; ++i) { 211 | var current = Math.floor(minValue) + upper; 212 | if (current < minValue) { 213 | break; 214 | } 215 | levels.push(current); 216 | upper /= base; 217 | } 218 | 219 | return levels; 220 | } 221 | 222 | function getStartingPoint(lineFunc, x, y) { 223 | x = Math.floor(x); 224 | y = Math.floor(y); 225 | var j = 0; 226 | while (true) { 227 | j += 1; 228 | if (!lineFunc(x+j, y)) { 229 | return [x+j, y]; 230 | } 231 | if (!lineFunc(x, y+j)) { 232 | return [x, y+j]; 233 | } 234 | } 235 | } 236 | 237 | function getContours(f, xScale, yScale, count, minima) { 238 | // figure out even distribution in log space of values 239 | var levels = getLogLevels(f, xScale, yScale, count); 240 | 241 | // use marching squares algo from d3.geom.contour to build up a series of paths 242 | var ret = []; 243 | for (var i = 0; i < levels.length; ++i) { 244 | var level = levels[i]; 245 | var lineFunc = isoline(f, level, xScale, yScale); 246 | 247 | var points= []; 248 | if (minima) { 249 | var initialPoints = []; 250 | for (var m = 0; m < minima.length; ++m) { 251 | var initial = getStartingPoint(lineFunc, xScale(minima[m].x), yScale(minima[m].y)); 252 | var current = d3_contour(lineFunc, initial); 253 | 254 | // don't add points if already seen 255 | var duplicate = false; 256 | for (var j = 0 ; j < current.length; ++j) { 257 | var point = current[j]; 258 | for (var k = 0; k < initialPoints.length; ++k) { 259 | var other = initialPoints[k]; 260 | if ((point[0] == other[0]) && 261 | (point[1] == other[1])) { 262 | duplicate = true; 263 | break; 264 | } 265 | } 266 | if (duplicate) break; 267 | } 268 | if (duplicate) continue; 269 | 270 | initialPoints.push(initial); 271 | 272 | smoothPoints(f, current, level, xScale, yScale); 273 | if (points.length) points.push(null); 274 | points = points.concat(current); 275 | } 276 | } else { 277 | points = d3_contour(lineFunc); 278 | smoothPoints(f, points, level, xScale, yScale); 279 | 280 | } 281 | 282 | ret.push(points); 283 | } 284 | 285 | // return the contours 286 | return {'paths': ret, 'levels': levels}; 287 | } 288 | 289 | function ContourPlot(width, height) { 290 | 291 | var drawAxis = false, 292 | f = function (x, y) { return (1 - x) * (1 - x) + 100 * (y - x * x) * ( y - x * x); }, 293 | yDomain = [3, -3], 294 | xDomain = [-2, 2], 295 | minima = null, 296 | contourCount = 14, 297 | colourScale = d3.scaleLinear().domain([1, contourCount/3, contourCount-1]).range(["rgb(240,244,246)", "rgb(217,225,232)", "#aec0ce"]), 298 | colourScaleBorder = d3.scaleLinear().domain([0, contourCount]).range(["lightgray", "darkgray"]), 299 | aspect_ratio = 0.4; 300 | 301 | // todo: resolution independent (sample say 200x200) 302 | // todo: handle function with multiple local minima 303 | 304 | function chart(selection) { 305 | var padding = (drawAxis) ? 24 : 0, 306 | yScale = d3.scaleLinear() 307 | .range([padding, height - padding]) 308 | .domain(yDomain), 309 | 310 | xScale = d3.scaleLinear() 311 | .range([padding, width - padding]) 312 | .domain(xDomain); 313 | 314 | // create tooltip if doesn't exist 315 | d3.select("body").selectAll(".contour_tooltip").data([0]).enter() 316 | .append("div") 317 | .attr("class", "contour_tooltip") 318 | .style("font-size", "12px") 319 | .style("position", "absolute") 320 | .style("text-align", "center") 321 | .style("width", "128px") 322 | .style("height", "32px") 323 | .style("background", "#333") 324 | .style("color", "#ddd") 325 | .style("padding", "0px") 326 | .style("border", "0px") 327 | .style("border-radius", "8px") 328 | .style("opacity", "0"); 329 | 330 | var tooltip = d3.selectAll(".contour_tooltip"); 331 | 332 | // create the svg element if it doesn't already exist 333 | selection.selectAll("svg").data([0]).enter().append("svg"); 334 | var svg = selection.selectAll("svg").data([0]); 335 | 336 | svg.attr("width", width) 337 | .attr("height", height) 338 | 339 | var contours = getContours(f, xScale, yScale, contourCount, minima); 340 | var paths = contours.paths, 341 | levels = contours.levels; 342 | 343 | var line = d3.line() 344 | .x(function(d) { return d[0]; }) 345 | .y(function(d) { return d[1]; }) 346 | .curve(d3.curveLinearClosed) 347 | .defined(function(d) { return d; }); 348 | 349 | var pathGroup = svg.append("g"); 350 | 351 | pathGroup.selectAll("path").data(paths).enter() 352 | .append("path") 353 | .attr("d", line) 354 | .style("fill", function(d, i) { return colourScale(i); }) 355 | .style("stroke-width", 0.8) 356 | .style("stroke", "#225577") 357 | .style("stroke-opacity","0.2") 358 | // .attr("transform", "translate(4,4)") 359 | .on("mouseover", function() { 360 | //d3.select(this).style("stroke-width", "4"); 361 | }) 362 | .on("mouseout", function() { 363 | //d3.select(this).style("stroke-width", "1.5"); 364 | }); 365 | 366 | // draw axii 367 | if (drawAxis) { 368 | var xAxis = d3.axisBottom().scale(xScale), 369 | yAxis = d3.axisLeft().scale(yScale); 370 | 371 | svg.append("g") 372 | .attr("class", "axis") 373 | .attr("transform", "translate(0," + (height - 1.0 * padding) + ")") 374 | .call(xAxis); 375 | 376 | svg.append("g") 377 | .attr("class", "axis") 378 | .attr("transform", "translate(" + (padding) + ",0)") 379 | .call(yAxis); 380 | } 381 | 382 | return {'xScale' : xScale, 'yScale' : yScale, 'svg' : svg}; 383 | } 384 | chart.drawAxis = function(_) { 385 | if (!arguments.length) return drawAxis; 386 | drawAxis = _; 387 | return chart; 388 | }; 389 | 390 | chart.xDomain = function(_) { 391 | if (!arguments.length) return xDomain; 392 | xDomain = _; 393 | return chart; 394 | }; 395 | 396 | chart.yDomain = function(_) { 397 | if (!arguments.length) return yDomain; 398 | yDomain = _; 399 | return chart; 400 | }; 401 | 402 | chart.colourScale = function(_) { 403 | if (!arguments.length) return colourScale; 404 | colourScale = _; 405 | return chart; 406 | }; 407 | 408 | chart.contourCount = function(_) { 409 | if (!arguments.length) return contourCount; 410 | contourCount = _; 411 | return chart; 412 | }; 413 | 414 | chart.minima = function(_) { 415 | if (!arguments.length) return minima; 416 | minima = _; 417 | return chart; 418 | }; 419 | 420 | chart.f = function(_) { 421 | if (!arguments.length) return f; 422 | f = _; 423 | return chart; 424 | }; 425 | 426 | return chart; 427 | } 428 | 429 | var version = "0.0.1"; 430 | 431 | exports.version = version; 432 | exports.isoline = isoline; 433 | exports.smoothPoints = smoothPoints; 434 | exports.getLogLevels = getLogLevels; 435 | exports.getContours = getContours; 436 | exports.ContourPlot = ContourPlot; 437 | 438 | })); 439 | -------------------------------------------------------------------------------- /public/assets/lib/contrib/auto-render.min.js: -------------------------------------------------------------------------------- 1 | (function(e){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=e()}else if(typeof define==="function"&&define.amd){define([],e)}else{var t;if(typeof window!=="undefined"){t=window}else if(typeof global!=="undefined"){t=global}else if(typeof self!=="undefined"){t=self}else{t=this}t.renderMathInElement=e()}})(function(){var e,t,r;return function n(e,t,r){function a(o,l){if(!t[o]){if(!e[o]){var f=typeof require=="function"&&require;if(!l&&f)return f(o,!0);if(i)return i(o,!0);var d=new Error("Cannot find module '"+o+"'");throw d.code="MODULE_NOT_FOUND",d}var s=t[o]={exports:{}};e[o][0].call(s.exports,function(t){var r=e[o][1][t];return a(r?r:t)},s,s.exports,n,e,t,r)}return t[o].exports}var i=typeof require=="function"&&require;for(var o=0;o px) { 88 | // East 89 | if (y > py) return "SE"; 90 | if (y < -py) return "NE"; 91 | if (x > r) return "E"; 92 | return null; 93 | } 94 | else if (x < -px) { 95 | // West 96 | if (y > py) return "SW"; 97 | if (y < -py) return "NW"; 98 | if (x < -r) return "W"; 99 | return null; 100 | } 101 | else { 102 | // Center 103 | if (y > r) return "S"; 104 | if (y < -r) return "N"; 105 | } 106 | } 107 | } 108 | 109 | function dragmoveCenter(d) { 110 | var gRingNote = d3.select(this.parentNode.parentNode); 111 | 112 | d.cx += d3.event.x; 113 | d.cy += d3.event.y; 114 | 115 | gRingNote 116 | .attr("transform", function(d) { 117 | return "translate(" + d.cx + "," + d.cy + ")"; 118 | }); 119 | } 120 | 121 | function dragmoveRadius(d) { 122 | var gRingNote = d3.select(this.parentNode.parentNode), 123 | gAnnotation = gRingNote.select(".annotation"), 124 | circle = gAnnotation.select("circle"), 125 | line = gAnnotation.select("path"), 126 | text = gAnnotation.select("text"), 127 | radius = d3.select(this); 128 | 129 | d.r += d3.event.dx; 130 | 131 | circle.attr("r", function(d) { return d.r; }); 132 | radius.attr("cx", function(d) { return d.r; }); 133 | line.call(updateLine); 134 | text.call(updateText); 135 | } 136 | 137 | function dragmoveText(d) { 138 | var gAnnotation = d3.select(this.parentNode), 139 | line = gAnnotation.select("path"), 140 | text = d3.select(this); 141 | 142 | d.textOffset[0] += d3.event.dx; 143 | d.textOffset[1] += d3.event.dy; 144 | 145 | text.call(updateText); 146 | line.call(updateLine); 147 | } 148 | 149 | function updateLine(selection) { 150 | return selection.attr("d", function(d) { 151 | var x = d.textOffset[0], 152 | y = d.textOffset[1], 153 | lineData = getLineData(x, y, d.r); 154 | return path(lineData); 155 | }); 156 | } 157 | 158 | function getLineData(x, y, r) { 159 | var region = getRegion(x, y, r); 160 | 161 | if (region == null) { 162 | // No line if text is inside the circle 163 | return []; 164 | } 165 | else { 166 | // Cardinal directions 167 | if (region == "N") return [[0, -r], [0, y]]; 168 | if (region == "E") return [[r, 0], [x, 0]]; 169 | if (region == "S") return [[0, r], [0, y]]; 170 | if (region == "W") return [[-r, 0],[x, 0]]; 171 | 172 | var d0 = r * Math.cos(Math.PI/4), 173 | d1 = Math.min(Math.abs(x), Math.abs(y)) - d0; 174 | 175 | // Intermediate directions 176 | if (region == "NE") return [[ d0, -d0], [ d0 + d1, -d0 - d1], [x, y]]; 177 | if (region == "SE") return [[ d0, d0], [ d0 + d1, d0 + d1], [x, y]]; 178 | if (region == "SW") return [[-d0, d0], [-d0 - d1, d0 + d1], [x, y]]; 179 | if (region == "NW") return [[-d0, -d0], [-d0 - d1, -d0 - d1], [x, y]]; 180 | } 181 | } 182 | 183 | function updateText(selection) { 184 | return selection.each(function(d) { 185 | var x = d.textOffset[0], 186 | y = d.textOffset[1], 187 | region = getRegion(x, y, d.r), 188 | textCoords = getTextCoords(x, y, region); 189 | 190 | d3.select(this) 191 | .attr("x", textCoords.x) 192 | .attr("y", textCoords.y) 193 | .text(d.text) 194 | .each(function(d) { 195 | var x = d.textOffset[0], 196 | y = d.textOffset[1], 197 | textAnchor = getTextAnchor(x, y, region); 198 | 199 | var dx = textAnchor == "start" ? "0.33em" : 200 | textAnchor == "end" ? "-0.33em" : "0"; 201 | 202 | var dy = textAnchor !== "middle" ? ".33em" : 203 | ["NW", "N", "NE"].indexOf(region) !== -1 ? "-.33em" : "1em"; 204 | 205 | var orientation = textAnchor !== "middle" ? undefined : 206 | ["NW", "N", "NE"].indexOf(region) !== -1 ? "bottom" : "top"; 207 | 208 | d3.select(this) 209 | .style("text-anchor", textAnchor) 210 | .attr("dx", dx) 211 | .attr("dy", dy) 212 | .call(wrapText, d.textWidth || 960, orientation); 213 | }); 214 | }); 215 | } 216 | 217 | function getTextCoords(x, y, region) { 218 | if (region == "N") return { x: 0, y: y }; 219 | if (region == "E") return { x: x, y: 0 }; 220 | if (region == "S") return { x: 0, y: y }; 221 | if (region == "W") return { x: x, y: 0 }; 222 | return { x: x, y: y }; 223 | } 224 | 225 | function getTextAnchor(x, y, region) { 226 | if (region == null) { 227 | return "middle"; 228 | } 229 | else { 230 | // Cardinal directions 231 | if (region == "N") return "middle"; 232 | if (region == "E") return "start"; 233 | if (region == "S") return "middle"; 234 | if (region == "W") return "end"; 235 | 236 | var xLonger = Math.abs(x) > Math.abs(y); 237 | 238 | // Intermediate directions` 239 | if (region == "NE") return xLonger ? "start" : "middle"; 240 | if (region == "SE") return xLonger ? "start" : "middle"; 241 | if (region == "SW") return xLonger ? "end" : "middle"; 242 | if (region == "NW") return xLonger ? "end" : "middle"; 243 | } 244 | } 245 | 246 | // Adapted from: https://bl.ocks.org/mbostock/7555321 247 | function wrapText(text, width, orientation) { 248 | text.each(function(d) { 249 | var text = d3.select(this), 250 | words = text.text().split(/\s+/).reverse(), 251 | word, 252 | line = [], 253 | lineNumber = 1, 254 | lineHeight = 1.1, // ems 255 | x = text.attr("x"), 256 | dx = text.attr("dx"), 257 | tspan = text.text(null).append("tspan").attr("x", x).attr("dx", dx); 258 | while (word = words.pop()) { 259 | line.push(word); 260 | tspan.text(line.join(" ")); 261 | if (tspan.node().getComputedTextLength() > width) { 262 | line.pop(); 263 | tspan.text(line.join(" ")); 264 | line = [word]; 265 | tspan = text.append("tspan") 266 | .attr("x", x) 267 | .attr("dx", dx) 268 | .attr("dy", lineHeight + "em") 269 | .text(word); 270 | lineNumber++; 271 | } 272 | } 273 | 274 | var dy; 275 | if (orientation == "bottom") { 276 | dy = -lineHeight * (lineNumber-1) - .33; 277 | } 278 | else if (orientation == "top") { 279 | dy = 1; 280 | } 281 | else { 282 | dy = -lineHeight * ((lineNumber-1) / 2) + .33; 283 | } 284 | text.attr("dy", dy + "em"); 285 | 286 | }); 287 | } 288 | 289 | function styleControl(selection) { 290 | selection 291 | .attr("r", controlRadius) 292 | .style("fill-opacity", "0") 293 | .style("stroke", "black") 294 | .style("stroke-dasharray", "3, 3") 295 | .style("cursor", "move"); 296 | } 297 | 298 | return draw; 299 | }; -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_AMS-Regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_AMS-Regular.eot -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_AMS-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_AMS-Regular.ttf -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_AMS-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_AMS-Regular.woff -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_AMS-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_AMS-Regular.woff2 -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_Caligraphic-Bold.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_Caligraphic-Bold.eot -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_Caligraphic-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_Caligraphic-Bold.ttf -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_Caligraphic-Bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_Caligraphic-Bold.woff -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_Caligraphic-Bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_Caligraphic-Bold.woff2 -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_Caligraphic-Regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_Caligraphic-Regular.eot -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_Caligraphic-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_Caligraphic-Regular.ttf -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_Caligraphic-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_Caligraphic-Regular.woff -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_Caligraphic-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_Caligraphic-Regular.woff2 -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_Fraktur-Bold.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_Fraktur-Bold.eot -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_Fraktur-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_Fraktur-Bold.ttf -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_Fraktur-Bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_Fraktur-Bold.woff -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_Fraktur-Bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_Fraktur-Bold.woff2 -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_Fraktur-Regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_Fraktur-Regular.eot -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_Fraktur-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_Fraktur-Regular.ttf -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_Fraktur-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_Fraktur-Regular.woff -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_Fraktur-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_Fraktur-Regular.woff2 -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_Main-Bold.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_Main-Bold.eot -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_Main-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_Main-Bold.ttf -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_Main-Bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_Main-Bold.woff -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_Main-Bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_Main-Bold.woff2 -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_Main-Italic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_Main-Italic.eot -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_Main-Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_Main-Italic.ttf -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_Main-Italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_Main-Italic.woff -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_Main-Italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_Main-Italic.woff2 -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_Main-Regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_Main-Regular.eot -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_Main-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_Main-Regular.ttf -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_Main-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_Main-Regular.woff -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_Main-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_Main-Regular.woff2 -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_Math-BoldItalic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_Math-BoldItalic.eot -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_Math-BoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_Math-BoldItalic.ttf -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_Math-BoldItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_Math-BoldItalic.woff -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_Math-BoldItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_Math-BoldItalic.woff2 -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_Math-Italic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_Math-Italic.eot -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_Math-Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_Math-Italic.ttf -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_Math-Italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_Math-Italic.woff -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_Math-Italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_Math-Italic.woff2 -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_Math-Regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_Math-Regular.eot -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_Math-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_Math-Regular.ttf -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_Math-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_Math-Regular.woff -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_Math-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_Math-Regular.woff2 -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_SansSerif-Bold.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_SansSerif-Bold.eot -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_SansSerif-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_SansSerif-Bold.ttf -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_SansSerif-Bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_SansSerif-Bold.woff -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_SansSerif-Bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_SansSerif-Bold.woff2 -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_SansSerif-Italic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_SansSerif-Italic.eot -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_SansSerif-Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_SansSerif-Italic.ttf -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_SansSerif-Italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_SansSerif-Italic.woff -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_SansSerif-Italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_SansSerif-Italic.woff2 -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_SansSerif-Regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_SansSerif-Regular.eot -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_SansSerif-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_SansSerif-Regular.ttf -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_SansSerif-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_SansSerif-Regular.woff -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_SansSerif-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_SansSerif-Regular.woff2 -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_Script-Regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_Script-Regular.eot -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_Script-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_Script-Regular.ttf -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_Script-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_Script-Regular.woff -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_Script-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_Script-Regular.woff2 -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_Size1-Regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_Size1-Regular.eot -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_Size1-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_Size1-Regular.ttf -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_Size1-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_Size1-Regular.woff -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_Size1-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_Size1-Regular.woff2 -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_Size2-Regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_Size2-Regular.eot -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_Size2-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_Size2-Regular.ttf -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_Size2-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_Size2-Regular.woff -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_Size2-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_Size2-Regular.woff2 -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_Size3-Regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_Size3-Regular.eot -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_Size3-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_Size3-Regular.ttf -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_Size3-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_Size3-Regular.woff -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_Size3-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_Size3-Regular.woff2 -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_Size4-Regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_Size4-Regular.eot -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_Size4-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_Size4-Regular.ttf -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_Size4-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_Size4-Regular.woff -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_Size4-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_Size4-Regular.woff2 -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_Typewriter-Regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_Typewriter-Regular.eot -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_Typewriter-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_Typewriter-Regular.ttf -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_Typewriter-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_Typewriter-Regular.woff -------------------------------------------------------------------------------- /public/assets/lib/fonts/KaTeX_Typewriter-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabianp/overview_optalgs/5712df1eee023ac4214ebf15c43945dcc35a44e7/public/assets/lib/fonts/KaTeX_Typewriter-Regular.woff2 -------------------------------------------------------------------------------- /public/assets/milestones.js: -------------------------------------------------------------------------------- 1 | function renderMilestones(div, updateTick) { 2 | var lambda = [1,10,100] 3 | var totalIters = 151 4 | 5 | div.append("defs").append("marker") 6 | .attr("id", "arrowhead") 7 | .attr("refX", 3) 8 | .attr("refY", 2) 9 | .attr("markerWidth", 4) 10 | .attr("markerHeight", 4) 11 | .attr("orient", "auto") 12 | .append("path") 13 | .attr("d", "M 0,0 V 4 L4,2 Z"); //this is actual shape for arrowhead 14 | 15 | var markers = [] 16 | for (var i = 0; i < 3; i ++) { 17 | var marker = div.append("defs").append("marker") 18 | .attr("id", "arrowhead" + i) 19 | .attr("refX", 0) 20 | .attr("refY", 1) 21 | .attr("markerWidth", 4) 22 | .attr("markerHeight", 4) 23 | .attr("orient", "auto") 24 | .append("path") 25 | .attr("d", "M 0,0 V 2 L2,1 Z") //this is actual shape for arrowhead 26 | .attr("fill", colorbrewer.RdPu[3][i]) 27 | markers.push(marker) 28 | } 29 | 30 | var f = function(x) { 31 | var fx = 0.5*(lambda[0]*x[0]*x[0] + lambda[1]*x[1]*x[1] + lambda[2]*x[2]*x[2]) 32 | var g = [lambda[0]*x[0], lambda[1]*x[1], lambda[2]*x[2]] 33 | return [fx, g] 34 | } 35 | 36 | /* 37 | Gets information about iterates with certain parameter alpha and beta. 38 | > v = getTrace(0.5, 0) 39 | v[0] -> z iterates 40 | v[1] -> w iterates 41 | v[2] -> [c1, c2, c3] where c1, c2, c3 are the contributions to the loss 42 | */ 43 | function getTrace(alpha, beta) { 44 | var w0 = [1,1/Math.sqrt(lambda[1]),1/Math.sqrt(lambda[2])] 45 | var v = runMomentum(f, w0, alpha, beta, totalIters) 46 | var fxstack = [] 47 | // Add contributions to the objective 48 | for (var i = 0; i < v[0].length; i++) { 49 | var x = v[1][i] 50 | fxstack.push([lambda[0]*x[0]*x[0]/2, lambda[1]*x[1]*x[1]/2, lambda[2]*x[2]*x[2]/2 ]) 51 | } 52 | v.push(fxstack) 53 | return v 54 | } 55 | 56 | var stackedBar = stackedBarchartGen(totalIters, 3)(div) 57 | 58 | var seperation = 14 59 | 60 | var r = [] 61 | var lines = [] 62 | 63 | var progressmeter = div.append("g") 64 | for (var i = 0; i < 3; i ++) { 65 | var ri = progressmeter.append("line") 66 | .attr("x1", stackedBar.X(-1) + "px") 67 | .attr("y1", (202 + i*seperation)+ "px") 68 | .attr("stroke", colorbrewer.RdPu[3][i]) 69 | .attr("y2", (202 + i*seperation) + "px") 70 | .attr("stroke-width", 4) 71 | r.push(ri) 72 | 73 | var linei = progressmeter.append("line") 74 | .style("stroke", "black") 75 | .style("stroke-width",1.5) 76 | .attr("marker-end", "url(#arrowhead)") 77 | .attr("opacity", 0.6) 78 | lines.push(linei) 79 | 80 | progressmeter.append("text") 81 | .attr("class", "figtext2") 82 | .attr("x", 0) 83 | .attr("y", 206 + i*seperation) 84 | .attr("text-anchor", "end") 85 | .attr("fill", "gray") 86 | .html((i == 0) ? "Eigenvalue " + (i+1) : (i+1) ) 87 | } 88 | 89 | 90 | var updateStep = function(alpha, beta) { 91 | var trace = getTrace(alpha/lambda[2], beta) 92 | // Update the milestones on the slider 93 | var milestones = [0,0,0] 94 | for (var i = 0; i < trace[1].length; i++) { 95 | if (trace[2][i][0] > 0.01) { milestones[2] = i } 96 | if (trace[2][i][1] > 0.01) { milestones[1] = i } 97 | if (trace[2][i][2] > 0.01) { milestones[0] = i } 98 | } 99 | stackedBar.update(trace[2], milestones) 100 | 101 | for (var i = 0; i < 3; i++) { 102 | 103 | var endpoint = stackedBar.stack[i].selectAll("line").nodes()[milestones[2-i]] 104 | var stack = endpoint.getBBox() 105 | var ctm = endpoint.getCTM() 106 | if (milestones[2-i] < 150) { 107 | lines[i].attr("x2", stack.x) 108 | .attr("y2", stack.y + 5) 109 | .attr("x1", stack.x) 110 | .attr("y1", 203.5 + seperation*(i)) 111 | .style("visibility", "visible") 112 | r[i].attr("marker-end", "url()") 113 | } else { 114 | lines[i].style("visibility", "hidden") 115 | r[i].attr("marker-end", "url(#arrowhead" + i + ")") 116 | } 117 | //setTM(lines[i].node(), ctm) // transform the lines into stackedplot space 118 | r[i].attr("x2", (stackedBar.X(milestones[2-i]) - 2) + "px") 119 | 120 | //setTM(r[i].node(), ctm) // transform the lines into stackedplot space 121 | setTM(progressmeter.node(), ctm) 122 | } 123 | } 124 | 125 | updateStep(100*2/(101.5), 0) 126 | 127 | return updateStep 128 | } -------------------------------------------------------------------------------- /public/assets/momentum.js: -------------------------------------------------------------------------------- 1 | /* 2 | Render an overlay layer 3 | */ 4 | 5 | function renderOverlay(svg, nodes) { 6 | 7 | var ringPath = ringPathGen(5, 0, 0) 8 | 9 | var updates = [] 10 | 11 | for (var i = 0; i < 5; i++) { 12 | 13 | var adjust = [0,0,0,0,0][i] 14 | var x1 = nodes[i].offsetLeft + 15 15 | var y1 = nodes[i].offsetTop + adjust 16 | 17 | var line = svg.append("line") 18 | .style("stroke", "black") 19 | .style("stroke-width", "1px") 20 | // .attr("stroke-dasharray", "2,2") 21 | .attr("opacity", 0.7) 22 | .attr("x1", x1) 23 | .attr("y1", y1) 24 | .attr("x2", x1) 25 | .attr("y2", y1 - adjust) 26 | .attr("shape-rendering", "crispEdges") 27 | 28 | var paths = svg.append("g"); 29 | 30 | paths.append("path") 31 | .attr("class", "leader-line") 32 | .attr("d", ringPath([110,110],[x1,y1]).d) 33 | .style("stroke-width", "3px") 34 | .style("fill", "none") 35 | .attr("stroke", "white") 36 | // .attr("stroke-dasharray", "2,2") 37 | .attr("stroke-opacity", 0.4) 38 | .attr("shape-rendering", "crispEdges"); 39 | 40 | paths.append("path") 41 | .attr("class", "leader-line") 42 | .attr("d", ringPath([110,110],[x1,y1]).d) 43 | .style("stroke-width", "1px") 44 | .style("fill", "none") 45 | .attr("stroke", "black") 46 | // .attr("stroke-dasharray", "2,2") 47 | .attr("stroke-opacity", 0.3) 48 | .attr("shape-rendering", "crispEdges"); 49 | 50 | var path = paths.selectAll(".leader-line") 51 | 52 | var circ = svg.append("g") 53 | .attr("transform", "translate(" + x1 + "," + y1 + ")"); 54 | 55 | circ.append("circle") 56 | .attr("r", 5) 57 | .attr("fill","none") 58 | .attr("stroke", "white") 59 | .attr("stroke-width", 4) 60 | .attr("stroke-opacity", 0.5); 61 | 62 | circ.append("circle") 63 | .attr("r", 5) 64 | .attr("fill","none") 65 | .attr("stroke", "black") 66 | .attr("stroke-width", 1); 67 | 68 | n = nodes 69 | var updatePath = (function(xin, yin, pathin, circin,i, aline) { 70 | return function(x2, y2, bold) { 71 | 72 | if (!bold) { 73 | d3.select(nodes[i]).style("opacity", 0.1) 74 | } else { 75 | d3.select(nodes[i]).style("opacity", 1) 76 | } 77 | 78 | circin.attr("transform", "translate(" + x2 + "," + y2 + ")"); 79 | 80 | if (i < 2) { 81 | pathin.attr("d", ringPath([x2, y2],[xin, yin]).d); 82 | } else { 83 | pathin.attr("d", ringPath([xin + 5, yin + 5],[x2 + 4, y2]).d); 84 | } 85 | aline.attr("opacity", bold? 1 : 0.7).style("stroke-width", bold? 1:1).style("stroke", "rgb(150, 150, 150)") 86 | } 87 | })(x1, y1, path, circ,i,line) 88 | 89 | updates.push(updatePath) 90 | } 91 | 92 | return updates 93 | } 94 | 95 | /* 96 | Render the whole momentum widget 97 | */ 98 | function renderTaxonomy(div) { 99 | 100 | var valueline = d3.line() 101 | .x(function(d) { return d[0]; }) 102 | .y(function(d) { return d[1]; }); 103 | 104 | function drawPath(svg, s1, s2, e1, e2) { 105 | 106 | svg.append("path") 107 | .attr("opacity", 1) 108 | .style("stroke", "black") 109 | .style("stroke-width", "1px") 110 | .style("stroke-linecap","round") 111 | .attr("d", genPath( s1, s2, e1, e2 )) 112 | 113 | } 114 | 115 | var num_iters = 40 116 | 117 | function getTrace(alpha, beta, xy, coord) { 118 | var m = [] 119 | var lambda = [1,100] 120 | var iter = geniterMomentum([[1, 0],[0, 1]], lambda, lambda, alpha, beta).iter 121 | // run for 500 iterations 122 | for (var i = 0; i <= num_iters; i++) { 123 | if (xy == 1) { m.push(numeric.add(iter(i)[xy],-1)) } 124 | if (xy == 0) { m.push(numeric.mul(iter(i)[xy],0.005)) } 125 | } 126 | return numeric.transpose(m)[coord] 127 | } 128 | 129 | div.style("display", "block") 130 | .style("margin-left","auto") 131 | .style("margin-right","auto") 132 | .style("position", "relative") 133 | .style("border-radius", "5px") 134 | 135 | var divs = [] 136 | function genPhase(i,t,l, range,title,text) { 137 | 138 | var outdiv = div.append("div") 139 | .style("position", "absolute") 140 | .style("top", t +"px") 141 | .style("left", l +"px") 142 | .style("width", "180px") 143 | .style("height", "300px") 144 | .style("border-top", "1px solid #ccc") 145 | 146 | divs.push(outdiv.node()) 147 | 148 | var updatePath = stemGraphGen(170, 120, num_iters) 149 | .radius1(1) 150 | .axis(range) 151 | .labelSize("0px") 152 | .numTicks(2) 153 | .borderTop(30) 154 | (outdiv) 155 | 156 | outdiv.append("span") 157 | .style("position", "absolute") 158 | .style("top","8px") 159 | .style("width", "150px") 160 | .style("height", "130px") 161 | .style("font-size", "13px") 162 | .attr("class", "figtext") 163 | .style("text-align", "left") 164 | .html(""+title+"") 165 | 166 | outdiv.append("figcaption") 167 | .style("position", "absolute") 168 | .style("top","160px") 169 | .style("width", "160px") 170 | .style("height", "130px") 171 | .style("text-align", "left") 172 | .html(text) 173 | 174 | 175 | return updatePath 176 | } 177 | 178 | var top = 270 179 | var spacing = 190 180 | var updateDR = genPhase(0,top,0, [-1.4,1.4], "Ripples", "R's eigenvalues are complex, and the iterates display low frequency ripples. Surprisingly, the convergence rate " + MathCache("two-sqrt-beta") + " is independent of " + MathCache("alpha") + " and " + MathCache("lambda-i") + ".") 181 | updateDR(getTrace(0.0017,0.94,1,1)) 182 | 183 | var updateMC = genPhase(1,top,spacing*1,[-1.4,1.4], "Monotonic Decrease", "R's eigenvalues are both real, are positive, and have norm less than one. The behavior here resembles gradient descent.") 184 | updateMC(getTrace(0.00093, 0.16,1,1)) 185 | 186 | var updateD = genPhase(2,top,spacing*2,[-1.4,1.4], "1-Step Convergence", "When " + MathCache("alpha-equals-one-over-lambda-i") + ", and " + MathCache("beta-equals-zero") + ", we converge in one step. This is a very special point, and kills the error in the eigenspace completely.") 187 | updateD(getTrace(0.0213, 0.06,1,1)) 188 | 189 | var updateIC = genPhase(3,top,spacing*3,[-1.4,1.4], "Monotonic Oscillations", "When " + MathCache("alpha-gt-one-over-lambda-i") + ", the iterates flip between " + MathCache("plus") + " and " + MathCache("minus") + " at each iteration. These are often referred to as 'oscillations' in gradient descent.") 190 | updateIC(getTrace(0.01, 0.0001,1,1)) 191 | 192 | var updateMO = genPhase(4,top,spacing*4,[-5,5], "Divergence", "When " + MathCache("max-sigma-one") + ", the iterates diverge. ") 193 | updateMO(getTrace(0.02, 0.045,1,1)) 194 | 195 | var svg = div.append("svg") 196 | .style("position", "absolute") 197 | .style("width","920px") 198 | .style("height","500px") 199 | .style("z-index", 3) 200 | .style("pointer-events","none") 201 | 202 | function wrap(f) { 203 | return function(alpha, beta) { 204 | return f(getTrace(alpha, beta, 1,1)) 205 | } 206 | } 207 | 208 | return {update:[wrap(updateDR), wrap(updateMC), wrap(updateD), wrap(updateIC), wrap(updateMO)], div:divs } 209 | } 210 | 211 | /* 212 | Render 2D slider thingy to the right. 213 | */ 214 | function render2DSliderGen(updateDR, updateMC, updateIC, updateMO, updateD, 215 | defaults) { 216 | 217 | var slider2Dtop = 10 // Margin at top 218 | var slider2D_size = 200; // Dimensions (square) of 2D Slider 219 | var slider2Dleft = 0 // How far to the left to put the 2D Slider 220 | 221 | function render2DSlider(divin){ 222 | 223 | function getEigs(alpha, beta,lambda) { 224 | var E = [[ beta , lambda ], 225 | [ -1*alpha*beta , 1 - alpha*lambda]] 226 | return numeric.eig(E)["lambda"] 227 | } 228 | 229 | var div = divin 230 | .append("div") 231 | .style("position","absolute") 232 | .attr("class", "d3-tip n") 233 | .style("z-index", 2) 234 | .html("s1 =
s2 =
complex") 235 | .style("opacity",0) 236 | 237 | var ybeta = d3.scaleLinear().domain([1,0]).range([0, slider2D_size]); 238 | var xalpha = d3.scaleLinear().domain([0,4/100]).range([0, 2*slider2D_size]); 239 | 240 | var prevregime = "" 241 | var canvas = divin 242 | .append('canvas') 243 | .style("position", 'absolute') 244 | .style("left", 137 + "px") 245 | .style("top", slider2Dtop + "px") 246 | .style("width", 2*slider2D_size) 247 | .style("height", slider2D_size) 248 | .attr("width", 2*slider2D_size/1) 249 | .attr("height", slider2D_size/1) 250 | .style("z-index", 1) 251 | .style("border","solid 1px black") 252 | // .style("box-shadow","0px 3px 10px rgba(0, 0, 0, 0.4)") 253 | .on("mousemove", function() { 254 | 255 | var pt = d3.mouse(this) 256 | 257 | var alpha = Math.max(0,xalpha.invert(pt[0])) 258 | var beta = ybeta.invert(pt[1]) 259 | 260 | var xy = convert(alpha, beta) 261 | 262 | xAxis.select("circle").attr("cx", pt[0]).style("visibility","visible") 263 | yAxis.select("circle").attr("cy", pt[1]).style("visibility","visible") 264 | 265 | var e = getEigs(alpha,beta, 100) 266 | var n1 = 0 267 | var n2 = 0 268 | var regime = "" 269 | var regime2 = "convergent" 270 | if (e.y === undefined) { 271 | n1 = Math.abs(e.x[0]) 272 | n2 = Math.abs(e.x[1]) 273 | regime = "real" 274 | } else { 275 | n1 = numeric.norm2(e.x[0], e.y[0]) 276 | n2 = numeric.norm2(e.x[1], e.y[1]) 277 | regime = "complex" 278 | } 279 | 280 | if (Math.max(n1,n2) < 1.0001) { 281 | regime2 = "convergent" 282 | } else { 283 | regime2 = "divergent" 284 | } 285 | 286 | if (alpha < 1/100) { 287 | regime3 = "short" 288 | } else if (alpha < 2/100) { 289 | regime3 = "long" 290 | } else { 291 | regime3 = "verylong" 292 | } 293 | 294 | if (regime == "real" && regime3 != "short" && regime2 != "divergent") { 295 | if (prevregime != "MO") { 296 | updateDR(defaults[0][0], defaults[0][1], false) 297 | updateMC(defaults[1][0], defaults[1][1], false) 298 | updateIC(defaults[2][0], defaults[2][1], false) 299 | updateD( defaults[4][0], defaults[4][1], false) 300 | } 301 | updateMO(alpha,beta, true) 302 | prevregime = "MO" 303 | } 304 | 305 | if (regime == "real" && regime3 == "short") { 306 | if (prevregime != "MC") { 307 | updateDR(defaults[0][0], defaults[0][1], false) 308 | updateIC(defaults[2][0], defaults[2][1], false) 309 | updateMO(defaults[3][0], defaults[3][1], false) 310 | updateD( defaults[4][0], defaults[4][1], false) 311 | } 312 | updateMC(alpha,beta, true) 313 | prevregime = "MC" 314 | } 315 | 316 | if (regime == "complex") { 317 | if (prevregime != "DR") { 318 | updateMC(defaults[1][0], defaults[1][1], false) 319 | updateIC(defaults[2][0], defaults[2][1], false) 320 | updateMO(defaults[3][0], defaults[3][1], false) 321 | updateD( defaults[4][0], defaults[4][1], false) 322 | } 323 | updateDR(alpha,beta, true) 324 | prevregime = "DR" 325 | } 326 | 327 | if (regime2 == "divergent") { 328 | if (prevregime != "D") { 329 | updateDR(defaults[0][0], defaults[0][1], false) 330 | updateMC(defaults[1][0], defaults[1][1], false) 331 | updateIC(defaults[2][0], defaults[2][1], false) 332 | updateMO(defaults[3][0], defaults[3][1], false) 333 | } 334 | updateD(alpha,beta, true) 335 | prevregime = "D" 336 | } 337 | 338 | }).on("mouseout", function() { 339 | updateDR(defaults[0][0], defaults[0][1], true) 340 | updateMC(defaults[1][0], defaults[1][1], true) 341 | updateIC(defaults[2][0], defaults[2][1], true) 342 | updateMO(defaults[3][0], defaults[3][1], true) 343 | updateD( defaults[4][0], defaults[4][1], true) 344 | xAxis.select("circle").style("visibility","hidden") 345 | yAxis.select("circle").style("visibility","hidden") 346 | 347 | prevregime = "" 348 | } 349 | 350 | 351 | ) 352 | .node(); 353 | 354 | var convert = function(alpha, beta) { 355 | return [xalpha(alpha) + canvas.offsetLeft + divin.node().offsetLeft, 356 | ybeta(beta) + canvas.offsetTop + divin.node().offsetTop] 357 | } 358 | 359 | renderHeatmap(canvas, function(i,j) { 360 | var e = getEigs(4*i,1-j, 1) 361 | return Math.max(e.getRow(0).norm2(), e.getRow(1).norm2()); 362 | }, d3.scaleLinear().domain([0,0.3,0.5,0.7,1,1.01]).range(colorbrewer.YlGnBu[5].concat(["black"]))) 363 | 364 | // /* Axis */ 365 | var canvasaxis = divin.append("svg").style("z-index", 0) 366 | .style("position","absolute") 367 | .style("left","86px") 368 | .style("top", (-20 + slider2Dtop) + "px") 369 | .style("width",2*slider2D_size + 70) 370 | .style("height",slider2D_size + 60) 371 | 372 | var xAxis = canvasaxis.append("g") 373 | xAxis.append("circle").attr("fill", "black").attr("r", 2).style("visibility","hidden") 374 | xAxis.attr("class", "grid figtext") 375 | .attr("transform", "translate(51,"+(slider2D_size + 25) +")") 376 | .call(d3.axisBottom(d3.scaleLinear().domain([0,4]).range([0, 2*slider2D_size])) 377 | .ticks(2) 378 | .tickSize(4)) 379 | 380 | var yAxis = canvasaxis.append("g") 381 | yAxis.append("circle").style("fill", "black").attr("r", 2).style("visibility","hidden") 382 | yAxis.attr("class", "grid figtext") 383 | .attr("transform", "translate(46,20)") 384 | .call(d3.axisLeft(ybeta).ticks(1).tickSize(4)) 385 | 386 | 387 | var html = MathCache("beta-equals"); 388 | divin 389 | .append("text") 390 | .style("position","absolute") 391 | .style("left", "23px") 392 | .style("width", "90px") 393 | .style("top", slider2Dtop -9 + "px") 394 | .attr("class", "figtext") 395 | .html("Momentum " + html) 396 | 397 | var html = MathCache("alpha-equals"); 398 | divin 399 | .append("text") 400 | .style("position","absolute") 401 | .style("left", "450px") 402 | .style("width", "90px") 403 | .style("top", slider2Dtop + 208 + "px") 404 | .attr("class", "figtext") 405 | .html("Step-size " + html) 406 | 407 | // Returns a function which converts alpha, beta into the parents 408 | // coordinate space 409 | return convert 410 | 411 | } 412 | 413 | render2DSlider.size = function (_) { 414 | slider2D_size = _; return render2DSlider 415 | } 416 | 417 | return render2DSlider 418 | } -------------------------------------------------------------------------------- /public/assets/phasediagram.js: -------------------------------------------------------------------------------- 1 | function phaseDiagram(divin) { 2 | 3 | var totalIters = 100 4 | var default_underdamp = 0.97 5 | var default_overdamp = 0.05 6 | 7 | function getTrace(alpha, beta, coord, sign) { 8 | var m = [] 9 | var lambda = [1,100] 10 | var iter = geniterMomentum([[1, 0],[0, 1]], lambda, [1,sign*100], alpha, beta).iter 11 | // run for 500 iterations 12 | for (var i = 0; i <= totalIters; i++) { 13 | var x = numeric.add(iter(i)[1],-sign*1) 14 | var y = numeric.mul(iter(i)[0],(1/200)) 15 | m.push([y[coord], x[coord]]) 16 | } 17 | mG = m 18 | return m 19 | } 20 | 21 | var textCaptions = ["
Overdamping
When " + MathCache("beta") + " is too small (e.g. in Gradient Descent, " + MathCache("beta-equals-zero") + "), we're over-damping. The particle is immersed in a viscous fluid which saps it of its kinetic energy at every timestep.", 22 | "
Critical Damping
The best value of " + MathCache("beta") + " lies in the middle of the two extremes. This sweet spot happens when the eigenvalues of " + MathCache("r") + " are repeated, when " + MathCache("beta-equals-one-minus") + ".", 23 | "
Underdamping
When " + MathCache("beta") + " is too large we're under-damping. Here the resistance is too small, and spring oscillates up and down forever, missing the optimal value over and over. "] 24 | 25 | var al = 0.0001 26 | var optbeta = Math.pow(1 - Math.sqrt(al*100),2) 27 | 28 | var w = 170 29 | var h = 170 30 | var a = 1.0 31 | 32 | var axis = [[-a*5,a*5],[-a,a]] 33 | var width_bar = 620 34 | var X = d3.scaleLinear().domain([1,0]).range([0, width_bar]) 35 | 36 | var valueline = d3.line() 37 | .x(function(d) { return d[0]; }) 38 | .y(function(d) { return d[1]; }); 39 | 40 | var overlay = divin.append("svg") 41 | .style("position", "absolute") 42 | .attr("width", 648) 43 | .attr("height", 520) 44 | .style("z-index", 10) 45 | .style("pointer-events", "none") 46 | renderDraggable(overlay, [320.5, 361+35], [346.5, 378+35], 6, "reachesoptimum") 47 | //renderDraggable(overlay, [102, 312], [107, 310], 6, "initial point:x = 1, y = 0") 48 | //renderDraggable(overlay, [581.5, 360+35], [597.5, 321+35], 6, "misses optimum") 49 | 50 | // Draw the three phases 51 | var updateCallbacks = [] 52 | var divs = [] 53 | var ringPath = ringPathGen(5, 0, 0) 54 | var paths = [] 55 | for (var i = 0; i < 3; i ++ ) { 56 | 57 | var div = divin.append("div") 58 | .style("position","absolute") 59 | .style("width",w + "px") 60 | .style("height",h + "px") 61 | .style("left", [455, 235, 15][i] + "px") 62 | .style("top", [110, 110, 110][i] + "px") 63 | .style("border-top", "solid 1px gray") 64 | 65 | divs.push(div) 66 | var z = div.node() 67 | 68 | var divx = z.offsetLeft + z.offsetWidth/2 69 | var divy = z.offsetTop 70 | var path = overlay.append("path") 71 | .style("stroke", "grey") 72 | .style("stroke-width", "1px") 73 | .style("fill", "none") 74 | .attr("stroke-dasharray", "5,3") 75 | .attr("opacity", 0.7) 76 | 77 | if (i == 0) { 78 | 79 | var updateAnnotationOverDamp = (function(pathin, divxin, divyin) { 80 | return function(x,y,d) { 81 | pathin.transition().duration(d).attr("d", ringPath([x+10,y],[divxin,divyin]).d) 82 | } 83 | })(path, divx, divy) 84 | updateAnnotationOverDamp(X(default_overdamp), 30, 0) 85 | } 86 | 87 | if (i == 1) { 88 | path.attr("d", ringPath([X(0.8)+5,30],[divx - 40,divy -40]).d + "L" + divx + "," + divy + " ") 89 | } 90 | 91 | if (i == 2) { 92 | 93 | var updateAnnotationUnderDamp = (function(pathin, divxin, divyin) { 94 | return function(x,y,d) { 95 | pathin.transition().duration(d).attr("d", ringPath([x+10,y],[divxin,divyin]).d) 96 | } 97 | })(path, divx, divy) 98 | updateAnnotationUnderDamp(X(default_underdamp), 30, 0) 99 | 100 | } 101 | 102 | paths.push(path) 103 | 104 | div.append("figcaption") 105 | .style("position","absolute") 106 | .style("width", "180px") 107 | .style("height", "200px") 108 | .style("text-align", "left") 109 | .style("top", [10, 10, 10][i] + "px") 110 | .style("left", "00px") 111 | .html(textCaptions[i]) 112 | 113 | var svg = div.append("svg") 114 | .style("position", 'absolute') 115 | .style("left", 0) 116 | .style("top", "200px") 117 | .style("width", w) 118 | .style("height", h) 119 | .style("border-radius", "5px") 120 | 121 | svg.append("g").attr("class", "grid") 122 | .attr("transform", "translate(0," + h/2 +")") 123 | .attr("opacity", 0.2) 124 | .call(d3.axisBottom(X).ticks(0).tickSize(0)) 125 | 126 | svg.append("g").attr("class", "grid") 127 | .attr("transform", "translate(" + w/2 + ",0)") 128 | .attr("opacity", 0.2) 129 | .call(d3.axisLeft(X).ticks(0).tickSize(0)) 130 | 131 | var colorRange = d3.scaleLinear().domain([0, totalIters/16, totalIters/2]).range(colorbrewer.OrRd[3]) 132 | 133 | var Xaxis = d3.scaleLinear().domain(axis[0]).range([0, w]) 134 | var Yaxis = d3.scaleLinear().domain(axis[1]).range([0, h]) 135 | 136 | var update = plot2dGen(Xaxis, Yaxis, colorRange) 137 | .pathOpacity(1) 138 | .pathWidth(1.5) 139 | .circleRadius(1.5) 140 | .stroke(colorbrewer.OrRd[3][0])(svg) 141 | 142 | update(getTrace(al, [0.01, optbeta + 0.0001 , default_underdamp][i], 1,1)) 143 | updateCallbacks.push(update) 144 | 145 | } 146 | 147 | var linesvg = divin 148 | .append("svg") 149 | 150 | // Axis 151 | var axis = linesvg.append("g") 152 | .attr("class", "figtext") 153 | .attr("opacity", 0.3) 154 | .attr("transform", "translate(0,32)") 155 | .call(d3.axisBottom(X) 156 | .ticks(5) 157 | .tickSize(5)) 158 | 159 | axis.selectAll("path").remove() 160 | axis.select("text").style("text-anchor", "start"); 161 | 162 | var html = MathCache("beta"); 163 | // Axis 164 | linesvg.append("text") 165 | .attr("class", "figtext") 166 | .attr("opacity", 1) 167 | .attr("transform", "translate(0,12)") 168 | .html("Momentum β") 169 | 170 | linesvg.style("position","absolute") 171 | .style("width", "920px") 172 | .style("height", "570px") 173 | .style("left", "10px") 174 | .append("line") 175 | .attr("x1", 0) 176 | .attr("y1", 30) 177 | .attr("x2", 0 + width_bar) 178 | .attr("y2", 30) 179 | .style("border", "solid 2px black") 180 | .style("stroke", "#CCC") 181 | .style("fill", "white") 182 | .style("stroke-width", "1.5px") 183 | 184 | var underdamp = linesvg 185 | .append("circle") 186 | .attr("cx", X(default_overdamp)) 187 | .attr("cy", 30) 188 | .attr("r", 6) 189 | .style("fill", "#ff6600") 190 | 191 | var criticaldamp = linesvg 192 | .append("circle") 193 | .attr("cx", X(optbeta)) 194 | .attr("cy", 30) 195 | .attr("r", 6) 196 | .style("fill", "#ff6600") 197 | 198 | var overdamp = linesvg 199 | .append("circle") 200 | .attr("cx", X(default_underdamp)) 201 | .attr("cy", 30) 202 | .attr("r", 6) 203 | .style("fill", "#ff6600") 204 | 205 | var prevState = "" 206 | 207 | linesvg.style("position","absolute") 208 | .style("width", "920px") 209 | .style("height", "570px") 210 | .append("line") 211 | .attr("x1", 0) 212 | .attr("y1", 30) 213 | .attr("x2", 0 + width_bar) 214 | .attr("y2", 30) 215 | .style("border", "solid 2px black") 216 | .style("stroke", "black") 217 | .style("fill", "white") 218 | .style("opacity", 0) 219 | .style("z-index", 3) 220 | .style("stroke-width", "40px") 221 | .on("mousemove", function () { 222 | 223 | var pt = d3.mouse(this) 224 | var beta = X.invert(pt[0]) 225 | if (beta < optbeta) { 226 | underdamp.attr("cx", pt[0]) 227 | updateCallbacks[0](getTrace(al, X.invert(pt[0]), 1,1)) 228 | 229 | overdamp.attr("cx", X(default_underdamp)) 230 | updateAnnotationOverDamp(pt[0], 30, 0) 231 | 232 | if (prevState != "Over"){ 233 | divs[0].style("opacity",1) 234 | divs[1].style("opacity",0.2) 235 | divs[2].style("opacity",0.2) 236 | 237 | updateCallbacks[2](getTrace(al, default_underdamp, 1,1)) 238 | updateAnnotationUnderDamp(X(default_underdamp), 30, 20) 239 | } 240 | prevState = "Over" 241 | } 242 | if (beta > optbeta) { 243 | overdamp.attr("cx", pt[0]) 244 | underdamp.attr("cx", X(default_overdamp)) 245 | updateCallbacks[2](getTrace(al, Math.min(X.invert(pt[0]),1), 1,1)) 246 | 247 | updateAnnotationUnderDamp(pt[0], 30, 0) 248 | 249 | if (prevState != "Under") { 250 | divs[0].style("opacity",0.2) 251 | divs[1].style("opacity",0.2) 252 | divs[2].style("opacity",1) 253 | 254 | updateCallbacks[0](getTrace(al, default_overdamp, 1,1)) 255 | updateAnnotationOverDamp(X(default_overdamp), 30, 20) 256 | } 257 | prevState = "Under" 258 | } 259 | 260 | }) 261 | .on("mouseout", function () { 262 | divs[0].style("opacity",1) 263 | divs[1].style("opacity",1) 264 | divs[2].style("opacity",1) 265 | 266 | underdamp.transition().duration(50).attr("cx", X(default_overdamp)) 267 | updateCallbacks[0](getTrace(al, default_overdamp, 1,1)) 268 | 269 | overdamp.transition().duration(50).attr("cx", X(default_underdamp)) 270 | updateCallbacks[2](getTrace(al, default_underdamp, 1,1)) 271 | 272 | updateAnnotationUnderDamp(X(default_underdamp), 30, 50) 273 | updateAnnotationOverDamp(X(default_overdamp), 30, 50) 274 | prevState = "" 275 | 276 | }) 277 | 278 | 279 | 280 | } 281 | -------------------------------------------------------------------------------- /public/assets/phasediagram_description.js: -------------------------------------------------------------------------------- 1 | function phaseDiagram_dec(divin) { 2 | 3 | var totalIters = 250 4 | var default_underdamp = 0.97 5 | var default_overdamp = 0.05 6 | 7 | function myRunMomentum(f, w0, alpha, beta, totalIters) { 8 | var W = []; var Z = []; var z = zeros(w0.length); var w = w0 9 | z[1] = 1 10 | var gx = f(w0); 11 | W.push(w0); 12 | Z.push(numeric.mul(-1,z)); 13 | for (var i = 0; i < totalIters; i++) { 14 | var z = numeric.add(numeric.mul(beta, z), gx) 15 | var w = numeric.add(w, numeric.mul(-alpha, z)) 16 | gx = f(w); 17 | if (w.every(isFinite)) { 18 | W.push(w) 19 | Z.push(numeric.mul(-1, z)) 20 | } else{ break; } 21 | } 22 | return [Z,W] 23 | } 24 | 25 | function getTrace(alpha, beta, lambda) { 26 | var m = [] 27 | var iter = myRunMomentum(function(x) { return [x[0],lambda*x[1]] }, [2,0.92], alpha, beta, totalIters) 28 | // run for 500 iterations 29 | for (var i = 0; i <= totalIters; i++) { 30 | var x = -1*iter[1][i][1] 31 | var y = (1.4)*iter[0][i][1] 32 | m.push([y, x]) 33 | } 34 | mG = m 35 | return m 36 | } 37 | 38 | var al = 0.0001 39 | var optbeta = Math.pow(1 - Math.sqrt(al*100),2) 40 | 41 | var w = 95 42 | var h = 95 43 | var a = 1.0 44 | 45 | var axis = [[-a*5,a*5],[-a,a]] 46 | var width_bar = 620 47 | var X = d3.scaleLinear().domain([0,1]).range([0, width_bar]) 48 | 49 | var valueline = d3.line() 50 | .x(function(d) { return d[0]; }) 51 | .y(function(d) { return d[1]; }); 52 | 53 | var overlay = divin.append("svg") 54 | .style("position", "absolute") 55 | .attr("width", 348) 56 | .attr("height", 620) 57 | .style("z-index", 10) 58 | .style("pointer-events", "none") 59 | 60 | // Draw the three phases 61 | 62 | var lambdas = [0, 0.02, 0.1, 0.25] 63 | var betas = [1, 0.985, 0.95, 0.9, 0.85, 0.8, 0] 64 | 65 | for (var i = 0; i < 6; i ++ ) { 66 | divin.append("figcaption") 67 | .style("position","absolute") 68 | .style("width",(w-10) + "px") 69 | .style("height",20 + "px") 70 | .style("left", 65 + (w+14)*i + "px") 71 | .style("top", 0 + "px") 72 | .attr("class", "figtext") 73 | .style("border-bottom", "1px solid black" ) 74 | .html((i != 0 ? "" : "β = ") + betas[i]) 75 | } 76 | 77 | for (var j = 0; j < 4; j ++ ) { 78 | divin.append("figcaption") 79 | .style("position","absolute") 80 | .style("width", 35 + "px") 81 | .style("height", h + "px") 82 | .style("left", 0 + "px") 83 | .style("top", 50 + 125*j + "px") 84 | .attr("class", "figtext") 85 | .style("border-right", "1px solid black" ) 86 | .html( (j != 0 ? " " : "
λ = ") + lambdas[j]) 87 | } 88 | 89 | divin.append("figcaption") 90 | .style("position","absolute") 91 | .style("width",35 + "px") 92 | .style("height",h + "px") 93 | .style("left", 90 + "px") 94 | .style("top", 27 + "px") 95 | .html( "Velocity") 96 | 97 | divin.append("figcaption") 98 | .style("position","absolute") 99 | .style("width",100 + "px") 100 | .style("height",h + "px") 101 | .style("left", 64 + "px") 102 | .style("top", -17 + "px") 103 | .attr("class", "figtext") 104 | .html( "Damping") 105 | 106 | divin.append("figcaption") 107 | .style("position","absolute") 108 | .style("width",100 + "px") 109 | .style("height",h + "px") 110 | .style("left", -55 + "px") 111 | .style("top", 50 + "px") 112 | .attr("class", "figtext") 113 | .html( "External Force") 114 | 115 | divin.append("figcaption") 116 | .style("position","absolute") 117 | .style("width",35 + "px") 118 | .style("height",h + "px") 119 | .style("left", 75 + "px") 120 | .style("top", 56 + "px") 121 | .style("transform","rotate(-90deg)") 122 | .html( "Position") 123 | 124 | divin.append("figcaption") 125 | .style("position","absolute") 126 | .style("width",120 + "px") 127 | .style("height",h + "px") 128 | .style("left", 730 + "px") 129 | .style("top", 60 + "px") 130 | .style("font-size", "12px") 131 | .html("" + MathCache("beta") + ": Horizontal Axis
When " + MathCache("lambda-i-equals-zero") + " and " + MathCache("beta-equals-one") + ", the object moves at constant speed. As " + MathCache("beta") + " goes down, the particle decelerates, losing a proportion of its energy at each tick. ") 132 | 133 | divin.append("figcaption") 134 | .style("position","absolute") 135 | .style("width",120 + "px") 136 | .style("height",h + "px") 137 | .style("left", 730 + "px") 138 | .style("top", (120*2 + 50) + "px") 139 | .style("font-size", "12px") 140 | .html(" " + MathCache("lambda") + ": Vertical Axis
The external force causes the particle to return to the origin. Combining damping and the force field, the particle behaves like a damped harmonic oscillator, returning lazily to equlibrium.") 141 | 142 | for (var i = 0; i < 6; i ++ ) { 143 | for (var j = 0; j < 4; j ++) { 144 | 145 | var hborder = (j == 0) ? 0 : 35 146 | 147 | var div = divin.append("div") 148 | .style("position","absolute") 149 | .style("width", w + "px") 150 | .style("height",h + "px") 151 | .style("left", 65 + (w+14)*i + "px") 152 | .style("top", 50 + 125*j - hborder + "px") 153 | 154 | var svg = div.append("svg") 155 | .style("position", 'absolute') 156 | .style("left", 0) 157 | .style("top", "px") 158 | .style("width", w) 159 | .style("height", h + (2*hborder)) 160 | .style("border-radius", "5px") 161 | 162 | svg.append("g").attr("class", "grid") 163 | .attr("transform", "translate(0," + (h + 2*hborder)/2 +")") 164 | .attr("opacity", 0.2) 165 | .call(d3.axisBottom(X).ticks(0).tickSize(0)) 166 | 167 | svg.append("g").attr("class", "grid") 168 | .attr("transform", "translate(" + w/2 + ",0)") 169 | .attr("opacity", 0.2) 170 | .call(d3.axisLeft(d3.scaleLinear().domain([0,1]).range([hborder, h+hborder])).ticks(0).tickSize(0)) 171 | 172 | var colorRange = d3.scaleLinear().domain([0, 10, 50, totalIters]).range(colorbrewer.OrRd[4]) 173 | 174 | var Xaxis = d3.scaleLinear().domain(axis[0]).range([0, w]) 175 | var Yaxis = d3.scaleLinear().domain(axis[1]).range([hborder, h+hborder]) 176 | 177 | var update = plot2dGen(Xaxis, Yaxis, colorRange) 178 | .pathOpacity(1) 179 | .pathWidth(0.5) 180 | .circleRadius(1) 181 | .stroke(colorbrewer.OrRd[5][2])(svg) 182 | 183 | update(getTrace(0.02, betas[i], lambdas[j])) 184 | } 185 | } 186 | 187 | 188 | 189 | } -------------------------------------------------------------------------------- /public/assets/stochastic_milestones.js: -------------------------------------------------------------------------------- 1 | Math.randn = function() { 2 | var x1, x2, rad, y1; 3 | do { 4 | x1 = 2 * this.random() - 1; 5 | x2 = 2 * this.random() - 1; 6 | rad = x1 * x1 + x2 * x2; 7 | } while(rad >= 1 || rad == 0); 8 | var c = this.sqrt(-2 * Math.log(rad) / rad); 9 | return x1 * c; 10 | }; 11 | 12 | function renderStochasticMilestones(div, updateTick) { 13 | 14 | var lambda = [1,10,100] 15 | var totalIters = 151 16 | 17 | div.append("defs").append("marker") 18 | .attr("id", "arrowhead") 19 | .attr("refX", 3) 20 | .attr("refY", 2) 21 | .attr("markerWidth", 4) 22 | .attr("markerHeight", 4) 23 | .attr("orient", "auto") 24 | .append("path") 25 | .attr("d", "M 0,0 V 4 L4,2 Z"); //this is actual shape for arrowhead 26 | 27 | var lam = 1 28 | var epsilon = 3 29 | 30 | var f = function(x) { 31 | var fx = 0.5*(lam*x[0]*x[0]) 32 | var g = [lam*x[0]] 33 | return [fx, g] 34 | } 35 | 36 | 37 | var stochasticf = function(x) { 38 | var fx = 0.5*(lam*x[0]*x[0]) 39 | var g = [lam*x[0] + epsilon*Math.randn()] 40 | return [fx, g] 41 | } 42 | 43 | 44 | /* 45 | Gets information about iterates with certain parameter alpha and beta. 46 | > v = getTrace(0.5, 0) 47 | v[0] -> z iterates 48 | v[1] -> w iterates 49 | v[2] -> [c1, c2, c3] where c1, c2, c3 are the contributions to the loss 50 | */ 51 | function getTrace(alpha, beta) { 52 | 53 | var Rmat = function (i) { 54 | return [[ beta, lam ], 55 | [ -1*alpha*beta, 1 - alpha*lam ]] 56 | } 57 | 58 | var R = Rmat(1) 59 | var w0 = [Math.sqrt(3)] 60 | var v = runMomentum(f, w0, alpha, beta, totalIters) 61 | var fxstack = [] 62 | var errx = [epsilon, -alpha*epsilon] 63 | var errsum = 0 64 | 65 | var nsamples = 1 66 | svsamples = [] 67 | for (var i = 0; i < nsamples; i++) { 68 | var sv = runMomentum(stochasticf, w0, alpha, beta, totalIters) 69 | svsamples.push(sv[1]) 70 | } 71 | fxaverage = [] 72 | for (var i = 0; i < v[0].length; i++) { 73 | var mean = 0 74 | for (var j = 0; j < nsamples; j++) { 75 | mean = mean + (lam*svsamples[j][i][0]*svsamples[j][i][0])/2 76 | } 77 | fxaverage.push([mean/nsamples]) 78 | } 79 | var stochasticfx = [] 80 | // Add contributions to the objective 81 | for (var i = 0; i < v[0].length; i++) { 82 | errsum = errsum + errx[1]*errx[1]/2 83 | errx = numeric.dot(R, errx) 84 | var x = v[1][i] 85 | fxstack.push([errsum, lam*x[0]*x[0]/2]) 86 | stochasticfx.push([lam*sv[1][i][0]*sv[1][i][0]/2]) 87 | } 88 | v.push(fxstack) 89 | 90 | return {deterministic:v, stochastic:fxaverage} 91 | } 92 | 93 | 94 | var stackedBar = stackedBarchartGen(totalIters, 2) 95 | .col(colorbrewer.BuPu) 96 | .translatey(30) 97 | .translatex(110) 98 | .highlightcol("darkblue")(div) 99 | 100 | 101 | var stackedBar2 = stackedBarchartGen(totalIters, 1) 102 | .col(colorbrewer.BuPu) 103 | .translatey(30) 104 | .translatex(110) 105 | .cr(1.2) 106 | .copacity(0.5) 107 | .lineopacity(0) 108 | .drawgrid(false) 109 | .highlightcol("darkblue")(div) 110 | 111 | 112 | div.append("rect") 113 | .attr("x", 0) 114 | .attr("y", 0) 115 | .attr("width", 1000) 116 | .attr("height", 30) 117 | .attr("fill", "white") 118 | 119 | var seperation = 14 120 | 121 | 122 | var progressmeter = div.append("g") 123 | 124 | var textl = progressmeter.append("g") 125 | 126 | textl.append("line") 127 | .attr("y1",-5) 128 | .attr("y2",-5) 129 | .attr("x1",110) 130 | .attr("x2",120) 131 | .attr("stroke","black") 132 | .attr("stroke-width", 1.5) 133 | .attr("marker-end", "url(#arrowhead)") 134 | 135 | textl.append("text") 136 | .attr("class", "figtext2") 137 | .text("Fine-tuning phase") 138 | 139 | var textr = progressmeter.append("g") 140 | 141 | textr.append("text") 142 | .attr("class", "figtext2") 143 | .attr("text-anchor", "end") 144 | .text("Transient phase") 145 | 146 | 147 | textr.append("line") 148 | .attr("y1",-5) 149 | .attr("y2",-5) 150 | .attr("x1",-100) 151 | .attr("x2",-110) 152 | .attr("stroke","black") 153 | .attr("stroke-width", 1.5) 154 | .attr("marker-end", "url(#arrowhead)") 155 | 156 | var divider2 = progressmeter.append("line") 157 | .style("stroke", "white") 158 | .style("stroke-width",5) 159 | .attr("opacity", 0.9) 160 | 161 | var divider = progressmeter.append("line") 162 | .style("stroke", "black") 163 | .style("stroke-width",1.5) 164 | .attr("opacity", 0.9) 165 | 166 | var updateStep = function(alpha, beta) { 167 | var tracebath = getTrace(alpha/lambda[2], beta) 168 | var trace = tracebath.deterministic 169 | var strace = tracebath.stochastic 170 | 171 | // Update the milestones on the slider 172 | var milestones = [0,0] 173 | for (var i = 0; i < trace[1].length; i++) { 174 | if (trace[2][i][1] > trace[2][i][0]) { milestones[0] = i; milestones[1] = i; } else { break} 175 | } 176 | stackedBar.update(trace[2], milestones) 177 | stackedBar2.update(strace, milestones) 178 | var endpoint = stackedBar.stack[0].selectAll("line").nodes()[milestones[0]] 179 | var stack = endpoint.getBBox() 180 | var ctm = endpoint.getCTM() 181 | 182 | if (milestones[0] < 150) { 183 | textl.attr("transform", "translate(" + (stack.x + 10) + ",-15)").style("visibility", "visible") 184 | textr.attr("transform", "translate(" + (stack.x - 10) + ",-16)").style("visibility", "visible") 185 | divider.attr("x2", stack.x) 186 | .attr("y2", -25) 187 | .attr("x1", stack.x) 188 | .attr("y1", 160) 189 | .style("visibility", "visible") 190 | divider2.attr("x2", stack.x) 191 | .attr("y2", -25) 192 | .attr("x1", stack.x) 193 | .attr("y1", 160) 194 | .style("visibility", "visible") 195 | } else { 196 | endpointend = stackedBar.stack[0].selectAll("line").nodes()[149].getBBox().x 197 | console.log(endpointend) 198 | textr.attr("transform", "translate(" + (endpointend + 10) + ",-16)").style("visibility", "visible") 199 | divider.style("visibility", "hidden") 200 | textl.style("visibility", "hidden") 201 | divider2.style("visibility", "hidden") 202 | } 203 | setTM(progressmeter.node(), ctm) 204 | 205 | } 206 | 207 | updateStep(100*2/(101.5), 0) 208 | 209 | return updateStep 210 | } -------------------------------------------------------------------------------- /public/assets/widgets.css: -------------------------------------------------------------------------------- 1 | .framed { 2 | border: 1px black dashed; 3 | padding: 20px; 4 | } 5 | .ticks { 6 | font: 10px sans-serif; 7 | } 8 | 9 | .track, 10 | .track-inset, 11 | .track-overlay { 12 | stroke-linecap: round; 13 | 14 | } 15 | 16 | .track { 17 | stroke: #e6e6e6; 18 | stroke-opacity: 0.5; 19 | stroke-width: 2px; 20 | } 21 | 22 | .track-inset { 23 | stroke: #e6e6e6; 24 | stroke-width: 5px; 25 | 26 | } 27 | 28 | .track-overlay { 29 | pointer-events: stroke; 30 | stroke-width: 50px; 31 | stroke: rgba(0,0,0,0) 32 | } 33 | 34 | .handle { 35 | fill: #fff; 36 | fill-opacity: 0.2; 37 | stroke: #000; 38 | stroke-opacity: 0.5; 39 | stroke-width: 1.5px; 40 | } 41 | 42 | .figtext path{ 43 | stroke: black; 44 | stroke-width:1; 45 | fill: none; 46 | } 47 | 48 | /* Tooltip Styles */ 49 | 50 | .d3-tip { 51 | line-height: 1; 52 | font-weight: bold; 53 | padding: 5px; 54 | background: rgba(0, 0, 0, 0.8); 55 | color: #fff; 56 | border-radius: 2px; 57 | pointer-events: none; 58 | font-size: 10px; 59 | } 60 | 61 | /* Creates a small triangle extender for the tooltip */ 62 | .d3-tip:after { 63 | box-sizing: border-box; 64 | display: inline; 65 | font-size: 10px; 66 | width: 100%; 67 | line-height: 1; 68 | color: rgba(0, 0, 0, 0.8); 69 | position: absolute; 70 | pointer-events: none; 71 | } 72 | 73 | /* Northward tooltips */ 74 | .d3-tip.n:after { 75 | content: "\25BC"; 76 | margin: -1px 0 0 0; 77 | top: 100%; 78 | left: 0; 79 | text-align: center; 80 | } 81 | 82 | /* Eastward tooltips */ 83 | .d3-tip.e:after { 84 | content: "\25C0"; 85 | margin: -4px 0 0 0; 86 | top: 50%; 87 | left: -8px; 88 | } 89 | 90 | /* Southward tooltips */ 91 | .d3-tip.s:after { 92 | content: "\25B2"; 93 | margin: 0 0 1px 0; 94 | top: -8px; 95 | left: 0; 96 | text-align: center; 97 | } 98 | 99 | /* Westward tooltips */ 100 | .d3-tip.w:after { 101 | content: "\25B6"; 102 | margin: -4px 0 0 -1px; 103 | top: 50%; 104 | left: 100%; 105 | } 106 | 107 | #eigenFeatures .stage { 108 | position: relative; 109 | margin-bottom: 24px; 110 | } 111 | #eigenFeatures .waveform { 112 | position: absolute; 113 | opacity: 0.7; 114 | } 115 | #eigenFeatures .pointer { 116 | position: absolute; 117 | width: 26px; 118 | height: 26px; 119 | top: 36px; 120 | left: -48px; 121 | } 122 | #eigenFeatures svg { 123 | z-index: 1; 124 | position: absolute; 125 | margin-left:auto; 126 | margin-right:auto; 127 | width: 920px; 128 | 129 | } 130 | #eigenFeatures svg .labels { 131 | font-size: 12px; 132 | fill-opacity: 0.5; 133 | } 134 | #eigenFeatures figcaption { 135 | text-align: center; 136 | } 137 | #eigenFeatures .background { 138 | fill: rgb(240, 240, 245); 139 | fill-opacity: 0.1; 140 | border:solid 1px black; 141 | } 142 | #eigenFeatures .audio-background { 143 | fill: none; 144 | stroke: black; 145 | stroke-opacity: 0.3; 146 | } 147 | #eigenFeatures .cell .node { 148 | fill: white; 149 | fill-opacity: 0.5; 150 | stroke: black; 151 | stroke-width: 1.5px; 152 | stroke-opacity: 0.5; 153 | } 154 | #eigenFeatures .cell:hover .node { 155 | stroke-opacity: 1; 156 | fill:#7570b3; 157 | stroke:#7570b3; 158 | stroke-width: 2.0px; 159 | } 160 | #eigenFeatures .cell .shadow { 161 | fill: black; 162 | fill-opacity: 0.07; 163 | } 164 | #eigenFeatures .cell text { 165 | font-size: 13px; 166 | fill-opacity: 0.5; 167 | text-anchor: middle; 168 | alignment-baseline: middle; 169 | } 170 | #eigenFeatures .cell text.label { 171 | font-size: 10px; 172 | /*fill-opacity: 0.8;*/ 173 | text-anchor: middle; 174 | alignment-baseline: middle; 175 | } 176 | 177 | #eigenFeatures .link-group { 178 | transition: opacity, 0.3s, linear; 179 | } 180 | #eigenFeatures .link-group .node-highlight { 181 | transition: stroke-opacity, 0.3s, linear; 182 | stroke: black; 183 | stroke-opacity: 0; 184 | fill: none; 185 | } 186 | #eigenFeatures .link-group:hover .node-highlight { 187 | stroke-opacity: 1; 188 | } 189 | #eigenFeatures .link { 190 | fill: none; 191 | stroke: black; 192 | stroke-width: 1.5px; 193 | pointer-events: none; 194 | } 195 | #eigenFeatures .arrow { 196 | stroke: black; 197 | stroke-opacity: 0.3; 198 | } 199 | #eigenFeatures .cell:last-child .arrow:first-of-type { 200 | display: none; 201 | } 202 | #eigenFeatures .tick { 203 | stroke: black; 204 | stroke-opacity: 0.2; 205 | } 206 | 207 | 208 | .figtext{ 209 | font-size:12px; 210 | line-height:18px; 211 | font-family:Helvetica; 212 | font-weight: bold; 213 | } 214 | 215 | .figtext2{ 216 | font-size:13px; 217 | line-height:18px; 218 | font-family:Helvetica; 219 | text-align:left; 220 | color:gray; 221 | } 222 | 223 | 224 | .annotatetext{ 225 | font-size:12px; 226 | line-height:18px; 227 | font-family:Helvetica; 228 | color:gray; 229 | } 230 | 231 | .annotatetext path{ 232 | stroke: black; 233 | stroke-width:1; 234 | fill: none; 235 | } 236 | 237 | 238 | .ticktext{ 239 | font-size:12px; 240 | line-height:18px; 241 | font-family:Helvetica; 242 | text-align:right; 243 | } 244 | 245 | .mycaptiontext{ 246 | font-size:15px; 247 | line-height:22px !important; 248 | font-family:Open Sans; 249 | text-align:right; 250 | color:gray; 251 | } 252 | 253 | 254 | .links line { 255 | stroke: #000; 256 | stroke-opacity: 1; 257 | } 258 | 259 | .nodes circle { 260 | stroke: #000; 261 | stroke-width: 1px; 262 | } 263 | .axis line, .axis path { 264 | fill: none; 265 | stroke: #000; 266 | shape-rendering: crispEdges; 267 | } 268 | 269 | .annotations path{ 270 | fill: none; 271 | stroke: black; 272 | } 273 | .annotations g:hover circle{ 274 | stroke: red; 275 | } 276 | .annotations g:hover text{ 277 | fill: red; 278 | } 279 | 280 | .draggable-number > .katex { 281 | /*hsl(24, 100%, 50%)*/ 282 | border-bottom: dotted 1px #bbb; 283 | /*color: hsl(24, 100%, 45%);*/ 284 | padding-bottom: 4px; 285 | } 286 | 287 | .draggable-number:hover > .katex { 288 | color: hsl(24, 100%, 45%); 289 | border-bottom: dotted 1px hsl(24, 100%, 50%); 290 | } 291 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 57 | 83 | 88 | 89 | 90 | 91 | 92 | 110 | 117 | 120 | 123 | 126 | 130 | 132 | 134 | 135 | 136 | 137 | 138 |

A birds-eye view of optimization algorithms

139 | 140 | 141 | 142 |

Outline

143 | 154 |

Credits. This material was created by Fabian Pedregosa for an invied lecture at McGill University. 155 | Source code can be found here. 156 | The template and the visualizations are modified from the distill article How momentum really works. Some parts of the knowing your problem section are based on the scipy lecture notes.

157 | 158 |
159 | -------------------------------------------------------------------------------- /public/newton.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 13 | 14 | 15 | 40 | 41 | 44 | 45 | 46 | 47 | 48 | 49 | 80 | 106 | 111 | 112 | 113 | 114 | 115 | 133 | 140 | 143 | 146 | 149 | 153 | 155 | 157 | 158 | 159 | 160 | 161 |
162 | $$ 163 | \DeclareMathOperator*{\argmin}{{arg\,min}} 164 | \DeclareMathOperator*{\argmax}{{arg\,max}} 165 | \DeclareMathOperator*{\minimize}{{minimize}} 166 | $$ 167 |
168 | 169 |

Newton’s method

170 | 171 |

The Newton method is an iterative method to solve the following unconstrained optimization problem

172 |

\begin{equation}\label{eq:fw_objective} 173 | \minimize_{\boldsymbol{x} \in \RR^p} f(\boldsymbol{x}) ~, 174 | \end{equation}

175 |

when $f$ is twice differentiable.

176 | 177 |

178 | In Newton's method, we approximate the objective with a quadratic surrogate of the form 179 | \begin{equation} 180 | Q_t(\xx) = c_t + \boldsymbol{g}_t^T(\xx - \xx_t) + \frac{1}{2 \gamma}(\xx - \xx_t)^T \boldsymbol{H}_t (\xx - \xx_t)~. 181 | \end{equation} 182 | Compared to gradient descent, the quadratic term is not fixed the be the identity but instead can incorporate an arbitrary (positive semi-definite) matrix $\boldsymbol{H}_t$. 183 |

184 |

A reasonable condition to impose on this surrogate function is that it at $\xx_t$ it coincides with $f$ in its value and first derivative, that is: 185 | \begin{align} 186 | Q_t(\xx_t) &= f(\xx_t) \implies c_t = f(\xx_t)\\ 187 | \nabla Q_t(\xx_t) &= \nabla f(\xx_t) \implies \boldsymbol{g}_t = \nabla f(\xx_t)\\ 188 | \nabla^2 Q_t(\xx_t) &= \nabla^2 f(\xx_t) \implies \boldsymbol{H}_t = \nabla^2 f(\xx_t)~, 189 | \end{align} 190 | where $\nabla^2 f(\xx_t)$ is the Hessian of $f$: 191 | \begin{equation} 192 | \nabla^2 f(\xx_t)= \begin{bmatrix} 193 | \dfrac{\partial^2 f}{\partial x_1^2} & \dfrac{\partial^2 f}{\partial x_1\,\partial x_2} & \cdots & \dfrac{\partial^2 f}{\partial x_1\,\partial x_n} \\[2.2ex] 194 | \dfrac{\partial^2 f}{\partial x_2\,\partial x_1} & \dfrac{\partial^2 f}{\partial x_2^2} & \cdots & \dfrac{\partial^2 f}{\partial x_2\,\partial x_n} \\[2.2ex] 195 | \vdots & \vdots & \ddots & \vdots \\[2.2ex] 196 | \dfrac{\partial^2 f}{\partial x_n\,\partial x_1} & \dfrac{\partial^2 f}{\partial x_n\,\partial x_2} & \cdots & \dfrac{\partial^2 f}{\partial x_n^2} 197 | \end{bmatrix}~, 198 | \end{equation} 199 | where in this last equation the subindex refers to the entries in the vector and not to the iterates. 200 | 201 | Alternatively, you might also see $Q_t$ as the second-order Taylor expansion of $f$ at $\xx_t$. In all, we have the following surrogate function: 202 | \begin{equation} 203 | Q_t(\xx_t) = f(\xx_t) + \nabla f(\xx_t)^T (\xx - \xx) + \frac{1}{2 \gamma}(\xx - \xx_t)^T \nabla^2 f(\xx_t) (\xx - \xx_t)~. 204 | \end{equation} 205 |

206 |

207 | We can find the optimum of the function deriving and equating to zero. This way we find (assuming the Hessian is invertible) 208 | \begin{equation} 209 | \xx_{t+1} = \argmin_{\xx} Q_t(\xx) = \xx_t - \gamma [\nabla^2 f(\xx_t)]^{-1} \nabla f(\xx_t) 210 | \end{equation} 211 |

212 | 213 |

214 | Where applicable, Newton's method converges much faster towards a local maximum or minimum than gradient descent. In fact, every local minimum has a neighborhood such that, if we start within this neighborbood, Newton's method with step size $\gamma=1$ converges quadratically assuming the Hessian is invertible and Lipschitz continuous. 215 |

216 | 217 |

The biggest drawback of Newton's method is that finding the inverse of the Hessian in high dimensions can be an expensive operation. In such cases, instead of directly inverting the Hessian it's better to calculate the vector $\boldsymbol\Delta$ as the solution to the system of linear equations 218 | 219 | $$\nabla^2 f(\mathbf{x}_t) \boldsymbol{\Delta} = -\nabla f(\mathbf{x}_t) 220 | $$ 221 | 222 | which may be solved by various factorizations or approximately (but to great accuracy). 223 |

224 | 225 | 226 |

Examples

227 |
228 |
229 |
230 | Step-size α = 1 231 |
232 |
233 | In this case the approximation is exact and we converge on a single iteration. 234 |
235 | 236 |
237 | 238 | 239 |
240 |
241 |
242 | Step-size α = 1 243 |
244 | 245 |
246 | 247 | 248 | 249 |
250 |
251 |
252 | Step-size α = 1 253 |
254 |
255 | When the Hessian is close to singular there might be some numerical instabilities. 256 |
257 | 258 |
259 | 260 | 261 | 262 | 263 | 264 | 357 | 358 | 359 | 360 | 394 | 395 |

Next: Quasi-Newton

396 |

Previous: Gradient Descent

397 | 398 |
399 | -------------------------------------------------------------------------------- /public/surrogate.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 13 | 14 | 15 | 16 | 17 | 40 | 41 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 81 | 107 | 112 | 113 | 114 | 115 | 116 | 134 | 141 | 144 | 147 | 150 | 154 | 156 | 158 | 159 | 160 | 161 | 162 | $$ 163 | \DeclareMathOperator*{\argmin}{{arg\,min}} 164 | \DeclareMathOperator*{\argmax}{{arg\,max}} 165 | \DeclareMathOperator*{\minimize}{{minimize}} 166 | $$ 167 | 168 |

A unifying principle: surrogate optimization

169 | 170 |

We aim to solve an optimization problem of the form 171 |

172 |

\begin{equation}\label{eq:fw_objective} 173 | \minimize_{\boldsymbol{x} \in \RR^p} f(\boldsymbol{x}) ~. 174 | \end{equation}

175 |

A key idea is to start at an initial estimate $\xx_0$ and successively minimize an approximating function $Q_t(\xx)$: 176 | \begin{equation} 177 | \xx_{t+1} = \argmin_{\xx \in \RR^p} Q_t(\xx)~. 178 | \end{equation} 179 |

180 |

We will call $Q_t$ a surrogate function. It is also known as merit function.

181 |

How to find such surrogate function?

182 |

A good surrogate function should:

183 |
    184 |
  • Approximate the objective function.
  • 185 |
  • Easy to optimize.
  • 186 |
187 | 188 |

Linear surrogates

189 |

The simplest class of surrogates we can think of are linear surrogates, that is, functions of the form 190 | $$ 191 | Q_t(\xx) = (\xx - \xx_t)^T \boldsymbol{b}_t + c_t~. 192 | $$ 193 |

194 |

While simple, they are general unbounded, making thir minimization problematic -- although they do have some uses in constrained optimization

195 | 196 |

Quadratic surrogates

197 |

Slightly more complex are quadratic functions. These are of the form 198 | $$ 199 | Q_t(\xx) = (\xx - \xx_t)^T \boldsymbol{A} (\xx - \xx_t) + \boldsymbol{b}_t^T (\xx - \xx_t) + c_t. 200 | $$ 201 |

202 |

Yes! Many examples: Gradient descent, Newton, etc.

203 | 204 |

Next: Gradient Descent

205 |

Previous: Introduction

206 |
207 | 208 | 209 | 210 | 211 | 212 | 229 | 230 | 231 | 266 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | commander@2, commander@^2.9.0: 6 | version "2.9.0" 7 | resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" 8 | dependencies: 9 | graceful-readlink ">= 1.0.0" 10 | 11 | d3-array@1, d3-array@1.1.1: 12 | version "1.1.1" 13 | resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-1.1.1.tgz#a01abe63a25ffb91d3423c3c6d051b4d36bc8a09" 14 | 15 | d3-axis@1.0.6: 16 | version "1.0.6" 17 | resolved "https://registry.yarnpkg.com/d3-axis/-/d3-axis-1.0.6.tgz#dccbc21a73e5786de820bf1a22b237f522b878be" 18 | 19 | d3-brush@1.0.4: 20 | version "1.0.4" 21 | resolved "https://registry.yarnpkg.com/d3-brush/-/d3-brush-1.0.4.tgz#00c2f238019f24f6c0a194a26d41a1530ffe7bc4" 22 | dependencies: 23 | d3-dispatch "1" 24 | d3-drag "1" 25 | d3-interpolate "1" 26 | d3-selection "1" 27 | d3-transition "1" 28 | 29 | d3-chord@1.0.4: 30 | version "1.0.4" 31 | resolved "https://registry.yarnpkg.com/d3-chord/-/d3-chord-1.0.4.tgz#7dec4f0ba886f713fe111c45f763414f6f74ca2c" 32 | dependencies: 33 | d3-array "1" 34 | d3-path "1" 35 | 36 | d3-collection@1, d3-collection@1.0.3: 37 | version "1.0.3" 38 | resolved "https://registry.yarnpkg.com/d3-collection/-/d3-collection-1.0.3.tgz#00bdea94fbc1628d435abbae2f4dc2164e37dd34" 39 | 40 | d3-color@1, d3-color@1.0.3: 41 | version "1.0.3" 42 | resolved "https://registry.yarnpkg.com/d3-color/-/d3-color-1.0.3.tgz#bc7643fca8e53a8347e2fbdaffa236796b58509b" 43 | 44 | d3-dispatch@1, d3-dispatch@1.0.3: 45 | version "1.0.3" 46 | resolved "https://registry.yarnpkg.com/d3-dispatch/-/d3-dispatch-1.0.3.tgz#46e1491eaa9b58c358fce5be4e8bed626e7871f8" 47 | 48 | d3-drag@1, d3-drag@1.0.4: 49 | version "1.0.4" 50 | resolved "https://registry.yarnpkg.com/d3-drag/-/d3-drag-1.0.4.tgz#a9c1609f11dd5530ae275ebd64377ec54efb9d8f" 51 | dependencies: 52 | d3-dispatch "1" 53 | d3-selection "1" 54 | 55 | d3-dsv@1, d3-dsv@1.0.5: 56 | version "1.0.5" 57 | resolved "https://registry.yarnpkg.com/d3-dsv/-/d3-dsv-1.0.5.tgz#419f7db47f628789fc3fdb636e678449d0821136" 58 | dependencies: 59 | commander "2" 60 | iconv-lite "0.4" 61 | rw "1" 62 | 63 | d3-ease@1, d3-ease@1.0.3: 64 | version "1.0.3" 65 | resolved "https://registry.yarnpkg.com/d3-ease/-/d3-ease-1.0.3.tgz#68bfbc349338a380c44d8acc4fbc3304aa2d8c0e" 66 | 67 | d3-force@1.0.6: 68 | version "1.0.6" 69 | resolved "https://registry.yarnpkg.com/d3-force/-/d3-force-1.0.6.tgz#ea7e1b7730e2664cd314f594d6718c57cc132b79" 70 | dependencies: 71 | d3-collection "1" 72 | d3-dispatch "1" 73 | d3-quadtree "1" 74 | d3-timer "1" 75 | 76 | d3-format@1, d3-format@1.1.1: 77 | version "1.1.1" 78 | resolved "https://registry.yarnpkg.com/d3-format/-/d3-format-1.1.1.tgz#26e094e7b0fa925d3615aa6f43b265c5ca82b46e" 79 | 80 | d3-geo@1.6.3: 81 | version "1.6.3" 82 | resolved "https://registry.yarnpkg.com/d3-geo/-/d3-geo-1.6.3.tgz#21683a43a061eaba21a7f254b51d5937eb640756" 83 | dependencies: 84 | d3-array "1" 85 | 86 | d3-hierarchy@1.1.4: 87 | version "1.1.4" 88 | resolved "https://registry.yarnpkg.com/d3-hierarchy/-/d3-hierarchy-1.1.4.tgz#96c3942f3f21cf997a11b4edf00dde2a77b4c6d0" 89 | 90 | d3-interpolate@1, d3-interpolate@1.1.4: 91 | version "1.1.4" 92 | resolved "https://registry.yarnpkg.com/d3-interpolate/-/d3-interpolate-1.1.4.tgz#a43ec5b3bee350d8516efdf819a4c08c053db302" 93 | dependencies: 94 | d3-color "1" 95 | 96 | d3-path@1, d3-path@1.0.5: 97 | version "1.0.5" 98 | resolved "https://registry.yarnpkg.com/d3-path/-/d3-path-1.0.5.tgz#241eb1849bd9e9e8021c0d0a799f8a0e8e441764" 99 | 100 | d3-polygon@1.0.3: 101 | version "1.0.3" 102 | resolved "https://registry.yarnpkg.com/d3-polygon/-/d3-polygon-1.0.3.tgz#16888e9026460933f2b179652ad378224d382c62" 103 | 104 | d3-quadtree@1, d3-quadtree@1.0.3: 105 | version "1.0.3" 106 | resolved "https://registry.yarnpkg.com/d3-quadtree/-/d3-quadtree-1.0.3.tgz#ac7987e3e23fe805a990f28e1b50d38fcb822438" 107 | 108 | d3-queue@3.0.5: 109 | version "3.0.5" 110 | resolved "https://registry.yarnpkg.com/d3-queue/-/d3-queue-3.0.5.tgz#0ceffe1f131c459b13b9f69f1056b41dfc33c00d" 111 | 112 | d3-random@1.0.3: 113 | version "1.0.3" 114 | resolved "https://registry.yarnpkg.com/d3-random/-/d3-random-1.0.3.tgz#6526c844aa5e7c457e29ddacd6f2734f845b42c1" 115 | 116 | d3-request@1.0.5: 117 | version "1.0.5" 118 | resolved "https://registry.yarnpkg.com/d3-request/-/d3-request-1.0.5.tgz#4daae946d1dd0d57dfe01f022956354958d51f23" 119 | dependencies: 120 | d3-collection "1" 121 | d3-dispatch "1" 122 | d3-dsv "1" 123 | xmlhttprequest "1" 124 | 125 | d3-scale@1.0.5: 126 | version "1.0.5" 127 | resolved "https://registry.yarnpkg.com/d3-scale/-/d3-scale-1.0.5.tgz#418506f0fb18eb052b385e196398acc2a4134858" 128 | dependencies: 129 | d3-array "1" 130 | d3-collection "1" 131 | d3-color "1" 132 | d3-format "1" 133 | d3-interpolate "1" 134 | d3-time "1" 135 | d3-time-format "2" 136 | 137 | d3-selection@1, d3-selection@1.0.5: 138 | version "1.0.5" 139 | resolved "https://registry.yarnpkg.com/d3-selection/-/d3-selection-1.0.5.tgz#948c73b41a44e28d1742ae2ff207c2aebca2734b" 140 | 141 | d3-shape@1.0.6: 142 | version "1.0.6" 143 | resolved "https://registry.yarnpkg.com/d3-shape/-/d3-shape-1.0.6.tgz#b09e305cf0c7c6b9a98c90e6b42f62dac4bcfd5b" 144 | dependencies: 145 | d3-path "1" 146 | 147 | d3-swoopy-drag@^0.0.3: 148 | version "0.0.3" 149 | resolved "https://registry.yarnpkg.com/d3-swoopy-drag/-/d3-swoopy-drag-0.0.3.tgz#0a85b6ac1b8a3ba4bae4ecec9b96f7ac11b0fb2c" 150 | dependencies: 151 | d3 "4" 152 | 153 | d3-time-format@2, d3-time-format@2.0.5, d3-time-format@^2.0.3: 154 | version "2.0.5" 155 | resolved "https://registry.yarnpkg.com/d3-time-format/-/d3-time-format-2.0.5.tgz#9d7780204f7c9119c9170b1a56db4de9a8af972e" 156 | dependencies: 157 | d3-time "1" 158 | 159 | d3-time@1, d3-time@1.0.6: 160 | version "1.0.6" 161 | resolved "https://registry.yarnpkg.com/d3-time/-/d3-time-1.0.6.tgz#a55b13d7d15d3a160ae91708232e0835f1d5e945" 162 | 163 | d3-timer@1, d3-timer@1.0.5: 164 | version "1.0.5" 165 | resolved "https://registry.yarnpkg.com/d3-timer/-/d3-timer-1.0.5.tgz#b266d476c71b0d269e7ac5f352b410a3b6fe6ef0" 166 | 167 | d3-tip@^0.7.1: 168 | version "0.7.1" 169 | resolved "https://registry.yarnpkg.com/d3-tip/-/d3-tip-0.7.1.tgz#78cbf554f67b720a70e3b0f191e14cffe68cdd79" 170 | dependencies: 171 | d3 "^4.2" 172 | 173 | d3-transition@1, d3-transition@1.0.4: 174 | version "1.0.4" 175 | resolved "https://registry.yarnpkg.com/d3-transition/-/d3-transition-1.0.4.tgz#e1a9ebae3869a9d9c2874ab00841fa8313ae5de5" 176 | dependencies: 177 | d3-color "1" 178 | d3-dispatch "1" 179 | d3-ease "1" 180 | d3-interpolate "1" 181 | d3-selection "1" 182 | d3-timer "1" 183 | 184 | d3-voronoi@1.1.2: 185 | version "1.1.2" 186 | resolved "https://registry.yarnpkg.com/d3-voronoi/-/d3-voronoi-1.1.2.tgz#1687667e8f13a2d158c80c1480c5a29cb0d8973c" 187 | 188 | d3-zoom@1.1.3: 189 | version "1.1.3" 190 | resolved "https://registry.yarnpkg.com/d3-zoom/-/d3-zoom-1.1.3.tgz#0bd488622f22dc0534894f744a40ec979599fdc4" 191 | dependencies: 192 | d3-dispatch "1" 193 | d3-drag "1" 194 | d3-interpolate "1" 195 | d3-selection "1" 196 | d3-transition "1" 197 | 198 | d3@4, d3@^4.2, d3@^4.7.1: 199 | version "4.7.3" 200 | resolved "https://registry.yarnpkg.com/d3/-/d3-4.7.3.tgz#1bc7b0282b41d97642bdb673372c88e81ecca4a3" 201 | dependencies: 202 | d3-array "1.1.1" 203 | d3-axis "1.0.6" 204 | d3-brush "1.0.4" 205 | d3-chord "1.0.4" 206 | d3-collection "1.0.3" 207 | d3-color "1.0.3" 208 | d3-dispatch "1.0.3" 209 | d3-drag "1.0.4" 210 | d3-dsv "1.0.5" 211 | d3-ease "1.0.3" 212 | d3-force "1.0.6" 213 | d3-format "1.1.1" 214 | d3-geo "1.6.3" 215 | d3-hierarchy "1.1.4" 216 | d3-interpolate "1.1.4" 217 | d3-path "1.0.5" 218 | d3-polygon "1.0.3" 219 | d3-quadtree "1.0.3" 220 | d3-queue "3.0.5" 221 | d3-random "1.0.3" 222 | d3-request "1.0.5" 223 | d3-scale "1.0.5" 224 | d3-selection "1.0.5" 225 | d3-shape "1.0.6" 226 | d3-time "1.0.6" 227 | d3-time-format "2.0.5" 228 | d3-timer "1.0.5" 229 | d3-transition "1.0.4" 230 | d3-voronoi "1.1.2" 231 | d3-zoom "1.1.3" 232 | 233 | distill-template@^1.0.1: 234 | version "1.0.1" 235 | resolved "https://registry.yarnpkg.com/distill-template/-/distill-template-1.0.1.tgz#3e85cbf72b65bc4af59842ec4d40ca011c7a5bbb" 236 | dependencies: 237 | commander "^2.9.0" 238 | d3-time-format "^2.0.3" 239 | html-escape "^2.0.0" 240 | mustache "^2.3.0" 241 | 242 | "graceful-readlink@>= 1.0.0": 243 | version "1.0.1" 244 | resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" 245 | 246 | html-escape@^2.0.0: 247 | version "2.0.0" 248 | resolved "https://registry.yarnpkg.com/html-escape/-/html-escape-2.0.0.tgz#60c8ddd465edf0cae02af9e99fdf5f883b09be49" 249 | 250 | iconv-lite@0.4: 251 | version "0.4.15" 252 | resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.15.tgz#fe265a218ac6a57cfe854927e9d04c19825eddeb" 253 | 254 | mustache@^2.3.0: 255 | version "2.3.0" 256 | resolved "https://registry.yarnpkg.com/mustache/-/mustache-2.3.0.tgz#4028f7778b17708a489930a6e52ac3bca0da41d0" 257 | 258 | numeric@^1.2.6: 259 | version "1.2.6" 260 | resolved "https://registry.yarnpkg.com/numeric/-/numeric-1.2.6.tgz#765b02bef97988fcf880d4eb3f36b80fa31335aa" 261 | 262 | rw@1: 263 | version "1.3.3" 264 | resolved "https://registry.yarnpkg.com/rw/-/rw-1.3.3.tgz#3f862dfa91ab766b14885ef4d01124bfda074fb4" 265 | 266 | xmlhttprequest@1: 267 | version "1.8.0" 268 | resolved "https://registry.yarnpkg.com/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz#67fe075c5c24fef39f9d65f5f7b7fe75171968fc" 269 | --------------------------------------------------------------------------------