Dirac Lagrangian by Ciro Santilli 35 Updated +Created
where:
Remember that is a 4-vetor, gamma matrices are 4x4 matrices, so the whole thing comes down to a dot product of two 4-vectors, with a modified by matrix multiplication/derivatives, and the result is a scalar, as expected for a Lagrangian.
Like any other Lagrangian, you can then recover the Dirac equation, which is the corresponding equations of motion, by applying the Euler-Lagrange equation to the Lagrangian.
Pre-order depth-first search by Ciro Santilli 35 Updated +Created
This is the order in which you would want to transverse to read the chapters of a book.
Like breadth-first search, this also has the property of visiting parents before any children.
Or equivalently, the set of rows is orthonormal, and so is the set of columns. TODO proof that it is equivalent to the orthogonal group is the group of all matrices that preserve the dot product.
Bisection (software engineering) by Ciro Santilli 35 Updated +Created
One of the Holiest age old debugging techniques!
Git has some helpers to help you achieve bisection Nirvana: stackoverflow.com/questions/4713088/how-to-use-git-bisect/22592593#22592593
Obviously not restricted to software engineering alone, and used in all areas of engineering, e.g. Video "Air-tight vs. Vacuum-tight by AlphaPhoenix (2020)" uses it in vacuum engineering.
The cool thing about bisection is that it is a brainless process: unlike when using a debugger, you don't have to understand anything about the system, and it incredibly narrows down the problem cause for you. Not having to think is great!
WikiLeaks by Ciro Santilli 35 Updated +Created
CC BY by Ciro Santilli 35 Updated +Created
SymPy by Ciro Santilli 35 Updated +Created
This is the dream cheating software every student should know about.
It also has serious applications obviously. www.sympy.org/scipy-2017-codegen-tutorial/ mentions code generation capabilities, which sounds super cool!
The code in this section was tested on sympy==1.8 and Python 3.9.5.
Let's start with some basics. fractions:
from sympy import *
sympify(2)/3 + sympify(1)/2
outputs:
7/6
Note that this is an exact value, it does not get converted to floating-point numbers where precision could be lost!
We can also do everything with symbols:
from sympy import *
x, y = symbols('x y')
expr = x/3 + y/2
print(expr)
outputs:
x/3 + y/2
We can now evaluate that expression object at any time:
expr.subs({x: 1, y: 2})
outputs:
4/3
How about a square root?
x = sqrt(2)
print(x)
outputs:
sqrt(2)
so we understand that the value was kept without simplification. And of course:
sqrt(2)**2
outputs 2. Also:
sqrt(-1)
outputs:
I
I is the imaginary unit. We can use that symbol directly as well, e.g.:
I*I
gives:
-1
Let's do some trigonometry:
cos(pi)
gives:
-1
and:
cos(pi/4)
gives:
sqrt(2)/2
The exponential also works:
exp(I*pi)
gives;
-1
Now for some calculus. To find the derivative of the natural logarithm:
from sympy import *
x = symbols('x')
print(diff(ln(x), x))
outputs:
1/x
Just read that. One over x. Beauty. And now for some integration:
print(integrate(1/x, x))
outputs:
log(x)
OK.
Let's do some more. Let's solve a simple differential equation:
y''(t) - 2y'(t) + y(t) = sin(t)
Doing:
from sympy import *
x = symbols('x')
f, g = symbols('f g', cls=Function)
diffeq = Eq(f(x).diff(x, x) - 2*f(x).diff(x) + f(x), sin(x)**4)
print(dsolve(diffeq, f(x)))
outputs:
Eq(f(x), (C1 + C2*x)*exp(x) + cos(x)/2)
which means:
To be fair though, it can't do anything crazy, it likely just goes over known patterns that it has solvers for, e.g. if we change it to:
diffeq = Eq(f(x).diff(x, x)**2 + f(x), 0)
it just blows up:
NotImplementedError: solve: Cannot solve f(x) + Derivative(f(x), (x, 2))**2
Sad.
Let's try some polynomial equations:
from sympy import *
x, a, b, c = symbols('x a b c d e f')
eq = Eq(a*x**2 + b*x + c, 0)
sol = solveset(eq, x)
print(sol)
which outputs:
FiniteSet(-b/(2*a) - sqrt(-4*a*c + b**2)/(2*a), -b/(2*a) + sqrt(-4*a*c + b**2)/(2*a))
which is a not amazingly nice version of the quadratic formula. Let's evaluate with some specific constants after the fact:
sol.subs({a: 1, b: 2, c: 3})
which outputs
FiniteSet(-1 + sqrt(2)*I, -1 - sqrt(2)*I)
Let's see if it handles the quartic equation:
x, a, b, c, d, e, f = symbols('x a b c d e f')
eq = Eq(e*x**4 + d*x**3 + c*x**2 + b*x + a, 0)
solveset(eq, x)
Something comes out. It takes up the entire terminal. Naughty. And now let's try to mess with it:
x, a, b, c, d, e, f = symbols('x a b c d e f')
eq = Eq(f*x**5 + e*x**4 + d*x**3 + c*x**2 + b*x + a, 0)
solveset(eq, x)
and this time it spits out something more magic:
ConditionSet(x, Eq(a + b*x + c*x**2 + d*x**3 + e*x**4 + f*x**5, 0), Complexes)
Oh well.
Let's try some linear algebra.
m = Matrix([[1, 2], [3, 4]])
Let's invert it:
m**-1
outputs:
Matrix([
[ -2,    1],
[3/2, -1/2]])
Cloud computing platform by Ciro Santilli 35 Updated +Created
Everything can break everything by Ciro Santilli 35 Updated +Created
Whenever someone asks:
I can only see this one thing different our setups, do you think it could be the cause of our different behaviour?
you don't need to read anymore, just point them to this page immediately. Virtualization for the win.
Keep debug notes by Ciro Santilli 35 Updated +Created
When debugging complex software, make sure to keep notes of every interesting find you make in a note file, as you extract it from the integrated development environment or debugger.
Especially if your memory sucks like Ciro's.
This is incredibly helpful in fully understanding and then solving complex bugs.
Plasmid by Ciro Santilli 35 Updated +Created
Hydrogen chemosynthesis by Ciro Santilli 35 Updated +Created
Cell wall by Ciro Santilli 35 Updated +Created
Sass (stylesheet language) by Ciro Santilli 35 Updated +Created
The more of their syntax gets merged into mainline Cascading Style Sheets, the better the world will be.
Sugar by Ciro Santilli 35 Updated +Created
We define a "sugar" as either of:because these are small carbohydrates, and they taste sweet to humans.
Fundação Estudar by Ciro Santilli 35 Updated +Created
Video 1.
What I learned in Harvard part 1 by Jorge Paulo Lemann (2012)
Source. Portuguese talk about his experiences. A bit bably, but has a few good comments:
  • You don't learn the Harvard experience, you absorb it.
  • Being amongst excellent people makes you learn what excelent people are like, just like only by tasting many different types of wine can you know what good wine is like.
    This one does have bias danger though. But detecting greatness, is as type of bias arguably.
University of São Carlos by Ciro Santilli 35 Updated +Created
How Bitcoin works by Ciro Santilli 35 Updated +Created
Here is a very direct description of the system:
  • each transaction (transaction is often abbreviated "tx") has a list of inputs, and a list of outputs
  • each input is the output of a previous transaction. You verify your identity as the indented receiver by producing a digital signature for the public key specified on the output
  • each output specifies the public key of the receiver and the value being sent
  • the sum of output values cannot obvious exceed the sum of input values. If it is any less, the leftover is sent to the miner of the transaction as a transaction fee, which is an incentive for mining.
  • once an output is used from an input, it becomes marked as spent, and cannot be reused again. Every input uses the selected output fully. Therefore, if you want to use an input of 1 BTC to pay 0.1 BTC, what you do is to send 0.1 BTC to the receiver, and 0.9 BTC back to yourself as change. This is why the vast majority of transactions has two outputs: one "real", and the other change back to self.
Code 1. "Sample Bitcoin transaction graph" illustrates these concepts:
  • tx0: magic transaction without any inputs, i.e. either Genesis block or a coinbase mining reward. Since it is a magic transaction, it produces 3 Bitcoins from scratch: 1 in out0 and 2 in out1. The initial value was actually 50 BTC and reduced with time: Section "Bitcoin halving"
  • tx1: regular transaction that takes:
    • a single input from tx0 out0, with value 1
    • produces two outputs:
      • out0 for value 0.5
      • out1 for value 0.3
    • this means that there was 0.2 left over from the input. This value will be given to the miner that mines this transaction.
    Since this is a regular transaction, no new coins are produced.
  • tx2: regular transaction with a single input and a single output. It uses up the entire input, leading to 0 miner fees, so this greedy one might (will?) never get mined.
  • tx3: regular transaction with two inputs and one output. The total input is 2.3, and the output is 1.8, so the miner fee will be 0.5
                   tx1                     tx3
  tx0            +---------------+       +---------------+
+----------+     | in0           |       | in0           |
| out0     |<------out: tx0 out0 |  +------out: tx1 out1 |
| value: 1 |     +---------------+  |    +---------------+
+----------+     | out0          |  |    | in1           |
| out1     |<-+  | value: 0.5    |  | +----out: tx2 out0 |
| value: 2 |  |  +---------------+  | |  +---------------+
+----------+  |  | out1          |<-+ |  | out1          |
              |  | value: 0.3    |    |  | value: 1.8    |
              |  +---------------+    |  +---------------+
              |                       |
              |                       |
              |                       |
              |    tx2                |
              |  +---------------+    |
              |  | in0           |    |
              +----out: tx0 out1 |    |
                 +---------------+    |
                 | out0          |<---+
                 | value: 2      |
                 +---------------+
Code 1.
Sample Bitcoin transaction graph
.
Since every input must come from a previous output, there must be some magic way of generating new coins from scratch to bootstrap the system. This mechanism is that when the miner mines successfully, they get a mining fee, which is a magic transaction without any valid inputs and a pre-agreed value, and an incentive to use their power/compute resources to mine. This magic transaction is called a "coinbase transaction".
The key innovation of Bitcoin is how to prevent double spending, i.e. use a single output as the input of two different transactions, via mining.
For example, what prevents me from very quickly using a single output to pay two different people in quick succession?
The solution are the blocks. Blocks discretize transactions into chunks in a way that prevents double spending.
A block contains:
  • a list of transactions that are valid amongst themselves. Notably, there can't be double spending within a block.
    People making transactions send them to the network, and miners select which ones they want to add to their block. Miners prefer to pick transactions that are:
    • small, as less bytes means less hashing costs. Small generally means "doesn't have a gazillion inputs/outputs".
    • have higher transaction fees, for obvious reasons
  • the ID of its parent block. Blocks therefore form a linear linked list of blocks, except for temporary ties that are soon resolved. The longest known list block is considered to be the valid one.
  • a nonce, which is an integer chosen "arbitrarily by the miner"
For a block to be valid, besides not containing easy to check stuff like double spending, the miner must also select a nonce such that the hash of the block starts with N zeroes.
For example, considering the transactions from Code 1. "Sample Bitcoin transaction graph", the block structure shown at Code 2. "Sample Bitcoin blockchain" would be valid. In it block0 contains two transactions: tx0 and tx1, and block1 also contains two transactions: tx2 and tx3.
 block0           block1             block2
+------------+   +--------------+   +--------------+
| prev:      |<----prev: block0 |<----prev: block1 |
+------------+   +--------------+   +--------------+
| txs:       |   | txs:         |   | txs:         |
| - tx0      |   | - tx2        |   | - tx4        |
| - tx1      |   | - tx3        |   | - tx5        |
+------------+   +--------------+   +--------------+
| nonce: 944 |   | nonce: 832   |   | nonce: 734   |
+------------+   +--------------+   +--------------+
Code 2.
Sample Bitcoin blockchain
.
The nonces are on this example arbitrary chosen numbers that would lead to a desired hash for the block.
block0 is the Genesis block, which is magic and does not have a previous block, because we have to start from somewhere. The network is hardcoded to accept that as a valid starting point.
Now suppose that the person who created tx2 had tried to double spend and also created another transaction tx2' at the same time that looks like this:
  tx2'
+---------------+
| in0           |
| out: tx0 out1 |
+---------------+
| out0          |
| value: 2      |
+---------------+
Clearly, this transaction would try to spend tx0 out1 one more time in addition to tx2, and should not be allowed! If this were attempted, only the following outcomes are possible:
  • block1 contains tx2. Then when block2 gets made, it cannot contain tx2', because tx0 out1 was already spent by tx2
  • block1 contains tx2'. tx2 cannot be spent anymore
Notably, it is not possible that block1 contains both tx2 and tx2', as that would make the block invalid, and the network would not accept that block even if a miner found a nonce.
Since hashes are basically random, miners just have to try a bunch of nonces randomly until they find one that works.
The more zeroes, the harder it is to find the hash. For example, on the extreme case where N is all the bits of the hash output, we are trying to find a hash of exactly 0, which is statistically impossible. But if e.g. N=1, you will in average have to try only two nonces, N=2 four nonces, and so on.
The value N is updated every 2 weeks, and aims to make blocks to take 10 minutes to mine on average. N has to be increased with time, as more advanced hashing hardware has become available.
Once a miner finds a nonce that works, they send their block to the network. Other miners then verify the block, and once they do, they are highly incentivized to stop their hashing attempts, and make the new valid block be the new parent, and start over. This is because the length of the chain has already increased: they would need to mine two blocks instead of one if they didn't update to the newest block!
Therefore if you try to double spend, some random miner is going to select only one of your transactions and add it to the block.
They can't pick both, otherwise their block would be invalid, and other miners wouldn't accept is as the new longest one.
Then sooner or later, the transaction will be mined and added to the longest chain. At this point, the network will move to that newer header, and your second transaction will not be valid for any miner at all anymore, since it uses a spent output from the first one that went in. All miners will therefore drop that transaction, and it will never go in.
The goal of having this mandatory 10 minutes block interval is to make it very unlikely that two miners will mine at the exact same time, and therefore possibly each one mine one of the two double spending transactions. When ties to happen, miners randomly choose one of the valid blocks and work on top of it. The first one that does, now has a block of length L + 2 rather than L + 1, and therefore when that is propagated, everyone drops what they are doing and move to that new longest one.

Unlisted articles are being shown, click here to show only listed articles.