From 2915643008fdd783189e89497e97656dedbd51a7 Mon Sep 17 00:00:00 2001 From: Noa Aarts Date: Sun, 16 Nov 2025 10:56:47 +0100 Subject: [PATCH] make a presentation for kick-off --- planning/main.typ | 2 +- presentations/main.typ | 127 ++++++++++++ presentations/theme.typ | 426 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 554 insertions(+), 1 deletion(-) create mode 100644 presentations/main.typ create mode 100644 presentations/theme.typ diff --git a/planning/main.typ b/planning/main.typ index 5bf59c4..2752478 100644 --- a/planning/main.typ +++ b/planning/main.typ @@ -124,7 +124,7 @@ to join as well. = Project Planning #let kickoff-day = datetime(day: 10, month:11, year:2025) -#let week(offset) = [#(kickoff-day + duration(weeks: offset)).display("[month]/[day]") - #(kickoff-day + duration(weeks: offset, days: 6)).display("[month]/[day]")] +#let week(offset) = [#(kickoff-day + duration(weeks: offset)).display("[month]/[day]") - #(kickoff-day + duration(weeks: offset, days: 6)).display("[day]/[month]")] #table( columns: (auto, auto), diff --git a/presentations/main.typ b/presentations/main.typ new file mode 100644 index 0000000..bca004d --- /dev/null +++ b/presentations/main.typ @@ -0,0 +1,127 @@ +#import "@preview/touying:0.6.1": * +#import "@preview/physica:0.9.5": * +#import "@preview/cetz:0.3.4" +#import "@preview/typsium:0.2.0": ce +#import "@preview/numbly:0.1.0": numbly +#import "./theme.typ": * + +#set heading(numbering: numbly("{1}.", default: "1.1")) +#show ref: set text(size:0.5em, baseline: -0.75em) + +#let cetz-canvas = touying-reducer.with(reduce: cetz.canvas, cover: cetz.draw.hide.with(bounds: true)) + + +#show: university-theme.with( + config-info( + title: "Implementation Specific QAS", // Required + date: datetime.today().display(), + authors: ("Noa Aarts"), + + // Optional Styling (for more / explanation see in the typst universe) + // ignore how bad the images look i'll adjust it until Monday + title-color: blue.darken(10%), + ), + config-common( + // handout: true, // enable this for a version without animations + ), + aspect-ratio: "16-9", + config-colors( + primary: rgb("#00a6d6"), + secondary: rgb("#00b3dc"), + tertiary: rgb("#b8cbde"), + neutral-lightest: rgb("#ffffff"), + neutral-darkest: rgb("#000000"), + ), +) + + +// References displayed like [1], [2] and captions to images +// Introduction + + +#title-slide() + +#show outline.entry: it => link( + it.element.location(), + text(fill: rgb("#00b3dc"), size: 1.3em)[#it.indented(it.prefix(), it.body())], +) + + +#outline(depth: 1, title: text(fill: rgb("#00a6d6"))[Content]) + += + +== Context + +- VQE for NISQ +- Ansatz $->$ big effect +- QAS to optimize + - noise + - parameters + +== Research Question + +#align(center + horizon)[ + _ + How can hardware knowledge about noise, connectivity and native gates + be used to improve the performance of Quantum Architecture Search + for Variational Quantum Eigensolvers? + _ +] + +== Planning + +#let chev(start, len, f: none) = { + import cetz.draw: * + line(fill: f, + cetz.vector.add(start,(-1 , -1)) + , cetz.vector.add(start, (len - 1, -1)) + , cetz.vector.add(start,(len, 0)) + , cetz.vector.add(start, (len - 1, 1)) + , cetz.vector.add(start,(-1,1)) + , start + , cetz.vector.add(start,(-1,-1))) +} + +#let lg(color1, color2) = gradient.linear(color2, color1, color2, angle: 90deg) + +#slide[ + #cetz-canvas({ + import cetz.draw: * + + content((1, 0.1), anchor: "south", [today]) + + for x in (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24) { + content((x, 0), text(size: 12pt)[#(datetime(day: 10, month: 11, year: 2025) + duration(weeks: x)).display("[day]/[month]")], anchor: "north") + line(stroke: (paint: lime, dash: "dashed"), (x, -0.5), (x,-5)) + } + line((1, -0.5), (1, -5), stroke: (paint: rgb("#ff00cc"))) + + // yellow = literature + // green = planning + // blue = free + // red = make thing + line((5.5, -0.5), (5.5, -5), stroke: (paint: rgb("#ff00cc"))) + content((5.0, -5.1), anchor: "north", "Introduction") + + line((14.5, -0.5), (14.5, -5), stroke: (paint: rgb("#ff00cc"))) + content((14, -5.1), anchor: "north", "Midterm") + + chev((0.6,-2), 6.6, f: lg(yellow, yellow.darken(10%))) + chev((6.2,-2), 1.0, f: gradient.linear(green, rgb(0,0,0,0), angle: 60deg).sharp(3).repeat(6)) + content((1.1,-2), anchor: "west", "Literature") + chev((7, -2), 2, f: lg(blue.lighten(20%), blue.lighten(5%))) + content((7, -3.5), anchor: "north", "Holiday") + + chev((9, -2), 6, f: lg(red, red.darken(10%))) + content((10, -2), anchor: "west", "Make V1") + + chev((15.5, -2), 10.5, f: lg(red, red.darken(10%))) + content((15.5, -1.5), anchor: "west", "Improvements") + content((19.5, -2.5), anchor: "west", "Testing") + + chev((15.5 + 10.5, -2), 2, f: lg(purple, purple.darken(10%))) + content((25.5, -3.5), anchor: "north", "Writing") + }) + +] diff --git a/presentations/theme.typ b/presentations/theme.typ new file mode 100644 index 0000000..1879ce4 --- /dev/null +++ b/presentations/theme.typ @@ -0,0 +1,426 @@ +// University theme + +// Originally contributed by Pol Dellaiera - https://github.com/drupol + +#import "@preview/touying:0.6.1": * + +/// Default slide function for the presentation. +/// +/// - config (dictionary): is the configuration of the slide. Use `config-xxx` to set individual configurations for the slide. To apply multiple configurations, use `utils.merge-dicts` to combine them. +/// +/// - repeat (int, auto): is the number of subslides. The default is `auto`, allowing touying to automatically calculate the number of subslides. The `repeat` argument is required when using `#slide(repeat: 3, self => [ .. ])` style code to create a slide, as touying cannot automatically detect callback-style `uncover` and `only`. +/// +/// - setting (dictionary): is the setting of the slide, which can be used to apply set/show rules for the slide. +/// +/// - composer (array, function): is the layout composer of the slide, allowing you to define the slide layout. +/// +/// For example, `#slide(composer: (1fr, 2fr, 1fr))[A][B][C]` to split the slide into three parts. The first and the last parts will take 1/4 of the slide, and the second part will take 1/2 of the slide. +/// +/// If you pass a non-function value like `(1fr, 2fr, 1fr)`, it will be assumed to be the first argument of the `components.side-by-side` function. +/// +/// The `components.side-by-side` function is a simple wrapper of the `grid` function. It means you can use the `grid.cell(colspan: 2, ..)` to make the cell take 2 columns. +/// +/// For example, `#slide(composer: 2)[A][B][#grid.cell(colspan: 2)[Footer]]` will make the `Footer` cell take 2 columns. +/// +/// If you want to customize the composer, you can pass a function to the `composer` argument. The function should receive the contents of the slide and return the content of the slide, like `#slide(composer: grid.with(columns: 2))[A][B]`. +/// +/// - bodies (arguments): is the contents of the slide. You can call the `slide` function with syntax like `#slide[A][B][C]` to create a slide. +#let slide( + config: (:), + repeat: auto, + setting: body => body, + composer: auto, + align: auto, + ..bodies, +) = touying-slide-wrapper(self => { + if align != auto { + self.store.align = align + } + let header(self) = { + set std.align(top) + grid( + rows: (auto, auto), + row-gutter: 3mm, + if self.store.progress-bar { + components.progress-bar( + height: 2pt, + self.colors.primary, + self.colors.tertiary, + ) + }, + block( + inset: (x: .5em), + components.left-and-right( + text( + fill: self.colors.primary, + weight: "bold", + size: 1.2em, + utils.call-or-display(self, self.store.header), + ), + text(fill: self.colors.primary.lighten(65%), utils.call-or-display( + self, + self.store.header-right, + )), + ), + ), + ) + } + let footer(self) = { + set std.align(center + bottom) + set text(size: .4em) + { + let cell(..args, it) = components.cell( + ..args, + inset: 1mm, + std.align(horizon, text(fill: white, it)), + ) + show: block.with(width: 100%, height: auto) + grid( + columns: self.store.footer-columns, + rows: 1.5em, + cell(fill: self.colors.primary, utils.call-or-display( + self, + self.store.footer-a, + )), + cell(fill: self.colors.secondary, utils.call-or-display( + self, + self.store.footer-b, + )), + cell(fill: self.colors.tertiary, utils.call-or-display( + self, + self.store.footer-c, + )), + ) + } + } + let self = utils.merge-dicts( + self, + config-page( + header: header, + footer: footer, + ), + ) + let new-setting = body => { + show: std.align.with(self.store.align) + show: setting + body + } + touying-slide( + self: self, + config: config, + repeat: repeat, + setting: new-setting, + composer: composer, + ..bodies, + ) +}) + + +/// Title slide for the presentation. You should update the information in the `config-info` function. You can also pass the information directly to the `title-slide` function. +/// +/// Example: +/// +/// ```typst +/// #show: university-theme.with( +/// config-info( +/// title: [Title], +/// logo: emoji.school, +/// ), +/// ) +/// +/// #title-slide(subtitle: [Subtitle]) +/// ``` +/// +/// - config (dictionary): is the configuration of the slide. Use `config-xxx` to set individual configurations for the slide. To apply multiple configurations, use `utils.merge-dicts` to combine them. +/// +/// - extra (string, none): is the extra information for the slide. This can be passed to the `title-slide` function to display additional information on the title slide. +#let title-slide( + config: (:), + extra: none, + ..args, +) = touying-slide-wrapper(self => { + self = utils.merge-dicts( + self, + config, + config-common(freeze-slide-counter: true), + ) + let info = self.info + args.named() + info.authors = { + let authors = if "authors" in info { + info.authors + } else { + info.author + } + if type(authors) == array { + authors + } else { + (authors,) + } + } + let body = { + if info.logo != none { + place(right, text(fill: self.colors.primary, info.logo)) + } + std.align( + center + horizon, + { + block( + inset: 0em, + breakable: false, + { + text(size: 2em, fill: self.colors.primary, strong(info.title)) + if info.subtitle != none { + parbreak() + text(size: 1.2em, fill: self.colors.primary, info.subtitle) + } + }, + ) + set text(size: .8em) + grid( + columns: (1fr,) * calc.min(info.authors.len(), 3), + column-gutter: 1em, + row-gutter: 1em, + ..info.authors.map(author => text( + fill: self.colors.neutral-darkest, + author, + )) + ) + v(1em) + if info.institution != none { + parbreak() + text(size: .9em, info.institution) + } + if info.date != none { + parbreak() + text(size: .8em, utils.display-info-date(self)) + } + }, + ) + } + touying-slide(self: self, body) +}) + + +/// New section slide for the presentation. You can update it by updating the `new-section-slide-fn` argument for `config-common` function. +/// +/// Example: `config-common(new-section-slide-fn: new-section-slide.with(numbered: false))` +/// +/// - config (dictionary): is the configuration of the slide. Use `config-xxx` to set individual configurations for the slide. To apply multiple configurations, use `utils.merge-dicts` to combine them. +/// +/// - level (int, none): is the level of the heading. +/// +/// - numbered (boolean): is whether the heading is numbered. +/// +/// - body (auto): is the body of the section. This will be passed automatically by Touying. +#let new-section-slide( + config: (:), + level: 1, + numbered: true, + body, +) = touying-slide-wrapper(self => { + let slide-body = { + set std.align(horizon) + show: pad.with(20%) + set text(size: 1.5em, fill: self.colors.primary, weight: "bold") + stack( + dir: ttb, + spacing: .65em, + utils.display-current-heading(level: level, numbered: numbered), + block( + height: 2pt, + width: 100%, + spacing: 0pt, + components.progress-bar( + height: 2pt, + self.colors.primary, + self.colors.primary-light, + ), + ), + ) + body + } + touying-slide(self: self, config: config, slide-body) +}) + + +/// Focus on some content. +/// +/// Example: `#focus-slide[Wake up!]` +/// +/// - config (dictionary): is the configuration of the slide. Use `config-xxx` to set individual configurations for the slide. To apply multiple configurations, use `utils.merge-dicts` to combine them. +/// +/// - background-color (color, none): is the background color of the slide. Default is the primary color. +/// +/// - background-img (string, none): is the background image of the slide. Default is none. +#let focus-slide( + config: (:), + background-color: none, + background-img: none, + body, +) = touying-slide-wrapper(self => { + let background-color = if ( + background-img == none and background-color == none + ) { + rgb(self.colors.primary) + } else { + background-color + } + let args = (:) + if background-color != none { + args.fill = background-color + } + if background-img != none { + args.background = { + set image(fit: "stretch", width: 100%, height: 100%) + background-img + } + } + self = utils.merge-dicts( + self, + config-common(freeze-slide-counter: true), + config-page(margin: 1em, ..args), + ) + set text(fill: self.colors.neutral-lightest, weight: "bold", size: 2em) + touying-slide(self: self, std.align(horizon, body)) +}) + + +// Create a slide where the provided content blocks are displayed in a grid and coloured in a checkerboard pattern without further decoration. You can configure the grid using the rows and `columns` keyword arguments (both default to none). It is determined in the following way: +/// +/// - If `columns` is an integer, create that many columns of width `1fr`. +/// - If `columns` is `none`, create as many columns of width `1fr` as there are content blocks. +/// - Otherwise assume that `columns` is an array of widths already, use that. +/// - If `rows` is an integer, create that many rows of height `1fr`. +/// - If `rows` is `none`, create that many rows of height `1fr` as are needed given the number of co/ -ntent blocks and columns. +/// - Otherwise assume that `rows` is an array of heights already, use that. +/// - Check that there are enough rows and columns to fit in all the content blocks. +/// +/// That means that `#matrix-slide[...][...]` stacks horizontally and `#matrix-slide(columns: 1)[...][...]` stacks vertically. +/// +/// - config (dictionary): is the configuration of the slide. Use `config-xxx` to set individual configurations for the slide. To apply multiple configurations, use `utils.merge-dicts` to combine them. +#let matrix-slide( + config: (:), + columns: none, + rows: none, + ..bodies, +) = touying-slide-wrapper(self => { + self = utils.merge-dicts( + self, + config-common(freeze-slide-counter: true), + config-page(margin: 0em), + ) + touying-slide( + self: self, + config: config, + composer: components.checkerboard.with(columns: columns, rows: rows), + ..bodies, + ) +}) + + +/// Touying university theme. +/// +/// Example: +/// +/// ```typst +/// #show: university-theme.with(aspect-ratio: "16-9", config-colors(primary: blue))` +/// ``` +/// +/// The default colors: +/// +/// ```typ +/// config-colors( +/// primary: rgb("#04364A"), +/// secondary: rgb("#176B87"), +/// tertiary: rgb("#448C95"), +/// neutral-lightest: rgb("#ffffff"), +/// neutral-darkest: rgb("#000000"), +/// ) +/// ``` +/// +/// - aspect-ratio (string): is the aspect ratio of the slides. Default is `16-9`. +/// +/// - align (alignment): is the alignment of the slides. Default is `top`. +/// +/// - progress-bar (boolean): is whether to show the progress bar. Default is `true`. +/// +/// - header (content, function): is the header of the slides. Default is `utils.display-current-heading(level: 2)`. +/// +/// - header-right (content, function): is the right part of the header. Default is `self.info.logo`. +/// +/// - footer-columns (tuple): is the columns of the footer. Default is `(25%, 1fr, 25%)`. +/// +/// - footer-a (content, function): is the left part of the footer. Default is `self.info.author`. +/// +/// - footer-b (content, function): is the middle part of the footer. Default is `self.info.short-title` or `self.info.title`. +/// +/// - footer-c (content, function): is the right part of the footer. Default is `self => h(1fr) + utils.display-info-date(self) + h(1fr) + context utils.slide-counter.display() + " / " + utils.last-slide-number + h(1fr)`. +#let university-theme( + aspect-ratio: "16-9", + align: top, + progress-bar: true, + header: utils.display-current-heading(level: 2, style: auto), + header-right: self => ( + box(utils.display-current-heading(level: 1)) + h(.3em) + self.info.logo + ), + footer-columns: (25%, 1fr, 25%), + footer-a: self => self.info.author, + footer-b: self => if self.info.short-title == auto { + self.info.title + } else { + self.info.short-title + }, + footer-c: self => { + h(1fr) + utils.display-info-date(self) + h(1fr) + context utils.slide-counter.display() + " / " + utils.last-slide-number + h(1fr) + }, + ..args, + body, +) = { + show: touying-slides.with( + config-page( + paper: "presentation-" + aspect-ratio, + header-ascent: 0em, + footer-descent: 0em, + margin: (top: 2em, bottom: 1.25em, x: 2em), + ), + config-common( + slide-fn: slide, + new-section-slide-fn: new-section-slide, + ), + config-methods( + init: (self: none, body) => { + set text(size: 25pt) + show heading.where(level: 3): set text(fill: self.colors.primary) + show heading.where(level: 4): set text(fill: self.colors.primary) + + body + }, + alert: utils.alert-with-primary-color, + ), + config-colors( + primary: rgb("#04364A"), + secondary: rgb("#176B87"), + tertiary: rgb("#448C95"), + neutral-lightest: rgb("#ffffff"), + neutral-darkest: rgb("#000000"), + ), + // save the variables for later use + config-store( + align: align, + progress-bar: progress-bar, + header: header, + header-right: header-right, + footer-columns: footer-columns, + footer-a: footer-a, + footer-b: footer-b, + footer-c: footer-c, + ), + ..args, + ) + + body +}