Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • lamp/cs206
  • bwermeil/cs206-2020
  • zabifade/cs206-2020
  • cauderan/cs206-2020
  • malonga/cs206-2020
  • dumoncel/cs206
  • bounekhe/cs206
  • bergerault/cs206
  • flealsan/cs206
  • hsu/cs206
  • mouchel/cs206
  • vebraun/cs206
  • vcanard/cs206
  • ybelghmi/cs206
  • belghmi/cs206
  • bousbina/cs206
  • waked/cs206
  • gtagemou/cs206
  • arahmoun/cs206
  • elhachem/cs206
  • benrahha/cs206
  • benslima/cs206
22 results
Show changes
Showing
with 0 additions and 2335 deletions
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="210mm"
height="297mm"
viewBox="0 0 744.09448819 1052.3622047"
id="svg2"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="angle-example-2.svg"
inkscape:export-filename="C:\cygwin\home\axel22\workspaces\scala\progfun\instructions\angle2.png"
inkscape:export-xdpi="32.263699"
inkscape:export-ydpi="32.263699">
<defs
id="defs4">
<marker
inkscape:stockid="Arrow1Lstart"
orient="auto"
refY="0.0"
refX="0.0"
id="Arrow1Lstart"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path4146"
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
transform="scale(0.8) translate(12.5,0)" />
</marker>
<marker
inkscape:stockid="Arrow1Lend"
orient="auto"
refY="0.0"
refX="0.0"
id="Arrow1Lend"
style="overflow:visible;"
inkscape:isstock="true">
<path
id="path4149"
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
transform="scale(0.8) rotate(180) translate(12.5,0)" />
</marker>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.9899495"
inkscape:cx="488.53326"
inkscape:cy="701.51987"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1600"
inkscape:window-height="877"
inkscape:window-x="-4"
inkscape:window-y="-4"
inkscape:window-maximized="1"
inkscape:snap-text-baseline="false" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#Arrow1Lstart)"
d="m 142.85714,101.50506 0,298.57143"
id="path3336"
inkscape:connector-curvature="0" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3.8496573;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Lend)"
d="m 142.85714,399.21935 668.06991,0"
id="path3340"
inkscape:connector-curvature="0" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:3,3;stroke-dashoffset:0"
d="m 143.44166,399.80366 c 88.89343,-20.20305 105.05587,-39.39595 105.05587,-39.39595"
id="path4640"
inkscape:connector-curvature="0" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:3,3;stroke-opacity:1;stroke-dashoffset:0"
d="m 248.24499,360.5773 c 0,0 34.72027,-23.20876 57.95379,-32.30013 39.28467,-15.37226 57.45614,8.89703 57.45614,8.89703 19.69797,32.32488 43.43656,27.27412 55.55839,8.08122 l 12.12183,-19.1929 0,0 c 40.4061,-86.87311 77.78174,-113.13708 77.78174,-113.13708 0,0 18.22571,-16.58543 45.38508,0.61276 28.26715,17.89967 41.48804,62.0167 41.48804,62.0167"
id="path4642"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cscscccsc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:3,3;stroke-opacity:1;stroke-dashoffset:0"
d="m 595.70683,274.55743 c 0,0 12.08157,73.3608 31.09283,77.76906 28.85051,6.68975 48.99239,-25.75889 48.99239,-25.75889 0,0 17.42513,-17.42513 27.27412,-14.89975 9.84899,2.52538 30.50526,33.55149 30.50526,33.55149"
id="path4752"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cscsc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
d="M 142.85714,398.79078 500,221.64792"
id="path4832"
inkscape:connector-curvature="0" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:6,3;stroke-dashoffset:0"
d="m 501.03566,222.01682 0,176.77669"
id="path5388"
inkscape:connector-curvature="0" />
<path
inkscape:connector-curvature="0"
id="path5390"
d="m 142.43151,219.99652 358.60415,-1e-5"
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:6, 3;stroke-dashoffset:0;stroke-opacity:1"
sodipodi:nodetypes="cc" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="310.11682"
y="200.8036"
id="text5392"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan5394"
x="310.11682"
y="200.8036">i</tspan></text>
<text
sodipodi:linespacing="125%"
id="text5396"
y="293.73761"
x="504.0661"
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
y="293.73761"
x="504.0661"
id="tspan5398"
sodipodi:role="line">xs(i)</tspan></text>
<path
inkscape:connector-curvature="0"
id="path3357"
d="m 632.35549,355.35695 0,41.41625"
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:6,3;stroke-dashoffset:0;stroke-opacity:1" />
<path
sodipodi:nodetypes="cc"
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3.48477578;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:6.96955149, 3.48477574;stroke-dashoffset:0;stroke-opacity:1"
d="m 148.49243,353.35696 483.86306,-1e-5"
id="path3359"
inkscape:connector-curvature="0" />
<text
sodipodi:linespacing="125%"
id="text3361"
y="347.29602"
x="458.60925"
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
y="347.29602"
x="458.60925"
id="tspan3363"
sodipodi:role="line">i'</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="637.40619"
y="385.66147"
id="text3365"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3367"
x="637.40619"
y="385.66147">xs(i')</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="486.89352"
y="201.81377"
id="text4181"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4183"
x="486.89352"
y="201.81377">A</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="625.28442"
y="344.24527"
id="text4185"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4187"
x="625.28442"
y="344.24527">B</tspan></text>
</g>
</svg>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="210mm"
height="297mm"
viewBox="0 0 744.09448819 1052.3622047"
id="svg2"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="angle-example.svg"
inkscape:export-filename="C:\cygwin\home\axel22\workspaces\scala\progfun\instructions\angle.png"
inkscape:export-xdpi="32.263699"
inkscape:export-ydpi="32.263699">
<defs
id="defs4">
<marker
inkscape:stockid="Arrow1Lstart"
orient="auto"
refY="0.0"
refX="0.0"
id="Arrow1Lstart"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path4146"
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
transform="scale(0.8) translate(12.5,0)" />
</marker>
<marker
inkscape:stockid="Arrow1Lend"
orient="auto"
refY="0.0"
refX="0.0"
id="Arrow1Lend"
style="overflow:visible;"
inkscape:isstock="true">
<path
id="path4149"
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
transform="scale(0.8) rotate(180) translate(12.5,0)" />
</marker>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.9899495"
inkscape:cx="488.53326"
inkscape:cy="701.51987"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1600"
inkscape:window-height="877"
inkscape:window-x="-4"
inkscape:window-y="-4"
inkscape:window-maximized="1"
inkscape:snap-text-baseline="false" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#Arrow1Lstart)"
d="m 142.85714,101.50506 0,298.57143"
id="path3336"
inkscape:connector-curvature="0" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3.8496573;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Lend)"
d="m 142.85714,399.21935 668.06991,0"
id="path3340"
inkscape:connector-curvature="0" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:3,3;stroke-dashoffset:0"
d="m 143.44166,399.80366 c 88.89343,-20.20305 105.05587,-39.39595 105.05587,-39.39595"
id="path4640"
inkscape:connector-curvature="0" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:3,3;stroke-opacity:1;stroke-dashoffset:0"
d="m 248.24499,360.5773 c 0,0 34.72027,-23.20876 57.95379,-32.30013 39.28467,-15.37226 57.45614,8.89703 57.45614,8.89703 19.69797,32.32488 43.43656,27.27412 55.55839,8.08122 l 12.12183,-19.1929 0,0 c 40.4061,-86.87311 77.78174,-113.13708 77.78174,-113.13708 0,0 18.22571,-16.58543 45.38508,0.61276 28.26715,17.89967 41.48804,62.0167 41.48804,62.0167"
id="path4642"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cscscccsc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:3,3;stroke-opacity:1;stroke-dashoffset:0"
d="m 595.70683,274.55743 c 0,0 12.08157,73.3608 31.09283,77.76906 28.85051,6.68975 48.99239,-25.75889 48.99239,-25.75889 0,0 17.42513,-17.42513 27.27412,-14.89975 9.84899,2.52538 30.50526,33.55149 30.50526,33.55149"
id="path4752"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cscsc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
d="M 142.85714,398.79078 500,221.64792"
id="path4832"
inkscape:connector-curvature="0" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:6,3;stroke-dashoffset:0"
d="m 501.03566,222.01682 0,176.77669"
id="path5388"
inkscape:connector-curvature="0" />
<path
inkscape:connector-curvature="0"
id="path5390"
d="m 142.43151,219.99652 358.60415,-1e-5"
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:6, 3;stroke-dashoffset:0;stroke-opacity:1"
sodipodi:nodetypes="cc" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="310.11682"
y="200.8036"
id="text5392"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan5394"
x="310.11682"
y="200.8036">i</tspan></text>
<text
sodipodi:linespacing="125%"
id="text5396"
y="326.0625"
x="506.0864"
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
y="326.0625"
x="506.0864"
id="tspan5398"
sodipodi:role="line">xs(i)</tspan></text>
</g>
</svg>
labs/lab2-reductions-and-prefix-sums/angle.png

4.04 KiB

labs/lab2-reductions-and-prefix-sums/angle2.png

5.98 KiB

labs/lab2-reductions-and-prefix-sums/terrain.png

2.8 KiB

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="210mm"
height="297mm"
viewBox="0 0 744.09448819 1052.3622047"
id="svg2"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="terain.svg">
<defs
id="defs4">
<marker
inkscape:stockid="Arrow1Lstart"
orient="auto"
refY="0.0"
refX="0.0"
id="Arrow1Lstart"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path4146"
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
transform="scale(0.8) translate(12.5,0)" />
</marker>
<marker
inkscape:stockid="Arrow1Lend"
orient="auto"
refY="0.0"
refX="0.0"
id="Arrow1Lend"
style="overflow:visible;"
inkscape:isstock="true">
<path
id="path4149"
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
transform="scale(0.8) rotate(180) translate(12.5,0)" />
</marker>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.49497475"
inkscape:cx="363.63782"
inkscape:cy="644.8613"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1600"
inkscape:window-height="877"
inkscape:window-x="-4"
inkscape:window-y="-4"
inkscape:window-maximized="1" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#Arrow1Lstart)"
d="m 142.85714,101.50506 0,298.57143"
id="path3336"
inkscape:connector-curvature="0" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3.8496573;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Lend)"
d="m 142.85714,399.21935 668.06991,0"
id="path3340"
inkscape:connector-curvature="0" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
d="m 143.44166,399.80366 c 88.89343,-20.20305 105.05587,-39.39595 105.05587,-39.39595"
id="path4640"
inkscape:connector-curvature="0" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 248.24499,360.5773 c 0,0 34.72027,-23.20876 57.95379,-32.30013 39.28467,-15.37226 57.45614,8.89703 57.45614,8.89703 19.69797,32.32488 43.43656,27.27412 55.55839,8.08122 l 12.12183,-19.1929 0,0 c 40.4061,-86.87311 77.78174,-113.13708 77.78174,-113.13708 0,0 18.22571,-16.58543 45.38508,0.61276 28.26715,17.89967 41.48804,62.0167 41.48804,62.0167"
id="path4642"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cscscccsc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 595.70683,274.55743 c 0,0 12.08157,73.3608 31.09283,77.76906 28.85051,6.68975 48.99239,-25.75889 48.99239,-25.75889 0,0 17.42513,-17.42513 27.27412,-14.89975 9.84899,2.52538 30.50526,33.55149 30.50526,33.55149"
id="path4752"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cscsc" />
</g>
</svg>
labs/lab2-reductions-and-prefix-sums/visibility.png

3.45 KiB

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="210mm"
height="297mm"
viewBox="0 0 744.09448819 1052.3622047"
id="svg2"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="visibility.svg">
<defs
id="defs4">
<marker
inkscape:stockid="Arrow1Lstart"
orient="auto"
refY="0.0"
refX="0.0"
id="Arrow1Lstart"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path4146"
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
transform="scale(0.8) translate(12.5,0)" />
</marker>
<marker
inkscape:stockid="Arrow1Lend"
orient="auto"
refY="0.0"
refX="0.0"
id="Arrow1Lend"
style="overflow:visible;"
inkscape:isstock="true">
<path
id="path4149"
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
transform="scale(0.8) rotate(180) translate(12.5,0)" />
</marker>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.98994949"
inkscape:cx="450.29691"
inkscape:cy="792.75432"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1600"
inkscape:window-height="877"
inkscape:window-x="-4"
inkscape:window-y="-4"
inkscape:window-maximized="1" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#Arrow1Lstart)"
d="m 142.85714,101.50506 0,298.57143"
id="path3336"
inkscape:connector-curvature="0" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3.8496573;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Lend)"
d="m 142.85714,399.21935 668.06991,0"
id="path3340"
inkscape:connector-curvature="0" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 143.44166,399.80366 C 229.1208,389.60061 247.60467,362.19342 247.60467,362.19342"
id="path4640"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 247.12126,362.59389 c 0,0 35.844,-25.22535 59.07752,-34.31672 50.7702,-20.12943 91.36602,-35.89748 158.70779,-62.92894 2.54896,-14.01596 48.13888,-55.27993 48.13888,-55.27993"
id="path4642"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:3, 3;stroke-dashoffset:0;stroke-opacity:1"
d="m 594.1916,275.56758 c 0,0 12.08157,73.3608 31.09283,77.76906 28.85051,6.68975 48.99239,-25.75889 48.99239,-25.75889 0,0 17.42513,-17.42513 27.27412,-14.89975 9.84899,2.52538 30.50526,33.55149 30.50526,33.55149"
id="path4752"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cscsc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 312.07723,326.23693 465.71429,265.21935"
id="path4754"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 511.25,211.11221 742.85714,79.505061"
id="path4756"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
sodipodi:nodetypes="cscscccsc"
inkscape:connector-curvature="0"
id="path4758"
d="m 245.5023,364.2185 c 0,0 35.844,-25.22535 59.07752,-34.31672 39.28467,-15.37226 57.45614,8.89703 57.45614,8.89703 19.69797,32.32488 43.43656,27.27412 55.55839,8.08122 l 12.12183,-19.1929 0,0 c 40.4061,-86.87311 77.78174,-113.13708 77.78174,-113.13708 0,0 18.22571,-16.58543 45.38508,0.61276 28.26715,17.89967 41.48804,62.0167 41.48804,62.0167"
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:3, 3;stroke-dashoffset:0;stroke-opacity:1" />
</g>
</svg>
# K-Means
Use the following commands to make a fresh clone of your repository:
```
git clone -b kmeans git@gitlab.epfl.ch:lamp/student-repositories-s21/cs206-GASPAR.git cs206-kmeans
```
## Useful links
* [A guide to the Scala parallel collections](https://docs.scala-lang.org/overviews/parallel-collections/overview.html)
* [The API documentation of the Scala parallel collections](https://www.javadoc.io/doc/org.scala-lang.modules/scala-parallel-collections_2.13/latest/scala/collection/index.html)
* [The API documentation of the Scala standard library](https://www.scala-lang.org/files/archive/api/2.13.4)
* [The API documentation of the Java standard library](https://docs.oracle.com/en/java/javase/15/docs/api/index.html)
**If you have issues with the IDE, try [reimporting the
build](https://gitlab.epfl.ch/lamp/cs206/-/blob/master/labs/example-lab.md#ide-features-like-type-on-hover-or-go-to-definition-do-not-work),
if you still have problems, use `compile` in sbt instead.**
## Introduction
In this assignment, you will implement the K-means algorithm for cluster
detection, which is used to partition *n* vectors into *k* clusters.
Here, vectors are separated into clusters based on their mutual similarity --
vectors that are closer to each other in space are more likely to end up in the
same cluster, and the distant vectors are likely to be in different clusters.
K-means has many applications: it is used in data mining, image filtering and
signal processing.
Here is a simple example -- let's say that we have a set of vectors in 2D space,
as shown in the following figure:
![points](points.png)
As a human, you can visually distinguish the three clusters of points in the
image:
![clusters](clusters.png)
When the number of clusters, dimensions and vectors grows, it becomes difficult
and even impossible to manually determine the clusters.
K-means is a simple algorithm that takes a set of vectors (called *points*) and
outputs as set of clusters as follows:
1. Pick `k` points called *means*. This is called *initialization*.
2. Associate each input point with the *mean* that is closest to it.
We obtain `k` *clusters* of points, and we refer to this process as
*classifying* the points.
3. Update each mean to have the average value of the corresponding cluster.
4. If the `k` means have significantly changed, go back to step 2.
If they did not, we say that the algorithm *converged*.
5. The `k` means represent different clusters -- every point is in the cluster
corresponding to the closest mean.
Above, two steps need additional discussion.
First, how do we pick the initial `k` means?
The initialization step can be done in many different ways -- we will just
randomly pick some of the input vectors.
Second, how do we know that the algorithm converged?
We will check that, for each mean, the square distance between the old value of
the mean and the new value of the mean is less than or equal to some value
`eta`.
For a better illustration, here are a few steps of the K-means algorithm.
Initially, we pick a random set of means, shown with "X" in the figure:
![step0](step0.png)
Then, we classify the points according to the closest mean ("X").
The means divide the space into regions, where each point is closer to the
corresponding mean than any other mean -- in the figure, the dotted line depicts
the borders of different regions:
![step1](step1.png)
All the points in the same region form one cluster. After having classified the
points, we can update the mean values to the average of all the points in the
cluster:
![step2](step2.png)
Each of the means was significantly updated.
This is a good indication that the algorithm did not yet converge,
so we repeat the steps again -- we first classify all the points:
![step3](step3.png)
And then we update the means again:
![step4](step4.png)
One of the means did not change at all in the last step.
Still, other means have changed so we continue this process until the change
in the position of each point drops below the `eta` value.
At each iteration of K-means, we can associate multiple points to clusters,
and compute the average of the `k` clusters, in parallel.
Note that the association of a point to its cluster is independent of the
other points in the input, and similarly, the computation of the average of a cluster
is independent of the other clusters.
Once all parallel tasks of the current iteration complete,
the algorithm can proceed to the next iteration.
K-means is an example of a *bulk synchronous parallel* algorithm (BSP).
BSP algorithms are composed from a sequence of supersteps, each of which
contains:
- *parallel computation*, in which processes independently perform local
computations and produce some values
- *communication*, in which processes exchange data
- *barrier synchronisation*, during which processes wait until every process
finishes
Data-parallel programming models are typically a good fit for BSP algorithms,
as each bulk synchronous phase can correspond to some number of data-parallel
operations.
## Classifying the points
In the first part of this assignment, you will classify the input points
according to the square distance to the means.
Input points are described with the following `Point` data-type:
class Point(val x: Double, val y: Double, val z: Double)
You will start by implementing the `classify` method:
def classify(points: ParSeq[Point], means: ParSeq[Point]): ParMap[Point, ParSeq[Point]]
This method take a sequence of points and a sequence of means, and return
a map collection, which maps each mean to the sequence of points in the corresponding
cluster.
Hint: Use `groupBy` and the `findClosest` method, which is already defined for
you. After that, make sure that all the means are in the resulting map, even if their
sequences are empty.
## Updating the means
In the second part of this assignment, you will update the means corresponding
to different clusters.
Implement the method `update`, which takes the map of classified points produced
in the previous step, and the sequence of previous means.
The method returns the new sequence of means:
def update(classified: ParMap[Point, ParSeq[Point]], oldMeans: ParSeq[Point]): ParSeq[Point]
Take care to preserve order in the resulting sequence -- the mean `i` in
the resulting sequence must correspond to the mean `i` from `oldMeans`.
Hint: Make sure you use the `findAverage` method that is predefined for you.
## Detecting convergence
Finally, you will implement convergence detection.
The convergence detection method takes a sequence of old
means and the sequence of updated means, and returns a boolean indicating if the
algorithm converged or not.
Given an `eta` parameter, `oldMeans` and `newMeans`, it returns `true` if the
algorithm converged, and `false` otherwise:
def converged(eta: Double, oldMeans: ParSeq[Point], newMeans: ParSeq[Point])
The algorithm converged iff the square distance between the old and the new mean is less
than or equal to `eta`, for all means.
Note: the means in the two lists are ordered -- the mean at `i` in `oldMeans`
is the previous value of the mean at `i` in `newMeans`.
Implement `converged`!
## Running the algorithm
We now have everything we need to run the K-means algorithm.
We only need to combine the previously defined methods in the right way.
The tail-recursive `kMeans` method takes a sequence of
points `points`, previously computed sequence of means `means`, and the `eta`
value:
@tailrec final def kMeans(points: ParSeq[Point],
means: ParSeq[Point], eta: Double): ParSeq[Point]
The `kMeans` method should return the sequence of means,
each corresponding to a specific cluster.
Hint: `kMeans` implements the steps 2-4 from the K-means pseudocode.
You can use the following command from within `sbt` to benchmark your code, the
parallel time shoul be significantly faster than the sequential time if your
computer has more than one core:
> runMain kmeans.KMeansRunner
## Use cases
And now for the fun part -- the K-means algorithm has a lot of use-cases!
In image processing applications, it can be used to reduce the size of the
color palette, thus compressing the image. This is done by turning a
[true color image](http://en.wikipedia.org/wiki/Color_depth), where each pixel
is encoded into 32 bits, into [indexed color](http://en.wikipedia.org/wiki/Indexed_color),
where each pixel can be encoded with just a few bits. This is done by using k-means to
"cluster" the important colors in the image, thus reducing its palette from
24-bit (`2^24` colors) to just 32 indexed colors, chosen from the 24-bit palette.
Here, pixels from the image are the input vectors,
and their coordinates are the different color channels.
This is the original true color (24-bit) image:
![start](start.png)
And this is the indexed color (32 colors) version of it:
![uniform-random-30steps](uniform-random-30steps.png)
So, thanks to your k-means implementation, ScalaShop can now compress images!
You can start ScalaShop by invoking from `sbt`:
> runMain kmeans.fun.ScalaShop
The k-means algorithm is very sensitive to the initial choice of means. There
are three choice strategies implemented in ScalaShop:
* `Uniform Choice` is the simplest strategy. It chooses `n` colors uniformly in
the entire color space, regardless of the colors used in the image. If the image
has a dominant color, the means created by this strategy will likely be very far
away from the clusters formed by this dominant color. You can try setting the
`Uniform Choice` strategy with 1, 10 and 30 steps. You will notice the initial
choice is quite bad, but the quality improves as the k-means algorithm is applied
in more steps.
* `Random Sampling` is another simple strategy, but with better results. For the
initial means, it randomly samples `n` colors from the image. This yields good
results if the image has few dominant colors, but it cannot handle subtle nuances
in the image. Again, if you try this strategy with 1, 10 and 30 k-means iteration
steps, you will notice improvements as the k-means algorithm is ran more.
* `Uniform Random` is the most complex strategy to pick means, but it also produces
the best results. It works by uniformly splitting the color space in sub-spaces.
It then counts the number of pixels that have colors belonging to that sub-space.
Based on this number, it chooses a proportional number of means in the sub-space,
by randomly sampling from the pixels in that sub-space. Therefore, if your image
has dominant colors, this strategy will drop a proportional number of means for
each dominant color, thus allowing the k-means algorithm to capture fine nuances.
In the EPFL image now available in ScalaShop, the mountains are a good way to see
how well each initial choice of means fares. You also have different strategies
for deciding convergence:
* `Steps` allows to run a fixed number of steps. After this, the k-means algorithm
is stopped.
* `Eta` corresponds to the means stability, as we showed earlier: if the
means did not move much since the last iteration, the result is considered stable.
* `Sound-to-noise` ratio is a more refined convergence strategy, which does not settle
for stability but tries to minimize the difference between the true color image
and the index color one. This strategy goes beyond `Eta`, but high Sound-to-noise
ratios will prevent the k-means algorithm from finishing!
With this in mind, enjoy ScalaShop, the ultimate image manipulation tool and
the nice, warm, sunny photo of EPFL!
labs/lab3-k-means/clusters.png

12.1 KiB

This diff is collapsed.
labs/lab3-k-means/points.png

5.65 KiB

This diff is collapsed.
labs/lab3-k-means/start.png

695 KiB

labs/lab3-k-means/step0.png

5.78 KiB

This diff is collapsed.
labs/lab3-k-means/step1.png

7.97 KiB

This diff is collapsed.
labs/lab3-k-means/step2.png

10.1 KiB

This diff is collapsed.