Markdownの練習

オイラーの公式の微分による証明

オイラーの公式は、数学で最も美しい関係の一つとされている。

  • e^{i \theta} = \cos \theta + i \sin \theta

この公式を微分を用いて証明する手順を簡潔に示す。

関数 f(\theta) の定義

まず、オイラーの公式の左辺と右辺の比をとって、次のような関数 f(\theta) を定義する。

  • f(\theta) = \frac{\cos \theta + i \sin \theta}{e^{i \theta}}

もし f(\theta) が恒等的に 1 に等しいと証明できれば、オイラーの公式が成立することになる。

関数 f(\theta) の微分

次に、この関数 f(\theta)\theta で微分する。積の微分公式を使うために f(\theta) を書き換える。

  • f(\theta) = (\cos \theta + i \sin \theta) \cdot e^{-i \theta}

これを \theta で微分する。

  • \frac{d}{d\theta} f(\theta) = \frac{d}{d\theta} (\cos \theta + i \sin \theta) \cdot e^{-i \theta} + (\cos \theta + i \sin \theta) \cdot \frac{d}{d\theta} (e^{-i \theta})

ここで、それぞれの微分を実行する。

  • \frac{d}{d\theta} (\cos \theta + i \sin \theta) = -\sin \theta + i \cos \theta
  • \frac{d}{d\theta} (e^{-i \theta}) = e^{-i \theta} \cdot (-i) = -i e^{-i \theta}

これらを代入し、共通因子 e^{-i \theta} でくくる。

  • \frac{d}{d\theta} f(\theta) = e^{-i \theta} \left[ (-\sin \theta + i \cos \theta) - i (\cos \theta + i \sin \theta) \right]

角括弧の中を展開し、i^2 = -1 を用いて整理する。

  • \frac{d}{d\theta} f(\theta) = e^{-i \theta} \left[ -\sin \theta + i \cos \theta - i \cos \theta - i^2 \sin \theta \right]
  • \frac{d}{d\theta} f(\theta) = e^{-i \theta} \left[ -\sin \theta + i \cos \theta - i \cos \theta + \sin \theta \right]

項がすべて打ち消し合い、結果は 0 になる。

  • \frac{d}{d\theta} f(\theta) = e^{-i \theta} \cdot 0 = 0

証明の完了

微分 \frac{d}{d\theta} f(\theta) が恒等的に 0 であるため、関数 f(\theta) は定数 C となる。

  • f(\theta) = C

\theta=0 を代入して定数を求める。

  • f(0) = \frac{\cos 0 + i \sin 0}{e^{i \cdot 0}} = \frac{1 + i \cdot 0}{e^0} = 1

よって、C=1 が導かれ、f(\theta)=1 が成立する。

  • \frac{\cos \theta + i \sin \theta}{e^{i \theta}} = 1

これにより、オイラーの公式が証明された。

  • e^{i \theta} = \cos \theta + i \sin \theta

Tkrzwの各種言語バインディング

DBMライブラリであるTkrzwは様々な言語のバインディングをサポートしている。C++、C、Java、Python、Ruby、Goにおける最も簡単なサンプルコードを個々に示す。

C++

#include "tkrzw_dbm_hash.h"

// Main routine.
int main(int argc, char** argv) {
  // All symbols of Tkrzw are under the namespace "tkrzw".
  using namespace tkrzw;

  // Creates the database manager.
  HashDBM dbm;

  // Opens a new database.
  dbm.Open("casket.tkh", true);

  // Stores records.
  dbm.Set("foo", "hop");
  dbm.Set("bar", "step");
  dbm.Set("baz", "jump");

  // Retrieves records.
  std::cout << dbm.GetSimple("foo", "*") << std::endl;
  std::cout << dbm.GetSimple("bar", "*") << std::endl;
  std::cout << dbm.GetSimple("baz", "*") << std::endl;
  std::cout << dbm.GetSimple("outlier", "*") << std::endl;

  // Traverses records.
  std::unique_ptr<DBM::Iterator> iter = dbm.MakeIterator();
  iter->First();
  std::string key, value;
  while (iter->Get(&key, &value) == Status::SUCCESS) {
    std::cout << key << ":" << value << std::endl;
    iter->Next();
  }

  // Closes the database.
  dbm.Close();

  return 0;
}

C

#include <stdio.h>
#include "tkrzw_langc.h"

// Main routine.
int main(int argc, char** argv) {
  // Opens the database file.
  TkrzwDBM* dbm = tkrzw_dbm_open(
      "casket.tkh", true, "truncate=true,num_buckets=100");

  // Stores records.
  tkrzw_dbm_set(dbm, "foo", -1, "hop", -1, true);
  tkrzw_dbm_set(dbm, "bar", -1, "step", -1, true);
  tkrzw_dbm_set(dbm, "baz", -1, "jump", -1, true);

  // Retrieves a record.
  char* value_ptr = tkrzw_dbm_get(dbm, "foo", -1, NULL);
  if (value_ptr) {
    puts(value_ptr);
    free(value_ptr);
  }

  // Traverses records.
  TkrzwDBMIter* iter = tkrzw_dbm_make_iterator(dbm);
  tkrzw_dbm_iter_first(iter);
  while (true) {
    char* key_ptr = NULL;
    if (!tkrzw_dbm_iter_get(iter, &key_ptr, NULL, &value_ptr, NULL)) {
      break;
    }
    printf("%s:%s\n", key_ptr, value_ptr);
    free(key_ptr);
    free(value_ptr);
    tkrzw_dbm_iter_next(iter);
  }
  tkrzw_dbm_iter_free(iter);

  // Closes the database file.
  tkrzw_dbm_close(dbm);

  return 0;
}

Java

import tkrzw.*;

public class Example1 {
  public static void main(String[] args) {
    // Prepares the database.
    DBM dbm = new DBM();
    dbm.open("casket.tkh", true);

    // Sets records.
    // Keys and values are implicitly converted into byte arrays.
    dbm.set("first", "hop");
    dbm.set("second", "step");
    dbm.set("third", "jump");

    // Retrieves record values.
    // If the operation fails, null is returned.
    // If the class of the key is String, the value is converted into String.
    System.out.println(dbm.get("first"));
    System.out.println(dbm.get("second"));
    System.out.println(dbm.get("third"));
    System.out.println(dbm.get("fourth"));

    // Checks and deletes a record.
    if (dbm.contains("first")) {
      dbm.remove("first");
    }

    // Traverses records.
    // After using the iterator, it should be destructed explicitly.
    Iterator iter = dbm.makeIterator();
    iter.first();
    while (true) {
      String[] record = iter.getString();
      if (record == null) {
        break;
      }
      System.out.println(record[0] + ": " + record[1]);
      iter.next();
    }
    iter.destruct();

    // Closes the database.
    dbm.close();
  }
}

Python

import tkrzw

## Prepares the database.
dbm = tkrzw.DBM()
dbm.Open("casket.tkh", True, truncate=True, num_buckets=100)

## Sets records.
## If the operation fails, a runtime exception is raised.
## Keys and values are implicitly converted into bytes.
dbm["first"] = "hop"
dbm["second"] = "step"
dbm["third"] = "jump"

## Retrieves record values.
## If the operation fails, a runtime exception is raised.
## Retrieved values are strings if keys are strings.
print(dbm["first"])
print(dbm["second"])
print(dbm["third"])
try:
    print(dbm["fourth"])
except tkrzw.StatusException as e:
    print(repr(e))

## Checks and deletes a record.
if "first" in dbm:
    del dbm["first"]

## Traverses records.
## Retrieved keys and values are always bytes so we decode them.
for key, value in dbm:
    print(key.decode(), value.decode())

## Closes the database.
dbm.Close()

Ruby

require 'tkrzw'

## Prepares the database.
dbm = Tkrzw::DBM.new
dbm.open("casket.tkh", true, truncate: true,num_buckets: 100)

## Sets records.
dbm["first"] = "hop"
dbm["second"] = "step"
dbm["third"] = "jump"

## Retrieves record values.
## If the operation fails, nil is returned.
p dbm["first"]
p dbm["second"]
p dbm["third"]
p dbm["fourth"]

## Checks and deletes a record.
if dbm.include?("first")
  dbm.remove("first")
end

## Traverses records.
dbm.each do |key, value|
  p key + ": " + value
end

## Closes and the database.
dbm.close

Go

package main

import (
  "fmt"
  "github.com/estraier/tkrzw-go"
)

func main() {
  // Prepares the database.
  dbm := tkrzw.NewDBM()
  dbm.Open("casket.tkh", true,
    tkrzw.ParseParams("truncate=true,num_buckets=100"))

  // Sets records.
  // Keys and values are implicitly converted into bytes.
  dbm.Set("first", "hop", true)
  dbm.Set("second", "step", true)
  dbm.Set("third", "jump", true)

  // Retrieves record values as strings.
  fmt.Println(dbm.GetStrSimple("first", "*"))
  fmt.Println(dbm.GetStrSimple("second", "*"))
  fmt.Println(dbm.GetStrSimple("third", "*"))

  // Checks and deletes a record.
  if dbm.Check("first") {
    dbm.Remove("first")
  }

  // Traverses records with a range over a channel.
  for record := range dbm.EachStr() {
    fmt.Println(record.Key, record.Value)
  }

  // Closes the database.
  dbm.Close()
}

Ubuntuをインストールした後の作業

STGYとは直接関係ないが、ついでにその他の開発用のツールを入れておく。

sudo apt install gcc
  • gcc, g++
  • python3, python3-dev
  • ruby, ruby-dev
  • perl, libperl-dev
  • lua5.5, liblua5.5-dev
  • make, automake, autoconf, pkgconf, libtool
  • libgtest-dev, cmake
  • imagemagick-7.q16hdri, ffmpeg, dcraw, enfuse, exiftool, libopencv-dev
  • postgresql-client

その後、Trkzwと各種バインディングをインストールする。

Pythonパッケージ導入のためにpip3を実行するとグローバルパッケージを入れるように促されるので、--break-system-packagesをつける。

sudo pip3 install --break-system-packages legacy-cgi
  • legacy-cgi
  • regex
  • numpy
  • opencv-python