Disabled external gits

This commit is contained in:
sora committed 2022-04-07 18:46:57 +02:00
1 parent 88cb3426ad
commit 15e7120d6d
5316 files changed
+4563444 -6

No files matched your search

+1
View File
@@ -0,0 +1 @@
[[[0.7573293773467382, 0.815047959624175, 0.0], [0.7382918866768229, 0.8077426395800297, 0.0], [0.712807971666606, 0.7957615925851973, 0.0], [0.7025417450220812, 0.7796701569309142, 0.0], [0.6905147333347126, 0.7641698088151446, 0.0], [0.6793643644045892, 0.7483741167757003, 0.0], [0.6673363171733719, 0.7328707847993249, 0.0], [0.6541204865584065, 0.7050700117825089, 0.0], [0.6438513735470383, 0.6889742567787731, 0.0], [0.6335847950959635, 0.6728768029722143, 0.0], [0.624194929186718, 0.6535565129899636, 0.0], [0.6072033550923888, 0.6406773330435204, 0.0], [0.5925570685472923, 0.628965823073566, 0.0], [0.5758661692185844, 0.6198853195169207, 0.0], [0.5732475248887626, 0.6383313847786196, 0.0], [0.5797140498702152, 0.6664329808910836, 0.0], [0.5896863234125586, 0.6845779265571226, 0.0], [0.5929267241510738, 0.7059500788604043, 0.0], [0.5906008050694399, 0.7252773384605989, 0.0], [0.573338669682959, 0.7408109043389407, 0.0], [0.5534242681248813, 0.7367290270551946, 0.0], [0.5340919192657138, 0.728546934259311, 0.0], [0.5229508967995333, 0.7127450201498058, 0.0], [0.5161988164330544, 0.692546786657812, 0.0], [0.5176433286115328, 0.6705846056000913, 0.0], [0.5284610605006752, 0.6532983843659802, 0.0], [0.5337132572810496, 0.633966401827168, 0.0], [0.5146815088164846, 0.6178549030844644, 0.0], [0.4962530023539942, 0.6210860140535831, 0.0], [0.4778298101267601, 0.6243323141529102, 0.0], [0.45910709047789033, 0.6237903203823153, 0.0], [0.4231461376634795, 0.6329988144889741, 0.0], [0.40269389127869387, 0.6389484437451657, 0.0], [0.38487379724532883, 0.6440284986173911, 0.0], [0.36004525200227483, 0.6515085516542231, 0.0], [0.3407301868385678, 0.6522199326934308, 0.0], [0.31820845211132603, 0.6550103118053049, 0.0], [0.29803362107883724, 0.6589626036868257, 0.0], [0.27897167080827456, 0.6547015804149422, 0.0], [0.26078687906728837, 0.6501391554987626, 0.0], [0.2446143127277615, 0.639999408573925, 0.0], [0.24017775026661636, 0.6371835829261571, 0.0], [0.24780161368549525, 0.6350016068799627, 0.0], [0.2671412673271519, 0.6372133837367266, 0.0], [0.2561844113695899, 0.6194277265530355, 0.0], [0.27438988297428896, 0.6269159084119125, 0.0], [0.2882521156256806, 0.6417554628674451, 0.0], [0.3782687416748515, 0.6159581040830083, 0.0], [0.39788265318089827, 0.6131985642091516, 0.0], [0.44143872235135195, 0.5916428110295225, 0.0], [0.4610552680405679, 0.5860101394146493, 0.0], [0.47745021071223154, 0.5765997623363373, 0.0], [0.4844719918212728, 0.5566705801614275, 0.0], [0.48768557091512166, 0.5370357075131162, 0.0], [0.49001771394177024, 0.5176909168459198, 0.0], [0.4894171396308898, 0.49833944935318464, 0.0], [0.47536571766691904, 0.48540927868348427, 0.0], [0.45779673964764533, 0.4765708371340902, 0.0], [0.4231924737353384, 0.4869853805484602, 0.0], [0.40355752827422076, 0.49248552938677986, 0.0], [0.3851022091596394, 0.4956531843672938, 0.0], [0.36664698891732705, 0.4988202960332706, 0.0], [0.3481923124812031, 0.5019840391616612, 0.0], [0.32798802892606443, 0.5028050213701808, 0.0], [0.30954915350146606, 0.5001177396128447, 0.0], [0.3137068905413534, 0.480219431163938, 0.0], [0.30028676208822025, 0.46320015822917926, 0.0], [0.28950152091836373, 0.44531112234637094, 0.0], [0.2962843505940312, 0.42746960228374464, 0.0], [0.3077538171729307, 0.40905572855802474, 0.0], [0.3189225759265874, 0.3926924653459375, 0.0], [0.33183695332492746, 0.37867189881994306, 0.0], [0.3447443528619924, 0.364645323244238, 0.0], [0.3579353951423729, 0.35148054178665555, 0.0], [0.37112584673199467, 0.33831520156477846, 0.0], [0.3811170566467762, 0.3184053615503294, 0.0], [0.39402170622207217, 0.3043516221588848, 0.0], [0.4081041793030111, 0.29086397057182295, 0.0], [0.42418973317575387, 0.2804925367213136, 0.0], [0.4192266424898786, 0.2527379985072552, 0.0], [0.4090802353274594, 0.2323460911169658, 0.0], [0.3992815160520114, 0.21173990338173992, 0.0], [0.38527905825946634, 0.171175680926293, 0.0], [0.38479359771489124, 0.15094202586083685, 0.0], [0.38486308522160545, 0.13160554906355823, 0.0], [0.3854159702047642, 0.11016045290083347, 0.0], [0.38437358036209796, 0.0842756255957775, 0.0], [0.37213982673142726, 0.0683330336449822, 0.0], [0.364480880979052, 0.050603245684088936, 0.0], [0.37963678428673914, 0.035880692802962355, 0.0], [0.37927492077045655, 0.006330563839934674, 0.0], [0.37962962962962965, 0.0, 0.0], [0.3990740740740741, 0.0, 0.0], [0.4043166575303929, 0.017374031935027297, 0.0], [0.4122795069100327, 0.039982855211266814, 0.0], [0.41688964758463526, 0.06124430641791995, 0.0], [0.41483675252111685, 0.08088963268248343, 0.0], [0.42296258914843415, 0.13184066280759787, 0.0], [0.4304547752608189, 0.16500368614579322, 0.0], [0.435619873059154, 0.19020078306067437, 0.0], [0.4371210217143472, 0.20968749943011267, 0.0], [0.4528574464746929, 0.2201640974773047, 0.0], [0.46357062063000454, 0.23605648853564196, 0.0], [0.47501742508185535, 0.2507272326121305, 0.0], [0.48741557480733655, 0.2651260810910351, 0.0], [0.49930646626004144, 0.28062501Line truncated
@@ -0,0 +1 @@
[[[0.8102453102453102, 0.6623376623376623, 0.0], [0.8391053391053391, 0.6515151515151515, 0.0], [0.8816738816738817, 0.6479076479076479, 0.0], [0.911976911976912, 0.6457431457431457, 0.0], [0.943001443001443, 0.6219336219336219, 0.0], [0.9581529581529582, 0.5952380952380952, 0.0], [0.9595959595959596, 0.564935064935065, 0.0], [0.93001443001443, 0.5562770562770563, 0.0], [0.8997113997113997, 0.5584415584415584, 0.0], [0.8679653679653679, 0.5569985569985569, 0.0], [0.8917748917748918, 0.5382395382395382, 0.0], [0.9213564213564214, 0.5317460317460317, 0.0], [0.9090909090909091, 0.5043290043290043, 0.0], [0.8773448773448773, 0.5028860028860029, 0.0], [0.8347763347763347, 0.4956709956709957, 0.0], [0.8023088023088023, 0.4956709956709957, 0.0], [0.7784992784992785, 0.47691197691197695, 0.0], [0.7662337662337663, 0.44877344877344877, 0.0], [0.7582972582972582, 0.41919191919191917, 0.0], [0.7481962481962482, 0.38961038961038963, 0.0], [0.7705627705627706, 0.3686868686868687, 0.0], [0.7994227994227994, 0.3578643578643579, 0.0], [0.8145743145743146, 0.32972582972582976, 0.0], [0.79004329004329, 0.3477633477633478, 0.0], [0.7561327561327561, 0.3528138528138528, 0.0], [0.7554112554112554, 0.3217893217893218, 0.0], [0.7777777777777778, 0.297979797979798, 0.0], [0.8001443001443002, 0.2777777777777778, 0.0], [0.8059163059163059, 0.24675324675324678, 0.0], [0.7914862914862915, 0.22005772005772006, 0.0], [0.7655122655122655, 0.23593073593073594, 0.0], [0.784992784992785, 0.25901875901875904, 0.0], [0.7633477633477633, 0.2828282828282828, 0.0], [0.7402597402597403, 0.30303030303030304, 0.0], [0.7215007215007215, 0.3268398268398268, 0.0], [0.6984126984126984, 0.3023088023088023, 0.0], [0.6565656565656566, 0.25613275613275616, 0.0], [0.6327561327561327, 0.2373737373737374, 0.0], [0.6305916305916306, 0.1897546897546898, 0.0], [0.6363636363636364, 0.15800865800865804, 0.0], [0.6522366522366523, 0.1305916305916306, 0.0], [0.6782106782106783, 0.11038961038961037, 0.0], [0.6991341991341992, 0.08874458874458879, 0.0], [0.6695526695526696, 0.08225108225108224, 0.0], [0.6392496392496393, 0.08441558441558439, 0.0], [0.6233766233766234, 0.1219336219336219, 0.0], [0.6103896103896104, 0.14935064935064934, 0.0], [0.5909090909090909, 0.1724386724386724, 0.0], [0.5793650793650794, 0.20057720057720058, 0.0], [0.5483405483405484, 0.20057720057720058, 0.0], [0.5202020202020202, 0.189033189033189, 0.0], [0.5079365079365079, 0.16089466089466087, 0.0], [0.4898989898989899, 0.13347763347763353, 0.0], [0.46176046176046176, 0.10245310245310246, 0.0], [0.44877344877344877, 0.07431457431457433, 0.0], [0.4538239538239538, 0.04401154401154406, 0.0], [0.4588744588744589, 0.01443001443001446, 0.0], [0.46320346320346323, 0.0, 0.0], [0.40404040404040403, 0.0, 0.0], [0.4083694083694084, 0.03679653679653683, 0.0], [0.4033189033189033, 0.07215007215007219, 0.0], [0.4163059163059163, 0.09956709956709953, 0.0], [0.424963924963925, 0.1298701298701299, 0.0], [0.42568542568542567, 0.16594516594516595, 0.0], [0.424963924963925, 0.1976911976911977, 0.0], [0.3708513708513709, 0.20490620490620493, 0.0], [0.33405483405483405, 0.20202020202020204, 0.0], [0.30014430014430016, 0.1976911976911977, 0.0], [0.23809523809523808, 0.19624819624819623, 0.0], [0.20707070707070707, 0.19985569985569984, 0.0], [0.1774891774891775, 0.20634920634920634, 0.0], [0.14862914862914864, 0.21500721500721504, 0.0], [0.12121212121212122, 0.2272727272727273, 0.0], [0.09379509379509379, 0.2453102453102453, 0.0], [0.07142857142857142, 0.2676767676767677, 0.0], [0.056998556998557, 0.2943722943722944, 0.0], [0.049783549783549784, 0.3246753246753247, 0.0], [0.05194805194805195, 0.354978354978355, 0.0], [0.07431457431457432, 0.38961038961038963, 0.0], [0.10101010101010101, 0.40404040404040403, 0.0], [0.13203463203463203, 0.41053391053391053, 0.0], [0.16305916305916307, 0.41053391053391053, 0.0], [0.19336219336219337, 0.40476190476190477, 0.0], [0.2215007215007215, 0.3939393939393939, 0.0], [0.18831168831168832, 0.3924963924963925, 0.0], [0.1471861471861472, 0.39466089466089466, 0.0], [0.11832611832611832, 0.386002886002886, 0.0], [0.09812409812409813, 0.36363636363636365, 0.0], [0.09956709956709957, 0.3333333333333333, 0.0], [0.11976911976911978, 0.31096681096681095, 0.0], [0.15007215007215008, 0.30303030303030304, 0.0], [0.18037518037518038, 0.2987012987012987, 0.0], [0.22727272727272727, 0.29653679653679654, 0.0], [0.2597402597402597, 0.2994227994227994, 0.0], [0.29004329004329005, 0.3037518037518038, 0.0], [0.3203463203463203, 0.31096681096681095, 0.0], [0.3492063492063492, 0.3217893217893218, 0.0], [0.37662337662337664, 0.3354978354978355, 0.0], [0.39826839826839827, 0.3564213564213564, 0.0], [0.4365079365079365, 0.39754689754689754, 0.0], [0.461038961038961, 0.417027417027417, 0.0], [0.48773448773448774, 0.43362193362193363, 0.0], [0.5165945165945166, 0.4444444444444445, 0.0], [0.5512265512265512, 0.45165945165945165, 0.0], [0.5851370851370852, 0.4538239538239538, 0.0], [0.6154401154401155, 0.4603Line truncated
+1
View File
@@ -0,0 +1 @@
[[[0.3359440158378602, 0.9210224383966962, 0.0], [0.32330958658996634, 0.9062254765507053, 0.0], [0.3076839760844945, 0.8837254786449036, 0.0], [0.31354971286607275, 0.8607661751481109, 0.0], [0.321406620993005, 0.8429419861529877, 0.0], [0.32331842290331164, 0.8224977474697632, 0.0], [0.32383955805200093, 0.803573760300344, 0.0], [0.3214512431473188, 0.7847919066507826, 0.0], [0.3219624012166767, 0.7658660359772153, 0.0], [0.32247311506444515, 0.7469383179895955, 0.0], [0.32060640677825175, 0.7269665663626877, 0.0], [0.3211139611840756, 0.7080391290491052, 0.0], [0.32486052958534073, 0.6898226088089582, 0.0], [0.3325492432956687, 0.6690834054447675, 0.0], [0.33425509333256087, 0.6506726147545958, 0.0], [0.3380118435267127, 0.6324533310164088, 0.0], [0.3385403892661957, 0.6135149670964838, 0.0], [0.3370399633761822, 0.5943831813106111, 0.0], [0.3367280766910994, 0.5757814214734019, 0.0], [0.3381381640182549, 0.5565156996462688, 0.0], [0.3398736149960969, 0.5381080515959777, 0.0], [0.3445211856902299, 0.5195630711069649, 0.0], [0.3507443476854958, 0.4974556659594086, 0.0], [0.35657710993872394, 0.4794221759084357, 0.0], [0.36122999915700127, 0.4608587949567714, 0.0], [0.36798728755375926, 0.4375350736268683, 0.0], [0.375892094751611, 0.41968675895754504, 0.0], [0.3778798855765219, 0.3991953801466888, 0.0], [0.3784851610461282, 0.3802175523095769, 0.0], [0.3725103941819698, 0.35687375214274614, 0.0], [0.3702425192906588, 0.3380143889285765, 0.0], [0.36477820959132895, 0.3184019397736501, 0.0], [0.3630146222022237, 0.2983540190402495, 0.0], [0.35579264071058164, 0.2693744713203477, 0.0], [0.35005184811024936, 0.2506824310015569, 0.0], [0.34194213463440887, 0.23087115438175282, 0.0], [0.33940358765735706, 0.21202646827870036, 0.0], [0.3382782037371713, 0.1908394605862153, 0.0], [0.33579137320381025, 0.1717331870672063, 0.0], [0.3341910832675664, 0.1525202643609999, 0.0], [0.32651436498426833, 0.1291014630469347, 0.0], [0.32182488405793674, 0.10776361590173708, 0.0], [0.3129514206239005, 0.05987638600351459, 0.0], [0.3128480315922206, 0.02758337985395738, 0.0], [0.2978109446137065, 0.015794175098239823, 0.0], [0.3076216712580349, 0.0, 0.0], [0.37281910009182734, 0.0, 0.0], [0.37475623585072704, 0.02019234841347489, 0.0], [0.35066797301342756, 0.024678023994566034, 0.0], [0.345503650810237, 0.04614821977306916, 0.0], [0.3459196788540045, 0.07113476140514413, 0.0], [0.3543711225143529, 0.09127687362371499, 0.0], [0.3625732051273669, 0.13016953623313438, 0.0], [0.37069202250719313, 0.14652134200159217, 0.0], [0.38712828249988385, 0.1952866147446364, 0.0], [0.3883408498121473, 0.2138145248443017, 0.0], [0.4011145654549177, 0.22752144114485207, 0.0], [0.41736490553430144, 0.23684426614683915, 0.0], [0.4147449445228406, 0.21718839719446598, 0.0], [0.42064694931514013, 0.19919365405993028, 0.0], [0.4325598346081077, 0.17891464100737828, 0.0], [0.4508766243858671, 0.18566975979818517, 0.0], [0.4693976261899756, 0.19039734599308575, 0.0], [0.48195109029697036, 0.20527222074124524, 0.0], [0.4927776740744, 0.22080135943523474, 0.0], [0.4962073424380454, 0.2401296404154867, 0.0], [0.5018890917537571, 0.25761120173958213, 0.0], [0.5276700289072956, 0.2478309341026045, 0.0], [0.5478001437894935, 0.24904900974237523, 0.0], [0.5642048892866172, 0.25855934852810986, 0.0], [0.5823949582874507, 0.2546774961509056, 0.0], [0.600913028844294, 0.2516873534469379, 0.0], [0.62060417124299, 0.24922447379722482, 0.0], [0.6401837997697901, 0.2517281441772848, 0.0], [0.6583771291356296, 0.2479149142108905, 0.0], [0.6780741636202686, 0.245529608561992, 0.0], [0.6969982802662241, 0.24635383173496667, 0.0], [0.7153781363733951, 0.24837067319900116, 0.0], [0.7342028676965743, 0.2463117471416321, 0.0], [0.7536641098782242, 0.2459773744957077, 0.0], [0.7748463943641791, 0.24500667594427183, 0.0], [0.7959351401063506, 0.241133154118492, 0.0], [0.8149446624769359, 0.24487819394520238, 0.0], [0.8342682083976085, 0.24949167328598584, 0.0], [0.830835117088705, 0.26935876055504526, 0.0], [0.8124255474954948, 0.27517914891994294, 0.0], [0.7924241980110471, 0.2766944255608475, 0.0], [0.7735096921470452, 0.2758509593649, 0.0], [0.7361895332162711, 0.28082421296436144, 0.0], [0.7151095056149884, 0.28469905867614653, 0.0], [0.6966167727100511, 0.2876307132273694, 0.0], [0.6777081728377085, 0.28679779784180326, 0.0], [0.6517003784003726, 0.290565257755461, 0.0], [0.6308646566752287, 0.29243734853444037, 0.0], [0.6021825394273206, 0.30219582459934985, 0.0], [0.5832918281440399, 0.30928177331154166, 0.0], [0.5645110317792913, 0.31144767936965084, 0.0], [0.5467056007819816, 0.3162027747867516, 0.0], [0.5358267545999726, 0.33405792062102874, 0.0], [0.5236482872497418, 0.34847937563462994, 0.0], [0.5136374618145731, 0.36600017123770795, 0.0], [0.5097627094224002, 0.3841465416234051, 0.0], [0.5041823054386294, 0.4029479318603322, 0.0], [0.49858792982459504, 0.4267085592646809, 0.0], [0.49272067112878676, 0.4446458121389922, 0.0], [0.4953849708947529, 0.4642659940Line truncated
@@ -0,0 +1,782 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"import meshplot as mp\n",
"import numpy as np\n",
"import sys\n",
"import matplotlib.pyplot as plt\n",
"import json\n",
"import math\n",
"import igl\n",
"from matplotlib import pyplot as plt\n",
"sys.path.append(\"../src/\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# 1. Visualize Gradient"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"For a scalar value function $E$ using mesh vertices as variable (i.e, most of our energy function), \n",
"\n",
"we can visualize its gradient by drawing an arrow $\\frac{\\partial E}{\\partial \\boldsymbol{x}} $ at each of the mesh vertex $\\boldsymbol{x}$, which help debug your code."
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"def draw_mesh_and_gradient(V, F, G):\n",
" fig = plt.figure()\n",
" plt.triplot(V[:, 0], V[:, 1], triangles = F)\n",
" plt.quiver(V[:, 0], V[:, 1], G[:, 0], G[:, 1])\n",
" plt.axis('equal')\n",
" plt.ylim([min(V[:, 1]) - 0.5, max(V[:, 1]) + 0.5])\n",
" plt.show() "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 1.1 Gradient of Mesh Area"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"from energies import compute_faces_area_gradient, vertex_cells_sum\n",
"def compute_mesh_area_gradient(V, F):\n",
" dAfx, dAfy = compute_faces_area_gradient(V, F)\n",
" dAx = vertex_cells_sum(dAfx, F)\n",
" dAy = vertex_cells_sum(dAfy, F)\n",
" dA = np.column_stack([dAx, dAy])\n",
" return dA"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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 truncated
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"V = np.array([[0, 0, 0], [1, 0, 0], [0, 1, 0], [1, 1, 0]], dtype = float)\n",
"F = np.array([[0, 1, 2], [1, 3, 2]])\n",
"G = compute_mesh_area_gradient(V, F)\n",
"draw_mesh_and_gradient(V, F, G)"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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 truncated
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"V = np.array([[0, 0, 0], [1, 0, 0], [0, 1, 0], [-1, 0, 0], [0, -1, 0]], dtype = float)\n",
"F = np.array([[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 1]])\n",
"G = compute_mesh_area_gradient(V, F)\n",
"draw_mesh_and_gradient(V, F, G)"
]
},
{
"attachments": {
"gradient_area_01.png": {
"image/png": "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 truncated
},
"gradient_area_02.png": {
"image/png": "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 truncated
}
},
"cell_type": "markdown",
"metadata": {},
"source": [
"Referenced image\n",
"![gradient_area_01.png](attachment:gradient_area_01.png)\n",
"![gradient_area_02.png](attachment:gradient_area_02.png)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 1.2 Gradient of Equilibrium Energy"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"scrolled": true
},
"outputs": [
{
"data": {
"image/png": "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 truncated
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"V = np.array([[0, 0, 0], [1, 0, 0], [0, 1, 0], [1, 1, 0]], dtype = float)\n",
"F = np.array([[0, 1, 2], [1, 3, 2]])\n",
"from energies import compute_equilibrium_energy_gradient\n",
"G = compute_equilibrium_energy_gradient(V, F, 0.0)\n",
"draw_mesh_and_gradient(V, F, G)"
]
},
{
"attachments": {
"gradient_equilibrium.png": {
"image/png": "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 truncated
}
},
"cell_type": "markdown",
"metadata": {},
"source": [
"Referenced image\n",
"![gradient_equilibrium.png](attachment:gradient_equilibrium.png)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 1.3 Gradient of Shape Energy"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAX4AAAD8CAYAAABw1c+bAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjQuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/MnkTPAAAACXBIWXMAAAsTAAALEwEAmpwYAAAZHUlEQVR4nO3df5BU5Z3v8feHAYyCJatodJEJaIi5EfSKcwFl44/4A6UwbKpSW2hkTeIwq7lYwcLNFXIj0VjBXVO5roqXIEHiTYLeW0qEXBColAbU1fCjnMgPNeDGOA5ZFhRkooE7+r1/dEPaoYc5M9Mz3afP51U1Nd3P85ye71OPfvpw+vQ5igjMzCw7+pS7ADMz610OfjOzjHHwm5lljIPfzCxjHPxmZhnj4Dczy5gOg1/SUEnPSNomaYukbxYZc4mkfZJezv/cUdB3laTXJG2XdHupJ2BmZp3TN8GYVmBmRGySdDywUdKaiNjaZty6iJhU2CCpBpgHXAE0AeslLSuyrZmZ9ZIO9/gjYmdEbMo/3g9sA4YkfP0xwPaIeCMiDgKPAZO7WqyZmXVfkj3+wyQNA84DXirSfYGkRqAZuC0itpB7g3irYEwTMLad124AGgAGDBhw/mc/+9nOlGZmlmkbN27cHREnJxmbOPglDQSeAGZExHttujcBn4qIFkkTgV8AIwAVeami14iIiAXAAoC6urrYsGFD0tLMzDJP0ptJxyY6q0dSP3Kh/7OIeLJtf0S8FxEt+ccrgH6SBpPbwx9aMPR0cv8iMDOzMklyVo+AHwPbIuKH7Yw5NT8OSWPyr7sHWA+MkDRcUn9gCrCsVMWbmVnnJTnUMx6YCrwi6eV822ygFiAi5gNfBm6W1Ap8AEyJ3GU/WyVNB1YBNcCi/LF/MzMrE1XiZZl9jN/MrHMkbYyIuiRj/c1dM7OMcfCbmWWMg9/MLGMc/GZmGePgNzPLGAe/mVnGOPjNzDLGwW9mljEOfjOzjHHwm5lljIPfzCxjHPxmZhnj4DczyxgHv5lZxjj4zcwyxsFvZpYxDn4zs4xx8JuZZUySm60PlfSMpG2Stkj6ZpExX5H02/zPC5LOLej7vaRXJL0syfdTNDMrsyQ3W28FZkbEJknHAxslrYmIrQVj/g24OCLelXQ1sAAYW9B/aUTsLl3ZZmbWVR0Gf0TsBHbmH++XtA0YAmwtGPNCwSYvAqeXuE4zMyuRTh3jlzQMOA946SjDbgRWFjwPYLWkjZIaOl2hmZmVVJJDPQBIGgg8AcyIiPfaGXMpueD/m4Lm8RHRLOkUYI2kVyNibZFtG4AGgNra2k5MwczMOiPRHr+kfuRC/2cR8WQ7Y84BFgKTI2LPofaIaM7/3gUsBcYU2z4iFkREXUTUnXzyyZ2bhZmZJZbkrB4BPwa2RcQP2xlTCzwJTI2I1wvaB+Q/EEbSAOBKYHMpCjczs65JcqhnPDAVeEXSy/m22UAtQETMB+4ATgIeyr1P0BoRdcAngaX5tr7AzyPi6VJOwMzMOifJWT3PAepgTD1QX6T9DeDcI7cwM7Ny8Td3zcwyxsFvZpYxDn4zs4xx8JuZZYyD3z5myZIl7Ny5s9xlmFkPcvDbxwwfPpwRI0bwne98h/feK/oFbTNLOQe/fcy4ceOYMGECd999N2eccQb33XcfBw4cKHdZZlZCDn47wve//31qamrYs2cPt956K2eddRY//elP+eijj8pdmpmVgIPfjnDWWWfx9a9//fDzN998k6lTpzJ69GhWrlxJRJSxOjPrLge/FTVnzhyOPfbYj7U1NjYyceJEvvCFL/Cb3/ymTJWZWXc5+K2oIUOGMGPGjKJ9zz77LLfeeitbtmzp3aLMrCQc/Naub33rW5x44olHtD/++OM8//zznH322WWoysy6y8Fv7Ro0aBDf/va3j2i/8cYbeeGFF4psYdXMn+1UDwe/HdU3vvENamtr6devHz/4wQ8AaGlpYcKECQ7/jNi0aROzZs1y8FcRB78d1Sc+8QnuuusuJkyYwMyZM3n44YcBh38W7Nixg+uuu47zzz+fyy67jD59HBfVIvE9dy27rr/+ej7zmc8AUF+fu+3CtGnTDof/qlWruPDCC8tZopXQrl27+N73vsf8+fNpbW3l8ssv5/LLLy93WVZCfgu3DtXU1HDBBRccfl5fX+89/yq0f/9+7rzzTs4880wefPBBWltbAbjnnnvKXJmVmoPfusThXz0OHjzIvHnz+PSnP813v/tdWlpaDvdNmTKF888/v4zVWU9w8FuXOfzT7aOPPuKxxx7jc5/7HNOnT2fXrl0f6+/bty933313maqzntRh8EsaKukZSdskbZH0zSJjJOl+Sdsl/VbS6IK+qyS9lu+7vdQTsPJy+KfXgQMH+PDDDxk5ciT9+/c/ov+mm27izDPPLENl1tPU0Slakk4DTouITZKOBzYCfxsRWwvGTARuASYCY4F/iYixkmqA14ErgCZgPXBt4bbF1NXVxYYNG7oxLettCxcuZNq0aaA+nFD7Wf7v44s5f/Tojje0svvXF1/imi9O5k979wC5PBg4cCA7duzglFNOKW9xlpikjRFRl2Rsh2f1RMROYGf+8X5J24AhQGF4TwYejdy7yIuSBuXfMIYB2yPijXxhj+XHHjX4LX0One0z8+GnGXTp1/jK0l2w9OkyV2VJDf6HxbQuvgX2NnPgwAFmzpzp0K9inTqdU9Iw4DzgpTZdQ4C3Cp435duKtY9t57UbgAaA2trazpRlFaK+vp6WYwZzX/4SPoOO60fDRWeUtyjr0E//9U2a9/2Zhx96kBX/53/xq1/9ipkzZ5a7LOtBiYNf0kDgCWBGRLS9NZOKbBJHaT+yMWIBsAByh3qS1mWV5UsTr+C+Lc8CsPf9/0eNxD9c7OPElez4Y/rynae2cPWVlzGAPzN+/HiOP/74cpdlPShR8EvqRy70fxYRTxYZ0gQMLXh+OtAM9G+n3arcP3/5HNb9bjdzV74K4PBPiauvvpqamppyl2E9rMPglyTgx8C2iPhhO8OWAdPzx/DHAvsiYqek/wBGSBoOvA1MAa4rTelWyfr2Ef/j784FcPinSNt7MFh1SrLHPx6YCrwi6eV822ygFiAi5gMryJ3Rsx14H/havq9V0nRgFVADLIoIX8Q9I/rW9HH4m1WgJGf1PEfxY/WFYwL4r+30rSD3xmAZ5PA3qzy+SJv1OIe/WWVx8FuvcPibVQ4Hv/Uah79ZZXDwW69y+JuVn4Pfep3D36y8HPxWFg5/s/Jx8FvZOPzNysPBb2Xl8DfrfQ5+KzuHv1nvcvBbRXD4m/UeB79VDIe/We9w8FtFcfib9TwHv1Uch79Zz3LwW0Vy+Jv1HAe/VSyHv1nPcPBbRXP4m5Weg98qnsPfrLQc/JYKDn+z0klys/VFwCRgV0SMLNL/j8BXCl7vPwEnR8Q7kn4P7Ac+BFojoq5UhVv2OPzNSiPJHv9i4EHg0WKdEXEvcC+ApGuAWyPinYIhl0bE7m7WaQY4/M1KIcnN1tdKGpbw9a4FlnSrIrMOOPzNuqdkx/glHQdcBUwvaA5gtaQAfhQRC46yfQPQAFBbW1uqsqxKOfzNuq6UH+5eAzzf5jDP+IholnQKsEbSqxGxttjG+TeFBQB1dXVRwrqsSjn8zbqmlME/hTaHeSKiOf97l6SlwBigaPCbdYXD36zzShL8kk4ALgauL2gbAPSJiP35x1cCd5Xi75kVcvibdU6S0zmXAJcAgyU1AXOAfgARMT8/7EvA6oj4U8GmnwSWSjr0d34eEU+XrnSzv3D4myWX5KyeaxOMWUzutM/CtjeAc7tamFlnOfzNkvE3d62qOPzNOubgt6rj8Dc7Oge/VSWHv1n7HPxWtRz+ZsU5+K2qOfzNjuTgt6rn8Df7OAe/ZYLD3+wvHPyWGQ5/sxwHv2WKw9/MwW8Z5PC3rHPwWyY5/C3LHPyWWQ5/yyoHv2Waw9+yyMFvmefwt6xx8Jvh8LdscfCb5Tn8LSsc/GYFHP6WBQ5+szYc/lbt+nQ0QNIiSbskbW6n/xJJ+yS9nP+5o6DvKkmvSdou6fZSFm7Wkw6F/zXn/jVzV77Kj369o9wlmZVMkj3+xcCDwKNHGbMuIiYVNkiqAeYBVwBNwHpJyyJiaxdrNetV3vO3apXkZutrJQ3rwmuPAbbnb7qOpMeAyYCD31LD4W/VqFTH+C+Q1Ag0A7dFxBZgCPBWwZgmYGx7LyCpAWgAqK2tLVFZZt3n8LdqU4rg3wR8KiJaJE0EfgGMAFRkbLT3IhGxAFgAUFdX1+44s3Jw+Fs16XbwR8R7BY9XSHpI0mBye/hDC4aeTu5fBGap5PC3atHt4Jd0KvDvERGSxpA7U2gPsBcYIWk48DYwBbiuu3/PrJwc/lYNOgx+SUuAS4DBkpqAOUA/gIiYD3wZuFlSK/ABMCUiAmiVNB1YBdQAi/LH/s1SzeFvaZfkrJ5rO+h/kNzpnsX6VgArulaaWeVy+Fua+Zu7Zl3k8Le0cvCbdYPD39LIwW/WTQ5/SxsHv1kJOPwtTRz8ZiXi8Le0cPCblZDD39LAwW9WYg5/q3QOfrMe4PC3SubgN+shDn+rVA5+sx7k8LdK5OA362EOf6s0Dn6zXuDwt0ri4DfrJQ5/qxQOfrNe5PC3SuDgN+tlDn8rNwe/WRk4/K2cHPxmZeLwt3Jx8JuVkcPfyiHJPXcXAZOAXRExskj/V4D/ln/aAtwcEY35vt8D+4EPgdaIqCtR3WZVw+FvvS3JHv9icvfUfbSd/n8DLo6IdyVdDSwAxhb0XxoRu7tVpVmVc/hbb0pys/W1koYdpf+FgqcvAqeXoC6zzHH4W28p9TH+G4GVBc8DWC0pgB9FxIL2NpTUADQA1NbWlrgss3Rw+FtvKFnwS7qUXPD/TUHz+IholnQKsEbSqxGxttj2+TeFBQB1dXVRqrrM0sbhbz2tJMEv6RxgIXB1ROw51B4RzfnfuyQtBcYARYPfzP7C4W8Line truncated
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"V = np.array([[1, 1, 0], [2, 1, 0], [1, 2, 0], [2, 2, 0]], dtype = float)\n",
"F = np.array([[0, 1, 2], [1, 3, 2]])\n",
"E = igl.edges(F)\n",
"from energies import compute_shape_energy_gradient\n",
"G = compute_shape_energy_gradient(V, E, [0.0, 0.0, 0.0, 0.0, 0.0])\n",
"draw_mesh_and_gradient(V, F, G)"
]
},
{
"attachments": {
"gradient_shape.png": {
"image/png": "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 truncated
}
},
"cell_type": "markdown",
"metadata": {},
"source": [
"Referenced image\n",
"![gradient_shape.png](attachment:gradient_shape.png)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# 2. Analytical Gradient Compared with Finite Differences"
]
},
{
"attachments": {
"errors.png": {
"image/png": "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 truncated
}
},
"cell_type": "markdown",
"metadata": {},
"source": [
"Compare your hande written derivatives with the finite difference.\n",
"\n",
"Given a function $f(\\boldsymbol{x}), \\boldsymbol{x} \\in R^n$, because of the taylor expension, $f(\\boldsymbol{x} + \\boldsymbol{h}) = f(\\boldsymbol{x}) + \\nabla f(\\boldsymbol{x})^T\\boldsymbol{h} + o(\\vert \\vert \\boldsymbol{h} \\vert \\vert)$\n",
"\n",
"The finite difference at point $\\boldsymbol{x}$ with step $\\boldsymbol{h}$ is defined as $Df_h = f(\\boldsymbol{x} + \\boldsymbol{h}) - f(\\boldsymbol{x})$\n",
"\n",
"When $\\vert \\vert \\boldsymbol{h} \\vert \\vert \\rightarrow 0$, \n",
"\n",
"$$Err(f) = \\frac{Df_h - \\nabla f(\\boldsymbol{x})^T\\boldsymbol{h}}{\\vert \\vert \\boldsymbol{h} \\vert \\vert} \\rightarrow 0$$\n",
"\n",
"We can draw the error graph $Err(f)$ by gradually deceasing the size of $\\vert \\vert \\boldsymbol{h} \\vert \\vert$.\n",
"\n",
"![Error Graph](attachment:errors.png)\n",
"\n",
"When $\\vert \\vert \\boldsymbol{h} \\vert \\vert \\leq 10^{-8}$, the percision of our computer is not enough to compute $Df_h$ correctly which causes the error grows significantly. All figures generated in this section should have this pattern (the absolute value does not matter), otherwise please check your derivatives."
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
"V = np.array([[0, 0, 0], [1, 0, 0], [0, 1, 0], [1, 1, 0]], dtype = float)\n",
"F = np.array([[0, 1, 2], [1, 3, 2]])\n",
"E = igl.edges(F)\n",
"deltaV = np.random.rand(V.shape[0], 2)\n",
"deltaV /= np.linalg.norm(deltaV)\n",
"scales = [math.pow(10, -x) for x in np.arange(3, 12.0, 0.01)]\n",
"def plot_finite_difference_errors(errors):\n",
" fig = plt.figure()\n",
" ax = fig.gca()\n",
" ax.set_yscale('log')\n",
" ax.set_xscale('log')\n",
" ax.plot(scales, errors)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 2.1 Mesh Area"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"scrolled": true
},
"outputs": [
{
"data": {
"image/png": "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 truncated
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"from geometry import compute_mesh_area\n",
"\n",
"def compute_finite_difference_for_mesh_area(V, F, deltaV):\n",
" V1 = V.copy()\n",
" V1[:, 0 : 2] += deltaV\n",
" finite_difference = compute_mesh_area(V1, F) - compute_mesh_area(V, F)\n",
" return finite_difference\n",
"\n",
"gradient = compute_mesh_area_gradient(V, F)\n",
"errors = []\n",
"for scale in scales:\n",
" finite_difference = compute_finite_difference_for_mesh_area(V, F, deltaV * scale)\n",
" analytical = gradient * deltaV * scale\n",
" errors.append(abs(finite_difference - np.sum(analytical)) / scale)\n",
"plot_finite_difference_errors(errors)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 2.2 Equilibrium Energy"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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 truncated
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"from energies import compute_equilibrium_energy\n",
"from energies import compute_equilibrium_energy_gradient\n",
"\n",
"\n",
"def compute_finite_difference_for_equilibrium_energy(V, F, x_csl, deltaV):\n",
" V1 = V.copy()\n",
" V1[:, 0 : 2] += deltaV\n",
" return compute_equilibrium_energy(V1, F, x_csl) - compute_equilibrium_energy(V, F, x_csl)\n",
"\n",
"x_csl = 0\n",
"gradient = compute_equilibrium_energy_gradient(V, F, x_csl)\n",
"errors = []\n",
"for scale in scales:\n",
" finite_difference = compute_finite_difference_for_equilibrium_energy(V, F, x_csl, deltaV * scale)\n",
" analytical = gradient * deltaV * scale\n",
" errors.append(abs(finite_difference - np.sum(analytical)) / scale)\n",
"plot_finite_difference_errors(errors)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 2.3 Shape Energy"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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 truncated
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"from energies import compute_shape_energy\n",
"from energies import compute_shape_energy_gradient\n",
"from energies import compute_edges_length\n",
"\n",
"def compute_finite_difference_for_shape_energy(V, E, l0, deltaV):\n",
" V1 = V.copy()\n",
" V1[:, 0 : 2] += deltaV\n",
" return compute_shape_energy(V1, E, l0) - compute_shape_energy(V, E, l0)\n",
"\n",
"x_csl = 0\n",
"l0 = [0, 0, 0, 0, 0]\n",
"gradient = compute_shape_energy_gradient(V, E, l0)\n",
"errors = []\n",
"for scale in scales:\n",
" finite_difference = compute_finite_difference_for_shape_energy(V, E, l0, deltaV * scale)\n",
" analytical = gradient * deltaV * scale\n",
" errors.append(abs(finite_difference - np.sum(analytical)) / scale)\n",
"plot_finite_difference_errors(errors)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# 3. Fixed Step Gradient Descent"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [],
"source": [
"from geometry import compute_mesh_centroid\n",
"\n",
"shader = {\"flat\":True, # Flat or smooth shading of triangles\n",
" \"wireframe\": True, \"wire_width\": 0.03, \"wire_color\": \"black\", # Wireframe rendering\n",
" \"width\": 600, \"height\": 600, # Size of the viewer canvas\n",
" \"antialias\": True, # Antialising, might not work on all GPUs\n",
" \"scale\": 2.0, # Scaling of the model\n",
" \"side\": \"DoubleSide\", # FrontSide, BackSide or DoubleSide rendering of the triangles\n",
" \"colormap\": \"viridis\", \"normalize\": [None, None], # Colormap and normalization for colors\n",
" \"background\": \"#ffffff\", # Background color of the canvas\n",
" \"line_width\": 1.0, \"line_color\": \"black\", # Line properties of overlay lines\n",
" \"bbox\": False, # Enable plotting of bounding box\n",
" \"point_color\": \"red\", \"point_size\": 0.01 # Point properties of overlay points\n",
" }\n",
"\n",
"def draw_meshes_comparison(V1, F1, V2, F2, color1, color2):\n",
" mesh_plot = mp.plot(V1, F1, c = color1, return_plot=True)\n",
" mesh_plot.add_mesh(V2, F2, c = color2, shading=shader)\n",
" \n",
" center0 = np.array(compute_mesh_centroid(V2, F2))\n",
" center1 = center0.copy()\n",
" center1[1] = 0\n",
" vertices = np.vstack([center0, center1])\n",
" mesh_plot.add_points(vertices, shading={\"point_color\": \"black\", \"point_size\": 0.1})\n",
" mesh_plot.add_edges(vertices, np.array([[0, 1]]), shading={\"line_color\": \"black\", \"line_width\" : 0.5});"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# 3.1 Input Mesh"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [],
"source": [
"with open('../data/dinosaur.json', 'r') as infile:\n",
" [V, F] = json.load(infile)\n",
" V = np.array(V)\n",
" F = np.array(F)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# 3.2 Fixed Step Gradient Descent"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {
"scrolled": false
},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "a190a440ddb24e11b3302fe2085b2eb4",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"Renderer(camera=PerspectiveCamera(children=(DirectionalLight(color='white', intensity=0.6, position=(0.5660395…"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"from optimization import fixed_step_gradient_descent\n",
"from geometry import compute_center_support_line\n",
"\n",
"x_csl = compute_center_support_line(V)\n",
"[V1, F, objective, time] = fixed_step_gradient_descent(V, F, x_csl, w = 10, theta = 0.02, iters = 100)\n",
"\n",
"mesh_plot = draw_meshes_comparison(V, F, V1, F, np.array([0.3, 0.3, 0.3]), np.array([1.0, 1.0, 0]))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# 3.3 Draw Objective Energy Curve"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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 truncated
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
},
{
"data": {
"image/png": "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 truncated
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
},
{
"data": {
"image/png": "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 truncated
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"fig = plt.figure()\n",
"plt.plot(objective)\n",
"plt.xlabel(\"number of iteration\")\n",
"plt.ylabel(\"objective energy\")\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 3.4 Homework"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Please optimize other meshes in the data/ folder to make them equilibrium. \n",
"\n",
"Simply copy the code above, change the input mesh and save the notebook as a pdf for submission.\n",
"\n",
"Don't forgot to plot the objective energy curve."
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "5cc6a61da0a7472db18ef95466047ccc",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"Renderer(camera=PerspectiveCamera(children=(DirectionalLight(color='white', intensity=0.6, position=(0.5094172…"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"image/png": "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 truncated
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"with open('../data/dance.json', 'r') as infile:\n",
" [V, F] = json.load(infile)\n",
" V = np.array(V)\n",
" F = np.array(F)\n",
"\n",
"from optimization import fixed_step_gradient_descent\n",
"from geometry import compute_center_support_line\n",
"\n",
"x_csl = compute_center_support_line(V)\n",
"[V1, F, objective, time] = fixed_step_gradient_descent(V, F, x_csl, w = 10, theta = 0.02, iters = 100)\n",
"\n",
"mesh_plot = draw_meshes_comparison(V, F, V1, F, np.array([0.3, 0.3, 0.3]), np.array([1.0, 1.0, 0]))\n",
"\n",
"fig = plt.figure()\n",
"plt.plot(objective)\n",
"plt.xlabel(\"number of iteration\")\n",
"plt.ylabel(\"objective energy\")\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "ef80b383d7d34c348b908ef7b64875dd",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"Renderer(camera=PerspectiveCamera(children=(DirectionalLight(color='white', intensity=0.6, position=(0.5660395…"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"image/png": "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 truncated
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"with open('../data/gym.json', 'r') as infile:\n",
" [V, F] = json.load(infile)\n",
" V = np.array(V)\n",
" F = np.array(F)\n",
"\n",
"from optimization import fixed_step_gradient_descent\n",
"from geometry import compute_center_support_line\n",
"\n",
"x_csl = compute_center_support_line(V)\n",
"[V1, F, objective, time] = fixed_step_gradient_descent(V, F, x_csl, w = 10, theta = 0.02, iters = 100)\n",
"\n",
"mesh_plot = draw_meshes_comparison(V, F, V1, F, np.array([0.3, 0.3, 0.3]), np.array([1.0, 1.0, 0]))\n",
"\n",
"fig = plt.figure()\n",
"plt.plot(objective)\n",
"plt.xlabel(\"number of iteration\")\n",
"plt.ylabel(\"objective energy\")\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Derivations"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The derivation of $\\frac{\\delta x_f}{\\delta V}$ is relativly straight forward:\n",
"$$ \\frac{\\delta x_f}{\\delta V} = \\frac{\\delta}{\\delta V} (\\frac{v_a + v_b + v_c}{3}) = \\frac{1}{3} (\\frac{\\delta v_a}{\\delta v} + \\frac{\\delta v_b}{\\delta v} + \\frac{\\delta v_c}{\\delta v})$$\n",
"From this we can see that if $V=v_i$, and $x_f$ has a vertex $v_i$, then the derivative is $\\frac{1}{3}$, and otherwhise $0$ !"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The computation of $\\frac{\\delta E_{sh}}{\\delta V}$ is similarly straight forward:\n",
"\n",
"$$ \\frac{\\delta E_{sh}}{\\delta V} = \\frac{\\delta}{\\delta V}(\\frac{1}{2} \\sum_{e\\in E}(l_e - L_e)^2) = \\frac{1}{2} \\sum_{e\\in E} \\frac{\\delta}{\\delta V}(l_e - Le)^2 = \\sum_{e\\in E} (l_e - Le)\\frac{\\delta l_e}{\\delta V}$$\n",
"\n",
"Similarly as before, when we look at $\\frac{\\delta l_e}{\\delta V}$, we see that given that $l_e = \\sqrt{(x_a - x_b)^2 + (y_a - y_b)^2}$, the detivative is if $V=[x_a,y_a]$:\n",
"\n",
"$\\frac{\\delta l_e}{\\delta V} = \\frac{[x_a-x_b,y_a-y_b]}{l_e}$"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Remarks"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Some functions most notably `compute_shape_energy_gradient` and `compute_equilibrium_energy_gradient` are only partialy optimized for timing, in fact they still rely on a `for in range()` instruction to loop through vertices resulting in are rather large timing impact."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"`fixed_step_gradient_descent` also is partly complete, the slow runtime and lack of instructions made understanding the missing code portions and debuging the function troublesome."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.7"
}
},
"nbformat": 4,
"nbformat_minor": 4
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

@@ -0,0 +1,758 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"import meshplot as mp\n",
"import numpy as np\n",
"import sys\n",
"import matplotlib.pyplot as plt\n",
"import json\n",
"import math\n",
"import igl\n",
"from matplotlib import pyplot as plt\n",
"sys.path.append(\"../src/\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# 1. Visualize Gradient"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"For a scalar value function $E$ using mesh vertices as variable (i.e, most of our energy function), \n",
"\n",
"we can visualize its gradient by drawing an arrow $\\frac{\\partial E}{\\partial \\boldsymbol{x}} $ at each of the mesh vertex $\\boldsymbol{x}$, which help debug your code."
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"def draw_mesh_and_gradient(V, F, G):\n",
" fig = plt.figure()\n",
" plt.triplot(V[:, 0], V[:, 1], triangles = F)\n",
" plt.quiver(V[:, 0], V[:, 1], G[:, 0], G[:, 1])\n",
" plt.axis('equal')\n",
" plt.ylim([min(V[:, 1]) - 0.5, max(V[:, 1]) + 0.5])\n",
" plt.show() "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 1.1 Gradient of Mesh Area"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"from energies import compute_faces_area_gradient, vertex_cells_sum\n",
"def compute_mesh_area_gradient(V, F):\n",
" dAfx, dAfy = compute_faces_area_gradient(V, F)\n",
" dAx = vertex_cells_sum(dAfx, F)\n",
" dAy = vertex_cells_sum(dAfy, F)\n",
" dA = np.column_stack([dAx, dAy])\n",
" return dA"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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 truncated
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"V = np.array([[0, 0, 0], [1, 0, 0], [0, 1, 0], [1, 1, 0]], dtype = float)\n",
"F = np.array([[0, 1, 2], [1, 3, 2]])\n",
"G = compute_mesh_area_gradient(V, F)\n",
"draw_mesh_and_gradient(V, F, G)"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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 truncated
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"V = np.array([[0, 0, 0], [1, 0, 0], [0, 1, 0], [-1, 0, 0], [0, -1, 0]], dtype = float)\n",
"F = np.array([[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 1]])\n",
"G = compute_mesh_area_gradient(V, F)\n",
"draw_mesh_and_gradient(V, F, G)"
]
},
{
"attachments": {
"gradient_area_01.png": {
"image/png": "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 truncated
},
"gradient_area_02.png": {
"image/png": "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 truncated
}
},
"cell_type": "markdown",
"metadata": {},
"source": [
"Referenced image\n",
"![gradient_area_01.png](attachment:gradient_area_01.png)\n",
"![gradient_area_02.png](attachment:gradient_area_02.png)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 1.2 Gradient of Equilibrium Energy"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"scrolled": true
},
"outputs": [
{
"data": {
"image/png": "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 truncated
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"V = np.array([[0, 0, 0], [1, 0, 0], [0, 1, 0], [1, 1, 0]], dtype = float)\n",
"F = np.array([[0, 1, 2], [1, 3, 2]])\n",
"from energies import compute_equilibrium_energy_gradient\n",
"G = compute_equilibrium_energy_gradient(V, F, 0.0)\n",
"draw_mesh_and_gradient(V, F, G)"
]
},
{
"attachments": {
"gradient_equilibrium.png": {
"image/png": "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 truncated
}
},
"cell_type": "markdown",
"metadata": {},
"source": [
"Referenced image\n",
"![gradient_equilibrium.png](attachment:gradient_equilibrium.png)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 1.3 Gradient of Shape Energy"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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 truncated
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"V = np.array([[1, 1, 0], [2, 1, 0], [1, 2, 0], [2, 2, 0]], dtype = float)\n",
"F = np.array([[0, 1, 2], [1, 3, 2]])\n",
"E = igl.edges(F)\n",
"from energies import compute_shape_energy_gradient\n",
"G = compute_shape_energy_gradient(V, E, [0.0, 0.0, 0.0, 0.0, 0.0])\n",
"draw_mesh_and_gradient(V, F, G)"
]
},
{
"attachments": {
"gradient_shape.png": {
"image/png": "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 truncated
}
},
"cell_type": "markdown",
"metadata": {},
"source": [
"Referenced image\n",
"![gradient_shape.png](attachment:gradient_shape.png)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# 2. Analytical Gradient Compared with Finite Differences"
]
},
{
"attachments": {
"errors.png": {
"image/png": "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 truncated
}
},
"cell_type": "markdown",
"metadata": {},
"source": [
"Compare your hande written derivatives with the finite difference.\n",
"\n",
"Given a function $f(\\boldsymbol{x}), \\boldsymbol{x} \\in R^n$, because of the taylor expension, $f(\\boldsymbol{x} + \\boldsymbol{h}) = f(\\boldsymbol{x}) + \\nabla f(\\boldsymbol{x})^T\\boldsymbol{h} + o(\\vert \\vert \\boldsymbol{h} \\vert \\vert)$\n",
"\n",
"The finite difference at point $\\boldsymbol{x}$ with step $\\boldsymbol{h}$ is defined as $Df_h = f(\\boldsymbol{x} + \\boldsymbol{h}) - f(\\boldsymbol{x})$\n",
"\n",
"When $\\vert \\vert \\boldsymbol{h} \\vert \\vert \\rightarrow 0$, \n",
"\n",
"$$Err(f) = \\frac{Df_h - \\nabla f(\\boldsymbol{x})^T\\boldsymbol{h}}{\\vert \\vert \\boldsymbol{h} \\vert \\vert} \\rightarrow 0$$\n",
"\n",
"We can draw the error graph $Err(f)$ by gradually deceasing the size of $\\vert \\vert \\boldsymbol{h} \\vert \\vert$.\n",
"\n",
"![Error Graph](attachment:errors.png)\n",
"\n",
"When $\\vert \\vert \\boldsymbol{h} \\vert \\vert \\leq 10^{-8}$, the percision of our computer is not enough to compute $Df_h$ correctly which causes the error grows significantly. All figures generated in this section should have this pattern (the absolute value does not matter), otherwise please check your derivatives."
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
"V = np.array([[0, 0, 0], [1, 0, 0], [0, 1, 0], [1, 1, 0]], dtype = float)\n",
"F = np.array([[0, 1, 2], [1, 3, 2]])\n",
"E = igl.edges(F)\n",
"deltaV = np.random.rand(V.shape[0], 2)\n",
"deltaV /= np.linalg.norm(deltaV)\n",
"scales = [math.pow(10, -x) for x in np.arange(3, 12.0, 0.01)]\n",
"def plot_finite_difference_errors(errors):\n",
" fig = plt.figure()\n",
" ax = fig.gca()\n",
" ax.set_yscale('log')\n",
" ax.set_xscale('log')\n",
" ax.plot(scales, errors)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 2.1 Mesh Area"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"scrolled": true
},
"outputs": [
{
"data": {
"image/png": "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 truncated
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"from geometry import compute_mesh_area\n",
"\n",
"def compute_finite_difference_for_mesh_area(V, F, deltaV):\n",
" V1 = V.copy()\n",
" V1[:, 0 : 2] += deltaV\n",
" finite_difference = compute_mesh_area(V1, F) - compute_mesh_area(V, F)\n",
" return finite_difference\n",
"\n",
"gradient = compute_mesh_area_gradient(V, F)\n",
"errors = []\n",
"for scale in scales:\n",
" finite_difference = compute_finite_difference_for_mesh_area(V, F, deltaV * scale)\n",
" analytical = gradient * deltaV * scale\n",
" errors.append(abs(finite_difference - np.sum(analytical)) / scale)\n",
"plot_finite_difference_errors(errors)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 2.2 Equilibrium Energy"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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 truncated
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"from energies import compute_equilibrium_energy\n",
"from energies import compute_equilibrium_energy_gradient\n",
"\n",
"\n",
"def compute_finite_difference_for_equilibrium_energy(V, F, x_csl, deltaV):\n",
" V1 = V.copy()\n",
" V1[:, 0 : 2] += deltaV\n",
" return compute_equilibrium_energy(V1, F, x_csl) - compute_equilibrium_energy(V, F, x_csl)\n",
"\n",
"x_csl = 0\n",
"gradient = compute_equilibrium_energy_gradient(V, F, x_csl)\n",
"errors = []\n",
"for scale in scales:\n",
" finite_difference = compute_finite_difference_for_equilibrium_energy(V, F, x_csl, deltaV * scale)\n",
" analytical = gradient * deltaV * scale\n",
" errors.append(abs(finite_difference - np.sum(analytical)) / scale)\n",
"plot_finite_difference_errors(errors)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 2.3 Shape Energy"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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 truncated
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"from energies import compute_shape_energy\n",
"from energies import compute_shape_energy_gradient\n",
"from energies import compute_edges_length\n",
"\n",
"def compute_finite_difference_for_shape_energy(V, E, l0, deltaV):\n",
" V1 = V.copy()\n",
" V1[:, 0 : 2] += deltaV\n",
" return compute_shape_energy(V1, E, l0) - compute_shape_energy(V, E, l0)\n",
"\n",
"x_csl = 0\n",
"l0 = [0, 0, 0, 0, 0]\n",
"gradient = compute_shape_energy_gradient(V, E, l0)\n",
"errors = []\n",
"for scale in scales:\n",
" finite_difference = compute_finite_difference_for_shape_energy(V, E, l0, deltaV * scale)\n",
" analytical = gradient * deltaV * scale\n",
" errors.append(abs(finite_difference - np.sum(analytical)) / scale)\n",
"plot_finite_difference_errors(errors)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# 3. Fixed Step Gradient Descent"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [],
"source": [
"from geometry import compute_mesh_centroid\n",
"\n",
"shader = {\"flat\":True, # Flat or smooth shading of triangles\n",
" \"wireframe\": True, \"wire_width\": 0.03, \"wire_color\": \"black\", # Wireframe rendering\n",
" \"width\": 600, \"height\": 600, # Size of the viewer canvas\n",
" \"antialias\": True, # Antialising, might not work on all GPUs\n",
" \"scale\": 2.0, # Scaling of the model\n",
" \"side\": \"DoubleSide\", # FrontSide, BackSide or DoubleSide rendering of the triangles\n",
" \"colormap\": \"viridis\", \"normalize\": [None, None], # Colormap and normalization for colors\n",
" \"background\": \"#ffffff\", # Background color of the canvas\n",
" \"line_width\": 1.0, \"line_color\": \"black\", # Line properties of overlay lines\n",
" \"bbox\": False, # Enable plotting of bounding box\n",
" \"point_color\": \"red\", \"point_size\": 0.01 # Point properties of overlay points\n",
" }\n",
"\n",
"def draw_meshes_comparison(V1, F1, V2, F2, color1, color2):\n",
" mesh_plot = mp.plot(V1, F1, c = color1, return_plot=True)\n",
" mesh_plot.add_mesh(V2, F2, c = color2, shading=shader)\n",
" \n",
" center0 = np.array(compute_mesh_centroid(V2, F2))\n",
" center1 = center0.copy()\n",
" center1[1] = 0\n",
" vertices = np.vstack([center0, center1])\n",
" mesh_plot.add_points(vertices, shading={\"point_color\": \"black\", \"point_size\": 0.1})\n",
" mesh_plot.add_edges(vertices, np.array([[0, 1]]), shading={\"line_color\": \"black\", \"line_width\" : 0.5});"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# 3.1 Input Mesh"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [],
"source": [
"with open('../data/dinosaur.json', 'r') as infile:\n",
" [V, F] = json.load(infile)\n",
" V = np.array(V)\n",
" F = np.array(F)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# 3.2 Fixed Step Gradient Descent"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {
"scrolled": false
},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "802b490712b6432aa7930e5d327f2960",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"Renderer(camera=PerspectiveCamera(children=(DirectionalLight(color='white', intensity=0.6, position=(0.5046897…"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"from optimization import fixed_step_gradient_descent\n",
"from geometry import compute_center_support_line\n",
"\n",
"x_csl = compute_center_support_line(V)\n",
"[V1, F, objective, time] = fixed_step_gradient_descent(V, F, x_csl, w = 10, theta = 0.02, iters = 100)\n",
"\n",
"mesh_plot = draw_meshes_comparison(V, F, V1, F, np.array([0.3, 0.3, 0.3]), np.array([1.0, 1.0, 0]))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# 3.3 Draw Objective Energy Curve"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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 truncated
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"fig = plt.figure()\n",
"plt.plot(objective)\n",
"plt.xlabel(\"number of iteration\")\n",
"plt.ylabel(\"objective energy\")\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 3.4 Homework"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Please optimize other meshes in the data/ folder to make them equilibrium. \n",
"\n",
"Simply copy the code above, change the input mesh and save the notebook as a pdf for submission.\n",
"\n",
"Don't forgot to plot the objective energy curve."
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "6de410c9dcb4499cb12875656da3e24c",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"Renderer(camera=PerspectiveCamera(children=(DirectionalLight(color='white', intensity=0.6, position=(0.5094172…"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"image/png": "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 truncated
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"with open('../data/dance.json', 'r') as infile:\n",
" [V, F] = json.load(infile)\n",
" V = np.array(V)\n",
" F = np.array(F)\n",
"\n",
"from optimization import fixed_step_gradient_descent\n",
"from geometry import compute_center_support_line\n",
"\n",
"x_csl = compute_center_support_line(V)\n",
"[V1, F, objective, time] = fixed_step_gradient_descent(V, F, x_csl, w = 10, theta = 0.02, iters = 100)\n",
"\n",
"mesh_plot = draw_meshes_comparison(V, F, V1, F, np.array([0.3, 0.3, 0.3]), np.array([1.0, 1.0, 0]))\n",
"\n",
"fig = plt.figure()\n",
"plt.plot(objective)\n",
"plt.xlabel(\"number of iteration\")\n",
"plt.ylabel(\"objective energy\")\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "f0815cebdcac4f43ac6d2666d009cf19",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"Renderer(camera=PerspectiveCamera(children=(DirectionalLight(color='white', intensity=0.6, position=(0.5660395…"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"image/png": "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 truncated
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"with open('../data/gym.json', 'r') as infile:\n",
" [V, F] = json.load(infile)\n",
" V = np.array(V)\n",
" F = np.array(F)\n",
"\n",
"from optimization import fixed_step_gradient_descent\n",
"from geometry import compute_center_support_line\n",
"\n",
"x_csl = compute_center_support_line(V)\n",
"[V1, F, objective, time] = fixed_step_gradient_descent(V, F, x_csl, w = 10, theta = 0.02, iters = 100)\n",
"\n",
"mesh_plot = draw_meshes_comparison(V, F, V1, F, np.array([0.3, 0.3, 0.3]), np.array([1.0, 1.0, 0]))\n",
"\n",
"fig = plt.figure()\n",
"plt.plot(objective)\n",
"plt.xlabel(\"number of iteration\")\n",
"plt.ylabel(\"objective energy\")\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Derivations"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The derivation of $\\frac{\\delta x_f}{\\delta V}$ is relativly straight forward:\n",
"$$ \\frac{\\delta x_f}{\\delta V} = \\frac{\\delta}{\\delta V} (\\frac{v_a + v_b + v_c}{3}) = \\frac{1}{3} (\\frac{\\delta v_a}{\\delta v} + \\frac{\\delta v_b}{\\delta v} + \\frac{\\delta v_c}{\\delta v})$$\n",
"From this we can see that if $V=v_i$, and $x_f$ has a vertex $v_i$, then the derivative is $\\frac{1}{3}$, and otherwhise $0$ !"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The computation of $\\frac{\\delta E_{sh}}{\\delta V}$ is similarly straight forward:\n",
"\n",
"$$ \\frac{\\delta E_{sh}}{\\delta V} = \\frac{\\delta}{\\delta V}(\\frac{1}{2} \\sum_{e\\in E}(l_e - L_e)^2) = \\frac{1}{2} \\sum_{e\\in E} \\frac{\\delta}{\\delta V}(l_e - Le)^2 = \\sum_{e\\in E} (l_e - Le)\\frac{\\delta l_e}{\\delta V}$$\n",
"\n",
"Similarly as before, when we look at $\\frac{\\delta l_e}{\\delta V}$, we see that given that $l_e = \\sqrt{(x_a - x_b)^2 + (y_a - y_b)^2}$, the detivative is if $V=[x_a,y_a]$:\n",
"\n",
"$\\frac{\\delta l_e}{\\delta V} = \\frac{[x_a-x_b,y_a-y_b]}{l_e}$"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Remarks"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Some functions most notably `compute_shape_energy_gradient` and `compute_equilibrium_energy_gradient` are only partialy optimized for timing, in fact they still rely on a `for in range()` instruction to loop through vertices resulting in are rather large timing impact."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"`fixed_step_gradient_descent` also is partly complete, the slow runtime and lack of instructions made understanding the missing code portions and debuging the function troublesome."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.7"
}
},
"nbformat": 4,
"nbformat_minor": 4
}
+244
View File
@@ -0,0 +1,244 @@
import numpy as np
from scipy import sparse
# -----------------------------------------------------------------------------
# Functions from assignment_1_1
# -----------------------------------------------------------------------------
from geometry import compute_mesh_centroid
from geometry import compute_faces_centroid
from geometry import compute_faces_area
# -----------------------------------------------------------------------------
# Provided functions
# -----------------------------------------------------------------------------
def vertex_cells_sum(values, cells):
"""
Sums values at vertices from each incident n-cell.
Input:
- values : np.array (#cells,) or (#cells, n)
The cell values to be summed at vertices.
If shape (#cells,): The value is per-cell,
If shape (#cells, n): The value refers to the corresponding cell vertex.
- cells : np.array (#cells, n)
The array of cells.
Output:
- v_sum : np.array (#vertices,)
A vector with the sum at each i-th vertex in i-th position.
Note:
If n = 2 the cell is an edge, if n = 3 the cell is a triangle,
if n = 4 the cell can be a tetrahedron or a quadrilateral, depending on
the data structure.
"""
i = cells.flatten('F')
j = np.arange(len(cells))
j = np.tile(j, cells.shape[1])
v = values.flatten('F')
if len(v) == len(cells):
v = v[j]
v_sum = sparse.coo_matrix((v, (i, j)), (np.max(cells) + 1, len(cells)))
return np.array(v_sum.sum(axis=1)).flatten()
def compute_edges_length(V, E):
"""
Computes the edge length of each mesh edge.
Input:
- V : np.array (#V, 3)
The array of vertices positions.
Contains the coordinates of the i-th vertex in i-th row
- E : np.array (#edges, 2)
The array of mesh edges.
generated from the function E = igl.edges(F)
returns an array (#edges, 2) where i-th row contains the indices of the two vertices of i-th edge.
Output:
- l : np.array (#edges,)
The edge lengths.
"""
l = np.linalg.norm(V[E[:, 0]] - V[E[:, 1]], axis=1)
return l
# -----------------------------------------------------------------------------
# 2.5.1 Target energies
# -----------------------------------------------------------------------------
def compute_equilibrium_energy(V, F, x_csl):
"""
Computes the equilibrium energy E_eq = 1/2*(x_cm - x_csl)^2.
Input:
-- V : np.array (#V, 3)
The array of vertices positions.
Contains the coordinates of the i-th vertex in i-th row
- F : np.array (#F, 3)
The array of triangle faces.
- x_csl : float
The x coordinate of the center of the support line.
Output:
- E_eq : float
the equilibrium energy of the mesh with respect to the target centroid
x_csl.
"""
x_cm = compute_mesh_centroid(V,F)[0]
E_eq = 0.5 * (x_cm - x_csl)**2
return E_eq
def compute_shape_energy(V, E, L):
"""
Computes the energy E_sh = 1/2 sum_e (l_e - L_e)^2 in the current
configuration V, where l_e is the length of mesh edges, and L_e the
corresponding length in the undeformed configuration.
Input:
- V : np.array (#V, 3)
The array of vertices positions.
Contains the coordinates of the i-th vertex in i-th row
- E : np.array (#edges, 2)
The array of mesh edges.
- L : np.array (#edges,)
The rest lengths of mesh edges.
Output:
- E_sh : float
The energy E_sh in the current configuration V.
"""
l = compute_edges_length(V,E)
Lf = np.array(L)
e_vec = np.arange(len(E))
ldiff = (l[e_vec]-Lf[e_vec])**2
E_sh = 0.5 * np.sum(ldiff)
return E_sh
# -----------------------------------------------------------------------------
# 2.5.2 Faces area gradient
# -----------------------------------------------------------------------------
def compute_faces_area_gradient(V, F):
"""
Computes the gradient of faces area.
Input:
- V : np.array (#V, 3)
The array of vertices positions.
Contains the coordinates of the i-th vertex in i-th row
- F : np.array (#F, 3)
The array of triangle faces.
Output:
- dA_x : np.array (#F, 3)
The gradient of faces areas A_i with respect to the x coordinate of each
face vertex x_1, x_2, and x_3, with (i,0) = dA_i/dx_1, (i,1) = dA_i/dx_2,
and (i,2) = dA_i/dx_3.
- dA_y : np.array (#F, 3)
The gradient of faces areas A_i with respect to the y coordinate of each
face vertex y_1, y_2, and y_3, with (i,0) = dA_i/dy_1, (i,1) = dA_i/dy_2,
and (i,2) = dA_i/dy_3.
"""
grad = lambda a,b: (V[a]-V[b])
gradABC = lambda fi: [grad(fi[2],fi[1]),grad(fi[0],fi[2]),grad(fi[1],fi[0])]
dA = np.apply_along_axis(gradABC,1,F)/2
dA_x = -dA[:,:,1]
dA_y = dA[:,:,0]
return dA_x, dA_y
# -----------------------------------------------------------------------------
# 2.5.3 Equilibrium energy gradient
# -----------------------------------------------------------------------------
def compute_equilibrium_energy_gradient(V, F, x_csl):
"""
Computes the gradient of the energy E_eq = 1/2*(x_cm - x_csl)^2 with respect
to the x and y coordinates of each vertex, where x_cm is the x coordinate
of the area centroid and x_csl x coordinate of the center of the support
line.
Input:
- V : np.array (#V, 3)
The array of vertices positions.
Contains the coordinates of the i-th vertex in i-th row
- F : np.array (#F, 3)
The array of triangle faces.
- x_csl : float
The x coordinate of the center of the support line.
Output:
- grad_E_eq : np.array (#V, 2)
The gradient of the energy E_eq with respect to vertices v_i,
with (i, 0) = dE_eq/dx_i and (i, 1) = dE_eq/dy_i
"""
cm = compute_mesh_centroid(V,F)
x_cm = cm[0]
x_f = compute_faces_centroid(V,F)
A_f = compute_faces_area(V,F)
A_f_V_nonp = compute_faces_area_gradient(V, F)
A_f_V = np.stack(A_f_V_nonp,axis=-1)
A_omega = np.sum(A_f)
xfact = (x_cm - x_csl)/A_omega
xfV = lambda v: np.apply_along_axis(lambda x: np.array([1/3,0.0]) if np.any(x[:]==v) else np.zeros((2)),1,F)
AfV = lambda v: (np.where(F[:,0][:,None]==v,A_f_V[:,0,:2],
np.where(F[:,1][:,None]==v,A_f_V[:,1,:2],
np.where(F[:,2][:,None]==v,A_f_V[:,2,:2],np.zeros((F.shape[0],2))) )) )
cf = lambda v : AfV(v)*(x_f[:,0] - x_cm)[:, None] + (A_f[:, None]*xfV(v))
#v_vec = np.arange(len(V))
#veq = np.sum(cf(v_vec),axis=0)*xfact
veq = np.array([np.sum(cf(v),axis=0) for v in range(0,len(V))])*xfact
return veq
# -----------------------------------------------------------------------------
# 2.5.4 Shape energy gradient
# -----------------------------------------------------------------------------
def compute_shape_energy_gradient(V, E, L):
"""
Computes the gradient of the energy E_sh = 1/2 sum_e (l_e - L_e)^2 with
respect to the x and y coordinates of each vertex, where l_e is the length
of mesh edges, and L_e the corresponding length in the undeformed
configuration.
Input:
- V : np.array (#V, 3)
The array of vertices positions.
Contains the coordinates of the i-th vertex in i-th row
- E : np.array (#edges, 2)
The array of mesh edges.
- L : np.array (#edges,)
The rest lengths of mesh edges.
Output:
- grad_E_sh : np.array (#V, 2)
The gradient of the energy E_sh with respect to vertices v_i,
with (i, 0) = dE_sh/dx_i, (i, 1) = dE_sh/dy_i
"""
vdif = lambda ee0, ee1: (V[ee0]-V[ee1])[:,:2]
len_e_d = vdif(E[:,0],E[:,1])
len_e = np.linalg.norm(len_e_d, axis=1)
len_e_t = lambda v: (np.where(E[:,0][:,None]==v,len_e_d[:],
np.where(E[:,1][:,None]==v,-len_e_d[:],np.zeros(E.shape))))
veq = np.sum(np.array([len_e_t(v) for v in range(0,len(V))]),axis=1) - np.sum(L/len_e,axis=0)
return veq
+100
View File
@@ -0,0 +1,100 @@
import numpy as np
def compute_faces_area(V, F):
"""
Computes the area of the faces of a given triangle mesh (V, F).
Input:
- V : np.array (|V|, 3)
The array of vertices positions.
Contains the coordinates of the i-th vertex in i-th row
- F : np.array (|F|, 3)
The array of triangle faces.
Output:
- area : np.array (|F|,)
The area of the faces. The i-th position contains the area of the i-th
face.
"""
# HW.1.3.3
return np.linalg.norm(np.cross(V[F[:,1]] - V[F[:,0]],V[F[:,2]] - V[F[:,0]], axis=1), axis=1)/2.0
def compute_mesh_area(V, F):
"""
Computes the area of a given triangle mesh (V, F).
Input:
- V : np.array (|V|, 3)
The array of vertices positions.
Contains the coordinates of the i-th vertex in i-th row
- F : np.array (|F|, 3)
The array of triangle faces.
Output:
- area : float
The area of the mesh.
"""
# HW.1.3.3
return np.sum(compute_faces_area(V,F))
def compute_faces_centroid(V, F):
"""
Computes the area centroid of each face of a given triangle mesh (V, F).
Input:
- V : np.array (|V|, 3)
The array of vertices positions.
Contains the coordinates of the i-th vertex in i-th row
- F : np.array (|F|, 3)
The array of triangle faces.
Output:
- cf : np.array (|F|, 3)
The area centroid of the faces.
"""
# HW.1.3.4
return (V[F[:,0]]+ V[F[:,1]] + V[F[:,2]])/3.0
def compute_mesh_centroid(V, F):
"""
Computes the area centroid of a given triangle mesh (V, F).
Input:
- V : np.array (|V|, 3)
The array of vertices positions.
Contains the coordinates of the i-th vertex in i-th row
- F : np.array (|F|, 3)
The array of triangle faces.
Output:
- centroid : np.array (3,)
The area centroid of the mesh.
"""
# HW.1.3.4
face_centroid = compute_faces_centroid(V,F)
face_area = compute_faces_area(V,F)
return 1.0/np.sum(face_area) * np.sum(np.einsum('i,ij->ij', face_area, face_centroid), axis=0)
def compute_center_support_line(V):
"""
Computes the x coordinate of the center of the support line
Input:
- V : np.array (|V|, 3)
The array of vertices positions.
Contains the coordinates of the i-th vertex in i-th row
Output:
- x_csl : float
the x coordinate of the center of the support line
"""
# HW.1.3.5
support_v = np.fromiter((v[0] for v in V if v[1]<10**-5), dtype=V.dtype)
x_csl = np.amin(support_v)+(np.amax(support_v)-np.amin(support_v))/2
return x_csl
+138
View File
@@ -0,0 +1,138 @@
from energies import compute_edges_length
from energies import compute_equilibrium_energy_gradient, compute_equilibrium_energy
from energies import compute_shape_energy_gradient, compute_shape_energy
from geometry import compute_mesh_centroid
import numpy as np
import time
import igl
def compute_optimization_objective(V, F, E, x_csl, L0, w):
"""
Compute the objective function of make-it-stand problem.
E = E_equilibrium + w * E_shape
Input:
- V : np.array (#V, 3)
The array of vertices positions.
Contains the coordinates of the i-th vertex in i-th row
- F : np.array (#F, 3)
The array of triangle faces.
- E : np.array (#edges, 2)
The array of mesh edges.
- x_csl : float
The x coordinate of the center of the support line.
- L0 : np.array (#edges,)
The rest lengths of mesh edges.
- w : float
The weight for shape preservation energy.
Output:
- obj : float
The value of the objective function.
"""
E_eq = compute_equilibrium_energy(V, F, x_csl)
E_sh = compute_shape_energy(V, E, L0)
obj = E_eq + w*E_sh
return obj
def compute_optimization_objective_gradient(V, F, E, x_csl, L0, w):
"""
Compute the gradient of the objective function of make-it-stand problem.
D_E = D_E_equilibrium + w * D_E_shape
Input:
- V : np.array (#V, 3)
The array of vertices positions.
Contains the coordinates of the i-th vertex in i-th row
- F : np.array (#F, 3)
The array of triangle faces.
- E : np.array (#edges, 2)
The array of mesh edges.
- x_csl : float
The x coordinate of the center of the support line.
- l0 : np.array (#edges,)
The rest lengths of mesh edges.
- w : float
The weight for shape preservation energy.
Output:
- grad_obj : np.array (#V, 2)
The gradient of objective function.
"""
grad_E_eq = compute_equilibrium_energy_gradient(V, F, x_csl)
grad_E_sh = compute_shape_energy_gradient(V, E, L0)
grad_obj = grad_E_eq + w * grad_E_sh
return grad_obj
def fixed_step_gradient_descent(V, F, x_csl, w, theta, iters):
"""
Find equilibrium shape by using fixed step gradient descent method
Input:
- V : np.array (#V, 3)
The array of vertices positions.
Contains the coordinates of the i-th vertex in i-th row
- F : np.array (#F, 3)
The array of triangle faces.
- x_csl : float
The x coordinate of the center of the support line.
- w : float
The weight for shape preservation energy.
- theta : float
The optimization step.
- iters : int
The number of iteration for gradient descent.
Output:
- V1 : np.array (#V, 3)
The optimized mesh's vertices
- F : np.array (#F, 3)
The array of triangle faces.
- energy: np.array(iters, 1)
The objective function energy curve with respect to the number of iterations.
- running_time: float
The tot running time of the optimization
"""
V1 = V.copy()
# this function of libigl returns an array (#edges, 2) where i-th row
# contains the indices of the two vertices of i-th edge.
E = igl.edges(F)
fix = np.where(V1[:, 1] < 1e-3)[0]
L0 = compute_edges_length(V1, E)
t0 = time.time()
energy = []
for i in range(iters):
grad = compute_optimization_objective_gradient(V1, F, E, x_csl, L0, w)
obj = compute_optimization_objective(V1, F, E, x_csl, L0, w)
energy.append(obj)
grad[fix] = 0
### start of your code.
x_cm = compute_mesh_centroid(V, F)[0]
if abs(x_csl - x_cm)<=10**-3:
break
if (np.linalg.norm(grad)<=10**-3):
break
# grad_f = grad[:,3
grad_f = np.zeros((np.shape(grad)[0],3))
grad_f[:,:-1] = grad
V1 = V1 -(theta * grad_f)
### end of your code.
running_time = time.time() - t0
return [V1, F, energy, running_time]
+87
View File
@@ -0,0 +1,87 @@
# import pytest
import time
import pytest
import json
import sys
import igl
import numpy as np
sys.path.append('../')
sys.path.append('../src')
from src.energies import *
eps = 1E-6
with open('test_data2.json', 'r') as infile:
homework_datas = json.load(infile)
# @pytest.mark.timeout(1)
@pytest.mark.parametrize("data", homework_datas[0])
def test_shape_energy_correctness(data):
V = np.array(data[0], dtype=float)
E = np.array(data[1], dtype=int)
l0 = np.array(data[2], dtype=float)
shape_energy_ground_truth = np.array(data[3])
shape_energy_student = compute_shape_energy(V, E, l0)
assert np.linalg.norm(shape_energy_ground_truth - shape_energy_student) < eps
# @pytest.mark.timeout(1)
@pytest.mark.parametrize("data", homework_datas[1])
def test_equilibrium_engery_correctness(data):
V = np.array(data[0], dtype=float)
F = np.array(data[1], dtype=int)
x_csl = data[2]
equilibrium_engery_ground_truth = np.array(data[3])
equilibrium_engery_student = compute_equilibrium_energy(V, F, x_csl)
assert np.linalg.norm(equilibrium_engery_ground_truth - equilibrium_engery_student) < eps
@pytest.mark.timeout(1)
@pytest.mark.parametrize("data", homework_datas[2])
def test_faces_area_gradient_correctness(data):
V = np.array(data[0], dtype=float)
F = np.array(data[1], dtype=int)
faces_area_gradient_ground_truth_x = np.array(data[2])
faces_area_gradient_ground_truth_y = np.array(data[3])
[faces_area_gradient_student_x, faces_area_gradient_student_y] = compute_faces_area_gradient(V, F)
assert np.linalg.norm(faces_area_gradient_ground_truth_x - faces_area_gradient_student_x) < eps \
and np.linalg.norm(faces_area_gradient_ground_truth_y - faces_area_gradient_student_y) < eps
@pytest.mark.timeout(1)
@pytest.mark.parametrize("data", homework_datas[3])
def test_equilibrium_energy_gradient_correctness(data):
V = np.array(data[0], dtype=float)
F = np.array(data[1], dtype=int)
x_csl = data[2]
equilibrium_energy_gradient = np.array(data[3])
equilibrium_energy_student = compute_equilibrium_energy_gradient(V, F, x_csl)
assert np.linalg.norm(equilibrium_energy_gradient - equilibrium_energy_student) < eps
@pytest.mark.timeout(1)
@pytest.mark.parametrize("data", homework_datas[4])
def test_shape_energy_gradient_correctness(data):
V = np.array(data[0], dtype=float)
E = np.array(data[1], dtype=int)
l0 = np.array(data[2], dtype=float)
shape_energy_gradient_ground_truth = np.array(data[3])
shape_energy_gradient_student = compute_shape_energy_gradient(V, E, l0)
assert np.linalg.norm(shape_energy_gradient_ground_truth - shape_energy_gradient_student) < eps
n = 100000
F_big = np.arange(3 * n).reshape((n, 3))
V_big = np.random.random((3 * n, 3))
l0_big = np.zeros(3 * n)
E_big = igl.edges(F_big)
@pytest.mark.timeout(1)
def test_shape_energy_timing():
compute_shape_energy(V_big, E_big, l0_big)
@pytest.mark.timeout(1)
def test_faces_area_gradient_timing():
compute_faces_area_gradient(V_big, F_big)
@pytest.mark.timeout(1)
def test_equilibrium_energy_gradient_timing():
compute_equilibrium_energy_gradient(V_big, F_big, 0)
@pytest.mark.timeout(1)
def test_shape_energy_gradient_timing():
compute_shape_energy_gradient(V_big, E_big, l0_big)
@@ -0,0 +1 @@
[[[[[0, 0, 0], [1, 0, 0], [0, 1, 0]], [[0, 1], [0, 2], [1, 2]], [0.0, 0.0, 0.0], 2.0], [[[0, 0, 0], [1, 0, 0], [0, 1, 0], [1, 1, 0]], [[0, 1], [0, 2], [1, 2], [1, 3], [2, 3]], [0.0, 0.0, 0.0, 0.0, 0.0], 3.0]], [[[[0, 0, 0], [1, 0, 0], [0, 1, 0]], [[0, 1, 2]], 0, 0.05555555555555555], [[[0, 0, 0], [1, 0, 0], [0, 1, 0], [1, 1, 0]], [[0, 1, 2], [1, 3, 2]], 0, 0.125]], [[[[0, 0, 0], [1, 0, 0], [0, 1, 0]], [[0, 1, 2]], [[-0.5, 0.5, -0.0]], [[-0.5, -0.0, 0.5]]], [[[0, 0, 0], [1, 0, 0], [0, 1, 0], [1, 1, 0]], [[0, 1, 2], [1, 3, 2]], [[-0.5, 0.5, -0.0], [-0.0, 0.5, -0.5]], [[-0.5, -0.0, 0.5], [-0.5, 0.5, -0.0]]]], [[[[0, 0, 0], [1, 0, 0], [0, 1, 0]], [[0, 1, 2]], 0, [[0.1111111111111111, 0.0], [0.1111111111111111, 0.0], [0.1111111111111111, 0.0]]], [[[0, 0, 0], [1, 0, 0], [0, 1, 0], [1, 1, 0]], [[0, 1, 2], [1, 3, 2]], 0, [[0.125, 0.04166666666666667], [0.12499999999999999, -0.04166666666666666], [0.125, -0.04166666666666667], [0.12499999999999999, 0.04166666666666666]]]], [[[[0, 0, 0], [1, 0, 0], [0, 1, 0]], [[0, 1], [0, 2], [1, 2]], [0.0, 0.0, 0.0], [[-1.0, -1.0], [2.0, -1.0], [-1.0, 2.0]]], [[[0, 0, 0], [1, 0, 0], [0, 1, 0], [1, 1, 0]], [[0, 1], [0, 2], [1, 2], [1, 3], [2, 3]], [0.0, 0.0, 0.0, 0.0, 0.0], [[-1.0, -1.0], [2.0, -2.0], [-2.0, 2.0], [1.0, 1.0]]]]]