'초등함수'에 속하는 '초월함수'들 중에 지수함수인 e^x는 미분을 하던 적분을 하던.. 도함수나 부정적분이 전부 자기 자신과 동일한 굉장히 특이한 기본 함수이다.
지수는 저렇고, 삼각함수/쌍곡선함수는 그냥 답정너 정의에 가깝게 미분-적분 순환고리를 그냥 외운다.
그럼 e^x의 역함수인 ln x는 부정적분이 과연 어찌 될까?

ln x는 도함수가 1/x라는 간단한 형태로 정의되는 덕분에, '부분적분'으로 부정적분을 구하는 아주 교과서적인 예로 다뤄진다.
부분적분은 곱의 미분법으로부터 유도되어 두 함수 F, G의 곱에 대해

F(x)G(x) = ∫ F'(x)G(x) dx + ∫ F(x)G'(x) dx

가 된다는 원리이다. 보통은 저것보다는 순서를 바꿔서

∫ F'(x)G(x) dx = F(x)G(x) - ∫ F(x)G'(x) dx

요런 형태로 더 소개되는 편이다.
ln x의 경우, 위의 부분적분에서 F는 그냥 x로, G는 ln x를 집어넣으면 바로 풀린다. 그러면 F'(x)는 1이라는 상수가 되고 G'(x)는 1/x가 되므로

∫ ln x dx = x*ln x - ∫ x/x dx = x*ln x - x = x(ln x - 1)

이렇게 답이 구해진다. x*(ln x)' 가 x/x로 바뀌어서 1로 상쇄되는 것이 백미이다.;;

사용자 삽입 이미지

그럼 ln x의 0..1 정적분의 값은 얼마일까? 다시 말해 위의 그래프에서 선이 y축의 0 아래로 뚝 떨어지는 구간의 면적은 얼마일까?
저 역도함수에다가 0과 1을 대입해서 차를 구하면 -1임을 알 수 있다. 그러나 더 직관적으로 아는 방법도 있다.
저 구간은 ln x의 역함수인 exp(x)에서 x의 음수 구간 면적과 동일하기 때문이다.

사용자 삽입 이미지

그러니 exp(x)를 0부터 -∞까지 적분해 봐도 동일한 값을 더 쉽게 구할 수 있다. exp는 그냥 자기 함수에다 값을 대입하는 것만으로 적분값을 구할 수 있으니 말이다.

그리고 더 흥미로운 사실이 있다.
ln x의 부정적분인 x(ln x - 1)의 의미는 바로..
저 X축의 x, 그리고 Y축의 ln x라는 직사각형에서.. 맞은편의 역함수 exp(ln x) 구간의 면적을 뺀 나머지 면적이라는 것이다. -x의 의미는 바로 -exp(ln x)라는 것..!!

부분적분에서 곱을 구성하는 두 함수 중의 하나가 그냥 x 자체인 덕분에, 기하학적으로 이런 의미까지 지니게 된 셈이다.
앞서 부분적분 식에서는 x가 x*(1/x)를 적분해서 얻어졌었는데.. 여기서는 exp와 ln이 상쇄되어 얻어졌다는 게 흥미롭다.

이런 부분적분은 삼각함수 등 다른 초월함수들의 '역함수'의 부정적분을 구할 때도 요긴하게 쓰인다.
부분적분의 특성상 원함수의 도함수도 알아야 하는데, 그건 역함수의 미분법을 동원해서 구하면 된다.

다음으로, ln x를 넘어서 (ln x)^2의 정적분을 구하려면?
부분적분 패턴에서 F'(x)와 G(x)를 모두 ln x로 잡으면 된다. 그러면 F(x)는 x*(ln x -1)에 대응하고, 최종적으로는 아래와 같은 복잡한 식이 도출된다.

사용자 삽입 이미지

이를 일반화해서 (ln x)^n의 부정적분은

x*(ln x)^n - a*x*(ln x)^(n-1) + b*x*(ln x)^(n-2) ... +- z*x*(ln x) +- z*x + C (적분상수)

이런 꼴이 된다. 모든 항에 x는 기본으로 붙어 있고 그 다음에 (ln x)의 n승에 대한 항이 형성되어 항의 수는 총 n+1개..
부호는 -와 +가 번갈아가며 바뀐다.
맨 앞의 제일 고차항인 (ln x)^n의 계수는 언제나 1이지만, 그 다음 항인 a...z로 갈수록 n과 n-1, n-2... 가 차례로 곱해져서 n=2일 때는 2 2.. n=3일 때는 3 6 6, n=4일 때는 4 12 24 24... 이렇게 계수가 정해진다.

그러므로 0에서 1까지의 정적분 값은 n의 홀짝 여부에 따라 부호가 교대로 바뀌는(홀-음수, 짝-양수) n!이 된다.
원함수에다가 미리 -를 씌운 (-ln x)^n라고 해 주면 0..1 정적분은 간단하게 n!로 떨어진다. n이 홀수승일 때는 (ln x)^3의 값이 음수이던 것이 - 부호를 만나서 양수로 바뀌고, 짝수승일 때는 거듭제곱이 음수를 양수로 바꾸기 때문에 팩토리얼이 언제나 양수로 나오는 것이 보장된다.

로그의 거듭제곱의 적분이 팩토리얼과 관련이 있다니.. 신기한 노릇이다. 이 덕분에 지수뿐만 아니라 팩토리얼조차도 정의역이 단순히 자연수에 국한되지 않고, 지수함수와 적분와 동급인 실수 영역에 연속적인 형태로 정의될 수 있게 됐다.

(-ln x)^n의 0..1 정적분은 치환적분 기법을 동원해서 다음과 같은 형태로 바꿀 수 있다.

사용자 삽입 이미지

뭐.. 로그를 쓰면 구간이 0~1인데, 지수를 쓰면 구간이 0~무한대로 바뀐다는 차이가 있다. ㄲㄲㄲ
요 함수가 일명 '감마'(Γ) 함수라고 불린다. 단, 감마 함수는 모종의 이유로 인해 팩토리얼과 완전히 같지는 않아서 Γ(n+1)의 값이 n!에 대응한다.

x^x은 0일 때와 1일 때의 함수값이 동일하고, 그 사이엔 함수값이 살짝 작아졌다가 1 이후부터 폭발적으로 커진다.
감마 함수도 양의 실수 구간에서는 이와 비슷한 성질이 있어서 1과 2일 때의 함수값이 동일하다. 그 사이에는 함수값이 약간 작아졌다가 2 이후부터 폭발적으로 커진다.

단, x^x는 미분을 통해 그 최소값을 해석적으로 정확히 구할 수 있는 반면, 감마 함수는 대략 x≒1.46163에서의 최소값 0.88560...을 수치해석으로 구할 뿐이다. 이 수의 정확한 특성은 알려져 있지 않은 것 같다.
그런데.. 감마 함수는 소수점이 .5 인 수.. 다시 말해 자연수에다가 1/2이 첨가된 수에 대해서는 π(원주율)의 제곱근의 배수인 그 무언가를 되돌린다. 이런 것도 여느 지수함수나 그쪽 바리에이션에서는 발견할 수 없는 면모이다.

특히 Γ(1/2)의 값은 딱 정확하게 sqrt(pi)인데, 이것은 정규분포 함수의 원형인 e^(-x^2)의 전구간 적분 면적과 동일한 값이다.
1/2일 때 감마 함수 적분식은 적분변수 x를 sqrt(t)로 치환하면 딱 정확하게 e^(-x^2)의 전구간 적분과 동일한 식이 나오기 때문이다. ㅎㄷㄷㄷ..

물론 e^(-x^2)은 부정적분이 초등함수의 형태로 표현되지 않는 괴상한 물건이며, 가우스 적분이라는 완전히 새로운 방법론을 동원해야 전체 면적만을 구할 수 있다. 이 과정이 뱅그르르 회전과 관계가 있기 때문에 갑자기 원주율이 튀어나오는 것이다. 하지만 이건 이 글의 범위를 한참 넘어서기 때문에 더 자세한 얘기를 생략하겠다.

다시 본론으로 돌아오면.. 로그의 n승을 정적분 했더니 n팩토리얼이 튀어나왔다. 반대로 팩토리얼 값에 로그를 씌운 것도 로그와 관련이 있다. log N!은 수가 증가하는 정도가 N log N과 얼추 비슷하다.
왜 그런가 하면 N!은 1*2*3...*N이니 log N!은 log 1+log 2+log 3+ ...log N과 같기 때문이다. 그리고 이건 log N에 대한 적분에다 근사시킬 수 있으며, 그 부정적분에는 N log N이 포함되어 있다.

컴퓨터 알고리즘 중에서 정렬이라는 건 n개의 원소들을 나열하는 순열 최대 n!개의 가짓수 중에서 오름차순/내림차순 순서를 만족하는 것을 찾아내는 과정이다. 그런데 비교 연산을 한 번 할 때마다 그 가짓수를 이분 검색 하듯이 최대 절반으로 줄일 수 있다.

그러니 가짓수도 팩토리얼로 폭발적이고, 매 단계마다 가짓수를 줄이는 규모도 지수로 폭발적인데.. 결국 비교 연산을 수행하는 정렬 알고리즘의 이론적인 시간 복잡도는 팩토리얼의 로그급인 n log n으로 귀착되는 것이다.

팩토리얼 내지 팩토리얼의 로그를 근사하는 공식을 더 엄밀하게 파고들면 n log n에다가 다른 자잘한 항들도 여럿 붙는다. 이런 건 감마 함수를 변형해서 만들어지는데, '스털링의 근사 공식'이라고 한다.
애초에 x^n * e^(-x)도 e^(n ln x - x)로 바뀌니, n log n이라는 결론이 달라지지는 않는다.

이상이다. 로그에 이렇게 심오한 의미가 많이 담겨 있는 줄 몰랐다.;; 얘기가 꼬리에 꼬리를 물고 이어지는데, 로그의 밑 얘기만 하고 글을 맺도록 하겠다.

이공계에서 쓰이는 로그의 밑은 사실상 딱 세 종류.. 2, e, 아니면 10이라고 보면 되겠다.
2는 컴퓨터과학 전산학에서 특별히 아주 좋아하는 숫자이고, e는 지금까지 봐 왔듯이 천상 수학 미적분 해석학 전용이다. 10은 10진법과 관계가 있다 보니 데시벨이나 pH (산/염기 지수) 같은 로그 기반의 현실 과학 단위에서 쓰인다. 단, 복소해석학으로 가서 로그를 복소수 범위로 확장하면.. 0과 1만 빼고 -1이나 i조차 로그의 밑이 될 수 있으니 참 ㅎㄷㄷ하다.

현실에서 엄청 큰 측정값을 표기할 일이 있으면, 어지간해서는 메가· 기가· 테라· 페타 같은 접두사를 동원해서 자릿수를 줄이는 걸로 퉁칠 것이다. 아예 로그를 동원해서 자릿수를 후려친다는 건 정말 그 분야에서 얻을 수 있는 측정값의 스케일이 0의 개수 자릿수 차원에서 극단적으로 널뛰기 한다는 걸 뜻한다.

원래는 log 다음에 아래첨자로 밑을 일일이 써 주는 게 정석이다. 그러나 쓰이는 밑이 분야별로 저렇게 뻔히 답정너이니.. 그런 번거로운 표기는 잘 쓰이지 않는다. 밑이 e인 로그는 자연로그라고 해서 그냥 ln이라고 쓰는 정도?
밑을 생략한 log 표기는 밑이 무엇이건 중요하지 않고, 수가 증가하는 게 log 스케일이라는 것만이 중요할 때 쓰인다. 앞서 언급했던 시간 복잡도 표기처럼 말이다.

Posted by 사무엘

2022/10/01 08:35 2022/10/01 08:35
, , , , ,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/2073

우리는 학교에서 산수를 배우면서 덧셈을 가장 먼저 배우고, 그 뒤 이들을 묶은 형태인 곱셈을 배운다. 그리고 나중에는 곱셈을 묶은 거듭제곱이라는 걸 배운다. 그런데 덧셈이나 곱셈과는 달리, 거듭제곱은 같은 수를 곱하기를 반복한다는 직관적인 정의만 적용해서는 정수가 아닌 형태의 거듭제곱을 생각하기가 쉽지 않다.

지수법칙이 있으니 유리수 승까지는 그래도 괜찮다. 정수 승과 정수 제곱근으로 설명이 가능하기 때문이다. 하지만 이를 초월하여 2^sqrt(2)처럼 임의의 실수 승은 어떻게 해야 계산하고 표현할 수 있을까?

거듭제곱을 모든 실수 범위에서 정의함으로써 지수함수라 불리는 연속인 함수의 형태로 영역을 확장하는 데는, '연속'이라는 개념에서 알 수 있듯, 미분의 도입이 큰 기여를 했다. 자연상수 e가 발견되고 로그 함수라는 게 생기면서 지수함수는 로그의 역함수로서 정체성을 확립하게 되었다.

이 글에서 수학적으로 엄밀한 디테일을 다 말할 수는 없지만, e는 임의의 수에다 제곱근을 반복하면서 지수가 0에 가까워지고 원래 수가 1에 한없이 가까워질 때 그 수의 소숫점, 다시 말해 숫자에서 1을 뺀 값이 지수와 어떤 비례 관계가 있는지를 규명하는 과정에서 발견되었다. (1+1/n)^n에서 n의 무한대 극한이라는 원론적인 정의가 바로 거기서 유래되었으며, 사실, (1+x/n)^n라고 해 주면 그냥 exp(x)를 바로 구할 수 있다.

exp(x)는 0인 지점에서 기울기가 1이다. 그리고 미분해도 도함수가 자기 자신과 같다는 매우 중요한 특징이 있다. 즉, y=exp(x)에 있는 점 (x, y)의 기울기는 곧 y라는 뜻. 그럼 이놈의 역함수는 어떻게 될까? 본디 함수와 그 역함수는 y=x에 대해 대칭이므로, 점 (y, x)의 기울기는 곧 1/y여야 한다.

미분하면 1/x가 되는 함수를 찾아보니 다름아닌 ln x이다. 복잡한 거듭제곱을 곱셈으로, 곱셈은 덧셈으로 바꿀 수 있는 놀라운 함수 말이다. 그래서 exp는 로그의 역함수인 고로 그 정체가 e^x인 지수함수라는 결론이 도출되고, 그래서 로그와 지수의 함수 관계가 완성될 수 있었다.

a^b = e^(b ln a)이다. ln a^b는 b ln a이므로 양변에 자연로그를 씌우면 아주 자연스럽게 유도 가능하다.

또한 굳이 밑이 e가 아닌 임의의 a인 로그를 생각하더라도, log[a] b = ln b / ln a이다. 이것은 지수보다는 약간 연상이 쉽지 않을지 모르나, 이 경우를 생각해 보자. 로그의 정의상 당연히 a^(log[a] b) = b이다. 이 식 자체에다가 자연로그를 씌우면 log[a] b * ln a = ln b가 되고, 그 후의 논리 전개는 생략. ㄲㄲ

이건 굉장히 유용한 특징이다. 이 덕분에 exp와 ln만 있으면 우리는 임의의 지수의 값도 구할 수 있고, 임의의 로그의 값도 구할 수 있게 된다.
그럼 이 함수의 값을 실제로 컴퓨터로 어떻게 계산하면 좋을까?

이걸 연구하는 분야는 기호, 순수함, 추상성만을 좋아하는 전통적인 수학에서 벗어나 일면 '지저분한 이단아'처럼 보일 수도 있는 수치해석 쪽으로 가게 된다. 컴퓨터에서 exp, ln, cos, sin 같은 기초적인 초월함수의 값을 조금이라도 더 빠르고 정확하게 구하는 기법은 이미 천재 컴덕후, 수학자, 공학자들이 연구할 대로 다 연구해서 소프트웨어 정도가 아니라 아예 하드웨어에 회로에 다 코딩되어 있을 정도이다.

그러니 내가 거기에 뭔가를 더 기여할 게 있다고 여겨지지는 않는다. 단지 본인은 핵심적인 아이디어만 직접 짜 보고 넘어갈 생각이다.
초월함수들의 근사값을 계산하는 아이디어도 미분에서 유래되었다. 단순히 1차함수 접선을 구하는 것을 넘어서 곡선과 가장 가까운 n차 근사 다항식을 구하는 것으로 생각을 확장하면 '테일러 근사 다항식'이라는 걸 구할 수 있고, 무한히 미분 가능한 함수에 대해서는 무한합인 그 이름도 유명한 테일러 급수라는 걸 유도할 수 있다.

* 이말년 씨리즈와 Taylor series는 서로 느껴지는 포스가 확 다르다. 흠.;;;

exp(x)는 예전에도 글로 썼듯이, 원론적인 정의를 이용해서 값을 구할 리는 절대 없고, 테일러 급수를 쓴다. 아래의 코드는 16항 정도까지 계산했다.

double pseudo_exp(double x)
{
    double v=1.0, p=x,q=1.0;
    for(int i=1; i<=16; i++, v+=p/q, p*=x, q*=i);
    return v;
}

단, 이 급수는 x=0인 지점을 기준으로 구한 것이기 때문에 x가 8~9 정도만 넘어가도 오차가 상당히 커진다. 하지만 컴퓨터 부동소숫점에도 한계가 있으니 항을 한없이 많이 계산할 수도 없는 노릇이고, 큰 수에 대해서는 다른 방법으로 보정이 필요할 듯하다.

한편, 로그는 어떻게 구할까?
자연로그도 다음과 같은 직관적인 형태의 테일러 급수가 있긴 하다.

ln (1+x) = x (+-) x^n/n (n이 짝수일 때는 빼기, 홀수일 때는 더하기)

그런데 이 급수는 x가 -1 초과 1 미만일 때만 유효하고, 따라서 0과 2 사이의 로그값만 구할 수 있다. 나머지 범위는 항을 제아무리 많이 계산해 줘도 아예 원천적으로 원함수와 전혀 일치하지 않게 된다. 테일러 급수가 모든 범위에 대해서 무조건 만능은 아님을 알 수 있다.

하지만 지수함수와는 달리 로그는 ln ab = ln a + ln b라고 큰 숫자를 한없이 쪼개는 마법과 같은 공식이 있다. 그러므로 저것만 있어도 아무 수의 로그라도 구할 수 있다.

즉, ln 2의 값을 미리 갖고 있다가 임의의 수에 대해서 2보다 작아질 때까지 ln 2를 따로 더하면서 계속 2로 나누면 된다. 2는 잘 알다시피 2진법을 쓰는 컴퓨터가 좋아하는 수이기도 하고 말이다. 그래서 주어진 수가 2 이하의 범위에 들어오면 그때 급수를 써서 최종적으로 구한 로그값을 또 더하면 된다.

double pseudo_ln(double x)
{
    #define LN_2  0.693147180559945
    double v=0;
    while(x>2.0) x/=2.0, v+=LN_2;

    double x_min1 = x-1, xm = x_min1;
    for(int i=1; i<=16; i++, xm*=x_min1)
    if(i&1) v+=xm/i; else v-=xm/i;
    return v;
}

단, 이 급수의 아쉬운 점은 x가 0이나 2라는 양 극단에 가까워질 때 정확도가 꽤 크게 떨어진다는 점이다. 이는 계산하는 항의 수를 충분히 크게 잡아도 쉽게 극복되지 않는다.

그래서 성능면에서 실용적인 가치는 별로-_- 없지만, ln이 exp의 역함수라는 점을 이용하여, 기존 exp 함수로부터 방정식 근 찾기 기법을 이용하여 로그를 구하는 방법도 이 기회에 실습하게 되었다. 그게 없으면 무엇보다도 초기에 정확하게 값이 구해진 채 공급되어야 하는 LN_2 내장값은 또 어떻게 구하겠는가?

일변수 방정식의 근을 찾는 기법은 수치해석 교재에서 가장 먼저 다뤄지는 기초 주제이다.
exp(x)는 기복이 없으며 그래프 모양이 워낙 예쁘고 원천적이기-_- 때문에, 근이 존재하는 초기 구간만 잡아 주면, 어떤 근 찾기 알고리즘을 쓰더라도 근을 구할 수는 있다. 단지 얼마나 빨리 수렴하여 구해 내느냐가 문제일 뿐이다. 애초에 지수 함수 정도면 범용적인 방정식 근 찾기 알고리즘이 과분하게 느껴질 정도로 특징이 너무 분명하기도 하고 말이다.

가장 먼저 나오는 것은 이분법(bisect)이다. 이게 자료구조에서는 이분법이라고 하면 이분 검색처럼 log n 시간 만에 문제를 푸는 효율적인 알고리즘이라고 불리는 반면, 수치해석에서는 정수 개의 discrete한 데이터가 아니라 사실상 연속인 구간을 다룬다. 그렇기 때문에 통상적인 이분법조차도 수렴이 느린 비효율적인 방법으로 간주된다.

double solve_bisect( double (*pfn)(double), double v )
{
    double f=-10.0, t=10.0; int nt=0;
    while(1) {
        double d = (f+t)/2.0;
        double p = pfn(d) - v;
        if(fabs(p) < 0.000001) break;
        if(p > 0) t=d; else f=d; nt++;
    }
    return f; //nt는 계산 횟수 counter
}

double pseudo_ln2(double x)
{
    return solve_bisect(pseudo_exp, x);
}

근 찾기 알고리즘 중에서는 뉴턴-랩슨(혹은 그냥 뉴턴) 법이 수렴이 매우 빠른 알고리즘으로 여겨지고 있다. 이 방법은 이분법과는 달리 시작점과 끝점이라는 구간을 잡고 시작하는 게 아니라 시작점에서 해당 방정식의 접선을 그은 뒤, 접선과 x축이 만나는(y=0) 지점을 다음 점으로 잡는다. 이 작업을 방정식의 값이 근인 0과 충분히 가까워질 때까지 반복한다.

사용자 삽입 이미지


방정식 f(x) 위의 점 (x_0, f(x_0))을 지나는 접선의 방정식은 기울기가 f'(x_0)일 테니 y=f'(x_0)*x + f(x_0) -f'(x_0)*x_0이 된다. 그래야 x에다가 x_0을 집어넣었을 때 f'(x_0) 나부랭이는 소거되고 함수값으로  f(x_0)만 남기 때문이다.
이 접선이 y=0을 만족시키는 다음 점 x_1을 방정식으로 풀면 x_1=x_0 - f(x_0)/f'(x_0)이라는 생각보다 깔끔한 식이 나온다. 이를 코딩하면,

double solve_newton( double (*pfn)(double), double (*pfn_prime)(double), double v )
{
    double d = 0.0; int nt=0;
    while(1) {
        double p = pfn(d) - v;
        if(fabs(p) < 0.000001) break;
        d = d - p / pfn_prime(d); nt++;
    }
    return d;
}

double pseudo_ln3(double x)
{
    return solve_newton(pseudo_exp, pseudo_exp, x);
}

뉴턴 법 함수는 도함수의 포인터를 별도로 받는데, exp는 어차피 도함수가 자신과 동일하므로 자신을 한번 더 넘겨주면 된다는 점도 특징이다.

프로그램을 실제로 돌려 보면 알겠지만, 동일 오차 범위를 줬을 때 뉴턴 법은 이분법보다 통상 2~5배나 더 빨리 수렴하는 걸 볼 수 있다. 마치 퀵 정렬이 pivot을 기준으로 자료가 그럭저럭 이미 정렬돼 있을수록 더욱 빨리 동작하고 자료의 상태에 민감하듯, 뉴턴 법은 접선과 가까운 형태의 부드러운 곡선일수록 수렴이 더욱 빨라진다.

자, 지금까지 공대 학부 수준의 아주 허접한 수학 덕질을 감각 유지 차원에서 잠시 복습해 보았다. 각종 공식들이 유도되는 원리를 좀 더 깊이 생각해 보고 싶으나 시간과 여유가 부족하다.

아, 수학에서는 거듭제곱뿐만이 아니라 팩토리얼까지도 자연수가 아닌 실수, 그리고 복소수 범위에까지 정의하고 그 증가폭을 측정하는 방법에 대해 연구가 진행돼 있다. 그 일환으로 ln n!이 n log n - n과 얼추 비슷하다는 스털링의 공식이 있고, 그보다 더 괴랄한 감마 함수라는 것도 있어서 z! = Γ(z+1)이다. 머리 좋은 똘똘이들의 수학 덕질의 끝은 도대체 어디까지인지를 다시 생각하게 된다.

Posted by 사무엘

2012/09/10 19:32 2012/09/10 19:32
, , , , ,
Response
No Trackback , 2 Comments
RSS :
http://moogi.new21.org/tc/rss/response/731


블로그 이미지

그런즉 이제 애호박, 단호박, 늙은호박 이 셋은 항상 있으나, 그 중에 제일은 늙은호박이니라.

- 사무엘

Archives

Authors

  1. 사무엘

Calendar

«   2024/04   »
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30        

Site Stats

Total hits:
2663323
Today:
498
Yesterday:
1553