diff options
| author | Prefetch | 2021-02-24 09:47:22 +0100 |
|---|---|---|
| committer | Prefetch | 2021-02-24 09:47:22 +0100 |
| commit | b5608ab92a4f8a5140571acabf54e3c6bdebd0e4 (patch) | |
| tree | 673b19fadbbaff9c1f765037896a1ba7d008a2b8 /content | |
Initial commit
Diffstat (limited to 'content')
27 files changed, 3535 insertions, 0 deletions
diff --git a/content/_index.md b/content/_index.md new file mode 100644 index 0000000..e9e5dcc --- /dev/null +++ b/content/_index.md @@ -0,0 +1,17 @@ +--- +title: "Home" +date: 2021-02-22T17:15:50+01:00 +draft: false +--- + +Welcome to my website. + +Once in a blue moon, I'll post something here +related to my areas of interest: +programming, optimization, +mathematics, physics and even linguistics. + +This site is served to you by [nginx](https://nginx.org/), +and statically generated by [Hugo](https://gohugo.io). +I intend to keep it forever free of advertising and trackers, +and to maintain my A+ score for [TLS quality](https://www.ssllabs.com/ssltest/analyze.html?d=prefetch.eu). diff --git a/content/blog/2020/email-server-extras.md b/content/blog/2020/email-server-extras.md new file mode 100644 index 0000000..72299c9 --- /dev/null +++ b/content/blog/2020/email-server-extras.md @@ -0,0 +1,414 @@ +--- +title: "Setting up an email server in 2020 with OpenSMTPD and Dovecot: extras" +publishDate: 2020-04-27 +date: 2021-02-22T17:19:49+01:00 +draft: false +--- + +# + +This sequel to my earlier [guide](/blog/2020/email-server/) discusses +extra tips and tricks to extend your email setup. +This page will be updated continuously as I come up with ideas. + +Last updated 2020-04-29. + + +## General + +### Multiple domains + +You can generalize your setup to handle multiple domains +with very little effort. In the following, +I'll assume that your two domains are called `foo.com` and `bar.com`. + + +#### DNS records + +There should be MX, SPF, DKIM and DMARC records for both domains, +as explained in the previous guide. Fortunately, these records +can have identical contents for both domains! + +However, it remains essential that the mail server's mailname +and reverse DNS domain name match up exactly, +so you should create MX records with that in mind. +Therefore, if the email server for both domains has `mx1.foo.com` +as reverse DNS name, the MX records should look like this: +```sh +foo.com. MX 42 mx1.foo.com. +bar.com. MX 42 mx1.foo.com. +``` +This is perfectly valid: the only thing that matters is that +what your SMTP server calls itself agrees with what reverse DNS +says that the server is actually called. + + +#### Dovecot + +To make Dovecot aware of multiple domains, +you only need to update the `/etc/dovecot/users` file +to add accounts for both domains. +However, in the original guide, I said to only write `user` +in the file, without the `@foo.com`, for an address `user@foo.com`. +Unsurprisingly, that isn't an option for multiple domains, +so you must put the full address in `/etc/dovecot/users`. + +Then update `/etc/dovecot/dovecot.conf` to reflect that, +by changing `%n` to `%u` in `username_format`: +```sh +userdb { + driver = passwd-file + args = username_format=%u /etc/dovecot/users + override_fields = uid=vmail gid=vmail home=/home/vmail/%d/%n +} +``` +Also note the change in the `home` setting: +the inbox of a user `user@foo.com` will now be stored +in `/home/vmail/foo.com/user`. +That's all you need to change. + + +#### OpenSMTPD + +To inform OpenSMTPD of all the domains, +create a new file `/etc/smtpd/domains`, +and in there put all desired names on their own line: +```sh +foo.com +bar.com +``` +And as I mentioned when discussing the DNS records, +you should check that `/etc/smtpd/mailname` agrees +with your server's reverse DNS. + +Then, in the main configuration file, tell OpenSMTPD to +use the new domains file when deciding whether to accept an message, +by declaring a new table and changing the `match` line for inbound mail: +```sh +table domains "/etc/smtpd/domains" +# ... +match from any for domain <domains> action "RECV" +``` + +#### Rspamd + +The last thing to do is to inform Rspamd of the multiple domains. +It's really easy: simply add multiple domain blocks: +```c +domain { + foo.com { + path = "/path/to/dkim/private.key"; + selector = "hello"; + } +} +domain { + bar.com { + path = "/path/to/dkim/private.key"; + selector = "world"; + } +} +``` + +### Advanced security + +SPF, DKIM and DMARC are email's traditional DNS-based security systems, +but in 2018 the IETF released [RFC 8460](https://tools.ietf.org/html/rfc8460) and [RFC 8461](https://www.rfc-editor.org/rfc/rfc8461.txt), +which respectively define TLSRPT and MTA-STS, +two fancy new systems focused on TLS-encrypted email transport. + +These security mechanisms are pretty new, +so you won't get a huge benefit from enabling them, +but big email providers' draconian spam filters might like it. + + +#### TLSRPT + +TLS reporting, or TLSRPT for short, is very simple: +all it does is provide a contact email address in case +somebody has trouble with the TLS configuration of your SMTP server. + +To enable it for your custom email domain `example.com`, +simply create a DNS TXT record for the `_smtp._tls` subdomain: +```sh +_smtp._tls.example.com. TXT "v=TLSRPTv1; rua=mailto:<contact>" +``` +Where `<contact>` is an email address of your choosing. +That's all! + + +#### MTA-STS + +MTA Strict Transport Security (MTA-STS) tells other servers +that you take TLS encryption of messages very seriously, +so they should avoid sending you unencrypted email, +and should only accept certain certificates from your side. + +Compared to the previously discussed DNS-based security extensions, +MTA-STS is a bit more work to set up, +because you'll also need an HTTP web server. + +The DNS part is still pretty simple: +create yet another DNS TXT record, +this time for the subdomain `_mta-sts`: +```sh +_mta-sts.example.com. TXT "v=STSv1; id=<id>" +``` +The `<id>` should identify the version of your policy, +so other servers can quickly see if something changed. +I recommend using today's date. + +For the next part, I'll assume that you already have +a web server running on a server with the IP address `1.2.3.4`. +I use [nginx](https://nginx.org/) for this, running +on the same server as OpenSMTPD and Dovecot, +but you don't have to do the same. + +Create an A record which binds your server +to the subdomain `mta-sts` (without underscore): +```sh +mta-sts.example.com. A 1.2.3.4 +``` +Set your web server to serve the file +`https://mta-sts.example.com/.well-known/mta-sts.txt` +(we'll discuss that file in a moment). +Note that this policy file **must** be served over HTTPS, +so you need a valid TLS certificate for that domain. + +The contents of the `mta-sts.txt` policy file are as follows, +where `mx1.example.com` and `mx2.example.com` are the hosts +mentioned in `example.com`'s DNS MX records: +```sh +version: STSv1 +mode: enforce +mx: mx1.example.com +mx: mx2.example.com +max_age: <age> +``` +All MX servers must be mentioned this way. +If you're feeling cautious, you may want to set +`mode` to `testing` in the beginning. +This policy is valid for `<age>` seconds, +which is recommended to be several weeks, +but to start with, I suggest using 86400 seconds (one day). +Finally, ensure that this file has CRLF Windows-style line endings. + +To correctly pass an MTA-STS test, the TLS certificate +presented by e.g. `mx1.example.com` should be valid for `mx1.exaple.com`. +To achieve this without needing to manage too many certificates, +you can specify multiple domains when requesting a certificate, +or you can use a wildcard domain (`*.example.com`). +Note, however, that MTA-STS testing tools don't like +the latter option, so I recommend the former. + +Once you're done, check your work by using either +[ESMTP](https://esmtp.email/tools/mta-sts/)'s or [Ayke](https://aykevl.nl/apps/mta-sts/)'s +online MTA-STS validation tools, +ignoring any warnings about DNSSEC or DANE. +If all is good, great! + +Even if you did everything correctly, +these tools will warn you that you're not using DNSSEC/DANE. +It might then be tempting to set that up for even more security, +but I recommend against that for private servers: take a look at [this](https://dane.sys4.de/common_mistakes). + + + +## OpenSMTPD + +### Client certificates (in addition to passwords) + +You can configure OpenSMTPD to request a client certificate +for sending emails, as a second factor for authentication. + + +#### Certificates + +We need to start with some cryptography to create and verify certificates. +I recommend that you do all of this on your trusted *client* device, +and only copy the necessary files to the server later. + +DISCLAIMER: +All the keys and certificates that we'll generate in this section are +for **private use** only, to handle a small number of trusted clients. +I'm not a cryptography expert, so you should **not** listen to me +for large-scale systems that may involve untrusted devices. + +The first step is to set up a private Certificate Authority (CA), +which issues the client certificates and can be used to verify them. +Start by generating an RSA private key, +which you should store in a safe place and not share with anyone: +```sh +$ openssl genrsa -out mailca.key 2048 +``` +Extract a public certificate from this key as follows. +Because we're lazy, we give it a lifetime of 36500 days: +```sh +$ openssl req -new -x509 -days 36500 -key mailca.key -out mailca.crt +``` +When running this command, OpenSSL will ask you some questions +about who this certificate is intended for. +Since this is for personal use, your answers don't matter, +so just use the defaults. +Some fields (I think only *Country Name* and *Organization Name*) +cannot be empty, but the others can. + +Moving on to the client, once again generate an RSA private key: +```sh +$ openssl genrsa -out mailclient.key 2048 +``` +From this private key, create a Certificate Signing Request (CSR) +as follows, where you'll be asked the same questions as before: +```sh +$ openssl req -new -key mailclient.key -out mailclient.csr +``` +By feeding this CSR to the CA, we can create a signed client certificate +that can be verified using the CA's public certificate. +```sh +$ openssl x509 -req -in mailclient.csr -out mailclient.crt \ + -days 36499 -CA mailca.crt -CAkey mailca.key +``` +If you want to multiple client certificates, +just repeat the last few steps for each one. + + +#### Server + +OpenSMTPD needs to verify the validity of client certificates +using the CA's public certificate, so you should copy that +to somewhere on the server, e.g. `/etc/smtpd/mailca.crt`, +and declare it to OpenSMTPD by adding this near +the top of `/etc/smtpd/smtpd.conf`: +```sh +ca "mailca" cert "/etc/smtpd/mailca.crt" +``` +Then replace the entire configuration for outbound mail as follows. +Note that this removes SMTPS support, leaving only STARTTLS: +```sh +# Outbound +listen on eth0 port 587 tls-require verify pki "example.com" ca "mailca" auth <passwds> filter "rspamd" +action "SEND" relay srs +match from any auth for any action "SEND" +``` +The magic word here is "`verify`", which tells OpenSMTPD +to ask for a client certificate and to verify it using the given CA. + + +#### Client + +Now you won't be able to send emails if your client doesn't +present its certificate to the server! +Unfortunately, not all mail clients support this; personally +I use [Thunderbird](https://www.thunderbird.net/) with success. +I won't include any client-specific configuration here, +but I will say this: + +For some clients (like Thunderbird), you'll have an easier time +importing your client certificate if you encode it in the +[PKCS #12](https://en.wikipedia.org/wiki/PKCS_12) storage format: +```sh +$ openssl pkcs12 -export -in mailclient.crt -inkey mailclient.key \ + -certfile mailca.crt -out mailclient.pfx +``` +OpenSSL will ask you to set a password, which you'll need to +enter again when importing the certificate into the client. + + + +### Client certificates (instead of passwords) + +If you really want to, you can use the client certificates +as a substitute for passwords. This is especially useful +if you set up a catchall inbox in Dovecot, +because this will allow you to send emails +from arbitrary addresses from your domain. + +To do this, follow the same procedure as in the previous section, +but with a slightly different OpenSMTPD configuration: +```sh +listen on eth0 port 587 tls-require verify pki "example.com" ca "mailca" filter "rspamd" tag "VALID" +action "SEND" relay srs +match from any tag "VALID" for any action "SEND" +``` +All incoming connections that present a good certificate +will be tagged as being `VALID`, and their mail will be relayed. + +Unfortunately, we're not quite done yet here, +because Rspamd is now very confused... + + +#### Rspamd + +When OpenSMTPD passes a message through Rspamd, it also includes +some metadata, most notably whether the sender has authenticated +successfully with OpenSMTPD... which is now no longer the case +for submissions, because we've removed the `auth` directive! + +Rspamd therefore starts regarding these outgoing emails +as *incoming* emails, because they don't seem +to come from a trusted user. So instead of signing them with DKIM +and handing them back to OpenSMTPD, it will do a full spam scan. +If they get a high spam score (which is likely for short test emails), +*your* spam filter, running on *your* server, +will be flagging *your* messages as spam! + +The solution is to whitelist your domain(s) in Rspamd, +so it won't scan them. To do this, create a new file +`/etc/rspamd/local.d/settings.conf` with these contents, +where `foo.com` and `bar.com` are the domains to whitelist: +```c +outbound { + priority = high; + from = "@foo.com"; + from = "@bar.com"; + apply { + actions { + add_header = 1000; + } + } +} +``` +Setting `priority` to `high` ensures that Rspamd checks +this rule before doing anything else. +You can add any number of `from` directives; +this rule will be applied if any of them match. +It only sets the threshold for the action `add_header` to `1000`. +That is, if the email doesn't get a spam score of at least 1000 +(the default is 6) Rspamd will not add any spam tags. + +Because Rspamd is still regarding your emails as inbound, +you also need to change the global settings of +the DKIM signer in `/etc/rspamd/local.d/dkim_signing.conf`, +such that they include the following: +```c +sign_inbound = true; +allow_hdrfrom_mismatch = true; +allow_username_mismatch = true; +``` +This tells Rspamd to add DKIM signatures to incoming emails, +which in this case includes yours. +Allowing these mismatches ensures that the messages still get signed, +even if you're sending from an arbitrary address. + + + +## Dovecot + +### Catchall inbox + +In Dovecot, you can create a catch-all inbox that will accept all +emails sent to your domain that don't match anyone in `/etc/dovecot/users`. +Just add another `userdb` block *after* the first: +```sh +userdb { + driver = static + args = uid=vmail gid=vmail home=/var/vmail/catchall allow_all_users=yes +} +``` +The `static` driver means there is no table file: +all configuration is directly within this `userdb` block. +If we don't specify `allow_all_users=yes`, then Dovecot +will check whether users exist using the `passdb` table, +and will conclude that the recipient is invalid. + + + diff --git a/content/blog/2020/email-server.md b/content/blog/2020/email-server.md new file mode 100644 index 0000000..3b7f439 --- /dev/null +++ b/content/blog/2020/email-server.md @@ -0,0 +1,718 @@ +--- +title: "Setting up an email server in 2020 with OpenSMTPD and Dovecot" +publishDate: 2020-04-27 +date: 2021-02-22T17:27:49+01:00 +draft: false +--- + +# + +So, you want to set up your own email server? In that case, welcome. + +There are many reasons to run a custom email server, +ranging from privacy concerns about providers like Google, +to just wanting to do it for fun and/or learning. +Since you're here, I assume you've already found a reason. + +Beware: this is a messy topic, and the available documentation +is even messier, so it could take a while before you get it to work properly. +I've compiled this guide according to my experiences +in an attempt to make this dark art more accessible, +but your mileage may vary considerably. I hope you find it useful. + +This guide is aimed at people who are comfortable with +the Linux/*BSD command line. + +When you're done, take a look at the +[sequel](/blog/2020/email-server-extras/) +for ideas to extend your setup. + +Last content update on 2020-04-29. Last correction on 2021-02-20. + + + +## Preparation + +Setting up email is relatively complex compared to e.g. a static website, +because you need to configure not one, but *two* server programs, +*and* you need to shoehorn modern security features into email's Stone-Age design. +I'll start by explaining the general structure of a mail server setup. + + +### How email works + +The programs involved in the exchange of emails are called [agents](https://en.wikipedia.org/wiki/Email_agent_(infrastructure)). +Officially, there are 5 different types of agent: MUA, MSA, MTA, MDA and MRA. +But fortunately, it's reasonable to treat the MRA and MSA +as being part of the MUA and MTA, respectively. + +The *Mail User Agent* (MUA) is simply the client on your device at home +that you use to send and receive emails, and this guide assumes +you already have a favourite program for this, e.g. [Thunderbird](https://www.thunderbird.net/en-US/). +Nowadays it's fashionable to use a web interface for emails, +but that's also beyond the scope of this guide. + +The *Mail Delivery Agent* (MDA) is a program that watches over +the server's copy of your mailbox: it manages your inbox, +remembers which messages you have or haven't read, +keeps a copy of your drafts, etc. +When you open your mailbox, your MUA will connect to +your server's MDA using the [IMAP](https://en.wikipedia.org/wiki/Internet_Message_Access_Protocol) protocol +(or [POP3](https://en.wikipedia.org/wiki/Post_Office_Protocol), but that one's [obsolete](https://pop2imap.com/)). + +The *Mail Transfer Agent* (MTA) is responsible for +making messages arrive at the right destination. +When you send an email, your MUA will pass it on to your server's MTA, +which will in turn pass it on to the recipient's mail server. +Likewise, when someone sends *you* an email from another server, +the MTA will receive it and hand it over to the MDA so you can read it later. +In both cases the MTA speaks the [SMTP](https://en.wikipedia.org/wiki/Simple_Mail_Transfer_Protocol) protocol. + +In this guide our MDA will be [Dovecot](https://dovecot.org/), +which is a very popular choice for that role. +As for the MTA, there exist several options, +the most popular being [Postfix](http://www.postfix.org/) and [Exim](https://exim.org/). +However, this guide uses the newer, lesser-known [OpenSMTPD](https://opensmtpd.org/), +which in my experience is *much* easier to set up: +Postfix and Exim have complex configurations and +are geared towards large-scale email providers, +whereas OpenSMTPD is more beginner-friendly. + + + +### Security + +The base email system is horribly insecure on its own, +so we still need to duct-tape on some security features. +In this context, "security" has two meanings: +spam protecion and privacy protection (encryption). + +Spam protection also means two things here: +defending yourself against spammers, and +preventing that *your* emails get flagged as spam. +The former is optional, but the latter is not: +big providers such as Google and Microsoft +use infamously strict spam filters, +and if they decide that your server is a spammer, +there's almost nothing you can do about it. +Spam protection techniques will be discussed +in more detail over the course of this guide. + +Privacy protection is important in the 21st century: +you don't want a random router in the Internet to read all your emails, +which may contain sensitive information such as +private conversations and account password reset links. +You should therefore try to make sure that emails are +transported over an encrypted channel. +To do this, you have two options for encryption: +*mandatory* and *opportunistic* encryption. + +Mandatory encryption is only practical for client-server +communication (not server-server), and is provided by IMAPS and SMTPS, +which wrap the IMAP and SMTP protocols in [TLS](https://en.wikipedia.org/wiki/Transport_Layer_Security), +in the same way that [HTTPS](https://en.wikipedia.org/wiki/HTTPS) does for [HTTP](https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol). + +For server-server communication, the only option is +opportunistic encryption in the form of [STARTTLS](https://en.wikipedia.org/wiki/STARTTLS), +where communication is only encrypted if both parties agree +after a short unencrypted discussion. +That last part is vulnerable to [MitM](https://en.wikipedia.org/wiki/Man-in-the-middle_attack) attacks, +where anyone along the path of the email servers' discussion +can alter the exchange to block the use of encryption, +which sometimes actually [happens](https://www.eff.org/deeplinks/2014/11/starttls-downgrade-attacks) in practice. + +The only way to make sure that STARTTLS is used in that case +is to refuse any exchange unless the servers agree to use encryption. +Unfortunately, that's a risky approach that I can't recommend, +because not all servers support encryption (unbelievable, right?). +For example, I've received airline booking confirmations, +full of personal details, and made with billion-dollar companies, +sent across the Internet without any protection. + +This guide includes intructions to enable encryption, +but assumes that you already have a TLS certificate for that. +If not, find a guide to get one from [Let's Encrypt](https://letsencrypt.org/) (it's free!), +and remember that you'll need to renew it every few months. +Using a self-signed certificate *may* work, but I don't recommend it. + +In the rest of this guide I'll assume that +you have a public full-chain TLS certificate at `/etc/ssl/certs/example.com.pem`, +and a private encryption key at `/etc/ssl/private/example.com.pem`. + + + +### Server + +Obviously, you'll need a server to run the MTA and MDA on. +You can host your own at home, but the more reliable option is +to rent one in a data center ([VPS](https://en.wikipedia.org/wiki/Virtual_private_server)). +This guide was written with a Linux server in mind, +but in theory it should also work on the BSDs +([OpenBSD](https://www.openbsd.org/), [FreeBSD](https://www.freebsd.org/), +[NetBSD](https://www.netbsd.org/), etc.) with minimal adaptation. + +The server must be online 24/7, you must have root SSH access, +it must have a static IP address, and TCP network port 25 must be open. +Especially check that last one: you may need to explicitly ask +your home ISP or the server provider to enable port 25, +because they often close it to prevent spam. +You can usually do this from their web interface. + +You also must have a domain name, which I'll call `example.com`. +This will be necessary for basically everything: +DNS records, TLS certificate, MTA network configuration, etc. +If you don't have one yet, you can choose between many registrars +to rent one from. Personally I use and can recommend [Gandi](https://www.gandi.net/). + +Note that it's a **bad** idea to use a domain like `foo.bar.com`, +where you control the `foo` part but *not* the `bar` part: +in that case, a spammer in control of `qux.bar.com` +could negatively affect *your* reputation +in the eyes of other email providers. + +Lastly, when setting up an email server, you also have the choice +between using to *system* users or *virtual* users. +With system users, if an email arrives for `john@example.com`, +then the MTA and MDA will expect that there exists +a `john` Unix user on the server to deliver it to. +With virtual users, you have much more flexibility, so that's what we'll use. +All email will be managed under a single Unix user/group called `vmail`. +Create it as follows: +```sh +# GNU CoreUtils: +$ groupadd vmail +$ useradd -g vmail vmail +# BusyBox: +$ addgroup vmail +$ adduser -D -G vmail vmail +# *BSD: +$ no clue, but it should be similar +``` + + +## DNS records + +Now we must set up all the necessary DNS records, which +is usually possible from the domain registrar's web interface. +It may take a while for your changes to propagate over the Internet, +so I recommend doing this section now and the rest tomorrow. + +Firstly, you should already have an A and/or AAAA record +to associate your domain `example.com` with the server's IP address. +For email it is **essential** that you also have [reverse DNS](https://en.wikipedia.org/wiki/Reverse_DNS_lookup) +set up correctly. If you're renting your server remotely, +you can often do this from the provider's configuration tool, +otherwise, you should create a PTR-type DNS record, +although that's beyond the scope of this guide. + +Once you're done, I recommend testing your DNS records +using the [MX Lookup](https://mxtoolbox.com/MXLookup.aspx) online tool. + + + +### MX + +To inform the rest of the Internet that your server is an email server, +create an MX (Mail eXchanger) DNS record for your domain. +Note the dot at the end of the domain name: +``` +example.com. MX 42 example.com. +``` +When a message is sent to an email address ending in `@example.com`, +the sender will query DNS for any MX records for `example.com`. +There it will find a domain name (in this case `example.com` again), +for which it will look up the IP address using an A/AAAA record. +The domain name in the record must **not** have an associated CNAME record; +it must be directly translatable to an IP address. + +You may have multiple MX records, containing different domain names, +each with a preference number (`42` in the example above). +The sender will try MX records with *lower* numbers first, +and if that server is unavailable, it will try a higher number. +If you have multiple mail servers (which is a good idea), +you can thus declare those as follows: +``` +example.com. MX 13 mx1.example.com. +example.com. MX 42 mx2.example.com. +``` +Here, a server sending an email to your domain `example.com` +will try to send it to the IP address of `mx1.example.com` first, +and if that fails, it will move on to `mx2.example.com`. +If both `mx1` and `mx2` have the same number, then the sender +will randomly choose one, which is useful for load balancing, +although that's probably overkill for a private server. + + + +### SPF + +The [Sender Policy Framework](https://en.wikipedia.org/wiki/Sender_Policy_Framework) (SPF), +is a feature which helps prevent spammers from impersonating +your server in an attempt to get around blacklists. +This security feature is **required** nowadays: +if you don't use it, you'll probably get flagged as spam. + +SPF works by specifying which IP addresses are authorized +to send emails from your domain name. +You must publish this information in a +TXT-type DNS record (**not** SPF-type, which also exists!) with the following contents: +``` +example.com. TXT "v=spf1 mx -all" +``` +Everything after the version `v=spf1` is a list of *verification mechanisms* +for a spam filter to try out in the given order. +The `-all` at the end says to reject your email +if all of the previous mechanisms fail. +See the [SPF spec](https://tools.ietf.org/html/rfc7208) for details. + +I recommend only using the `mx` mechanism, which tells the verifier +to look at the A/AAAA addresses of the domains in your MX records. +This allows you to add, remove, or change your servers +without needing to update this record. + + + +### DKIM + +Then we have [DomainKeys Identified Mail](https://en.wikipedia.org/wiki/DomainKeys_Identified_Mail) (DKIM), +which is a more comprehensive form of anti-impersonation, +and, like SPF, is practically **mandatory** in the modern era. + +It adds a cryptographic signature to all emails from your server, +which the receiver's spam filter will verify using the email's contents, +and a public key that you need to publish in a DNS record. +Again, you should implement *both* SPF and DKIM, despite their overlap. + +To set up DKIM, create an RSA keypair, using the `openssl` utility: +```sh +$ openssl genrsa -out /path/to/dkim/private.key 2048 +$ openssl rsa -in /path/to/dkim/private.key -out /path/to/dkim/public.key +``` +The minimum size is 1024 bits, but I recommend 2048 bits. +Bigger is better, but because DNS is involved you can't stretch it +to 4096 bits without causing discomfort to [some](https://serverfault.com/questions/747185/dkim-can-i-use-a-rsa-key-larger-than-2048bit-i-e-4096) servers. +And I think it goes without saying that you should keep the private key private. + +Importantly, the DKIM DNS record **cannot** be +attached directly to your domain `example.com`; +instead, it should belong to a subdomain of the form +`<selector>._domainkey.example.com`, +where `<selector>` is an alphanumeric string you can choose (e.g. today's date), +just remember your choice for later when configuring the DKIM signer. +And if you change your key, keep the old record around +for a while so old emails can still be verified. + +Your DKIM policy must be published in a TXT record +as follows, where `<pubkey>` is the public RSA key `MI...AB` +stored in `/path/to/dkim/public.key`, with the newlines removed: +``` +<selector>._domainkey.example.com. TXT "v=DKIM1; t=s; h=sha256; p=<pubkey>" +``` +Here, `v=DKIM1` is the version and must be the first tag. +The flag `t=s` enables strict mode, as recommended by the [DKIM spec](https://tools.ietf.org/html/rfc6376), +meaning that emails sent from subdomains immediately fail verification. +The optional tag `h=sha256` blocks the use of the old SHA1 algorithm. + + + +### DMARC + +Lastly, we have [Domain-based Message Authentication, Reporting and Conformance](https://en.wikipedia.org/wiki/DMARC) (DMARC), +which is *technically* optional, but *highly* recommended, +because it will make you look more legitimate in the eyes of Google and Microsoft. +It can modify the behaviour of SPF and DKIM, +and also provides advice about what a receiver should do +if one of your emails fails verification. + +To enable it, create yet another TXT record, which, +similarly to DKIM, **must** belong to the subdomain `_dmarc.example.com`, +and give it the following contents, +where `<admin>` is an email address of your choosing, +which may or may not belong to your domain: +``` +_dmarc.example.com. TXT "v=DMARC1; p=reject; sp=reject; pct=100; aspf=s; adkim=s; fo=1; ruf=mailto:<admin>" +``` +The version tag `v=DMARC1` must come first, +followed by `p=` and `sp=`, which control what to do to unverified messages +coming from the main domain and subdomains, respectively. +Unsurprisingly, `reject` means that delivery should be refused, +`none` asks to let it through anyway, and `quarantine` tells +the filter to take a closer look or to put it in a spam folder. +The percentage `pct=100` says how many of your emails to apply the policy to. +Next, `aspf=s` and `adkim=s` enable strict mode for both SPF and DKIM, +which blocks subdomains from passing the test. +Finally, `fo=1` asks the filter to create a forensic report +if any type of verification fails, and `ruf=` gives an address to send it to. +If in doubt, see the [DMARC spec](https://tools.ietf.org/html/rfc7489). + + + +## MDA: Dovecot + +[Dovecot](https://www.dovecot.org/) is a very popular IMAP server, +focused on being lightweight, simple, and secure, +and has extensive and up-to-date documentation. +It's very flexible and scalable, and keeps up well +with the lastest security best-practices. + +If you installed Dovecot via a package manager, +you'll probably have lots of configuration files +in the `/etc/dovecot` directory. +I want you to delete all of them. Yes, `rm -rf` that crap. +Dovecot is simple to configure, and doesn't care where +you put its settings, so having all that chaos in `/etc/dovecot` +just makes things unnecessarily confusing. + + + +### Network + +Create a new configuration file `/etc/dovecot/dovecot.conf`, +and start by filling in the details of your TLS certificate, +making clear that unencrypted connections are unacceptable: +```sh +ssl = required +ssl_cert = </etc/ssl/certs/example.com.pem +ssl_key = </etc/ssl/private/example.com.key + +ssl_min_protocol = TLSv1.2 +ssl_prefer_server_ciphers = yes + +disable_plaintext_auth = yes +``` +The final `disable_plaintext_auth` option tells Dovecot +to reject any passwords that were sent unencrypted. +This means it must be [hashed](https://en.wikipedia.org/wiki/Cryptographic_hash_function) +or sent over an encrypted connection, or both. + +Next, tell Dovecot which protocols to use +and where to expect them as follows: +```sh +protocols = lmtp imap + +service lmtp { + unix_listener lmtp { + user = vmail + group = vmail + } +} + +service imap-login { + inet_listener imap { + port = 143 + } + inet_listener imaps { + port = 993 + } +} +``` +LMTP is the Local Mail Transport Protocol, which is basically SMTP +but for exchanges within a single server or over a trusted network. +When an email is received, Dovecot will start a child process +under the `vmail` user/group to deliver the message to its recipient. + +Since we set `ssl = required` earlier, clients will only get their mail +if the STARTTLS handshake was successful during the IMAP exchange, +or if they connect via IMAPS to force the use of encryption. +You can therefore optionally remove one of the two +`inet_listener`s according to your preferences. + + + +### Users + +Next, we need to inform Dovecot which email addresses it should handle, +and what to do with their messages. Create a file `/etc/dovecot/users` for this, +which describes a user on each line in a similar format as `/etc/passwd`: +``` +user:password:uid:gid::homedir +``` +In this guide, we're using the `vmail` user for all accounts, +so leave the `uid`, `gid`, and `homedir` fields blank. +We'll be storing all emails in `vmail`'s home directory. +The `user` field should be the email address excluding the `@example.com` +(in fact, you *can* include it, but this guides assumes a small-scale +server managing only one domain, so we exclude it). +Create the password hash to put in the `password` field as follows: +```sh +# If your server is fast and has lots of RAM: +$ doveadm pw -s ARGON2ID-CRYPT +# If you're using a potato: +$ doveadm pw -s SHA512-CRYPT +``` +After you've entered your password, simply copy-paste the entire +hash string outputted by the program into the `password` field. + +Now, Dovecot needs a file describing user accounts on two separate occasions: +* To check whether a client logging into the IMAP server + is valid and has given the right password. + This is handled by the `passdb` block(s) in the configuration. +* To know which email addresses the server is responsible for. + This is given by the `userdb` block(s) in the configuration. + +These functions aren't necessarily fulfilled by the same `users` file: +you can map multiple email addresses to one acccount, +or multiple accounts to one email address. +For simplicity, though, we'll use the `users` file for both: +```sh +passdb { + driver = passwd-file + args = scheme=ARGON2ID-CRYPT username_format=%n /etc/dovecot/users + #args = scheme=SHA512-CRYPT username_format=%n /etc/dovecot/users +} + +userdb { + driver = passwd-file + args = username_format=%n /etc/dovecot/users + override_fields = uid=vmail gid=vmail home=/home/vmail/%n +} +``` +The `driver` option sets the kind of table Dovecot should expect. +We tell it to use a file in the `passwd`-like format described above, +but other possibilities include e.g. an SQL database. +The options available in `args` depend on the chosen `driver`. + +In the `passdb` block, the hashing algorithm is given by `scheme`, +while `username_format=%n` says that the `users` file +only contains `name` out of `name@example.com`. + +In the `userdb` block, we force the use of `vmail:vmail` +for all accounts, and tell Dovecot to put their data in `/home/vmail/%n`, +where `%n` means the address up until the `@`, so +e.g. mail to `name@example.com` is stored in `/home/vmail/name`. + +Now that Dovecot knows where to store messages, +we just need to specify in what format to store them: +```sh +mail_location = maildir:~/Maildir +``` +The two standard mailbox formats to choose from are `maildir` and `mbox`. +I highly recommend `maildir`; it's more modern than the ancient `mbox` format. +That `~/Maildir` says which subfolder to use. +Ensure that `/home/vmail` is owned by `vmail:vmail`, +so that Dovecot has write access. + + + +## MTA: OpenSMTPD + +[OpenSMTPD](https://opensmtpd.org/) is an MTA by the [OpenBSD](https://www.openbsd.org/) project, +who are known for their focus on security and minimalism. +Compared to other MTAs it's a joy to set up, thanks to +its intuitive configuration syntax and to-the-point manual. +This guide is for OpenSMTPD version 6.4 or newer: +older versions used a substantially different syntax. + +If you have any problems with OpenSMTPD, +take a look at the maintainer's [blog](https://poolp.org/), +which contains a lot of useful information, +and was a big help when writing this guide. + + + +### Users + +To begin, delete the contents of the `/etc/smtpd/aliases` file, +if it exists, which maps recipient addresses to system users. +In our case, we're using `vmail` for everyone, +and we'll let Dovecot manage the details by simply writing: +``` +@ vmail +``` +Then create a new file `/etc/smtpd/passwds` +and fill it in according to the following format: +``` +name@example.com <hash> +``` +Generate the password hash with this command for each user. +Be sure to use the same password for every account as in Dovecot: +```sh +$ smtpctl encrypt '<password>' +``` +Then, like with Dovecot, just delete the contents of +the main config file `/etc/smtpd/smtpd.conf`, +and start by putting in the following: +```sh +table aliases "/etc/smtpd/aliases" +table passwds "/etc/smtpd/passwds" +``` + + +### Network + +Write your domain name on a single line in `/etc/smtpd/mailname`. +This is the name that OpenSMTPD will use to introduce itself +to other servers, and it's important that this matches +the reverse DNS domain name of the server's IP: +```sh +example.com +# Or mx1.example.com or whatever +``` +Then continue in `/etc/smtpd/smtpd.conf` by importing your TLS certificate: +```sh +pki "prefet.ch" cert "/etc/ssl/certs/example.com.pem" +pki "prefet.ch" key "/etc/ssl/private/example.com.key" +``` +And tell OpenSMTPD which keys to use for the [Sender Rewriting Scheme](https://en.wikipedia.org/wiki/Sender_Rewriting_Scheme), +which prevents forwarded emails from breaking SPF and looking like spam: +```sh +srs key "<secret1>" +srs key backup "<secret2>" # optional, read below +``` +It's recommended to change the key every year or so, +but in that case you need to ensure that emails from the last month +can still be verified using the old one, so if you change it, +simply move it to the backup slot for a month. + +It's very important that the secrets can't be guessed, +otherwise *anyone* can send mail through your server, +so I recommend generating these keys randomly as follows: +```sh +$ head -c 30 /dev/urandom | base64 +``` +Next, define the spam filters as follows. +For the last line to work, you'll need to [download](https://github.com/poolpOrg/filter-rspamd) +and build the `filter-rspamd` adapter binary for yourself, +created by OpenSMTPD's official maintainer. +We'll set up the Rspamd service in the next section, +which will be responsible for spam filtering and DKIM signing: +```sh +filter "rdns" phase connect match !rdns disconnect "550 DNS error" +filter "fcrdns" phase connect match !fcrdns disconnect "550 DNS error" +filter "rspamd" proc-exec "/etc/smtpd/filter-rspamd" +``` +I cannot overstate the importance of the first two lines: +these will block hundreds of spam attempts, and have, +at least for me, never blocked anything legitimate so far. + +The only thing left to do here is to tell OpenSMTPD which ports to listen on +and what to do with the incoming traffic. +This comes in two parts: first, we listen on port 25 for incoming +messages for your domain coming from other email servers: +```sh +# Inbound +listen on eth0 port 25 tls pki "example.com" filter { "rdns", "fcrdns", "rspamd" } +action "RECV" lmtp "/var/run/dovecot/lmtp" rcpt-to virtual <aliases> +match from any for domain "example.com" action "RECV" +``` +Line 1 says to listen on `port 25` of interface `eth0`, +providing *optional* `tls` using the certificate for `example.com`, +and passing everything through the three filters definer earlier. +Making TLS mandatory is a **bad** idea here, because not all servers can use TLS. + +Line 2 defines an action called `RECV`, +which relays an email to Dovecot's LMTP socket, +with the `rcpt-to` and `virtual` making sure +that Dovecot will actually accept the message. + +Line 3 then simply says that any incoming mail +for your domain should have the action `RECV` applied to it, +unless the spam filters rejected it. + +Secondly, we listen on port 465 (SMTPS) +and/or port 587 (STARTTLS) for messages getting sent +from your email client to the rest of the world, +so we require user authentication: +```sh +# Outbound +listen on eth0 port 465 smtps pki "example.com" auth <passwds> filter "rspamd" +listen on eth0 port 587 tls-require pki "example.com" auth <passwds> filter "rspamd" +action "SEND" relay srs +match from any auth for any action "SEND" +``` +The only difference between lines 1 and 2 is the port and the protocol. +Both demand a mandatory TLS connection, and that users authenticate +themselves according to the password file created earlier. +The `filter` at the end is for DKIM signing of outgoing mail. + +Lines 3 and 4 are only triggered after successful `auth`entication, +and, unsurprisingly, `relay` the email to its destination. +The `srs` at the end enables using the SRS settings from earlier. + +OpenSMTPD is the only program in this setup that needs to handle +untrusted connections, when other MTAs send you messages. +Since, like most server software, it may have [vulnerabilities](https://opensmtpd.org/security.html), +it is **very** important that you keep it as up-to-date as possible. + + + +## Spam filter: Rspamd + +[Rspamd](https://www.rspamd.com/) is a modern spam filtering solution, +with many features that you could spend hours tweaking. +In this guide, however, we'll keep it short, +because we're only really interested in its ability add +our server's DKIM signature to outgoing messages. + +Besides, according to my limited experience, +for small-scale servers spam filtering isn't essential, +as long as you tell OpenSMTPD to check reverse DNS as described above. +However, there are some much more experienced people who disagree with me. + +Basically, for our purposes, don't touch any of Rspamd's default +configuration except for creating/editing the file +`/etc/rspamd/local.d/dkim_signing.conf` with the following contents, +where `<selector>` is the DKIM selector you chose in the DNS record: +```sh +allow_username_mismatch = true; + +domain { + example.com { + path = "/path/to/dkim/private.key"; + selector = "<selector>"; + } +} +``` +Make sure that the DKIM `private.key` file is +readable (and *only* readable) by `rspamd:rspamd`. +Allowing username mismatches is necessary, +because OpenSMTPD will only tell Rspamd about `username` +while the DKIM signer actually expects `username@example.com`. + +And... that's it! Of course, don't forget to start all the necessary daemons. + + + +## Testing + +Everything is set up now, so it's time to test. Fingers crossed! + +As mentioned earlier, you can check the correctness +of your DNS using the [MX Lookup](https://mxtoolbox.com/MXLookup.aspx) tool. +You can use the same website to test OpenSMTPD +with the [SMTP Diagnostics](https://mxtoolbox.com/diagnostic.aspx) tool. + +All decent email clients include an option to set the server for an email account. +This guide excludes instructions for that, +because it will vary a lot from client to client. +If asked for your login type, choose plain/normal/unencrypted passwords. +Don't worry, the client-server connection is TLS-encrypted, +so nobody will be able to steal it. + +Next, to test sending and receiving messages, +use the aptly-named [Is my email working?](http://ismyemailworking.com/) website. +After that, specifically test that SPF, DKIM an DMARC +are working correctly using the [DKIM validator](https://dkimvalidator.com/). +If everything is good so far, congratulations! + +Now comes the big scary final test: +sending an email to one of the "big guys", Google or Microsoft. +Their spam filters are very strict, so if you get through, great! +Because these companies probably use AI-powered account-aware filters, +you should *not* put anything identifiable in the test email. +For example, if your name is "John Smith", +do *not* put "John" nor "Smith" in the message, +and do *not* send it from an addres like `john.smith@example.com`. + +If something failed, then you have some investigating to do. +Either one of the daemons is misconfigured, or there's a problem +with your domain name and/or DNS records. +Do some research, and you'll get there, don't give up. + +But if everything works, congratulations! +You're now the proud administrator of a private email server. +Have fun with it, and don't forget to update your +TLS certificate and DKIM and SRS keys. + +PS: and please don't spam; you'll ruin it for everyone else. + diff --git a/content/blog/_index.md b/content/blog/_index.md new file mode 100644 index 0000000..3d4ffc2 --- /dev/null +++ b/content/blog/_index.md @@ -0,0 +1,7 @@ +--- +title: "Blog" +date: 2021-02-22T17:38:58+01:00 +draft: false +--- + +Just a bunch of random ramblings. diff --git a/content/know/_index.md b/content/know/_index.md new file mode 100644 index 0000000..41aeef6 --- /dev/null +++ b/content/know/_index.md @@ -0,0 +1,32 @@ +--- +title: "Knowledge base" +date: 2021-02-22T19:57:05+01:00 +draft: false +layout: "know" +--- + + +# Knowledge base + +Welcome to my knowledge base! + +Over the years, I've learned a lot of physics, mathematics, and computing. +These are vast, difficult subjects, and I've spent many hours of my life +trying to make sense of obscure, poorly explained concepts. +To help me remember what I learn, I write notes in LaTeX. + +This knowledge base is based on my notes, and +is freely available to anyone who might need it. +I hope it helps you in your studies or work. +Currently there's isn't much here yet, +but I have over 200 pages of LaTeX waiting to be converted. + +Keep in mind that I'm only human, +so there are probably mistakes in my work. +I take no responsibility for any injuries incurred as a consequence. +If you're doing something important, +you should check things yourself! + +The contents of this knowledge base are found here: +* [List of concepts](/know/concept/) +* [List of categories](/know/category/) diff --git a/content/know/category/_index.md b/content/know/category/_index.md new file mode 100644 index 0000000..b796457 --- /dev/null +++ b/content/know/category/_index.md @@ -0,0 +1,8 @@ +--- +title: "List of categories" +date: 2021-02-22T20:38:58+01:00 +draft: false +layout: "know-list" +--- + +This is an alphabetical list of the categories in this knowledge base. diff --git a/content/know/category/mathematics.md b/content/know/category/mathematics.md new file mode 100644 index 0000000..693252f --- /dev/null +++ b/content/know/category/mathematics.md @@ -0,0 +1,9 @@ +--- +title: "Mathematics" +firstLetter: "M" +date: 2021-02-23T14:44:07+01:00 +draft: false +layout: "category" +--- + +This page will fill itself. diff --git a/content/know/category/physics.md b/content/know/category/physics.md new file mode 100644 index 0000000..7b0eaed --- /dev/null +++ b/content/know/category/physics.md @@ -0,0 +1,9 @@ +--- +title: "Physics" +firstLetter: "P" +date: 2021-02-23T14:44:11+01:00 +draft: false +layout: "category" +--- + +This page will fill itself. diff --git a/content/know/category/quantum-mechanics.md b/content/know/category/quantum-mechanics.md new file mode 100644 index 0000000..bc36a6f --- /dev/null +++ b/content/know/category/quantum-mechanics.md @@ -0,0 +1,9 @@ +--- +title: "Quantum mechanics" +firstLetter: "Q" +date: 2021-02-23T14:38:56+01:00 +draft: false +layout: "category" +--- + +This page will fill itself. diff --git a/content/know/concept/_index.md b/content/know/concept/_index.md new file mode 100644 index 0000000..956724a --- /dev/null +++ b/content/know/concept/_index.md @@ -0,0 +1,8 @@ +--- +title: "List of concepts" +date: 2021-02-22T20:38:58+01:00 +draft: false +layout: "know-list" +--- + +This is an alphabetical list of the concepts in this knowledge base. diff --git a/content/know/concept/blochs-theorem/index.pdc b/content/know/concept/blochs-theorem/index.pdc new file mode 100644 index 0000000..1828d8a --- /dev/null +++ b/content/know/concept/blochs-theorem/index.pdc @@ -0,0 +1,115 @@ +--- +title: "Bloch's theorem" +firstLetter: "B" +publishDate: 2021-02-22 +categories: +- Quantum mechanics + +date: 2021-02-22T20:02:14+01:00 +draft: false +markup: pandoc +--- + +# Bloch's theorem +In quantum mechanics, **Bloch's theorem** states that, +given a potential $V(\vec{r})$ which is periodic on a lattice, +i.e. $V(\vec{r}) = V(\vec{r} + \vec{a})$ +for a primitive lattice vector $\vec{a}$, +then it follows that the solutions $\psi(\vec{r})$ +to the time-independent Schrödinger equation +take the following form, +where the function $u(\vec{r})$ is periodic on the same lattice, +i.e. $u(\vec{r}) = u(\vec{r} + \vec{a})$: + +$$ +\begin{aligned} + \boxed{ + \psi(\vec{r}) = u(\vec{r}) e^{i \vec{k} \cdot \vec{r}} + } +\end{aligned} +$$ + +In other words, in a periodic potential, +the solutions are simply plane waves with a periodic modulation, +known as **Bloch functions** or **Bloch states**. + +This is suprisingly easy to prove: +if the Hamiltonian $\hat{H}$ is lattice-periodic, +then both $\psi(\vec{r})$ and $\psi(\vec{r} + \vec{a})$ +are eigenstates with the same energy: + +$$ +\begin{aligned} + \hat{H} \psi(\vec{r}) = E \psi(\vec{r}) + \qquad + \hat{H} \psi(\vec{r} + \vec{a}) = E \psi(\vec{r} + \vec{a}) +\end{aligned} +$$ + +Now define the unitary translation operator $\hat{T}(\vec{a})$ such that +$\psi(\vec{r} + \vec{a}) = \hat{T}(\vec{a}) \psi(\vec{r})$. +From the previous equation, we then know that: + +$$ +\begin{aligned} + \hat{H} \hat{T}(\vec{a}) \psi(\vec{r}) + = E \hat{T}(\vec{a}) \psi(\vec{r}) + = \hat{T}(\vec{a}) \big(E \psi(\vec{r})\big) + = \hat{T}(\vec{a}) \hat{H} \psi(\vec{r}) +\end{aligned} +$$ + +In other words, if $\hat{H}$ is lattice-periodic, +then it will commute with $\hat{T}(\vec{a})$, +i.e. $[\hat{H}, \hat{T}(\vec{a})] = 0$. +Consequently, $\hat{H}$ and $\hat{T}(\vec{a})$ must share eigenstates $\psi(\vec{r})$: + +$$ +\begin{aligned} + \hat{H} \:\psi(\vec{r}) = E \:\psi(\vec{r}) + \qquad + \hat{T}(\vec{a}) \:\psi(\vec{r}) = \tau \:\psi(\vec{r}) +\end{aligned} +$$ + +Since $\hat{T}$ is unitary, +its eigenvalues $\tau$ must have the form $e^{i \theta}$, with $\theta$ real. +Therefore a translation by $\vec{a}$ causes a phase shift, +for some vector $\vec{k}$: + +$$ +\begin{aligned} + \psi(\vec{r} + \vec{a}) + = \hat{T}(\vec{a}) \:\psi(\vec{r}) + = e^{i \theta} \:\psi(\vec{r}) + = e^{i \vec{k} \cdot \vec{a}} \:\psi(\vec{r}) +\end{aligned} +$$ + +Let us now define the following function, +keeping our arbitrary choice of $\vec{k}$: + +$$ +\begin{aligned} + u(\vec{r}) + = e^{- i \vec{k} \cdot \vec{r}} \:\psi(\vec{r}) +\end{aligned} +$$ + +As it turns out, this function is guaranteed to be lattice-periodic for any $\vec{k}$: + +$$ +\begin{aligned} + u(\vec{r} + \vec{a}) + &= e^{- i \vec{k} \cdot (\vec{r} + \vec{a})} \:\psi(\vec{r} + \vec{a}) + \\ + &= e^{- i \vec{k} \cdot \vec{r}} e^{- i \vec{k} \cdot \vec{a}} e^{i \vec{k} \cdot \vec{a}} \:\psi(\vec{r}) + \\ + &= e^{- i \vec{k} \cdot \vec{r}} \:\psi(\vec{r}) + \\ + &= u(\vec{r}) +\end{aligned} +$$ + +Then Bloch's theorem follows from +isolating the definition of $u(\vec{r})$ for $\psi(\vec{r})$. diff --git a/content/know/concept/convolution-theorem/index.pdc b/content/know/concept/convolution-theorem/index.pdc new file mode 100644 index 0000000..fc96f30 --- /dev/null +++ b/content/know/concept/convolution-theorem/index.pdc @@ -0,0 +1,100 @@ +--- +title: "Convolution theorem" +firstLetter: "C" +publishDate: 2021-02-22 +categories: +- Mathematics + +date: 2021-02-22T21:35:23+01:00 +draft: false +markup: pandoc +--- + +# Convolution theorem + +The **convolution theorem** states that a convolution in the direct domain +is equal to a product in the frequency domain. This is especially useful +for computation, replacing an $\mathcal{O}(n^2)$ convolution with an +$\mathcal{O}(n \log(n))$ transform and product. + +## Fourier transform + +The convolution theorem is usually expressed as follows, where +$\hat{\mathcal{F}}$ is the [Fourier transform](/know/concept/fourier-transform/), +and $A$ and $B$ are constants from its definition: + +$$\begin{aligned} + \boxed{ + \begin{aligned} + A \cdot (f * g)(x) &= \hat{\mathcal{F}}^{-1}\{\tilde{f}(k) \: \tilde{g}(k)\} \\ + B \cdot (\tilde{f} * \tilde{g})(k) &= \hat{\mathcal{F}}\{f(x) \: g(x)\} + \end{aligned} + } +\end{aligned}$$ + +To prove this, we expand the right-hand side of the theorem and +rearrange the integrals: + +$$\begin{aligned} + \hat{\mathcal{F}}^{-1}\{\tilde{f}(k) \: \tilde{g}(k)\} + &= B \int_{-\infty}^\infty \tilde{f}(k) \Big( A \int_{-\infty}^\infty g(x') \exp(i s k x') \dd{x'} \Big) \exp(-i s k x) \dd{k} + \\ + &= A \int_{-\infty}^\infty g(x') \Big( B \int_{-\infty}^\infty \tilde{f}(k) \exp(- i s k (x - x')) \dd{k} \Big) \dd{x'} + \\ + &= A \int_{-\infty}^\infty g(x') f(x - x') \dd{x'} + = A \cdot (f * g)(x) +\end{aligned}$$ + +Then we do the same thing again, this time starting from a product in +the $x$-domain: + +$$\begin{aligned} + \hat{\mathcal{F}}\{f(x) \: g(x)\} + &= A \int_{-\infty}^\infty f(x) \Big( B \int_{-\infty}^\infty \tilde{g}(k') \exp(- i s x k') \dd{k'} \Big) \exp(i s k x) \dd{x} + \\ + &= B \int_{-\infty}^\infty \tilde{g}(k') \Big( A \int_{-\infty}^\infty f(x) \exp(i s x (k - k')) \dd{x} \Big) \dd{k'} + \\ + &= B \int_{-\infty}^\infty \tilde{g}(k') \tilde{f}(k - k') \dd{k'} + = B \cdot (\tilde{f} * \tilde{g})(k) +\end{aligned}$$ + + +## Laplace transform + +For functions $f(t)$ and $g(t)$ which are only defined for $t \ge 0$, +the convolution theorem can also be stated using the Laplace transform: + +$$\begin{aligned} + \boxed{(f * g)(t) = \hat{\mathcal{L}}^{-1}\{\tilde{f}(s) \: \tilde{g}(s)\}} +\end{aligned}$$ + +Because the inverse Laplace transform $\hat{\mathcal{L}}^{-1}$ is quite +unpleasant, the theorem is often stated using the forward transform +instead: + +$$\begin{aligned} + \boxed{\hat{\mathcal{L}}\{(f * g)(t)\} = \tilde{f}(s) \: \tilde{g}(s)} +\end{aligned}$$ + +We prove this by expanding the left-hand side. Note that the lower +integration limit is 0 instead of $-\infty$, because we set both $f(t)$ +and $g(t)$ to zero for $t < 0$: + +$$\begin{aligned} + \hat{\mathcal{L}}\{(f * g)(t)\} + &= \int_0^\infty \Big( \int_0^\infty g(t') f(t - t') \dd{t'} \Big) \exp(- s t) \dd{t} + \\ + &= \int_0^\infty \Big( \int_0^\infty f(t - t') \exp(- s t) \dd{t} \Big) g(t') \dd{t'} +\end{aligned}$$ + +Then we define a new integration variable $\tau = t - t'$, yielding: + +$$\begin{aligned} + \hat{\mathcal{L}}\{(f * g)(t)\} + &= \int_0^\infty \Big( \int_0^\infty f(\tau) \exp(- s (\tau + t')) \dd{\tau} \Big) g(t') \dd{t'} + \\ + &= \int_0^\infty \Big( \int_0^\infty f(\tau) \exp(- s \tau) \dd{\tau} \Big) g(t') \exp(- s t') \dd{t'} + \\ + &= \int_0^\infty \tilde{f}(s) g(t') \exp(- s t') \dd{t'} + = \tilde{f}(s) \: \tilde{g}(s) +\end{aligned}$$ diff --git a/content/know/concept/dirac-delta-function/index.pdc b/content/know/concept/dirac-delta-function/index.pdc new file mode 100644 index 0000000..3982afc --- /dev/null +++ b/content/know/concept/dirac-delta-function/index.pdc @@ -0,0 +1,109 @@ +--- +title: "Dirac delta function" +firstLetter: "D" +publishDate: 2021-02-22 +categories: +- Mathematics +- Physics + +date: 2021-02-22T21:35:38+01:00 +draft: false +markup: pandoc +--- + +# Dirac delta function + +The **Dirac delta function** $\delta(x)$, often just called the **delta function**, +is an infinitely narrow discontinuous "spike" at $x = 0$ whose area is +defined to be 1: + +$$\begin{aligned} + \boxed{ + \delta(x) = + \begin{cases} + +\infty & \mathrm{if}\: x = 0 \\ + 0 & \mathrm{if}\: x \neq 0 + \end{cases} + \quad \mathrm{and} \quad + \int_{-\varepsilon}^\varepsilon \delta(x) \dd{x} = 1 + } +\end{aligned}$$ + +It is sometimes also called the **sampling function**, due to its most +important property: the so-called **sampling property**: + +$$\begin{aligned} + \boxed{ + \int f(x) \: \delta(x - x_0) \: dx = \int f(x) \: \delta(x_0 - x) \: dx = f(x_0) + } +\end{aligned}$$ + +$\delta(x)$ is thus an effective weapon against integrals. This may not seem very +useful due to its "unnatural" definition, but in fact it appears as the +limit of several reasonable functions: + +$$\begin{aligned} + \delta(x) + = \lim_{n \to +\infty} \!\Big\{ \frac{n}{\sqrt{\pi}} \exp(- n^2 x^2) \Big\} + = \lim_{n \to +\infty} \!\Big\{ \frac{n}{\pi} \frac{1}{1 + n^2 x^2} \Big\} + = \lim_{n \to +\infty} \!\Big\{ \frac{\sin(n x)}{\pi x} \Big\} +\end{aligned}$$ + +The last one is especially important, since it is equivalent to the +following integral, which appears very often in the context of +[Fourier transforms](/know/concept/fourier-transform/): + +$$\begin{aligned} + \boxed{ + \delta(x) + %= \lim_{n \to +\infty} \!\Big\{\frac{\sin(n x)}{\pi x}\Big\} + = \frac{1}{2\pi} \int_{-\infty}^\infty \exp(i k x) \dd{k} + \:\:\propto\:\: \hat{\mathcal{F}}\{1\} + } +\end{aligned}$$ + +When the argument of $\delta(x)$ is scaled, the delta function is itself scaled: + +$$\begin{aligned} + \boxed{ + \delta(s x) = \frac{1}{|s|} \delta(x) + } +\end{aligned}$$ + +*__Proof.__ Because it is symmetric, $\delta(s x) = \delta(|s| x)$. Then by +substituting $\sigma = |s| x$:* + +$$\begin{aligned} + \int \delta(|s| x) \dd{x} + &= \frac{1}{|s|} \int \delta(\sigma) \dd{\sigma} = \frac{1}{|s|} +\end{aligned}$$ + +*__Q.E.D.__* + +An even more impressive property is the behaviour of the derivative of +$\delta(x)$: + +$$\begin{aligned} + \boxed{ + \int f(\xi) \: \delta'(x - \xi) \dd{\xi} = f'(x) + } +\end{aligned}$$ + +*__Proof.__ Note which variable is used for the +differentiation, and that $\delta'(x - \xi) = - \delta'(\xi - x)$:* + +$$\begin{aligned} + \int f(\xi) \: \dv{\delta(x - \xi)}{x} \dd{\xi} + &= \dv{x} \int f(\xi) \: \delta(x - \xi) \dd{x} + = f'(x) +\end{aligned}$$ + +*__Q.E.D.__* + +This property also generalizes nicely for the higher-order derivatives: + +$$\begin{aligned} + \boxed{ + \int f(\xi) \: \dv[n]{\delta(x - \xi)}{x} \dd{\xi} = \dv[n]{f(x)}{x} + } +\end{aligned}$$ diff --git a/content/know/concept/dirac-notation/index.pdc b/content/know/concept/dirac-notation/index.pdc new file mode 100644 index 0000000..f624574 --- /dev/null +++ b/content/know/concept/dirac-notation/index.pdc @@ -0,0 +1,129 @@ +--- +title: "Dirac notation" +firstLetter: "D" +publishDate: 2021-02-22 +categories: +- Quantum mechanics +- Physics + +date: 2021-02-22T21:35:46+01:00 +draft: false +markup: pandoc +--- + +# Dirac notation + +**Dirac notation** is a notation to do calculations in a Hilbert space +without needing to worry about the space's representation. It is +basically the *lingua franca* of quantum mechanics. + +In Dirac notation there are **kets** $\ket{V}$ from the Hilbert space +$\mathbb{H}$ and **bras** $\bra{V}$ from a dual $\mathbb{H}'$ of the +former. Crucially, the bras and kets are from different Hilbert spaces +and therefore cannot be added, but every bra has a corresponding ket and +vice versa. + +Bras and kets can be combined in two ways: the **inner product** +$\braket{V}{W}$, which returns a scalar, and the **outer product** +$\ket{V} \bra{W}$, which returns a mapping $\hat{L}$ from kets $\ket{V}$ +to other kets $\ket{V'}$, i.e. a linear operator. Recall that the +Hilbert inner product must satisfy: + +$$\begin{aligned} + \braket{V}{W} = \braket{W}{V}^* +\end{aligned}$$ + +So far, nothing has been said about the actual representation of bras or +kets. If we represent kets as $N$-dimensional columns vectors, the +corresponding bras are given by the kets' adjoints, i.e. their transpose +conjugates: + +$$\begin{aligned} + \ket{V} = + \begin{bmatrix} + v_1 \\ \vdots \\ v_N + \end{bmatrix} + \quad \implies \quad + \bra{V} = + \begin{bmatrix} + v_1^* & \cdots & v_N^* + \end{bmatrix} +\end{aligned}$$ + +The inner product $\braket{V}{W}$ is then just the familiar dot product $V \cdot W$: + +$$\begin{gathered} + \braket{V}{W} + = + \begin{bmatrix} + v_1^* & \cdots & v_N^* + \end{bmatrix} + \cdot + \begin{bmatrix} + w_1 \\ \vdots \\ w_N + \end{bmatrix} + = v_1^* w_1 + ... + v_N^* w_N +\end{gathered}$$ + +Meanwhile, the outer product $\ket{V} \bra{W}$ creates an $N \cross N$ matrix: + +$$\begin{gathered} + \ket{V} \bra{W} + = + \begin{bmatrix} + v_1 \\ \vdots \\ v_N + \end{bmatrix} + \cdot + \begin{bmatrix} + w_1^* & \cdots & w_N^* + \end{bmatrix} + = + \begin{bmatrix} + v_1 w_1^* & \cdots & v_1 w_N^* \\ + \vdots & \ddots & \vdots \\ + v_N w_1^* & \cdots & v_N w_N^* + \end{bmatrix} +\end{gathered}$$ + +If the kets are instead represented by functions $f(x)$ of +$x \in [a, b]$, then the bras represent *functionals* $F[u(x)]$ which +take an unknown function $u(x)$ as an argument and turn it into a scalar +using integration: + +$$\begin{aligned} + \ket{f} = f(x) + \quad \implies \quad + \bra{f} + = F[u(x)] + = \int_a^b f^*(x) \: u(x) \dd{x} +\end{aligned}$$ + +Consequently, the inner product is simply the following familiar integral: + +$$\begin{gathered} + \braket{f}{g} + = F[g(x)] + = \int_a^b f^*(x) \: g(x) \dd{x} +\end{gathered}$$ + +However, the outer product becomes something rather abstract: + +$$\begin{gathered} + \ket{f} \bra{g} + = f(x) \: G[u(x)] + = f(x) \int_a^b g^*(\xi) \: u(\xi) \dd{\xi} +\end{gathered}$$ + +This result makes more sense if we surround it by a bra and a ket: + +$$\begin{aligned} + \bra{u} \!\Big(\!\ket{f} \bra{g}\!\Big)\! \ket{w} + &= U\big[f(x) \: G[w(x)]\big] + = U\Big[ f(x) \int_a^b g^*(\xi) \: w(\xi) \dd{\xi} \Big] + \\ + &= \int_a^b u^*(x) \: f(x) \: \Big(\int_a^b g^*(\xi) \: w(\xi) \dd{\xi} \Big) \dd{x} + \\ + &= \Big( \int_a^b u^*(x) \: f(x) \dd{x} \Big) \Big( \int_a^b g^*(\xi) \: w(\xi) \dd{\xi} \Big) + \\ + &= \braket{u}{f} \braket{g}{w} +\end{aligned}$$ diff --git a/content/know/concept/fourier-transform/index.pdc b/content/know/concept/fourier-transform/index.pdc new file mode 100644 index 0000000..6d8901a --- /dev/null +++ b/content/know/concept/fourier-transform/index.pdc @@ -0,0 +1,117 @@ +--- +title: "Fourier transform" +firstLetter: "F" +publishDate: 2021-02-22 +categories: +- Mathematics +- Physics + +date: 2021-02-22T21:35:54+01:00 +draft: false +markup: pandoc +--- + +# Fourier transform + +The **Fourier transform** (FT) is an integral transform which converts a +function $f(x)$ into its frequency representation $\tilde{f}(k)$. +Great volumes have already been written about this subject, +so let us focus on the aspects that are useful to physicists. + +The **forward** FT is defined as follows, where $A$, $B$, and $s$ are unspecified constants +(for now): + +$$\begin{aligned} + \boxed{ + \tilde{f}(k) + = \hat{\mathcal{F}}\{f(x)\} + = A \int_{-\infty}^\infty f(x) \exp(i s k x) \dd{x} + } +\end{aligned}$$ + +The **inverse Fourier transform** (iFT) undoes the forward FT operation: + +$$\begin{aligned} + \boxed{ + f(x) + = \hat{\mathcal{F}}^{-1}\{\tilde{f}(k)\} + = B \int_{-\infty}^\infty \tilde{f}(k) \exp(- i s k x) \dd{k} + } +\end{aligned}$$ + +Clearly, the inverse FT of the forward FT of $f(x)$ must equal $f(x)$ +again. Let us verify this, by rearranging the integrals to get the +[Dirac delta function](/know/concept/dirac-delta-function/) $\delta(x)$: + +$$\begin{aligned} + \hat{\mathcal{F}}^{-1}\{\hat{\mathcal{F}}\{f(x)\}\} + &= A B \int_{-\infty}^\infty \exp(-i s k x) \int_{-\infty}^\infty f(x') \exp(i s k x') \dd{x'} \dd{k} + \\ + &= 2 \pi A B \int_{-\infty}^\infty f(x') \Big(\frac{1}{2\pi} \int_{-\infty}^\infty \exp(i s k (x' - x)) \dd{k} \Big) \dd{x'} + \\ + &= 2 \pi A B \int_{-\infty}^\infty f(x') \: \delta(s(x' - x)) \dd{x'} + = \frac{2 \pi A B}{|s|} f(x) +\end{aligned}$$ + +Therefore, the constants $A$, $B$, and $s$ are subject to the following +constraint: + +$$\begin{aligned} + \boxed{\frac{2\pi A B}{|s|} = 1} +\end{aligned}$$ + +But that still gives a lot of freedom. The exact choices of $A$ and $B$ +are generally motivated by the [convolution theorem](/know/concept/convolution-theorem/) +and [Parseval's theorem](/know/concept/parsevals-theorem/). + +The choice of $|s|$ depends on whether the frequency variable $k$ +represents the angular ($|s| = 1$) or the physical ($|s| = 2\pi$) +frequency. The sign of $s$ is not so important, but is generally based +on whether the analysis is for forward ($s > 0$) or backward-propagating +($s < 0$) waves. + + +## Derivatives + +The FT of a derivative has a very interesting property. +Below, after integrating by parts, we remove the boundary term by +assuming that $f(x)$ is localized, i.e. $f(x) \to 0$ for $x \to \pm \infty$: + +$$\begin{aligned} + \hat{\mathcal{F}}\{f'(x)\} + &= A \int_{-\infty}^\infty f'(x) \exp(i s k x) \dd{x} + \\ + &= A \big[ f(x) \exp(i s k x) \big]_{-\infty}^\infty - i s k A \int_{-\infty}^\infty f(x) \exp(i s k x) \dd{x} + \\ + &= (- i s k) \tilde{f}(k) +\end{aligned}$$ + +Therefore, as long as $f(x)$ is localized, the FT eliminates derivatives +of the transformed variable, which makes it useful against PDEs: + +$$\begin{aligned} + \boxed{ + \hat{\mathcal{F}}\{f'(x)\} = (- i s k) \tilde{f}(k) + } +\end{aligned}$$ + +This generalizes to higher-order derivatives, as long as these +derivatives are also localized in the $x$-domain, which is practically +guaranteed if $f(x)$ itself is localized: + +$$\begin{aligned} + \boxed{ + \hat{\mathcal{F}} \Big\{ \dv[n]{f}{x} \Big\} + = (- i s k)^n \tilde{f}(k) + } +\end{aligned}$$ + +Derivatives in the frequency domain have an analogous property: + +$$\begin{aligned} + \boxed{ + \dv[n]{\tilde{f}}{k} + = A \int_{-\infty}^\infty (i s x)^n f(x) \exp(i s k x) \dd{x} + = \hat{\mathcal{F}}\{ (i s x)^n f(x) \} + } +\end{aligned}$$ diff --git a/content/know/concept/gram-schmidt-method/index.pdc b/content/know/concept/gram-schmidt-method/index.pdc new file mode 100644 index 0000000..88488dd --- /dev/null +++ b/content/know/concept/gram-schmidt-method/index.pdc @@ -0,0 +1,47 @@ +--- +title: "Gram-Schmidt method" +firstLetter: "G" +publishDate: 2021-02-22 +categories: +- Mathematics + +date: 2021-02-22T21:36:08+01:00 +draft: false +markup: pandoc +--- + +# Gram-Schmidt method + +Given a set of linearly independent non-orthonormal vectors +$\ket*{V_1}, \ket*{V_2}, ...$ from a [Hilbert space](/know/concept/hilbert-space/), +the **Gram-Schmidt method** +turns them into an orthonormal set $\ket*{n_1}, \ket*{n_2}, ...$ as follows: + +1. Take the first vector $\ket*{V_1}$ and normalize it to get $\ket*{n_1}$: + + $$\begin{aligned} + \ket*{n_1} = \frac{\ket*{V_1}}{\sqrt{\braket*{V_1}{V_1}}} + \end{aligned}$$ + +2. Begin loop. Take the next non-orthonormal vector $\ket*{V_j}$, and + subtract from it its projection onto every already-processed vector: + + $$\begin{aligned} + \ket*{n_j'} = \ket*{V_j} - \ket*{n_1} \braket*{n_1}{V_j} - \ket*{n_2} \braket*{n_2}{V_j} - ... - \ket*{n_{j-1}} \braket*{n_{j-1}}{V_{j-1}} + \end{aligned}$$ + + This leaves only the part of $\ket*{V_j}$ which is orthogonal to + $\ket*{n_1}$, $\ket*{n_2}$, etc. This why the input vectors must be + linearly independent; otherwise $\ket{n_j'}$ may become zero at some + point. + +3. Normalize the resulting ortho*gonal* vector $\ket*{n_j'}$ to make it + ortho*normal*: + + $$\begin{aligned} + \ket*{n_j} = \frac{\ket*{n_j'}}{\sqrt{\braket*{n_j'}{n_j'}}} + \end{aligned}$$ + +4. Loop back to step 2, taking the next vector $\ket*{V_{j+1}}$. + +If you are unfamiliar with this notation, take a look at [Dirac notation](/know/concept/dirac-notation/). diff --git a/content/know/concept/hilbert-space/index.pdc b/content/know/concept/hilbert-space/index.pdc new file mode 100644 index 0000000..1faf08a --- /dev/null +++ b/content/know/concept/hilbert-space/index.pdc @@ -0,0 +1,202 @@ +--- +title: "Hilbert space" +firstLetter: "H" +publishDate: 2021-02-22 +categories: +- Mathematics +- Quantum mechanics + +date: 2021-02-22T21:36:24+01:00 +draft: false +markup: pandoc +--- + +# Hilbert space + +A **Hilbert space**, also known as an **inner product space**, is an +abstract **vector space** with a notion of length and angle. + + +## Vector space + +An abstract **vector space** $\mathbb{V}$ is a generalization of the +traditional concept of vectors as "arrows". It consists of a set of +objects called **vectors** which support the following (familiar) +operations: + ++ **Vector addition**: the sum of two vectors $V$ and $W$, denoted $V + W$. ++ **Scalar multiplication**: product of a vector $V$ with a scalar $a$, denoted $a V$. + +In addition, for a given $\mathbb{V}$ to qualify as a proper vector +space, these operations must obey the following axioms: + ++ **Addition is associative**: $U + (V + W) = (U + V) + W$ ++ **Addition is commutative**: $U + V = V + U$ ++ **Addition has an identity**: there exists a $\mathbf{0}$ such that $V + 0 = V$ ++ **Addition has an inverse**: for every $V$ there exists $-V$ so that $V + (-V) = 0$ ++ **Multiplication is associative**: $a (b V) = (a b) V$ ++ **Multiplication has an identity**: There exists a $1$ such that $1 V = V$ ++ **Multiplication is distributive over scalars**: $(a + b)V = aV + bV$ ++ **Multiplication is distributive over vectors**: $a (U + V) = a U + a V$ + +A set of $N$ vectors $V_1, V_2, ..., V_N$ is **linearly independent** if +the only way to satisfy the following relation is to set all the scalar coefficients $a_n = 0$: + +$$\begin{aligned} + \mathbf{0} = \sum_{n = 1}^N a_n V_n +\end{aligned}$$ + +In other words, these vectors cannot be expressed in terms of each +other. Otherwise, they would be **linearly dependent**. + +A vector space $\mathbb{V}$ has **dimension** $N$ if only up to $N$ of +its vectors can be linearly indepedent. All other vectors in +$\mathbb{V}$ can then be written as a **linear combination** of these $N$ **basis vectors**. + +Let $\vu{e}_1, ..., \vu{e}_N$ be the basis vectors, then any +vector $V$ in the same space can be **expanded** in the basis according to +the unique weights $v_n$, known as the **components** of $V$ +in that basis: + +$$\begin{aligned} + V = \sum_{n = 1}^N v_n \vu{e}_n +\end{aligned}$$ + +Using these, the vector space operations can then be implemented as follows: + +$$\begin{gathered} + V = \sum_{n = 1} v_n \vu{e}_n + \quad + W = \sum_{n = 1} w_n \vu{e}_n + \\ + \quad \implies \quad + V + W = \sum_{n = 1}^N (v_n + w_n) \vu{e}_n + \qquad + a V = \sum_{n = 1}^N a v_n \vu{e}_n +\end{gathered}$$ + + +## Inner product + +A given vector space $\mathbb{V}$ can be promoted to a **Hilbert space** +or **inner product space** if it supports an operation $\braket{U}{V}$ +called the **inner product**, which takes two vectors and returns a +scalar, and has the following properties: + ++ **Skew symmetry**: $\braket{U}{V} = (\braket{V}{U})^*$, where ${}^*$ is the complex conjugate. ++ **Positive semidefiniteness**: $\braket{V}{V} \ge 0$, and $\braket{V}{V} = 0$ if $V = \mathbf{0}$. ++ **Linearity in second operand**: $\braket{U}{(a V + b W)} = a \braket{U}{V} + b \braket{U}{W}$. + +The inner product describes the lengths and angles of vectors, and in +Euclidean space it is implemented by the dot product. + +The **magnitude** or **norm** $|V|$ of a vector $V$ is given by +$|V| = \sqrt{\braket{V}{V}}$ and represents the real positive length of $V$. +A **unit vector** has a norm of 1. + +Two vectors $U$ and $V$ are **orthogonal** if their inner product +$\braket{U}{V} = 0$. If in addition to being orthogonal, $|U| = 1$ and +$|V| = 1$, then $U$ and $V$ are known as **orthonormal** vectors. + +Orthonormality is desirable for basis vectors, so if they are +not already like that, it is common to manually turn them into a new +orthonormal basis using e.g. the [Gram-Schmidt method](/know/concept/gram-schmidt-method). + +As for the implementation of the inner product, it is given by: + +$$\begin{gathered} + V = \sum_{n = 1}^N v_n \vu{e}_n + \quad + W = \sum_{n = 1}^N w_n \vu{e}_n + \\ + \quad \implies \quad + \braket{V}{W} = \sum_{n = 1}^N \sum_{m = 1}^N v_n^* w_m \braket{\vu{e}_n}{\vu{e}_j} +\end{gathered}$$ + +If the basis vectors $\vu{e}_1, ..., \vu{e}_N$ are already +orthonormal, this reduces to: + +$$\begin{aligned} + \braket{V}{W} = \sum_{n = 1}^N v_n^* w_n +\end{aligned}$$ + +As it turns out, the components $v_n$ are given by the inner product +with $\vu{e}_n$, where $\delta_{nm}$ is the Kronecker delta: + +$$\begin{aligned} + \braket{\vu{e}_n}{V} = \sum_{m = 1}^N \delta_{nm} v_m = v_n +\end{aligned}$$ + + +## Infinite dimensions + +As the dimensionality $N$ tends to infinity, things may or may not +change significantly, depending on whether $N$ is **countably** or +**uncountably** infinite. + +In the former case, not much changes: the infinitely many **discrete** +basis vectors $\vu{e}_n$ can all still be made orthonormal as usual, +and as before: + +$$\begin{aligned} + V = \sum_{n = 1}^\infty v_n \vu{e}_n +\end{aligned}$$ + +A good example of such a countably-infinitely-dimensional basis are the +solution eigenfunctions of a [Sturm-Liouville problem](/know/concept/sturm-liouville-theory/). + +However, if the dimensionality is uncountably infinite, the basis +vectors are **continuous** and cannot be labeled by $n$. For example, all +complex functions $f(x)$ defined for $x \in [a, b]$ which +satisfy $f(a) = f(b) = 0$ form such a vector space. +In this case $f(x)$ is expanded as follows, where $x$ is a basis vector: + +$$\begin{aligned} + f(x) = \int_a^b \braket{x}{f} \dd{x} +\end{aligned}$$ + +Similarly, the inner product $\braket{f}{g}$ must also be redefined as +follows: + +$$\begin{aligned} + \braket{f}{g} = \int_a^b f^*(x) \: g(x) \dd{x} +\end{aligned}$$ + +The concept of orthonormality must be also weakened. A finite function +$f(x)$ can be normalized as usual, but the basis vectors $x$ themselves +cannot, since each represents an infinitesimal section of the real line. + +The rationale in this case is that action of the identity operator $\hat{I}$ must +be preserved, which is given here in [Dirac notation](/know/concept/dirac-notation/): + +$$\begin{aligned} + \hat{I} = \int_a^b \ket{\xi} \bra{\xi} \dd{\xi} +\end{aligned}$$ + +Applying the identity operator to $f(x)$ should just give $f(x)$ again: + +$$\begin{aligned} + f(x) = \braket{x}{f} = \matrixel{x}{\hat{I}}{f} + = \int_a^b \braket{x}{\xi} \braket{\xi}{f} \dd{\xi} + = \int_a^b \braket{x}{\xi} f(\xi) \dd{\xi} +\end{aligned}$$ + +Since we want the latter integral to reduce to $f(x)$, it is plain to see that +$\braket{x}{\xi}$ can only be a [Dirac delta function](/know/concept/dirac-delta-function/), +i.e $\braket{x}{\xi} = \delta(x - \xi)$: + +$$\begin{aligned} + \int_a^b \braket{x}{\xi} f(\xi) \dd{\xi} + = \int_a^b \delta(x - \xi) f(\xi) \dd{\xi} + = f(x) +\end{aligned}$$ + +Consequently, $\braket{x}{\xi} = 0$ if $x \neq \xi$ as expected for an +orthogonal set of basis vectors, but if $x = \xi$ the inner product +$\braket{x}{\xi}$ is infinite, unlike earlier. + +Technically, because the basis vectors $x$ cannot be normalized, they +are not members of a Hilbert space, but rather of a superset called a +**rigged Hilbert space**. Such vectors have no finite inner product with +themselves, but do have one with all vectors from the actual Hilbert +space. diff --git a/content/know/concept/legendre-transform/index.pdc b/content/know/concept/legendre-transform/index.pdc new file mode 100644 index 0000000..8a0d3e3 --- /dev/null +++ b/content/know/concept/legendre-transform/index.pdc @@ -0,0 +1,89 @@ +--- +title: "Legendre transform" +firstLetter: "L" +publishDate: 2021-02-22 +categories: +- Mathematics +- Physics + +date: 2021-02-22T21:36:35+01:00 +draft: false +markup: pandoc +--- + +# Legendre transform + +The **Legendre transform** of a function $f(x)$ is a new function $L(f')$, +which depends only on the derivative $f'(x)$ of $f(x)$, and from which +the original function $f(x)$ can be reconstructed. The point is, +analogously to other transforms (e.g. [Fourier](/know/concept/fourier-transform/)), +that $L(f')$ contains the same information as $f(x)$, just in a different form. + +Let us choose an arbitrary point $x_0 \in [a, b]$ in the domain of +$f(x)$. Consider a line $y(x)$ tangent to $f(x)$ at $x = x_0$, which has +a slope $f'(x_0)$ and intersects the $y$-axis at $-C$: + +$$\begin{aligned} + y(x) = f'(x_0) (x - x_0) + f(x_0) = f'(x_0) x - C +\end{aligned}$$ + +The Legendre transform $L(f')$ is defined such that $L(f'(x_0)) = C$ (or +sometimes $-C$ instead) for all $x_0 \in [a, b]$, where $C$ is the +constant corresponding to the tangent line at $x = x_0$. This yields: + +$$\begin{aligned} + L(f'(x)) = f'(x) \: x - f(x) +\end{aligned}$$ + +We want this function to depend only on the derivative $f'$, but +currently $x$ still appears here as a variable. We fix that problem in +the easiest possible way: by assuming that $f'(x)$ is invertible for all +$x \in [a, b]$. If $x(f')$ is the inverse of $f'(x)$, then $L(f')$ is +given by: + +$$\begin{aligned} + \boxed{ + L(f') = f' \: x(f') - f(x(f')) + } +\end{aligned}$$ + +The only requirement for the existence of the Legendre transform is thus +the invertibility of $f'(x)$ in the target interval $[a,b]$, which can +only be true if $f(x)$ is either convex or concave, i.e. its derivative +$f'(x)$ is monotonic. + +Crucially, the derivative of $L(f')$ with respect to $f'$ is simply +$x(f')$. In other words, the roles of $f'$ and $x$ are switched by the +transformation: the coordinate becomes the derivative and vice versa. +This is demonstrated here: + +$$\begin{aligned} + \boxed{ + \dv{L}{f'} = \dv{x}{f'} \: f' + x(f') - \dv{f}{x} \dv{x}{f'} = x(f') + } +\end{aligned}$$ + +Furthermore, Legendre transformation is an *involution*, meaning it is +its own inverse. Let $g(L')$ be the Legendre transform of $L(f')$: + +$$\begin{aligned} + g(L') = L' \: f'(L') - L(f'(L')) + = x(f') \: f' - f' \: x(f') + f(x(f')) = f(x) +\end{aligned}$$ + +Moreover, the inverse of a (forward) transform always exists, because +the Legendre transform of a convex function is itself convex. Convexity +of $f(x)$ means that $f''(x) > 0$ for all $x \in [a, b]$, which yields +the following proof: + +$$\begin{aligned} + L''(f') + = \dv{x(f')}{f'} + = \dv{x}{f'(x)} + = \frac{1}{f''(x)} + > 0 +\end{aligned}$$ + +Legendre transformation is important in physics, +since it connects Lagrangian and Hamiltonian mechanics to each other. +It is also used to convert between thermodynamic potentials. diff --git a/content/know/concept/parsevals-theorem/index.pdc b/content/know/concept/parsevals-theorem/index.pdc new file mode 100644 index 0000000..8f653f8 --- /dev/null +++ b/content/know/concept/parsevals-theorem/index.pdc @@ -0,0 +1,76 @@ +--- +title: "Parseval's theorem" +firstLetter: "P" +publishDate: 2021-02-22 +categories: +- Mathematics +- Physics + +date: 2021-02-22T21:36:44+01:00 +draft: false +markup: pandoc +--- + +# Parseval's theorem + +**Parseval's theorem** relates the inner product of two functions $f(x)$ and $g(x)$ to the +inner product of their [Fourier transforms](/know/concept/fourier-transform/) +$\tilde{f}(k)$ and $\tilde{g}(k)$. +There are two equivalent ways of stating it, +where $A$, $B$, and $s$ are constants from the Fourier transform's definition: + +$$\begin{aligned} + \boxed{ + \braket{f(x)}{g(x)} = \frac{2 \pi B^2}{|s|} \braket*{\tilde{f}(k)}{\tilde{g}(k)} + } + \\ + \boxed{ + \braket*{\tilde{f}(k)}{\tilde{g}(k)} = \frac{2 \pi A^2}{|s|} \braket{f(x)}{g(x)} + } +\end{aligned}$$ + +For this reason, physicists like to define their Fourier transform +with $A = B = 1 / \sqrt{2\pi}$ and $|s| = 1$, because then the FT nicely +conserves the total probability (quantum mechanics) or the total energy +(optics). + +To prove this, we insert the inverse FT into the inner product +definition: + +$$\begin{aligned} + \braket{f}{g} + &= \int_{-\infty}^\infty \big( \hat{\mathcal{F}}^{-1}\{\tilde{f}(k)\}\big)^* \: \hat{\mathcal{F}}^{-1}\{\tilde{g}(k)\} \dd{x} + \\ + &= B^2 \int + \Big( \int \tilde{f}^*(k_1) \exp(i s k_1 x) \dd{k_1} \Big) + \Big( \int \tilde{g}(k) \exp(- i s k x) \dd{k} \Big) + \dd{x} + \\ + &= 2 \pi B^2 \iint \tilde{f}^*(k_1) \tilde{g}(k) \Big( \frac{1}{2 \pi} \int_{-\infty}^\infty \exp(i s x (k_1 - k)) \dd{x} \Big) \dd{k_1} \dd{k} + \\ + &= 2 \pi B^2 \iint \tilde{f}^*(k_1) \: \tilde{g}(k) \: \delta(s (k_1 - k)) \dd{k_1} \dd{k} + \\ + &= \frac{2 \pi B^2}{|s|} \int_{-\infty}^\infty \tilde{f}^*(k) \: \tilde{g}(k) \dd{k} + = \frac{2 \pi B^2}{|s|} \braket*{\tilde{f}}{\tilde{g}} +\end{aligned}$$ + +Where $\delta(k)$ is the [Dirac delta function](/know/concept/dirac-delta-function/). +Note that we can just as well do it in the opposite direction, +which yields an equivalent result: + +$$\begin{aligned} + \braket*{\tilde{f}}{\tilde{g}} + &= \int_{-\infty}^\infty \big( \hat{\mathcal{F}}\{f(x)\}\big)^* \: \hat{\mathcal{F}}\{g(x)\} \dd{k} + \\ + &= A^2 \int + \Big( \int f^*(x_1) \exp(- i s k x_1) \dd{x_1} \Big) + \Big( \int g(x) \exp(i s k x) \dd{x} \Big) + \dd{k} + \\ + &= 2 \pi A^2 \iint f^*(x_1) g(x) \Big( \frac{1}{2 \pi} \int_{-\infty}^\infty \exp(i s k (x_1 - x)) \dd{k} \Big) \dd{x_1} \dd{x} + \\ + &= 2 \pi A^2 \iint f^*(x_1) \: g(x) \: \delta(s (x_1 - x)) \dd{x_1} \dd{x} + \\ + &= \frac{2 \pi A^2}{|s|} \int_{-\infty}^\infty f^*(x) \: g(x) \dd{x} + = \frac{2 \pi A^2}{|s|} \braket{f}{g} +\end{aligned}$$ diff --git a/content/know/concept/partial-fraction-decomposition/index.pdc b/content/know/concept/partial-fraction-decomposition/index.pdc new file mode 100644 index 0000000..1f4207f --- /dev/null +++ b/content/know/concept/partial-fraction-decomposition/index.pdc @@ -0,0 +1,60 @@ +--- +title: "Partial fraction decomposition" +firstLetter: "P" +publishDate: 2021-02-22 +categories: +- Mathematics + +date: 2021-02-22T21:36:56+01:00 +draft: false +markup: pandoc +--- + +# Partial fraction decomposition + +**Partial fraction decomposition** or **expansion** is a method to rewrite a +quotient of two polynomials $g(x)$ and $h(x)$, where the numerator +$g(x)$ is of lower order than $h(x)$, as a sum of fractions with $x$ in +the denominator: + +$$\begin{aligned} + f(x) = \frac{g(x)}{h(x)} = \frac{c_1}{x - h_1} + \frac{c_2}{x - h_2} + ... +\end{aligned}$$ + +Where $h_n$ etc. are the roots of the denominator $h(x)$. If all $N$ of +these roots are distinct, then it is sufficient to simply posit: + +$$\begin{aligned} + \boxed{ + f(x) = \frac{c_1}{x - h_1} + \frac{c_2}{x - h_2} + ... + \frac{c_N}{x - h_N} + } +\end{aligned}$$ + +The constants $c_n$ can either be found the hard way, +by multiplying the denominators around and solving a system of $N$ +equations, or the easy way by using this trick: + +$$\begin{aligned} + \boxed{ + c_n = \lim_{x \to h_n} \big( f(x) (x - h_n) \big) + } +\end{aligned}$$ + +If $h_1$ is a root with multiplicity $m > 1$, then the sum takes the form of: + +$$\begin{aligned} + \boxed{ + f(x) + = \frac{c_{1,1}}{x - h_1} + \frac{c_{1,2}}{(x - h_1)^2} + ... + } +\end{aligned}$$ + +Where $c_{1,j}$ are found by putting the terms on a common denominator, e.g. + +$$\begin{aligned} + \frac{c_{1,1}}{x - h_1} + \frac{c_{1,2}}{(x - h_1)^2} + = \frac{c_{1,1} (x - h_1) + c_{1,2}}{(x - h_1)^2} +\end{aligned}$$ + +And then, using the linear independence of $x^0, x^1, x^2, ...$, solving +a system of $m$ equations to find all $c_{1,1}, ..., c_{1,m}$. diff --git a/content/know/concept/pauli-exclusion-principle/index.pdc b/content/know/concept/pauli-exclusion-principle/index.pdc new file mode 100644 index 0000000..aa9609b --- /dev/null +++ b/content/know/concept/pauli-exclusion-principle/index.pdc @@ -0,0 +1,125 @@ +--- +title: "Pauli exclusion principle" +firstLetter: "P" +publishDate: 2021-02-22 +categories: +- Quantum mechanics +- Physics + +date: 2021-02-22T21:37:14+01:00 +draft: false +markup: pandoc +--- + +# Pauli exclusion principle + +In quantum mechanics, the **Pauli exclusion principle** is a theorem with +profound consequences for how the world works. + +Suppose we have a composite state +$\ket*{x_1}\ket*{x_2} = \ket*{x_1} \otimes \ket*{x_2}$, where the two +identical particles $x_1$ and $x_2$ each can occupy the same two allowed +states $a$ and $b$. We then define the permutation operator $\hat{P}$ as +follows: + +$$\begin{aligned} + \hat{P} \ket{a}\ket{b} = \ket{b}\ket{a} +\end{aligned}$$ + +That is, it swaps the states of the particles. Obviously, swapping the +states twice simply gives the original configuration again, so: + +$$\begin{aligned} + \hat{P}^2 \ket{a}\ket{b} = \ket{a}\ket{b} +\end{aligned}$$ + +Therefore, $\ket{a}\ket{b}$ is an eigenvector of $\hat{P}^2$ with +eigenvalue $1$. Since $[\hat{P}, \hat{P}^2] = 0$, $\ket{a}\ket{b}$ +must also be an eigenket of $\hat{P}$ with eigenvalue $\lambda$, +satisfying $\lambda^2 = 1$, so we know that $\lambda = 1$ or $\lambda = -1$: + +$$\begin{aligned} + \hat{P} \ket{a}\ket{b} = \lambda \ket{a}\ket{b} +\end{aligned}$$ + +As it turns out, in nature, each class of particle has a single +associated permutation eigenvalue $\lambda$, or in other words: whether +$\lambda$ is $-1$ or $1$ depends on the type of particle that $x_1$ +and $x_2$ are. Particles with $\lambda = -1$ are called +**fermions**, and those with $\lambda = 1$ are known as **bosons**. We +define $\hat{P}_f$ with $\lambda = -1$ and $\hat{P}_b$ with +$\lambda = 1$, such that: + +$$\begin{aligned} + \hat{P}_f \ket{a}\ket{b} = \ket{b}\ket{a} = - \ket{a}\ket{b} + \qquad + \hat{P}_b \ket{a}\ket{b} = \ket{b}\ket{a} = \ket{a}\ket{b} +\end{aligned}$$ + +Another fundamental fact of nature is that identical particles cannot be +distinguished by any observation. Therefore it is impossible to tell +apart $\ket{a}\ket{b}$ and the permuted state $\ket{b}\ket{a}$, +regardless of the eigenvalue $\lambda$. There is no physical difference! + +But this does not mean that $\hat{P}$ is useless: despite not having any +observable effect, the resulting difference between fermions and bosons +is absolutely fundamental. Consider the following superposition state, +where $\alpha$ and $\beta$ are unknown: + +$$\begin{aligned} + \ket{\Psi(a, b)} + = \alpha \ket{a}\ket{b} + \beta \ket{b}\ket{a} +\end{aligned}$$ + +When we apply $\hat{P}$, we can "choose" between two "intepretations" of +its action, both shown below. Obviously, since the left-hand sides are +equal, the right-hand sides must be equal too: + +$$\begin{aligned} + \hat{P} \ket{\Psi(a, b)} + &= \lambda \alpha \ket{a}\ket{b} + \lambda \beta \ket{b}\ket{a} + \\ + \hat{P} \ket{\Psi(a, b)} + &= \alpha \ket{b}\ket{a} + \beta \ket{a}\ket{b} +\end{aligned}$$ + +This gives us the equations $\lambda \alpha = \beta$ and +$\lambda \beta = \alpha$. In fact, just from this we could have deduced +that $\lambda$ can be either $-1$ or $1$. In any case, for bosons +($\lambda = 1$), we thus find that $\alpha = \beta$: + +$$\begin{aligned} + \ket{\Psi(a, b)}_b = C \big( \ket{a}\ket{b} + \ket{b}\ket{a} \big) +\end{aligned}$$ + +Where $C$ is a normalization constant. As expected, this state is +**symmetric**: switching $a$ and $b$ gives the same result. Meanwhile, for +fermions ($\lambda = -1$), we find that $\alpha = -\beta$: + +$$\begin{aligned} + \ket{\Psi(a, b)}_f = C \big( \ket{a}\ket{b} - \ket{b}\ket{a} \big) +\end{aligned}$$ + +This state is called **antisymmetric** under exchange: switching $a$ and $b$ +causes a sign change, as we would expect for fermions. + +Now, what if the particles $x_1$ and $x_2$ are in the same state $a$? +For bosons, we just need to update the normalization constant $C$: + +$$\begin{aligned} + \ket{\Psi(a, a)}_b + = C \ket{a}\ket{a} +\end{aligned}$$ + +However, for fermions, the state is unnormalizable and thus unphysical: + +$$\begin{aligned} + \ket{\Psi(a, a)}_f + = C \big( \ket{a}\ket{a} - \ket{a}\ket{a} \big) + = 0 +\end{aligned}$$ + +And this is the Pauli exclusion principle: **fermions may never +occupy the same quantum state**. One of the many notable consequences of +this is that the shells of atoms only fit a limited number of +electrons (which are fermions), since each must have a different quantum number. diff --git a/content/know/concept/probability-current/index.pdc b/content/know/concept/probability-current/index.pdc new file mode 100644 index 0000000..c67956a --- /dev/null +++ b/content/know/concept/probability-current/index.pdc @@ -0,0 +1,98 @@ +--- +title: "Probability current" +firstLetter: "P" +publishDate: 2021-02-22 +categories: +- Quantum mechanics +- Physics + +date: 2021-02-22T21:37:26+01:00 +draft: false +markup: pandoc +--- + +# Probability current + +In quantum mechanics, the **probability current** describes the movement +of the probability of finding a particle at given point in space. +In other words, it treats the particle as a heterogeneous fluid with density $|\psi|^2$. +Now, the probability of finding the particle within a volume $V$ is: + +$$\begin{aligned} + P = \int_{V} | \psi |^2 \dd[3]{\vec{r}} +\end{aligned}$$ + +As the system evolves in time, this probability may change, so we take +its derivative with respect to time $t$, and when necessary substitute +in the other side of the Schrödinger equation to get: + +$$\begin{aligned} + \pdv{P}{t} + &= \int_{V} \psi \pdv{\psi^*}{t} + \psi^* \pdv{\psi}{t} \dd[3]{\vec{r}} + = \frac{i}{\hbar} \int_{V} \psi (\hat{H} \psi^*) - \psi^* (\hat{H} \psi) \dd[3]{\vec{r}} + \\ + &= \frac{i}{\hbar} \int_{V} \psi \Big( \!-\! \frac{\hbar^2}{2 m} \nabla^2 \psi^* + V(\vec{r}) \psi^* \Big) + - \psi^* \Big( \!-\! \frac{\hbar^2}{2 m} \nabla^2 \psi + V(\vec{r}) \psi \Big) \dd[3]{\vec{r}} + \\ + &= \frac{i \hbar}{2 m} \int_{V} - \psi \nabla^2 \psi^* + \psi^* \nabla^2 \psi \dd[3]{\vec{r}} + = - \int_{V} \nabla \cdot \vec{J} \dd[3]{\vec{r}} +\end{aligned}$$ + +Where we have defined the probability current $\vec{J}$ as follows in +the $\vec{r}$-basis: + +$$\begin{aligned} + \vec{J} + = \frac{i \hbar}{2 m} (\psi \nabla \psi^* - \psi^* \nabla \psi) + = \mathrm{Re} \Big\{ \psi \frac{i \hbar}{m} \psi^* \Big\} +\end{aligned}$$ + +Let us rewrite this using the momentum operator +$\hat{p} = -i \hbar \nabla$ as follows, noting that $\hat{p} / m$ is +simply the velocity operator $\hat{v}$: + +$$\begin{aligned} + \boxed{ + \vec{J} + = \frac{1}{2 m} ( \psi^* \hat{p} \psi - \psi \hat{p} \psi^*) + = \mathrm{Re} \Big\{ \psi^* \frac{\hat{p}}{m} \psi \Big\} + = \mathrm{Re} \{ \psi^* \hat{v} \psi \} + } +\end{aligned}$$ + +Returning to the derivation of $\vec{J}$, we now have the following +equation: + +$$\begin{aligned} + \pdv{P}{t} + = \int_{V} \pdv{|\psi|^2}{t} \dd[3]{\vec{r}} + = - \int_{V} \nabla \cdot \vec{J} \dd[3]{\vec{r}} +\end{aligned}$$ + +By removing the integrals, we thus arrive at the **continuity equation** +for $\vec{J}$: + +$$\begin{aligned} + \boxed{ + \nabla \cdot \vec{J} + = - \pdv{|\psi|^2}{t} + } +\end{aligned}$$ + +This states that the total probability is conserved, and is reminiscent of charge +conservation in electromagnetism. In other words, the probability at a +point can only change by letting it "flow" towards or away from it. Thus +$\vec{J}$ represents the flow of probability, which is analogous to the +motion of a particle. + +As a bonus, this still holds for a particle in an electromagnetic vector +potential $\vec{A}$, thanks to the gauge invariance of the Schrödinger +equation. We can thus extend the definition to a particle with charge +$q$ in an SI-unit field, neglecting spin: + +$$\begin{aligned} + \boxed{ + \vec{J} + = \mathrm{Re} \Big\{ \psi^* \frac{\hat{p} - q \vec{A}}{m} \psi \Big\} + } +\end{aligned}$$ diff --git a/content/know/concept/slater-determinant/index.pdc b/content/know/concept/slater-determinant/index.pdc new file mode 100644 index 0000000..8bc4291 --- /dev/null +++ b/content/know/concept/slater-determinant/index.pdc @@ -0,0 +1,54 @@ +--- +title: "Slater determinant" +firstLetter: "S" +publishDate: 2021-02-22 +categories: +- Quantum mechanics +- Physics + +date: 2021-02-22T21:38:03+01:00 +draft: false +markup: pandoc +--- + +# Slater determinant + +In quantum mechanics, the **Slater determinant** is a trick +to create a many-particle wave function for a system of $N$ fermions, +with the necessary antisymmetry. + +Given an orthogonal set of individual states $\psi_n(x)$, we write +$\psi_n(x_n)$ to say that particle $x_n$ is in state $\psi_n$. Now the +goal is to find an expression for an overall many-particle wave +function $\Psi(x_1, ..., x_N)$ that satisfies the +[Pauli exclusion principle](/know/concept/pauli-exclusion-principle/). +Enter the Slater determinant: + +$$\begin{aligned} + \boxed{ + \Psi(x_1, ..., x_N) + = \frac{1}{\sqrt{N!}} \det\! + \begin{bmatrix} + \psi_1(x_1) & \cdots & \psi_N(x_1) \\ + \vdots & \ddots & \vdots \\ + \psi_1(x_N) & \cdots & \psi_N(x_N) + \end{bmatrix} + }\end{aligned}$$ + +Swapping the state of two particles corresponds to exchanging two rows, +which flips the sign of the determinant. +Similarly, switching two columns means swapping two states, +which also results in a sign change. +Finally, putting two particles into the same state makes $\Psi$ vanish. + +Not all valid many-fermion wave functions can be +written as a single Slater determinant; a linear combination of multiple +may be needed. Nevertheless, an appropriate choice of the input set +$\psi_n(x)$ can optimize how well a single determinant approximates a +given $\Psi$. + +In fact, there exists a similar trick for bosons, where the goal is to +create a symmetric wave function which allows multiple particles to +occupy the same state. In this case, one needs to take the **Slater +permanent** of the same matrix, which is simply the determinant, but with +all minuses replaced by pluses. diff --git a/content/know/concept/sturm-liouville-theory/index.pdc b/content/know/concept/sturm-liouville-theory/index.pdc new file mode 100644 index 0000000..7ccd625 --- /dev/null +++ b/content/know/concept/sturm-liouville-theory/index.pdc @@ -0,0 +1,346 @@ +--- +title: "Sturm-Liouville theory" +firstLetter: "S" +publishDate: 2021-02-23 +categories: +- Mathematics +- Physics + +date: 2021-02-23T08:52:28+01:00 +draft: false +markup: pandoc +--- + +# Sturm-Liouville theory + +**Sturm-Liouville theory** defines the analogue of Hermitian matrix +eigenvalue problems for linear second-order ODEs. + +It states that, given suitable boundary conditions, any linear +second-order ODE can be rewritten using the **Sturm-Liouville operator**, +and that the corresponding eigenvalue problem, known as a +**Sturm-Liouville problem**, will give real eigenvalues and a complete set +of eigenfunctions. + + +## General operator + +Consider the most general form of a second-order linear +differential operator $\hat{L}$, where $p_0(x)$, $p_1(x)$, and $p_2(x)$ +are real functions of $x \in [a,b]$ which are non-zero for all $x \in ]a, b[$: + +$$\begin{aligned} + \hat{L} \{u(x)\} = p_0(x) u''(x) + p_1(x) u'(x) + p_2(x) u(x) +\end{aligned}$$ + +We now define the **adjoint** or **Hermitian** operator +$\hat{L}^\dagger$ analogously to matrices: + +$$\begin{aligned} + \braket*{f}{\hat{L} g} + = \braket*{\hat{L}^\dagger f}{g} +\end{aligned}$$ + +What is $\hat{L}^\dagger$, given the above definition of $\hat{L}$? +We start from the inner product $\braket*{f}{\hat{L} g}$: + +$$\begin{aligned} + \braket*{f}{\hat{L} g} + &= \int_a^b f^*(x) \hat{L}\{g(x)\} \dd{x} + = \int_a^b (f^* p_0) g'' + (f^* p_1) g' + (f^* p_2) g \dd{x} + \\ + &= \big[ (f^* p_0) g' + (f^* p_1) g \big]_a^b - \int_a^b (f^* p_0)' g' + (f^* p_1)' g - (f^* p_2) g \dd{x} + \\ + &= \big[ f^* \big( p_0 g' \!+\! p_1 g \big) \!-\! (f^* p_0)' g \big]_a^b + \int_a^b \! \big( (f p_0)'' - (f p_1)' + (f p_2) \big)^* g \dd{x} + \\ + &= \big[ f^* \big( p_0 g' + (p_1 - p_0') g \big) - (f^*)' p_0 g \big]_a^b + \int_a^b \big( \hat{L}^\dagger\{f\} \big)^* g \dd{x} +\end{aligned}$$ + +We now have an expression for $\hat{L}^\dagger$, but are left with an +annoying boundary term: + +$$\begin{aligned} + \braket*{f}{\hat{L} g} + &= \big[ f^* \big( p_0 g' + (p_1 - p_0') g \big) - (f^*)' p_0 g \big]_a^b + \braket*{\hat{L}^\dagger f}{g} +\end{aligned}$$ + +To fix this, +let us demand that $p_1(x) = p_0'(x)$ and that +$[p_0(f^* g' - (f^*)' g)]_a^b = 0$, leaving: + +$$\begin{aligned} + \braket*{f}{\hat{L} g} + &= \big[ p_0 \big( f^* g' - (f^*)' g \big) \big]_a^b + \braket{\hat{L}^\dagger f}{g} + = \braket*{\hat{L}^\dagger f}{g} +\end{aligned}$$ + +Using the aforementioned restriction $p_1(x) = p_0'(x)$, +we then take a look at the definition of $\hat{L}^\dagger$: + +$$\begin{aligned} + \hat{L}^\dagger \{f\} + &= (p_0 f)'' - (p_1 f)' + (p_2 f) + \\ + &= p_0 f'' + (2 p_0' - p_1) f' + (p_0'' - p_1' + p_2) f + \\ + &= p_0 f'' + p_0' f' + p_2 f + \\ + &= (p_0 f')' + p_2 f +\end{aligned}$$ + +The original operator $\hat{L}$ reduces to the same form, +so it is **self-adjoint**: + +$$\begin{aligned} + \hat{L} \{f\} + &= p_0 f'' + p_0' f' + p_2 f + = (p_0 f')' + p_2 f + = \hat{L}^\dagger \{f\} +\end{aligned}$$ + +Consequently, every such second-order linear operator $\hat{L}$ is self-adjoint, +as long as it satisfies the constraints $p_1(x) = p_0'(x)$ and $[p_0 (f^* g' - (f^*)' g)]_a^b = 0$. + +Let us ignore the latter constraint for now (it will return later), +and focus on the former: what if $\hat{L}$ does not satisfy $p_0' \neq p_1$? +We multiply it by an unknown $p(x) \neq 0$, and divide by $p_0(x) \neq 0$: + +$$\begin{aligned} + \frac{p(x)}{p_0(x)} \hat{L} \{u\} = p(x) u'' + p(x) \frac{p_1(x)}{p_0(x)} u' + p(x) \frac{p_2(x)}{p_0(x)} u +\end{aligned}$$ + +We now define $q(x)$, +and demand that the derivative $p'(x)$ of the unknown $p(x)$ satisfies: + +$$\begin{aligned} + q(x) = p(x) \frac{p_2(x)}{p_0(x)} + \qquad + p'(x) = p(x) \frac{p_1(x)}{p_0(x)} +\end{aligned}$$ + +The latter is a differential equation for $p(x)$, which we solve by integration: + +$$\begin{gathered} + \frac{p_1(x)}{p_0(x)} = \frac{1}{p(x)} \dv{p}{x} + \quad \implies \quad + \frac{p_1(x)}{p_0(x)} \dd{x} = \frac{1}{p(x)} \dd{p} + \\ + \implies \quad + \int_a^x \frac{p_1(\xi)}{p_0(\xi)} \dd{\xi} = \int_{p(a)}^{p(x)} \frac{1}{f} \dd{f} + = \ln\Big( \frac{p(x)}{p(a)} \Big) + \\ + \implies \quad + p(x) = p(a) \exp\!\Big( \int_a^x \frac{p_1(\xi)}{p_0(\xi)} \dd{\xi} \Big) +\end{gathered}$$ + +Now that we have $p(x)$ and $q(x)$, we can define a new operator $\hat{L}_p$ as follows: + +$$\begin{aligned} + \hat{L}_p \{u\} + = \frac{p}{p_0} \hat{L} \{u\} + = p u'' + p' u' + q u + = (p u')' + q u +\end{aligned}$$ + +This is the self-adjoint form from earlier! +So even if $p_0' \neq p_1$, any second-order linear operator with $p_0(x) \neq 0$ +can easily be put in self-adjoint form. + +This general form is known as the **Sturm-Liouville operator** $\hat{L}_{SL}$, +where $p(x)$ and $q(x)$ are non-zero real functions of the variable $x \in [a,b]$: + +$$\begin{aligned} + \boxed{ + \hat{L}_{SL} \{u(x)\} + = \frac{d}{dx}\Big( p(x) \frac{du}{dx} \Big) + q(x) u(x) + = \hat{L}_{SL}^\dagger \{u(x)\} + } +\end{aligned}$$ + + +## Eigenvalue problem + +A **Sturm-Liouville problem** (SLP) is analogous to a matrix eigenvalue problem, +where $w(x)$ is a real weight function, $\lambda$ is the **eigenvalue**, +and $u(x)$ is the corresponding **eigenfunction**: + +$$\begin{aligned} + \boxed{ + \hat{L}_{SL}\{u(x)\} = - \lambda w(x) u(x) + } +\end{aligned}$$ + +Necessarily, $w(x) > 0$ except in isolated points, where $w(x) = 0$ is allowed; +the point is that any inner product $\braket{f}{w g}$ may never be zero due to $w$'s fault. +Furthermore, the convention is that $u(x)$ cannot be trivially zero. + +In our derivation of $\hat{L}_{SL}$, +we removed a boundary term to get self-adjointness. +Consequently, to have a valid SLP, the boundary conditions for +$u(x)$ must be as follows, otherwise the operator cannot be self-adjoint: + +$$\begin{aligned} + \Big[ p(x) \big( u^*(x) u'(x) - (u'(x))^* u(x) \big) \Big]_a^b = 0 +\end{aligned}$$ + +There are many boundary conditions (BCs) which satisfy this requirement. +Some notable ones are listed here non-exhaustively: + ++ **Dirichlet BCs**: $u(a) = u(b) = 0$ ++ **Neumann BCs**: $u'(a) = u'(b) = 0$ ++ **Robin BCs**: $\alpha_1 u(a) + \beta_1 u'(a) = \alpha_2 u(b) + \beta_2 u'(b) = 0$ with $\alpha_{1,2}, \beta_{1,2} \in \mathbb{R}$ ++ **Periodic BCs**: $p(a) = p(b)$, $u(a) = u(b)$, and $u'(a) = u'(b)$ ++ **Legendre "BCs"**: $p(a) = p(b) = 0$ + +Once this requirement is satisfied, Sturm-Liouville theory gives us +some very useful information about $\lambda$ and $u(x)$. +From the definition of an SLP, we know that, given two arbitrary (and possibly identical) +eigenfunctions $u_n$ and $u_m$, the following must be satisfied: + +$$\begin{aligned} + 0 = \hat{L}_{SL}\{u_n\} + \lambda_n w u_n = \hat{L}_{SL}\{u_m^*\} + \lambda_m^* w u_m^* +\end{aligned}$$ + +We subtract these expressions, multiply by the eigenfunctions, and integrate: + +$$\begin{aligned} + 0 + &= \int_a^b u_m^* \big(\hat{L}_{SL}\{u_n\} + \lambda_n w u_n\big) - u_n \big(\hat{L}_{SL}\{u_m^*\} + \lambda_m^* w u_m^*\big) \:dx + \\ + &= \int_a^b u_m^* \hat{L}_{SL}\{u_n\} - u_n \hat{L}_{SL}\{u_m^*\} + u_n u_m^* w (\lambda_n - \lambda_m^*) \:dx +\end{aligned}$$ + +Rearranging this a bit reveals that these are in fact three inner products: + +$$\begin{aligned} + \int_a^b u_m^* \hat{L}_{SL}\{u_n\} - u_n \hat{L}_{SL}\{u_m^*\} \:dx + &= (\lambda_m^* - \lambda_n) \int_a^b u_n u_m^* w \:dx + \\ + \braket*{u_m}{\hat{L}_{SL} u_n} - \braket*{\hat{L}_{SL} u_m}{u_n} + &= (\lambda_m^* - \lambda_n) \braket{u_m}{w u_n} +\end{aligned}$$ + +The operator $\hat{L}_{SL}$ is self-adjoint by definition, +so the left-hand side vanishes, leaving us with: + +$$\begin{aligned} + 0 + &= (\lambda_m^* - \lambda_n) \braket{u_m}{w u_n} +\end{aligned}$$ + +When $m = n$, the inner product $\braket{u_n}{w u_n}$ is real and positive +(assuming $u_n$ is not trivially zero, in which case it would be disqualified anyway). +In this case we thus know that $\lambda_n^* = \lambda_n$, +i.e. the eigenvalue $\lambda_n$ is real for any $n$. + +When $m \neq n$, then $\lambda_m^* - \lambda_n$ may or may not be zero, +depending on the degeneracy. If there is no degeneracy, we +see that $\braket{u_m}{w u_n} = 0$, i.e. the eigenfunctions are orthogonal. + +In case of degeneracy, manual orthogonalization is needed, but as it turns out, +this is guaranteed to be doable, using e.g. the [Gram-Schmidt method](/know/concept/gram-schmidt-method/). + +In conclusion, **a Sturm-Liouville problem has real eigenvalues $\lambda$, +and all the corresponding eigenfunctions $u(x)$ are mutually orthogonal**: + +$$\begin{aligned} + \boxed{ + \braket{u_m(x)}{w(x) u_n(x)} + = \braket{u_n}{w u_n} \delta_{nm} + = A_n \delta_{nm} + } +\end{aligned}$$ + +When you're solving a differential eigenvalue problem, +knowing that all eigenvalues are real is a *huge* simplification, +so it is always worth checking whether you're dealing with an SLP. + +Another useful fact of SLPs is that they always +have an infinite number of discrete eigenvalues. +Furthermore, the eigenvalues always ascend to $+\infty$; +in other words, there always exists a *lowest* eigenvalue $\lambda_0 > -\infty$, +known as the **ground state**. + + +## Completeness + +Not only are the eigenfunctions $u_n(x)$ of an SLP orthogonal, they +also form a **complete basis**, meaning that any well-behaved function $f(x)$ can be +expanded as a **generalized Fourier series** with coefficients $a_n$: + +$$\begin{aligned} + \boxed{ + f(x) + = \sum_{n = 0}^\infty a_n u_n(x) + \quad \mathrm{for}\: x \in ]a, b[ + } +\end{aligned}$$ + +This series will converge significantly faster if $f(x)$ +satisfies the same BCs as $u_n(x)$. In that case the +expansion will even be valid for the inclusive interval $x \in [a, b]$. + +To find an expression for the coefficients $a_n$, +we multiply the above generalized Fourier series by $w(x) u_m^*(x)$ for an arbitrary $m$: + +$$\begin{aligned} + f(x) w(x) u_m^*(x) + &= \sum_{n = 0}^\infty a_n u_n(x) w(x) u_m^*(x) +\end{aligned}$$ + +By integrating we get inner products on both the left and the right: + +$$\begin{aligned} + \int_a^b f(x) w(x) u_m^*(x) \dd{x} + &= \int_a^b \Big(\sum_{n = 0}^\infty a_n u_n(x) w(x) u_m^*(x)\Big) \dd{x} + \\ + \braket{u_m}{w f} + &= \sum_{n = 0}^\infty a_n \braket{u_m}{w u_n} +\end{aligned}$$ + +Because the eigenfunctions of an SLP are mutually orthogonal, +the summation disappears: + +$$\begin{aligned} + \braket{u_m}{w f} + &= \sum_{n = 0}^\infty a_n \braket{u_m}{w u_n} + = \sum_{n = 0}^\infty a_n A_n \delta_{nm} + = a_m A_m +\end{aligned}$$ + +After isolating this for $a_n$, we see that +the coefficients are given by the projection of the target +function $f(x)$ onto the normalized eigenfunctions $u_n(x) / A_n$: + +$$\begin{aligned} + \boxed{ + a_n + = \frac{\braket{u_n}{w f}}{A_n} + = \frac{\braket{u_n}{w f}}{\braket{u_n}{w u_n}} + } +\end{aligned}$$ + +As a final remark, we can see something interesting +by rearranging the generalized Fourier series +after inserting the expression for $a_n$: + +$$\begin{aligned} + f(x) + &= \sum_{n = 0}^\infty \frac{1}{A_n} \braket{u_n}{w f} u_n(x) + = \int_a^b \Big(\sum_{n = 0}^\infty \frac{1}{A_n} u_n^*(\xi) w(\xi) f(\xi) u_n(x) \Big) \dd{\xi} + \\ + &= \int_a^b f(\xi) \Big(\sum_{n = 0}^\infty \frac{1}{A_n} u_n^*(\xi) w(\xi) u_n(x) \Big) \dd{\xi} + %= \int_a^b f(\xi) \delta(x - \xi) \dd{\xi} +\end{aligned}$$ + +Upon closer inspection, the parenthesized summation +must be the [Dirac delta function](/know/concept/dirac-delta-function/) $\delta(x)$ +for the integral to work out. +This is in fact the underlying requirement for completeness: + +$$\begin{aligned} + \boxed{ + \sum_{n = 0}^\infty \frac{1}{A_n} u_n^*(\xi) w(\xi) u_n(x) = \delta(x - \xi) + } +\end{aligned}$$ + diff --git a/content/know/concept/time-independent-perturbation-theory/index.pdc b/content/know/concept/time-independent-perturbation-theory/index.pdc new file mode 100644 index 0000000..4f30ae8 --- /dev/null +++ b/content/know/concept/time-independent-perturbation-theory/index.pdc @@ -0,0 +1,329 @@ +--- +title: "Time-independent perturbation theory" +firstLetter: "T" +publishDate: 2021-02-22 +categories: +- Quantum mechanics +- Physics + +date: 2021-02-22T21:38:18+01:00 +draft: false +markup: pandoc +--- + +# Time-independent perturbation theory + +**Time-independent perturbation theory**, sometimes also called +**stationary state perturbation theory**, is a specific application of +perturbation theory to the time-independent Schrödinger +equation in quantum physics, for +Hamiltonians of the following form: + +$$\begin{aligned} + \hat{H} = \hat{H}_0 + \lambda \hat{H}_1 +\end{aligned}$$ + +Where $\hat{H}_0$ is a Hamiltonian for which the time-independent +Schrödinger equation has a known solution, and $\hat{H}_1$ is a small +perturbing Hamiltonian. The eigenenergies $E_n$ and eigenstates +$\ket{\psi_n}$ of the composite problem are expanded in the +perturbation "bookkeeping" parameter $\lambda$: + +$$\begin{aligned} + \ket{\psi_n} + &= \ket*{\psi_n^{(0)}} + \lambda \ket*{\psi_n^{(1)}} + \lambda^2 \ket*{\psi_n^{(2)}} + ... + \\ + E_n + &= E_n^{(0)} + \lambda E_n^{(1)} + \lambda^2 E_n^{(2)} + ... +\end{aligned}$$ + +Where $E_n^{(1)}$ and $\ket*{\psi_n^{(1)}}$ are called the **first-order +corrections**, and so on for higher orders. We insert this into the +Schrödinger equation: + +$$\begin{aligned} + \hat{H} \ket{\psi_n} + &= \hat{H}_0 \ket*{\psi_n^{(0)}} + + \lambda \big( \hat{H}_1 \ket*{\psi_n^{(0)}} + \hat{H}_0 \ket*{\psi_n^{(1)}} \big) \\ + &\qquad + \lambda^2 \big( \hat{H}_1 \ket*{\psi_n^{(1)}} + \hat{H}_0 \ket*{\psi_n^{(2)}} \big) + ... + \\ + E_n \ket{\psi_n} + &= E_n^{(0)} \ket*{\psi_n^{(0)}} + + \lambda \big( E_n^{(1)} \ket*{\psi_n^{(0)}} + E_n^{(0)} \ket*{\psi_n^{(1)}} \big) \\ + &\qquad + \lambda^2 \big( E_n^{(2)} \ket*{\psi_n^{(0)}} + E_n^{(1)} \ket*{\psi_n^{(1)}} + E_n^{(0)} \ket*{\psi_n^{(2)}} \big) + ... +\end{aligned}$$ + +If we collect the terms according to the order of $\lambda$, we arrive +at the following endless series of equations, of which in practice only +the first three are typically used: + +$$\begin{aligned} + \hat{H}_0 \ket*{\psi_n^{(0)}} + &= E_n^{(0)} \ket*{\psi_n^{(0)}} + \\ + \hat{H}_1 \ket*{\psi_n^{(0)}} + \hat{H}_0 \ket*{\psi_n^{(1)}} + &= E_n^{(1)} \ket*{\psi_n^{(0)}} + E_n^{(0)} \ket*{\psi_n^{(1)}} + \\ + \hat{H}_1 \ket*{\psi_n^{(1)}} + \hat{H}_0 \ket*{\psi_n^{(2)}} + &= E_n^{(2)} \ket*{\psi_n^{(0)}} + E_n^{(1)} \ket*{\psi_n^{(1)}} + E_n^{(0)} \ket*{\psi_n^{(2)}} + \\ + ... + &= ... +\end{aligned}$$ + +The first equation is the unperturbed problem, which we assume has +already been solved, with eigenvalues $E_n^{(0)} = \varepsilon_n$ and +eigenvectors $\ket*{\psi_n^{(0)}} = \ket{n}$: + +$$\begin{aligned} + \hat{H}_0 \ket{n} = \varepsilon_n \ket{n} +\end{aligned}$$ + +The approach to solving the other two equations varies depending on +whether this $\hat{H}_0$ has a degenerate spectrum or not. + + +## Without degeneracy + +We start by assuming that there is no degeneracy, in other words, each +$\varepsilon_n$ corresponds to one $\ket{n}$. At order $\lambda^1$, we +rewrite the equation as follows: + +$$\begin{aligned} + (\hat{H}_1 - E_n^{(1)}) \ket{n} + (\hat{H}_0 - \varepsilon_n) \ket*{\psi_n^{(1)}} = 0 +\end{aligned}$$ + +Since $\ket{n}$ form a complete basis, we can express +$\ket*{\psi_n^{(1)}}$ in terms of them: + +$$\begin{aligned} + \ket*{\psi_n^{(1)}} = \sum_{m \neq n} c_m \ket{m} +\end{aligned}$$ + +Importantly, $n$ has been removed from the summation to prevent dividing +by zero later. We are allowed to do this, because +$\ket*{\psi_n^{(1)}} - c_n \ket{n}$ also satisfies the order-$\lambda^1$ +equation for any value of $c_n$, as demonstrated here: + +$$\begin{aligned} + (\hat{H}_1 - E_n^{(1)}) \ket{n} + (\hat{H}_0 - \varepsilon_n) \ket*{\psi_n^{(1)}} - (\varepsilon_n - \varepsilon_n) c_n \ket{n} = 0 +\end{aligned}$$ + +Where we used $\hat{H}_0 \ket{n} = \varepsilon_n \ket{n}$. +We insert the series form of $\ket*{\psi_n^{(1)}}$ into the $\lambda^1$-equation: + +$$\begin{aligned} + (\hat{H}_1 - E_n^{(1)}) \ket{n} + \sum_{m \neq n} c_m (\varepsilon_m - \varepsilon_n) \ket{m} = 0 +\end{aligned}$$ + +We then put an arbitrary basis vector $\bra{k}$ in front of this +equation to get: + +$$\begin{aligned} + \matrixel{k}{\hat{H}_1}{n} - E_n^{(1)} \braket{k}{n} + \sum_{m \neq n} c_m (\varepsilon_m - \varepsilon_n) \braket{k}{m} = 0 +\end{aligned}$$ + +Suppose that $k = n$. Since $\ket{n}$ form an orthonormal basis, we end +up with: + +$$\begin{aligned} + \boxed{ + E_n^{(1)} = \matrixel{n}{\hat{H}_1}{n} + } +\end{aligned}$$ + +In other words, the first-order energy correction $E_n^{(1)}$ is the +expectation value of the perturbation $\hat{H}_1$ for the unperturbed +state $\ket{n}$. + +Suppose now that $k \neq n$, then only one term of the summation +survives, and we are left with the following equation, which tells us +$c_l$: + +$$\begin{aligned} + \matrixel{k}{\hat{H}_1}{n} + c_k (\varepsilon_k - \varepsilon_n) = 0 +\end{aligned}$$ + +We isolate this result for $c_k$ and insert it into the series form of +$\ket*{\psi_n^{(1)}}$ to get the full first-order correction to the wave +function: + +$$\begin{aligned} + \boxed{ + \ket*{\psi_n^{(1)}} + = \sum_{m \neq n} \frac{\matrixel{m}{\hat{H}_1}{n}}{\varepsilon_n - \varepsilon_m} \ket{m} + } +\end{aligned}$$ + +Here it is clear why this is only valid in the non-degenerate case: +otherwise we would divide by zero in the denominator. + +Next, to find the second-order correction to the energy $E_n^{(2)}$, we +take the corresponding equation and put $\bra{n}$ in front of it: + +$$\begin{aligned} + \matrixel{n}{\hat{H}_1}{\psi_n^{(1)}} + \matrixel{n}{\hat{H}_0}{\psi_n^{(2)}} + &= E_n^{(2)} \braket{n}{n} + E_n^{(1)} \braket{n}{\psi_n^{(1)}} + \varepsilon_n \braket{n}{\psi_n^{(2)}} +\end{aligned}$$ + +Because $\hat{H}_0$ is Hermitian, we know that +$\matrixel{n}{\hat{H}_0}{\psi_n^{(2)}} = \varepsilon_n \braket{n}{\psi_n^{(2)}}$, +i.e. we apply it to the bra, which lets us eliminate two terms. Also, +since $\ket{n}$ is normalized, we find: + +$$\begin{aligned} + E_n^{(2)} + = \matrixel{n}{\hat{H}_1}{\psi_n^{(1)}} - E_n^{(1)} \braket{n}{\psi_n^{(1)}} +\end{aligned}$$ + +We explicitly removed the $\ket{n}$-dependence of $\ket*{\psi_n^{(1)}}$, +so the last term is zero. By simply inserting our result for +$\ket*{\psi_n^{(1)}}$, we thus arrive at: + +$$\begin{aligned} + \boxed{ + E_n^{(2)} + = \sum_{m \neq n} \frac{\big| \matrixel{m}{\hat{H}_1}{n} \big|^2}{\varepsilon_n - \varepsilon_m} + } +\end{aligned}$$ + +In practice, it is not particulary useful to calculate more corrections. + + +## With degeneracy + +If $\varepsilon_n$ is $D$-fold degenerate, then its eigenstate could be +any vector $\ket{n, d}$ from the corresponding $D$-dimensional +eigenspace: + +$$\begin{aligned} + \hat{H}_0 \ket{n} = \varepsilon_n \ket{n} + \quad \mathrm{where} \quad + \ket{n} + = \sum_{d = 1}^{D} c_{d} \ket{n, d} +\end{aligned}$$ + +In general, adding the perturbation $\hat{H}_1$ will *lift* the +degeneracy, meaning the perturbed states will be non-degenerate. In the +limit $\lambda \to 0$, these $D$ perturbed states change into $D$ +orthogonal states which are all valid $\ket{n}$. + +However, the $\ket{n}$ that they converge to are not arbitrary: only +certain unperturbed eigenstates are "good" states. Without $\hat{H}_1$, +this distinction is irrelevant, but in the perturbed case it will turn +out to be important. + +For now, we write $\ket{n, d}$ to refer to any orthonormal set of +vectors in the eigenspace of $\varepsilon_n$ (not necessarily the "good" +ones), and $\ket{n}$ to denote any linear combination of these. We then +take the equation at order $\lambda^1$ and prepend an arbitrary +eigenspace basis vector $\bra{n, \delta}$: + +$$\begin{aligned} + \matrixel{n, \delta}{\hat{H}_1}{n} + \matrixel{n, \delta}{\hat{H}_0}{\psi_n^{(1)}} + &= E_n^{(1)} \braket{n, \delta}{n} + \varepsilon_n \braket{n, \delta}{\psi_n^{(1)}} +\end{aligned}$$ + +Since $\hat{H}_0$ is Hermitian, we use the same trick as before to +reduce the problem to: + +$$\begin{aligned} + \matrixel{n, \delta}{\hat{H}_1}{n} + &= E_n^{(1)} \braket{n, \delta}{n} +\end{aligned}$$ + +We express $\ket{n}$ as a linear combination of the eigenbasis vectors +$\ket{n, d}$ to get: + +$$\begin{aligned} + \sum_{d = 1}^{D} c_d \matrixel{n, \delta}{\hat{H}_1}{n, d} + = E_n^{(1)} \sum_{d = 1}^{D} c_d \braket{n, \delta}{n, d} + = c_{\delta} E_n^{(1)} +\end{aligned}$$ + +Let us now interpret the summation terms as matrix elements +$M_{\delta, d}$: + +$$\begin{aligned} + M_{\delta, d} = \matrixel{n, \delta}{\hat{H}_1}{n, d} +\end{aligned}$$ + +By varying the value of $\delta$ from $1$ to $D$, we end up with +equations of the form: + +$$\begin{aligned} + \begin{bmatrix} + M_{1, 1} & \cdots & M_{1, D} \\ + \vdots & \ddots & \vdots \\ + M_{D, 1} & \cdots & M_{D, D} + \end{bmatrix} + \begin{bmatrix} + c_1 \\ \vdots \\ c_D + \end{bmatrix} + = E_n^{(1)} + \begin{bmatrix} + c_1 \\ \vdots \\ c_D + \end{bmatrix} +\end{aligned}$$ + +This is an eigenvalue problem for $E_n^{(1)}$, where $c_d$ are the +components of the eigenvectors which represent the "good" states. +After solving this, let $\ket{n, g}$ be the resulting "good" states. +Then, as long as $E_n^{(1)}$ is a non-degenerate eigenvalue of $M$: + +$$\begin{aligned} + \boxed{ + E_{n, g}^{(1)} = \matrixel{n, g}{\hat{H}_1}{n, g} + } +\end{aligned}$$ + +Which is the same as in the non-degenerate case! Even better, the +first-order wave function correction is also unchanged: + +$$\begin{aligned} + \boxed{ + \ket*{\psi_{n,g}^{(1)}} + = \sum_{m \neq (n, g)} \frac{\matrixel{m}{\hat{H}_1}{n, g}}{\varepsilon_n - \varepsilon_m} \ket{m} + } +\end{aligned}$$ + +This works because the matrix $M$ is diagonal in the $\ket{n, g}$-basis, +such that when $\ket{m}$ is any vector $\ket{n, \gamma}$ in the +$\ket{n}$-eigenspace (except for $\ket{n,g}$, which is +explicitly excluded), then the corresponding numerator +$\matrixel{n, \gamma}{\hat{H}_1}{n, g} = M_{\gamma, g} = 0$, so the term +does not contribute. + +If any of the eigenvalues $E_n^{(1)}$ of $M$ are degenerate, then there +is still information missing about the components $c_d$ of the +"good" states, in which case we must find them some other way. + +Such an alternative way of determining these "good" states is also of +interest even if there is no degeneracy in $M$, since such a shortcut would +allow us to use the formulae from non-degenerate perturbation theory +straight away. + +The trick is to find a Hermitian operator $\hat{L}$ (usually using +symmetries of the system) which commutes with both $\hat{H}_0$ and $\hat{H}_1$: + +$$\begin{aligned} + \comm*{\hat{L}}{\hat{H}_0} = \comm*{\hat{L}}{\hat{H}_1} = 0 +\end{aligned}$$ + +So that it shares its eigenstates with $\hat{H}_0$ (and $\hat{H}_1$), +meaning all the vectors of the $D$-dimensional +$\ket{n}$-eigenspace are also eigenvectors of $\hat{L}$. + +The crucial part, however, is that $\hat{L}$ must be chosen such that +$\ket{n, d_1}$ and $\ket{n, d_2}$ have distinct eigenvalues +$\ell_1 \neq \ell_2$ for $d_1 \neq d_2$: + +$$\begin{aligned} + \hat{L} \ket{n, b_1} = \ell_1 \ket{n, b_1} + \qquad + \hat{L} \ket{n, b_2} = \ell_2 \ket{n, b_2} +\end{aligned}$$ + +When this holds for any orthogonal choice of $\ket{n, d_1}$ and +$\ket{n, d_2}$, then these specific eigenvectors of $\hat{L}$ are the +"good states", for any valid choice of $\hat{L}$. diff --git a/content/know/concept/wentzel-kramers-brillouin-approximation/index.pdc b/content/know/concept/wentzel-kramers-brillouin-approximation/index.pdc new file mode 100644 index 0000000..482650e --- /dev/null +++ b/content/know/concept/wentzel-kramers-brillouin-approximation/index.pdc @@ -0,0 +1,198 @@ +--- +title: "Wentzel-Kramers-Brillouin approximation" +firstLetter: "W" +publishDate: 2021-02-22 +categories: +- Quantum mechanics +- Physics + +date: 2021-02-22T21:38:35+01:00 +draft: false +markup: pandoc +--- + +# Wentzel-Kramers-Brillouin approximation + +In quantum mechanics, the **Wentzel-Kramers-Brillouin** or simply the **WKB +approximation** is a method to approximate the wave function $\psi(x)$ of +the one-dimensional time-independent Schrödinger equation. It is an example +of a **semiclassical approximation**, because it tries to find a +balance between classical and quantum physics. + +In classical mechanics, a particle travelling in a potential $V(x)$ +along a path $x(t)$ has a total energy $E$ as follows, which we +rearrange: + +$$\begin{aligned} + E = \frac{1}{2} m \dot{x}^2 + V(x) + \quad \implies \quad + m^2 (x')^2 = 2 m (E - V(x)) +\end{aligned}$$ + +The left-hand side of the rearrangement is simply the momentum squared, +so we define the magnitude of the momentum $p(x)$ accordingly: + +$$\begin{aligned} + p(x) = \sqrt{2 m (E - V(x))} +\end{aligned}$$ + +Note that this is under the assumption that $E > V$, which is always the +case in classical mechanics, but not necessarily so in quantum +mechanics, but we stick with it for now. We rewrite the Schrödinger +equation: + +$$\begin{aligned} + 0 + = \dv[2]{\psi}{x} + \frac{2 m}{\hbar^2} (E - V) \psi + = \dv[2]{\psi}{x} + \frac{p^2}{\hbar^2} \psi +\end{aligned}$$ + +If $V(x)$ were constant, and by extension $p(x)$ too, then the solution +is easy: + +$$\begin{aligned} + \psi(x) + = \psi(0) \exp(\pm i p x / \hbar) +\end{aligned}$$ + +This form is reminiscent of the generator of translations. In practice, +$V(x)$ and $p(x)$ vary with $x$, but we can still salvage this solution +by assuming that $V(x)$ varies slowly compared to the wavelength +$\lambda(x) = 2 \pi / k(x)$, where $k(x) = p(x) / \hbar$ is the +wavenumber. The solution then takes the following form: + +$$\begin{aligned} + \psi(x) + = \psi(0) \exp\!\Big(\!\pm\! \frac{i}{\hbar} \int_0^x \chi(\xi) \dd{\xi} \Big) +\end{aligned}$$ + +$\chi(\xi)$ is an unknown function, which intuitively should be related +to $p(x)$. The purpose of the integral is to accumulate the change of +$\chi$ from the initial point $0$ to the current position $x$. +Let us write this as an indefinite integral for convenience: + +$$\begin{aligned} + \psi(x) + = \psi(0) \exp\!\bigg( \!\pm\! \frac{i}{\hbar} \Big( \int \chi(x) \dd{x} - C \Big) \bigg) +\end{aligned}$$ + +Where $C = \int \chi(x) \dd{x} |_{x = 0}$ is the initial point of the definite integral. +For simplicity, we absorb the constant $C$ into $\psi(0)$. +We can now clearly see that: + +$$\begin{aligned} + \psi'(x) = \pm \frac{i}{\hbar} \chi(x) \psi(x) + \quad \implies \quad + \chi(x) = \pm \frac{\hbar}{i} \frac{\psi'(x)}{\psi(x)} +\end{aligned}$$ + +Next, we insert this ansatz for $\psi(x)$ into the Schrödinger equation +to get: + +$$\begin{aligned} + 0 + &= \pm \frac{i}{\hbar} \dv{(\chi \psi)}{x} + \frac{p^2}{\hbar^2} \psi + = \pm \frac{i}{\hbar} \chi' \psi \pm \frac{i}{\hbar} \chi \psi' + \frac{p^2}{\hbar^2} \psi + = \pm \frac{i}{\hbar} \chi' \psi - \frac{1}{\hbar^2} \chi^2 \psi + \frac{p^2}{\hbar^2} \psi +\end{aligned}$$ + +Dividing out $\psi$ and rearranging gives us the following, which is +still exact: + +$$\begin{aligned} + \pm \frac{\hbar}{i} \chi' + = p^2 - \chi^2 +\end{aligned}$$ + +Next, we expand this as a power series of $\hbar$. This is why it is +called *semiclassical*: so far we have been using full quantum mechanics, +but now we are treating $\hbar$ as a parameter which controls the +strength of quantum effects: + +$$\begin{aligned} + \chi(x) = \chi_0(x) + \frac{\hbar}{i} \chi_1(x) + \frac{\hbar^2}{i^2} \chi_2(x) + ... +\end{aligned}$$ + +The heart of the WKB approximation is its assumption that quantum effects are +sufficiently weak (i.e. $\hbar$ is small enough) that we only need to +consider the first two terms, or, more specifically, that we only go up to +$\hbar$, not $\hbar^2$ or higher. Inserting the first two terms of this +expansion into the equation: + +$$\begin{aligned} + \pm \frac{\hbar}{i} \chi_0' + &= p^2 - \chi_0^2 - 2 \frac{\hbar}{i} \chi_0 \chi_1 +\end{aligned}$$ + +Where we have discarded all terms containing $\hbar^2$. At order +$\hbar^0$, we then get the expected classical result for $\chi_0(x)$: + +$$\begin{aligned} + 0 = p^2 - \chi_0^2 + \quad \implies \quad + \chi_0(x) = p(x) +\end{aligned}$$ + +While at order $\hbar$, we get the following quantum-mechanical +correction: + +$$\begin{aligned} + \pm \frac{\hbar}{i} \chi_0' + = - 2 \frac{\hbar}{i} \chi_0 \chi_1 + \quad \implies \quad + \chi_1(x) = \mp \frac{1}{2} \frac{\chi_0'(x)}{\chi_0(x)} +\end{aligned}$$ + +Therefore, our approximated wave function $\psi(x)$ currently looks like +this: + +$$\begin{aligned} + \psi(x) + &\approx \psi(0) \exp\!\Big( \!\pm\! \frac{i}{\hbar} \int \chi_0(x) \dd{x} \Big) \exp\!\Big( \!\pm\! \int \chi_1(x) \dd{x} \Big) +\end{aligned}$$ + +We can reduce the latter exponential using integration by substitution: + +$$\begin{aligned} + \exp\!\Big( \!\pm\! \int \chi_1(x) \dd{x} \Big) + &= \exp\!\Big( \!-\! \frac{1}{2} \int \frac{\chi_0'(x)}{\chi_0(x)} \dd{x} \Big) + = \exp\!\Big( \!-\! \frac{1}{2} \int \frac{1}{\chi_0}\:d\chi_0 \Big) + \\ + &= \exp\!\Big( \!-\! \frac{1}{2} \ln\!\big(\chi_0(x)\big) \Big) + = \frac{1}{\sqrt{\chi_0(x)}} + = \frac{1}{\sqrt{p(x)}} +\end{aligned}$$ + +In the WKB approximation for $E > V$, the solution $\psi(x)$ is thus +given by: + +$$\begin{aligned} + \boxed{ + \psi(x) \approx \frac{A}{\sqrt{p(x)}} \exp\!\Big( \!\pm\! \frac{i}{\hbar} \int p(x) \dd{x} \Big) + } +\end{aligned}$$ + +What if $E < V$? In classical mechanics, this is not allowed; a ball +cannot simply go through a potential bump without the necessary energy. +However, in quantum mechanics, particles can **tunnel** through barriers. + +Conveniently, all we need to change for the WKB approximation is to let +the momentum take imaginary values: + +$$\begin{aligned} + p(x) = \sqrt{2 m (E - V(x))} = i \sqrt{2 m (V(x) - E)} +\end{aligned}$$ + +And then take the absolute value in the appropriate place in front of +$\psi(x)$: + +$$\begin{aligned} + \boxed{ + \psi(x) \approx \frac{A}{\sqrt{|p(x)|}} \exp\!\Big( \!\pm\! \frac{i}{\hbar} \int p(x) \dd{x} \Big) + } +\end{aligned}$$ + +In the classical region ($E > V$), the wave function oscillates, and +in the quantum-mechanical region ($E < V$) it is exponential. Note that for +$E \approx V$ the approximation breaks down, due to the appearance of +$p(x)$ in the denominator. diff --git a/content/uses.md b/content/uses.md new file mode 100644 index 0000000..fec4977 --- /dev/null +++ b/content/uses.md @@ -0,0 +1,110 @@ +--- +title: "Things I use" +date: 2021-02-23T16:16:18+01:00 +draft: false +--- + +# Things I use + +## Server +* [Alpine Linux](https://alpinelinux.org/): + Minimalist distribution powered by + [BusyBox](https://www.busybox.net/) and [musl](https://musl.libc.org/). + It has a large-enough selection of both cutting-edge + and stable packages to be practical. +* [nginx](https://nginx.org/): + Fast, secure and popular HTTP server, + and a breeze to set up. +* [OpenSMTPD](https://opensmtpd.org/): + Email SMTP server by the venerable [OpenBSD](https://www.openbsd.org/) project, + and the only one of its kind that nails the setup experience. +* [Dovecot](https://dovecot.org/): + One of the, if not *the* most popular email IMAP server. + And for good reason: it's fast, secure, and a pleasure to set up. +* [Rspamd](https://www.rspamd.com/): + Spam filter for email. + To be honest, I haven't looked into this one much. + It has lots of advanced features that I barely understand, + but still seems to be the most modern and usable spam filter out there. +* [Zola](https://www.getzola.org/): + Straightforward static site generator written in Rust. + The only thing it's missing is some kind of LaTeX formula support, + which is why I migrated to Hugo. +* [Hugo](https://gohugo.io/): + Another good static site generator, although not as good as Zola in my opinion. +* [cgit](https://git.zx2c4.com/cgit/about/): + JavaScript-free online Git frontend, + perfect for private setups. + If you need something more advanced like user accounts, + [Gitea](https://gitea.io) is a good choice too. +* [acme.sh](https://github.com/acmesh-official/acme.sh): + Straightforward tool to manage TLS certificates + issued by [Let's Encrypt](https://letsencrypt.org/). + + +## Desktop +* [Arch Linux](https://www.archlinux.org/): + The distribution that, for me, delivers the best cost-benefit ratio. + I'm not a big fan of [systemd](https://freedesktop.org/wiki/Software/systemd/) + or [glibc](https://www.gnu.org/software/libc/), + but the fantastic package manager and the huge repositories + make Arch Linux unbeatable for working techies' day-to-day computing. +* [i3](https://i3wm.org/) and [Sway](https://swaywm.org/): + Lightweight window managers. + Once you go tiling, you can never go back. +* [Firefox](https://www.mozilla.org/en-US/firefox/): + Web browsers suck. + This ones sucks the least, and is developed by Mozilla, + who still seem to care about privacy and security, and + who created the [Rust](https://www.rust-lang.org/) language. + Firefox has all the necessary modern features, + and provides an excellent curated set of add-ons. +* [Thunderbird](https://www.thunderbird.net/): + Email clients suck, just like email itself. + This one just sucks less, since it's also made by Mozilla. +* [Alacritty](https://github.com/alacritty/alacritty): + Simple, lightning-fast terminal emulator with + extra goodies like 24-bit colours + and live configuration reloading. +* [Neovim](https://neovim.io/): + A modernized fork of the venerable [Vim](https://www.vim.org/) text editor. +* [pass](https://www.passwordstore.org/): + Password manager for techies. + It's simple, secure, transparent, and extensible. +* [Anki](https://ankiweb.net/about): + Flashcard studying software, + with a big [library](https://ankiweb.net/shared/decks/) of community-made decks. + Frankly it's not very user-friendly, but it does the job. +* [Veusz](https://veusz.github.io/): + Fanstastic plotting software, + and one of the most underrated open-source tools that I know of. + It gives beautiful plots, can handle *huge* data files, and, + because its files are just plain Python, + you can automatically generate plots with a bit of scripting. + + +## Browser add-ons +* [uBlock Origin](https://addons.mozilla.org/en-US/firefox/addon/ublock-origin/): + The best adblocker out there. It's free *and* open-source! + + +## Android +* [Aegis](https://getaegis.app/): + Secure open-source 2FA authenticator app. +* [Shelter](https://f-droid.org/en/packages/net.typeblog.shelter/): + Isolates untrusted apps in an Android Work Profile. +* [AnkiDroid](https://f-droid.org/en/packages/com.ichi2.anki/): + Good mobile frontend for [Anki](https://ankiweb.net/about). + + +## Online services +* [Gandi](https://www.gandi.net/): + European domain registrar with the motto + "No bullshit since 1999". They provide an honest, + high-quality service at a competitive price. + This statement is not sponsored. +* [Let's Encrypt](https://letsencrypt.org/): + Provides free TLS encryption certificates + to anybody who asks politely, thereby making + online security more accessible for small sites like this one. + |
