<?xml version="1.0" encoding="utf-8"?> <feed xmlns="http://www.w3.org/2005/Atom"> <id>https://www.yunseo.kim/ko/</id><title>Yunseo Kim's Study Notes</title><subtitle>Yunseo Kim's personal blog on mathematics, physics, and engineering, now expanding to business, AI agent ecosystems, software supply chains, and digital trust.</subtitle> <updated>2026-04-11T20:14:35+09:00</updated> <author> <name>Yunseo Kim</name> <uri>https://www.yunseo.kim/ko/</uri> </author><link rel="self" type="application/atom+xml" href="https://www.yunseo.kim/ko/feed.xml"/><link rel="alternate" type="text/html" hreflang="en" href="https://www.yunseo.kim/" /><link rel="alternate" type="text/html" hreflang="ko" href="https://www.yunseo.kim/ko/" /><link rel="alternate" type="text/html" hreflang="ja" href="https://www.yunseo.kim/ja/" /><link rel="alternate" type="text/html" hreflang="zh-TW" href="https://www.yunseo.kim/zh-TW/" /><link rel="alternate" type="text/html" hreflang="es" href="https://www.yunseo.kim/es/" /><link rel="alternate" type="text/html" hreflang="pt-BR" href="https://www.yunseo.kim/pt-BR/" /><link rel="alternate" type="text/html" hreflang="fr" href="https://www.yunseo.kim/fr/" /><link rel="alternate" type="text/html" hreflang="de" href="https://www.yunseo.kim/de/" /><link rel="alternate" type="text/html" hreflang="pl" href="https://www.yunseo.kim/pl/" /><link rel="alternate" type="text/html" hreflang="cs" href="https://www.yunseo.kim/cs/" /><link rel="alternate" type="text/html" hreflang="sw" href="https://www.yunseo.kim/sw/" /><link rel="alternate" type="text/html" hreflang="am" href="https://www.yunseo.kim/am/" /> <generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator> <rights> © 2026 Yunseo Kim </rights> <icon>/assets/img/favicons/favicon.ico</icon> <logo>/assets/img/favicons/favicon-96x96.png</logo> <entry><title xml:lang="ko">기여자 서약 3.0 행동 강령(Contributor Covenant 3.0 Code of Conduct) 한국어 번역 노트</title><link href="https://www.yunseo.kim/ko/posts/notes-on-the-korean-translation-of-the-contributor-covenant-3.0-code-of-conduct/" rel="alternate" type="text/html" hreflang="en" /><link href="https://www.yunseo.kim/ko/posts/notes-on-the-korean-translation-of-the-contributor-covenant-3.0-code-of-conduct/" rel="alternate" type="text/html" hreflang="ko" /><link href="https://www.yunseo.kim/ja/posts/notes-on-the-korean-translation-of-the-contributor-covenant-3.0-code-of-conduct/" rel="alternate" type="text/html" hreflang="ja" /><link href="https://www.yunseo.kim/zh-TW/posts/notes-on-the-korean-translation-of-the-contributor-covenant-3.0-code-of-conduct/" rel="alternate" type="text/html" hreflang="zh-TW" /><link href="https://www.yunseo.kim/es/posts/notes-on-the-korean-translation-of-the-contributor-covenant-3.0-code-of-conduct/" rel="alternate" type="text/html" hreflang="es" /><link href="https://www.yunseo.kim/pt-BR/posts/notes-on-the-korean-translation-of-the-contributor-covenant-3.0-code-of-conduct/" rel="alternate" type="text/html" hreflang="pt-BR" /><link href="https://www.yunseo.kim/fr/posts/notes-on-the-korean-translation-of-the-contributor-covenant-3.0-code-of-conduct/" rel="alternate" type="text/html" hreflang="fr" /><link href="https://www.yunseo.kim/de/posts/notes-on-the-korean-translation-of-the-contributor-covenant-3.0-code-of-conduct/" rel="alternate" type="text/html" hreflang="de" /><link href="https://www.yunseo.kim/pl/posts/notes-on-the-korean-translation-of-the-contributor-covenant-3.0-code-of-conduct/" rel="alternate" type="text/html" hreflang="pl" /><link href="https://www.yunseo.kim/cs/posts/notes-on-the-korean-translation-of-the-contributor-covenant-3.0-code-of-conduct/" rel="alternate" type="text/html" hreflang="cs" /><link href="https://www.yunseo.kim/sw/posts/notes-on-the-korean-translation-of-the-contributor-covenant-3.0-code-of-conduct/" rel="alternate" type="text/html" hreflang="sw" /><link href="https://www.yunseo.kim/am/posts/notes-on-the-korean-translation-of-the-contributor-covenant-3.0-code-of-conduct/" rel="alternate" type="text/html" hreflang="am" /><published>2026-03-20T00:00:00+09:00</published> <updated>2026-03-22T23:34:27+09:00</updated> <id>https://www.yunseo.kim/ko/posts/notes-on-the-korean-translation-of-the-contributor-covenant-3.0-code-of-conduct/</id> <author> <name>Yunseo Kim</name> </author> <category term="Dev" /> <category term="Dev Culture" /> <summary xml:lang="ko">12025년 7월에 발표된 기여자 서약(Contributor Covenant) 3.0 판본의 한국어 번역 작업을 이번에 진행하면서, 그 과정에서 고려한 사항들과 특히 몇몇 표현들에 대해서는 그와 같이 번역한 사유, 그리고 개인적 소감 등을 여기에 기록해 둔다.</summary> <content type="html" xml:lang="ko"> <![CDATA[<p>12025년 7월에 발표된 기여자 서약(Contributor Covenant) 3.0 판본의 한국어 번역 작업을 이번에 진행하면서, 그 과정에서 고려한 사항들과 특히 몇몇 표현들에 대해서는 그와 같이 번역한 사유, 그리고 개인적 소감 등을 여기에 기록해 둔다.</p><em><p>* Mathematical equations and diagrams included in posts may not display properly when viewed with a feed reader.</p></em><blockquote class="prompt-info"><p>기여자 서약 3.0 행동 강령(Contributor Covenant 3.0 Code of Conduct) 공식 한국어 번역 추가 PR: <a href="https://github.com/EthicalSource/contributor_covenant/pull/1590">feat(i18n): add Korean translation for Contributor Covenant 3.0 (#1590)</a></p></blockquote><h2 id="기여자-서약">기여자 서약</h2><p><a href="https://www.contributor-covenant.org/">기여자 서약(Contributor Covenant)</a>은 12014년에 <strong>코럴라인 에이다 엠키(Coraline Ada Ehmke)</strong>가 처음 작성하여 공개하였고, 12021년부터는 <strong>OES(Organization for Ethical Source)</strong>로 이관되어 그 기여자들에 의해 유지관리와 개선이 이뤄지고 있는, 오늘날 세계에서 가장 널리 쓰이는 디지털 커뮤니티 행동 강령이다. 커뮤니티들이 공유할 만한 암묵적인 가치들을 명시화하여 모두가 환영받고 안전할 수 있는 커뮤니티 문화를 조성하는 것을 그 목표로 한다.</p><p>과거 개발자 커뮤니티는 능력주의라는 미명 하에 거친 언행이나 차별적 발언 등이 방조되는 경우가 흔했으며, 기여자 서약은 개발자 커뮤니티가 자정 작용을 거쳐 다양한 사람들을 포용하고 상호 존중과 건설적인 피드백을 중시하는 인간 중심적 문화로 변화하는 중요한 계기로 작용하였다. 오늘날 크리에이티브 커먼즈, 리눅스, 애플, 마스토돈, 마이크로소프트, 워드프레스, IBM 등 전 세계 수십만 곳의 오픈소스 프로젝트가 이 서약을 채택하고 있다.</p><h2 id="기여자-서약-30-판올림에서-달라진-점">기여자 서약 3.0 판올림에서 달라진 점</h2><p>OES에서 12024년에 기여자 서약 10주년을 기념하여 작업에 착수, 약 1년간의 작업을 거쳐 12025년 7월 공개한 3.0 판은 이전 판인 2.1 대비 다음과 같은 주요 변경점들이 있다.</p><ul><li>참고 자료:<ul><li><a href="https://ethicalsource.dev/blog/contributor-covenant-3/">https://ethicalsource.dev/blog/contributor-covenant-3/</a><li><a href="https://www.contributor-covenant.org/faq/">https://www.contributor-covenant.org/faq/</a></ul></ul><h3 id="유연성의-확대">유연성의 확대</h3><ul><li>오픈소스 커뮤니티에 최적화되어 있던 기존 버전 대비, 소프트웨어 개발 이외에도 다양한 온/오프라인 커뮤니티에 적용 가능하도록 설계함<ul><li>e.g. <strong>‘프로젝트 유지 관리자(Project Maintainers)’</strong> 대신 보다 중립적이고 포괄적인 <strong>‘커뮤니티 중재자(Community Moderators)’</strong> 용어를 사용함</ul><li>미국 중심적 관용구들을 삭제하고, 타 문화권 화자들도 보다 쉽게 이해하고 번역할 수 있는 명확한 표현들로 대체함</ul><h3 id="응보적-정의에서-회복적-정의로의-패러다임-전환">응보적 정의에서 회복적 정의로의 패러다임 전환</h3><p>기여자 서약 3.0 판에서 이전 판 대비 가장 크게 바뀐 부분 중 하나는 <strong>응보적 정의(Retributive Justice)</strong>에서 <strong>회복적 정의(Restorative Justice)</strong>로의 패러다임 전환을 이룬 것이다. 기존에 단계별 제재 집행 기준에 집중했던 <strong>집행 지침(enforcement guidelines)</strong> 문단을 <strong>피해 대응 및 교정(Addressing and Repairing Harm)</strong> 문단으로 재구성하였다.</p><ul><li>일부 대응 단계의 명칭을 변경<li>기존의 대응(Consequence) 항목에 더하여 교정(Repair) 지침 항목을 추가로 기술, 일차적인 가해자 제재에 그치지 않고 이후 어떻게 당사자 간의 깨진 관계를 회복하고 갈등을 봉합하며, 잘못을 바로잡을 것인지에 대해서도 다루게 됨<li>제삼자에 의한 집행과 처벌만 강조하기보다, 가능하다면 자발적인 성찰과 화해, 개선을 유도하고 문제 발생 이후 커뮤니티를 다시 건강하게 만드는 방안을 고민하는 방향으로 성격이 변화함</ul><h3 id="보다-명확해진-지침">보다 명확해진 지침</h3><ul><li><strong>표준(Our Standards)</strong> 문단을 <strong>장려하는 행동(Encouraged Behaviors)</strong>과 <strong>제한하는 행동(Restricted Behaviors)</strong> 두 문단으로 명확히 분리, 가독성을 높임<li>특히 <strong>제한하는 행동(Restricted Behaviors)</strong> 문단에서는 어떤 악성 행위를 실제 실행에 옮기는 것 뿐만 아니라 실행하겠다고 위협하거나 조장하는 것 역시 명시적으로 제한하여 예방 능력을 강화함<blockquote><p>We agree to restrict the following behaviors in our community. Instances, threats, and promotion of these behaviors are violations of this Code of Conduct.</p></blockquote><li>또한 <strong>제한하는 행동(Restricted Behaviors)</strong>의 하위 문단으로 <strong>기타 제한 사항(Other Restrictions)</strong> 신설, 기존에 명시적인 제한 규정이 미비하던 신원 위장(Misleading identity)과 출처 미표기(Failing to credit sources), 홍보성 자료(Promotional materials), 무책임한 소통(Irresponsible communication)에 대한 제한 지침을 추가로 명시함<li>기여자 서약을 실제 채택하여 운용하던 커뮤니티 관계자들을 대상으로 한 설문의 응답을 반영, 단계적 집행 기준(enforcement ladder)은 하나의 기준선일 뿐 커뮤니티 관리자의 재량권 행사를 제약하지 않음을 분명히 함<blockquote><p>This enforcement ladder is intended as a guideline. It does not limit the ability of Community Managers to use their discretion and judgment, in keeping with the best interests of our community.</p></blockquote></ul><h3 id="평등권-및-차별-금지-조문의-강화">평등권 및 차별 금지 조문의 강화</h3><p>첫 문단인 <strong>서약(Our Pledge)</strong>에서 다루는 평등권 및 차별 금지 조문을 보강, 일부 용어를 보다 포괄적인 표현으로 대체하고 몇몇 현대적인 다양성 가치들을 추가로 명시하는 등 보다 구체화하였다.</p><ul><li>‘신체 크기(body size)’와 ‘개인적 외양(personal appearance) 두 표현을 보다 포괄적인 ‘신체적 특징(physical characteristics)’으로 대체함<li>‘종교(religion)’를 보다 포괄적인 ‘신념 또는 종교(philosophy or religion)’로 대체함<li>‘국적(nationality)’을 보다 포괄적인 ‘출신 국가 또는 사회적 배경(national or social origin)’으로 대체함<li>‘신경다양성(neurodiversity)’을 추가로 명시함<li>‘언어(language)’를 추가로 명시, 비영어권 화자들을 보다 배려함<li>성 평등 및 다양성과 관련하여 전반적인 문구 수정 적용<blockquote><p><strong>v2.1</strong><br /> sex characteristics, gender identity and expression, or sexual identity and orientation</p><p><strong>v3.0</strong><br /> sex or gender, gender identity or expression, sexual orientation</p></blockquote></ul><h2 id="이번-한국어-번역-작업에서-고려한-사항들">이번 한국어 번역 작업에서 고려한 사항들</h2><h3 id="공통-고려-사항">공통 고려 사항</h3><h4 id="경어체의-사용">경어체의 사용</h4><p>서약 및 행동 강령을 한국어로 작성할 때, 경어체와 평어체 중 어느 쪽을 선택할 것인지는 지향점, 조직 문화, 그리고 전달하고자 하는 태도에 달려 있다. 과거에는 권위와 규율을 강조하는 평어체가 주를 이루었으나, 최근에는 수평적이고 존중하는 문화를 강조하기 위해 경어체로 작성하는 경우도 많다.</p><table><thead><tr><th>문체<th>경어체(~합니다, ~하겠습니다)<th>평어체(~한다)<tbody><tr><td>어감<td>상호 존중, 자발적 약속, 권유<td>단호함, 법적 효력, 객관적 규정<tr><td>조직 문화<td>유연하고 수평적인 문화<td>상대적으로 엄격한 문화<tr><td>주요 적용 상황<td>행동 강령, 윤리 선언문<td>보안 서약서, 근로 계약서, 법적 징계 규정<tr><td>심리적 효과<td>‘우리는 함께 지킨다’ (자발적 동의)<td>‘지켜야 한다’ (구속의 성격을 보다 강조)</table><p><a href="https://github.com/EthicalSource/contributor_covenant/pull/895#pullrequestreview-563210153">과거에 있었던 논의 내용</a>을 보면 과거 2.0판을 한국어로 옮길 때도 처음에 경어체를 고려하였다가 <a href="https://github.com/EthicalSource/contributor_covenant/commit/3971299d81149b3fc0ce603a5dd26400509f090f">평어체로 재작성</a>한 것으로 보인다. 과거에 있었던 논의와 그 결론을 존중하나, 그럼에도 이번에 재차 경어체로 번역한 이유는 다음과 같다.</p><p>오늘날 오픈소스 커뮤니티의 문화는 기본적으로 구속, 엄격함, 강제성을 갖는 집행 등과는 다소 거리가 있고, 그보다는 상호 존중, 자발적 참여와 기여 등을 지향한다. <a href="#응보적-정의에서-회복적-정의로의-패러다임-전환">이번 기여자 서약 3.0에서는 특히나 그러한 철학을 전반적으로 강하게 반영하였다</a>. 이번 판올림에서 원문이 전달하고자 한 핵심 가치와 철학, 그리고 커뮤니티 문화와 동향을 고려할 때 해당 글을 한국어로 옮길 때는 경어체가 적절하다고 판단하였다. 마찬가지로 경어체를 사용하는 <a href="https://rust-kr.org/pages/code-of-conduct/">한국 Rust 사용자 그룹</a>과 <a href="https://pythonkr.github.io/pycon-code-of-conduct/ko/coc/a_intent_and_purpose.html">파이콘 한국 행동 강령(PyCon KR CoC)</a>, <a href="https://kubernetes.io/ko/community/code-of-conduct/">쿠버네티스 커뮤니티 한국어 행동 강령</a>의 사례 역시 참고하였다.</p><h4 id="불필요한-피동-표현의-지양">불필요한 피동 표현의 지양</h4><p>수동태를 자주 사용하는 영어와 달리, 한국어는 기본적으로 피동 표현보다 능동 표현을 선호하는 언어이다. 영어 원문에서 수동태를 사용했다 하여 이를 기계적으로 피동 표현으로 옮기면 번역한 티가 다소 나는 부자연스러운 글이 되며, 문법적으로도 부적절하다.</p><p>한국어에서도 피동 표현을 활용하는 경우가 전혀 없는 것은 아니지만, 글의 의미를 왜곡하지 않는 선에서 가급적 원문에서는 수동태로 쓰인 표현이라도 한국어 번역문에서는 능동 표현으로 옮기고자 하였다.</p><p><strong>e.g.</strong></p><ul><li>“Encouraged Behaviors”: “장려<strong>되는</strong> 행동”(X), “장려<strong>하는</strong> 행동”(O)<li>“enforcement actions are carried out in private”: “집행 조치는 비공개로 진행<strong>된다</strong>“(X), “집행 조치는 비공개로 진행<strong>한다</strong>“(O)<li>“its own established enforcement process”: “자체적으로 확립<strong>된</strong> 집행 절차”(X), “자체적으로 확립<strong>한</strong> 집행 절차”(O)<li>“the following enforcement ladder may be used”: “다음의 단계적 집행 기준<strong>이 사용될</strong> 수 있습니다”(X), “다음의 단계적 집행 기준<strong>을 사용할</strong> 수 있습니다”(O)<li>“are provided at”: “에서 제공<strong>됩니다</strong>“(X), “에서 제공<strong>합니다</strong>“(O)</ul><h4 id="사전적-기계적-단어-번역보다는-해당-단어가-글-안에서-쓰인-맥락을-고려">사전적, 기계적 단어 번역보다는 해당 단어가 글 안에서 쓰인 맥락을 고려</h4><p>영어와 한국어는 다소 거리가 먼 언어이기 때문에, 당연히 단어와 단어가 정확히 일대일로 대응하지 않는다. 사전적으로는 같은 의미라고 나와 있다고 하더라도 그러하다.</p><p>가령, 다음 부분에서의 “intimate”는 맥락상 “친밀한”이 아니라 “성적인”의 의미로 쓰였다.</p><blockquote><p><strong>Sexualization.</strong> Behaving in a way that would generally be considered inappropriately <u>intimate</u> in the context or purpose of the community.</p></blockquote><p>또한, 다음 부분에서 “process”를 사전적으로 “처리할”이라고 번역하면 어색하다. 글의 맥락상 여기서의 “process”는 “추스를”이라 옮기는 것이 적절하다.</p><blockquote><p>… give the community members involved time to <u>process</u> the incident.</p></blockquote><blockquote class="prompt-tip"><p>(<a href="https://stdict.korean.go.kr/">표준국어대사전</a> 표제어 중)</p><p><strong>추스르다「3」</strong>: 일이나 생각 따위를 수습하여 처리하다.</p></blockquote><p>한편, 옮길 만한 고유어 표현이 마땅치 않은 외래어도 있다. 가령 “community”의 경우, 고유어로 옮기자면 “공동체” 정도로 옮길 수도 있겠으나 영어에서 “community”라는 단어가 갖는 어감과 한국어에서 “공동체”라는 단어가 갖는 어감에 제법 차이가 있다고 판단하였다. 가급적이면 외래어를 고유어로 순화하여 적되, 이처럼 원문의 뜻이나 어감을 왜곡할 우려가 크다고 판단할 시 “커뮤니티”와 같이 그대로 유지하였다.</p><p>이러한 점들을 고려하여, 사전적이고 기계적인 단어들의 단순 치환 작업을 하는 것이 아니라 원문의 뜻과 맥락에 가장 가까운 한국어 표현을 골라 번역하고자 하였다.</p><h4 id="그-밖에-한국어의-어문-규범-준수">그 밖에 한국어의 어문 규범 준수</h4><p>한글 맞춤법과 표준어 규정 등 한국어의 어문 규범을 가능한 정확히 준수하고자 노력하였다.</p><h3 id="서약our-pledge-문단">“서약(Our Pledge)” 문단</h3><h4 id="소제목">소제목</h4><p>“Our Pledge”를 직역하면 “우리의 맹세”가 되겠으나, <a href="https://www.contributor-covenant.org/ko/version/2/1/code_of_conduct/">기존 한국어 번역문</a>에서 “서약”으로 옮긴 바 있고 글의 자연스러움을 고려하면 충분히 허용 범위라 판단하므로 이번에도 “서약”으로 유지하였다.</p><h4 id="caste-용어의-번역">“caste” 용어의 번역</h4><p><a href="https://www.contributor-covenant.org/ko/version/2/1/code_of_conduct/">기존 2.1판의 한국어 번역문</a>에서는 이를 그대로 “카스트 제도”라 번역하였다. 카스트(caste)라는 단어가 <u>세계 각지의 정교하게 고착화된 신분 질서 제도</u>를 칭하는 학술적 일반명사로서의 의미도 가지므로 꼭 오역이라고만 보긴 어렵지만, 이러한 자세한 배경 정보가 주어지지 않았을 시 일상에서 한국어로 “카스트 제도”라고 하면 대다수는 “마누 법전 등으로부터 유래한 인도 내 힌두교도 특유의 신분제”로 이해하기 때문에 원문의 맥락을 고려하여 “계급”으로 번역하였다. 여기서의 “caste”는 특정 국가(인도)나 종교(힌두교)로 국한하지 않고 모든 종류, 형태의 신분제와 그에 따른 계급을 의미한다고 해석하는 것이 타당하다.</p><h4 id="성별-대신-성-표현-사용">“성별” 대신 “성” 표현 사용</h4><blockquote><p>We are committed to fostering an environment that respects and promotes the dignity, rights, and contributions of all individuals, regardless of … sex or gender, gender identity or expression, sexual orientation … or other status.</p></blockquote><p>원문에서 전달하고자 하는 가치와 맥락을 고려하면, 여기서 말하는 “sex”, “gender”, “sexual orientation” 등이 의미하는 것이 남녀 이분법에 따른 구별은 아닐 것이다. 따라서 남녀 이분법에 따른 구분의 의미를 은근히 내포하는 “성별” 대신 “성”이라는 단어를 사용하였고, 인문사회학적으로 sex, gender, sexuality 세 용어가 갖는 의미 차이를 가능한 살려서 다음과 같이 번역하였다.</p><blockquote><p>… 생물학적 또는 사회적 성, 성 정체성 또는 성 표현, 성적 지향…</p></blockquote><h3 id="장려하는-행동encouraged-behaviors-및-제한하는-행동restricted-behaviors-문단">“장려하는 행동(Encouraged Behaviors)” 및 “제한하는 행동(Restricted Behaviors)” 문단</h3><h4 id="콜론-제거">콜론(<code class="language-plaintext highlighter-rouge">:</code>) 제거</h4><blockquote><p>With these considerations in mind, we agree to behave mindfully toward each other and act in ways that center our shared values, including:</p><ol><li>Respecting the <strong>purpose of our community</strong>, our activities, and our ways of gathering.<li>Engaging <strong>kindly and honestly</strong> with others. …</ol></blockquote><p>영어 원문에서는 하나의 완결 문장 뒤에 예시 목록을 나열할 목적으로 위와 같이 콜론을 사용하는 용법이 흔하나, 현대 한국어의 어문 규범은 쌍점의 용법을 표제 다음에 해당 항목을 들거나 설명을 붙일 때 등 주로 개조식 표현으로 제한한다. 따라서 아예 개조식으로 작성한 글이라면 모를까, 다음과 같이 작성하는 것은 매우 어색하며 기계 번역이나 LLM을 이용해 대충 번역하였다는 인상을 주기 쉽다. 개인적으로 <a href="https://www.contributor-covenant.org/ko/version/2/1/code_of_conduct/">2.1 판의 한국어 번역본</a>에서도 많이 아쉬웠던 부분 중 하나이다.</p><blockquote><p>이러한 점을 유념하며, 우리는 서로를 사려 깊게 대하고 우리가 공유하는 다음 가치를 중심으로 행동할 것에 동의합니다:</p><ol><li>우리 <strong>공동체의 목적</strong>, 활동 및 모임 방식을 존중합니다.<li><strong>친절하고 정직하게</strong> 다른 사람들과 소통합니다. …</ol></blockquote><p>따라서 한국어의 용법에 맞게, 콜론을 사용한 부분을 그대로 쌍점으로 옮겨 적는 대신 마침표(<code class="language-plaintext highlighter-rouge">.</code>)로 바꿔 적어서 자연스러운 글이 되도록 하였다.</p><h4 id="that-would-generally-be-considered-inappropriately-표현의-번역">“that would generally be considered inappropriately” 표현의 번역</h4><p>여기서 “generally”를 “일반적으로”라고 직역하기보다는, 맥락상 보다 자연스럽게 “대부분의 사람들에게”로 번역하였다.</p><blockquote><p>…<u>대부분의 사람들이</u> 부적절하다고 간주할 만한…</p></blockquote><h3 id="act-on-표현의-번역">“act on” 표현의 번역</h3><p>처음에 “act on”을 단순히 “이용하다”로 번역할까 고민했으나, 맥락상 <u>의도를 불문하고 타인의 신상 정보 또는 개인적인 정보를 바탕으로 행하는</u> 모든 행위를 금한다는 내용에 가깝고 이를 “이용하다”로 번역하면 의미를 축소시키는 것 같아 다음과 같이 번역하였다.</p><blockquote><p><strong>비밀 침해.</strong> 타인의 신상 관련 정보 또는 개인적인 정보를 당사자의 허락 없이 공유하거나, 그 정보<u>를 바탕으로 행하는</u> 모든 행위.</p></blockquote><h3 id="문제-신고reporting-an-issue-문단">“문제 신고(Reporting an Issue)” 문단</h3><ul><li>“this Code of Conduct <strong>reinforces</strong> encouraged behaviors and norms that …”: “본 행동 강령은 …는 권장 행동 방식과 규범을 <strong>증진합니다</strong>“로 번역<li>“in a timely manner”: “적시에”로 번역<li>“while prioritizing safety and confidentiality”: “안전과 비밀 유지를 우선시한다는 전제 하에”로 번역<li>“In order to <strong>honor</strong> these values”: “이들 가치를 <strong>지키기</strong> 위해”로 번역<blockquote class="prompt-tip"><p>(<a href="https://www.oxfordlearnersdictionaries.com/">Oxford Learner’s Dictionaries</a> 표제어 중)</p><p><a href="https://www.oxfordlearnersdictionaries.com/definition/english/honor_2"><strong>honor</strong></a> <em>verb</em><br /> <u>keep promise</u> 3. <strong>honor something</strong> <em>(formal)</em> to do what you have agreed or promised to do</p></blockquote></ul><h3 id="피해-대응-및-교정addressing-and-repairing-harm-문단">“피해 대응 및 교정(Addressing and Repairing Harm)” 문단</h3><ul><li>“Addressing”: “대응”으로 번역<li>“Repairing”: “교정”으로 번역</ul><h4 id="event-consequence-repair의-번역"><code class="language-plaintext highlighter-rouge">Event:</code>, <code class="language-plaintext highlighter-rouge">Consequence:</code>, <code class="language-plaintext highlighter-rouge">Repair:</code>의 번역</h4><p>한국어로 옮기기가 애매해서 고민을 좀 했던 부분이다. “사건”, “결과”, “교정”로 직역하면 글이 상당히 어색해진다.</p><p>자연스러운 글이 되면서도 <a href="#응보적-정의에서-회복적-정의로의-패러다임-전환">원문의 철학</a>을 가능한 온전히 전달하기 위하여 고민한 끝에 다음과 같이 번역하였다.</p><ul><li>“Event”: “적용 상황”으로 번역.<li>“Consequence”: “대응 조치”로 번역.<li>“Repair”: 처음에는 “회복 조치”를 고려하였으나, “조치”라는 표현은 당사자의 자발적인 성찰과 개선보다는 타자가 개입하여 집행한다는 어감이 있어 원문의 취지에 어긋난다고 보고 기각. 최종적으로는 “교정 노력”으로 번역.</ul><h4 id="seeking-clarification-on-expectations-표현의-번역">“seeking clarification on expectations” 표현의 번역</h4><p>“expectations”는 “기대 사항”으로 직역할 수도 있고 이렇게 해도 의미는 통하지만, 좀 더 매끄러운 글을 위하여 “준수 사항”으로 번역하였다.</p><blockquote class="prompt-tip"><p>(<a href="https://www.oxfordlearnersdictionaries.com/">Oxford Learner’s Dictionaries</a> 표제어 중)</p><p><a href="https://www.oxfordlearnersdictionaries.com/definition/english/expectation"><strong>expectation</strong></a> <em>noun</em><br /> 3. [countable, usually plural] a strong belief about the way something should happen or how somebody should behave</p></blockquote><p>“seeking clarification”은 “해명(clarification) 요구(seeking)”로 번역할 수도 있지만, 맥락상 교정 노력(Repair) 항목에서는 문제를 일으킨 이가 취해야 할 바람직한 사후 행동과 태도를 기술하고 있으므로 clarification, seeking을 각각 해명, 요구로 번역하면 뜻이 이상해진다. 여기서는 스스로 반성하고 같은 잘못을 되풀이하지 않기 위하여 <u>준수 사항</u>(expectations)을 <u>명확히 확인하고 숙지하기</u>(clarification) 위한 <u>노력</u>(seeking)으로 번역함이 가장 적절하다고 보았다.</p><blockquote class="prompt-tip"><p>(<a href="https://www.oxfordlearnersdictionaries.com/">Oxford Learner’s Dictionaries</a> 표제어 중)</p><p><a href="https://www.oxfordlearnersdictionaries.com/definition/english/seek"><strong>seek</strong></a> <em>verb</em><br /> 2. [transitive] to ask somebody for something; to try to obtain or achieve something</p><p><a href="https://www.oxfordlearnersdictionaries.com/definition/english/clarification"><strong>clarification</strong></a> <em>noun</em><br /> [uncountable, countable] (formal)<br /> the act or process of making something clearer or easier to understand</p><ul><li><em>I am <strong>seeking clarification of</strong> the regulations.</em></ul></blockquote><h4 id="cooldown-표현의-번역">“cooldown” 표현의 번역</h4><p>사전적으로 냉각, (본 운동 이후의) 정리 운동, 진정 등의 뜻이 있고 여기서는 맥락상 진정에 제일 가까운 의미로 사용하였다. “머리 좀 식혀라.”라고 할 때의 “식히다”의 뜻에 제일 가깝다.</p><p>다만 “time-limited cooldown period”를 “한시적 진정 기간”이라고 옮기면 좀 어색하여, 이번 한국어 번역에서는 “cooldown period”를 “자숙 기간”으로 번역하였다.</p><h4 id="time-to-process-the-incident-표현의-번역">“time to process the incident” 표현의 번역</h4><p><a href="#사전적-기계적-단어-번역보다는-해당-단어가-글-안에서-쓰인-맥락을-고려">상술하였듯</a>, “해당 일을 추스를 시간”으로 번역하였다.</p><h4 id="suspension-및-ban-표현의-번역">“suspension” 및 “ban” 표현의 번역</h4><p><a href="https://www.contributor-covenant.org/ko/version/2/1/code_of_conduct/">기존 2.1판의 한국어 번역문</a>에서는 “ban”을 “제재”라 번역하였는데, 제재라 함은 하위 단계인 경고, 일시적 활동 제한 등 위반 행위에 대해 취할 수 있는 모든 조치를 포괄하는 뜻이기에 의미하는 바가 불명확하다. 그리고 영단어 “ban”은 그 뜻이 정지하다, 금지하다 로 명백한 데다 “(계정 등의) 영구 정지”라는 표현은 한국어로도 일상적으로 자주 사용하는 자연스러운 표현이므로 딱히 이를 피해서 의역해야 할 이유도 없다고 본다.</p><p>“suspension” 역시 마찬가지로, 정직, 정학 등 “정지”라는 뜻이 분명하며 굳이 의역할 이유가 없다.</p><p>따라서 “Temporary Suspension”, “Permanent Ban”은 각각 “일시적 정지”, “영구 정지”로 번역하였다.</p><h4 id="this-enforcement-ladder-is-intended-as-a-guideline-문장의-번역">“This enforcement ladder is intended as a guideline.” 문장의 번역</h4><p>“enforcement ladder” 표현은 “단계적 집행 기준”으로 번역하였다. 또한 이 문장은 상술한 단계적 집행 기준이 어디까지나 여러 가능한 선택지 중 하나로 제시하는 것일 뿐, 커뮤니티 관리자의 재량과 결정권을 보장한다는 맥락에서 쓰였으므로 관사 “a”를 “하나의”로 번역하였다. 이에 번역문에서는 다음과 같이 작성하였다.</p><blockquote><p><u>이 단계적 집행 기준은 하나의 기준선으로 마련한 것입니다.</u> 이는 커뮤니티의 최선의 이익에 부합하는 커뮤니티 관리자의 재량권과 판단 권한을 제한하지 않습니다.</p></blockquote><h2 id="마치며">마치며</h2><p>이러한 류의 공익적인 성격을 갖는 문서 및 프로젝트 중 상당수가 자원봉사자 및 기여자들에 의해 여러 언어로 번역 작업을 진행하곤 한다. 그러나 아쉽게도 한국어 번역의 경우 기여자가 없어서 번역본이 존재하지 않거나, 존재하더라도 기계적으로 번역한 티가 나는 어색한 글인 나머지 한국인임에도 불구하고 ‘차라리 영문으로 읽고 말지’ 하며 영문 페이지로 전환한 경험을 적잖이 한 바 있다.</p><p>이번에 한국어 번역 기여를 결심하고 작업하면서, 기왕 기여하기로 했다면 읽는 사람으로 하여금 한국인 저자가 처음부터 한국어로 쓴 글이라 해도 위화감이 없을 만한 수준의 양질의 번역문을 내놓고자 노력하였다. 원문이 담고자 했던 철학과 미묘한 맥락, 특히 기존 2.1판 대비 이번 3.0판에서 달라진 표현들이 무엇이 있으며 원 저자들이 어떠한 이유에서 그러한 선택을 하였을지를 이해하고 녹여내고자 고민하였다.</p><p>자연어의 특성상 번역이라는 게, 동일한 원문을 입력으로 받았다고 해서 무슨 함수처럼 동일한 출력이 나오는 것이 아니다. 번역가마다 약간씩은 다른 번역을 내놓게 되며, 이것은 번역가의 실력도 실력이지만 본질적으로 하나의 정해진 정답이라는 게 없는 번역, 나아가 작문의 특성에서 기인한다. 최근 들어 나는 거의 대부분의 작업에 AI를 보조적으로 활용하고 있고, 심지어 지금 이 블로그의 포스트도 LLM API를 연결해서 여러 언어로 자동 번역 및 발행하고 있다. 그러나 이번 이 작업만큼은 정말 각 잡고 제대로 된, 내가 할 수 있는 최선의 번역을 하고자 하였다. 표현 하나하나를 직접 여러 차례 검토하고, 어떤 표현을 쓰는 것이 원문의 뜻을 가장 왜곡 없이 온전하게, 그러면서도 자연스럽게 담아낼 수 있을지에 대해 고민하며, 그 결과 내놓은 내 주관적인, 그러나 최선의 판단과 해석을 반영하였다. 너도나도 AI를 활용하는 지금, 적어도 지금 이런 서약, 행동 강령 같은 중요한 문서의 번역에 있어서는 AI한테 원문 그대로 던져주고 번역해 달라 지시한 결과물 대비 비교 우위가 있어야만 번역본으로서 가치를 갖는다고 믿는다. 적어도 12026년 3월 현 시점 기준, 기계 번역이나 LLM으로는 다 살리지 못하는 원문의 미묘한 어감과 맥락 등을 <a href="https://github.com/EthicalSource/contributor_covenant/pull/1590">이번 번역본</a>에서는 온전히 보존하였노라 자부한다.</p><p>12026년 3월 20일 현 시점 기준으로 기여자 서약 3.0 판은 영어 원문과 내가 이번에 제출할 이 한국어 번역본을 제외하면 오직 벵골어, 독일어, 대륙 중국어 단 3개 언어로만 번역 완료되어 있고, <a href="https://github.com/EthicalSource/contributor_covenant/pulls">열려 있는 PR 목록</a>을 보면 번역본 초안이 PR로 제출되었으나 리뷰어가 없어 최종 승인되지 못하고 있는 상태의 언어들도 많다. 심지어 3.0판은 커녕 아직 1.4판에 머물러 있는 언어들도 상당히 많다. 어떠한 이유로든 이 글을 읽는 한국어 이외 언어의 화자가 있다면, <a href="https://github.com/EthicalSource/contributor_covenant?tab=contributing-ov-file#translators-and-native-speakers">기여 방법이 별로 복잡하지 않으므로</a> 주말 등 하루쯤 시간 내서 기여해 준다면 분명 OES와 해당 언어 사용자들에게 큰 도움이 될 것이다. 나 역시 이런 번역 작업에 기여한 경험도, 행동 강령 전문을 정독해 본 것도 이번이 처음이었는데, 몇 시간 정도 시간을 들일 만한 가치는 충분했던 작업이었다고 생각한다. 한국이 전체 인구 수 대비 GitHub 등 오픈소스 커뮤니티에서 활발히 활동하는 개발자 수가 상당히 많은 편에 속하는데, 그런 만큼 이번에 번역하여 제출한 기여자 서약 3.0 행동 강령의 <a href="https://github.com/EthicalSource/contributor_covenant/pull/1590">한국어 번역본</a>도 여러 다른 한국인 분들이 리뷰에 참여하고, 또 기왕이면 많은 분들이 여러 곳에서 유용하게 채택하고 활용해 준다면 기쁠 것 같다.</p><p><a href="https://ethicalsource.dev/blog/contributor-covenant-3/">OES의 블로그 글</a>에서 인용한 <strong>네이선 슈나이더(Nathan Schneider) 교수</strong>의 말처럼, 기여자 서약(Contributor Covenant)은 책임감 있고 투명한 커뮤니티를 구축하는 데 있어 필수적인 토대로서 기능하며, 실제로 갈등을 해소하는 데 기여해 왔다. 관례적으로 GitHub 등에서 “Add a code of conduct” 버튼을 눌러서 템플릿을 붙여 넣는 경우가 흔할 텐데, GitHub에서 자동 제공하는 템플릿은 어째서인지 2.0판을 마지막으로 업데이트가 안 되고 있다. 3.0판은 이전 2.0, 2.1판 대비 큰 변화와 개선이 있었으므로 기왕이면 <a href="https://www.contributor-covenant.org/adopt/">공식 페이지</a>를 통해서 최신 판본을 채택하는 것이 어떨지 권유해 본다. 내용이 막상 그리 길지도 않으니, 그 과정에서 한번쯤 전문을 찬찬히 읽어본다면 더더욱 의미 있을 것이라 생각한다. 기여자 서약 3.0 행동 강령과 이번에 작업한 <a href="https://github.com/EthicalSource/contributor_covenant/pull/1590">한국어 번역본</a>에 많은 관심을 가져 주길 바라며, 이만 줄인다.</p>]]> </content> </entry> <entry><title xml:lang="ko">IR 자료 작성하는 법 (How to Prepare IR Materials)</title><link href="https://www.yunseo.kim/ko/posts/how-to-prepare-ir-materials/" rel="alternate" type="text/html" hreflang="en" /><link href="https://www.yunseo.kim/ko/posts/how-to-prepare-ir-materials/" rel="alternate" type="text/html" hreflang="ko" /><link href="https://www.yunseo.kim/ja/posts/how-to-prepare-ir-materials/" rel="alternate" type="text/html" hreflang="ja" /><link href="https://www.yunseo.kim/zh-TW/posts/how-to-prepare-ir-materials/" rel="alternate" type="text/html" hreflang="zh-TW" /><link href="https://www.yunseo.kim/es/posts/how-to-prepare-ir-materials/" rel="alternate" type="text/html" hreflang="es" /><link href="https://www.yunseo.kim/pt-BR/posts/how-to-prepare-ir-materials/" rel="alternate" type="text/html" hreflang="pt-BR" /><link href="https://www.yunseo.kim/fr/posts/how-to-prepare-ir-materials/" rel="alternate" type="text/html" hreflang="fr" /><link href="https://www.yunseo.kim/de/posts/how-to-prepare-ir-materials/" rel="alternate" type="text/html" hreflang="de" /><link href="https://www.yunseo.kim/pl/posts/how-to-prepare-ir-materials/" rel="alternate" type="text/html" hreflang="pl" /><link href="https://www.yunseo.kim/cs/posts/how-to-prepare-ir-materials/" rel="alternate" type="text/html" hreflang="cs" /><link href="https://www.yunseo.kim/sw/posts/how-to-prepare-ir-materials/" rel="alternate" type="text/html" hreflang="sw" /><link href="https://www.yunseo.kim/am/posts/how-to-prepare-ir-materials/" rel="alternate" type="text/html" hreflang="am" /><published>2026-01-11T00:00:00+09:00</published> <updated>2026-01-11T00:00:00+09:00</updated> <id>https://www.yunseo.kim/ko/posts/how-to-prepare-ir-materials/</id> <author> <name>Yunseo Kim</name> </author> <category term="Startup" /> <category term="IR" /> <summary xml:lang="ko">IR 자료란 무엇인지 이해하고, 성공적으로 투자를 유치하기 위한 좋은 IR 자료에 들어가야 할 내용들을 정리한다.</summary> <content type="html" xml:lang="ko"> <![CDATA[<p>IR 자료란 무엇인지 이해하고, 성공적으로 투자를 유치하기 위한 좋은 IR 자료에 들어가야 할 내용들을 정리한다.</p><em><p>* Mathematical equations and diagrams included in posts may not display properly when viewed with a feed reader.</p></em><h2 id="ir-자료란">IR 자료란?</h2><p><strong>IR</strong>은 <strong>Investor Relations</strong>의 약어로, 투자자들을 대상으로 기업을 설명하고 홍보하며, 관계를 맺고 투자를 유치하는 데 필요한 모든 자료와 활동을 포괄적으로 일컫는 용어이다. IR 자료라고 하면 보통은 투자 유치를 위해 기업이 투자자들에게 소개하는 자료를 의미한다.</p><h2 id="ir-자료에-들어가야-할-내용">IR 자료에 들어가야 할 내용</h2><p>IR 자료의 목적은 투자 유치이므로, 투자자 입장에서 이 회사에 투자해야 하는 이유가 무엇인지 설득력 있게 제시하는 것이 필요하다. 따라서 서비스 요약, 시장 환경, 제품/서비스 설명, 경쟁 환경, 성과, 사업 모형, 향후 성장 계획, 팀 구성 등 사업 전반적인 내용을 포함해야 한다.</p><ul><li><strong>피치 덱(Pitch Deck)</strong>:<ul><li><strong>짧고 강렬하게</strong>, 폭넓은 잠재적 투자자들에게 <strong>긍정적인 첫인상</strong>을 남기는 것이 목적<li>초기 단계 투자 유치에서 사용<li>슬라이드 10-15장 분량으로, 간결하고 시각적인 자료 위주로 구성</ul><li><strong>IR 덱(IR Deck)</strong>:<ul><li>회사의 <strong>심층적인 재무 정보와 장기 전략</strong>을 제공<li>어느 정도 관심을 보이기 시작한, 결정을 앞둔 전문 투자자들에게 제공<li>투자자들이 <strong>더 깊이 있는 평가와 판단</strong>을 내릴 수 있도록 함<li>슬라이드 20-30장 분량으로, 보다 구체적인 <strong>재무 계획, 시장 분석, 팀 구성, 경쟁자 분석</strong> 등 자세한 정보 제공</ul></ul><h3 id="미션비전-missionvision">미션/비전 (Mission/Vision)</h3><ul><li>당사가 제공하고자 하는 본질적인 가치가 무엇인가?</ul><blockquote class="prompt-tip"><p>회사의 핵심 정체성이라고 할 수 있는 부분으로, IR 자료의 제일 첫 부분에 당사의 미션과 비전을 각각 한 문장으로 간결하면서도 명확하게 표현하는 것이 좋다.</p></blockquote><h3 id="서비스-요약">서비스 요약</h3><h4 id="문제-problem">문제 (Problem)</h4><ul><li>해당 서비스가 해결하고자 하는 시중의 문제는 무엇인가?<li>소비자들이 이 문제에 대해 얼마나 불편해하는가?<li>그 문제가 왜 중요한가?<li>문제 해결에 대한 수요가 있는가? 타깃이 누구인가?</ul><h4 id="솔루션-solution">솔루션 (Solution)</h4><ul><li>앞서 언급한 문제를 구체적으로 어떻게 해결할 것인가?<li>기존 방식 대비 소비자 및 최종 사용자가 얻는 이점이 무엇인가?</ul><blockquote class="prompt-tip"><p>투자자들이 해당 분야에 대한 전문가는 아닌 경우가 많기 때문에 개발자가 아닌 소비자의 입장에서 서비스를 설명하고, 기술적인 세부사항은 추후 질문이 들어오거나 하면 개별적으로 대응하는 것이 좋다.</p></blockquote><h3 id="시장-규모-market-size">시장 규모 (Market Size)</h3><p>시장 규모를 금액으로 직접 설정할 경우, 산출 방식이나 여러 변수들에 따라 결과가 크게 달라질 수 있는 데다가 이견이 제기될 위험도 비교적 크다. 잠재적인 사용자 수, 거래 횟수/빈도 등의 다른 지표를 설정하여 제시하면 보다 안전하게, 효과적으로 시장 규모를 보일 수 있다.</p><ul><li><strong>TAM(Total Addressable Market, 전체 시장)</strong>: 모든 경쟁사를 배제하고 세계 시장 점유율 100%를 달성한다는 이상적인 상황을 가정, 제품이나 서비스를 전 세계를 대상으로 제공할 때 이론적으로 접근 가능한 시장의 최대 규모<li><strong>SAM(Service Available Market, 유효 시장)</strong>: 지리적, 인프라적, 규제적 제약 조건들을 고려하여 현실적으로 서비스를 제공할 수 있는, 실제로 당사가 추구하는 범위의 시장 규모<li><strong>SOM(Service Obtainable Market, 수익시장)</strong>: 경쟁 상황, 회사의 역량, 마케팅 전략 등을 고려할 때, SAM 안에서도 초기에 실제로 점유할 수 있는 시장 규모</ul><blockquote class="prompt-tip"><p>시장 규모를 추산할 때 전체 시장이나 유효 시장의 규모에 대해서는 제삼자의 시장 조사 자료를 인용하여 구체적인 수치와 지표를 제시하면서, 정작 스타트업 입장에서 당장 중요한 수익시장 규모에 대해서는 “해당 시장에서 점유율 몇 %를 달성하면 매출 얼마를 달성할 수 있다”라는 식으로 설명하는 경우가 많다. 솔직히 말해, 나도 창업을 막 준비하면서 처음 내부적으로 작성한 IR자료 초안에서는 이런 식으로 작성했었다.</p><p>그러나 이렇게 했을 때의 문제는, 투자자 입장에서 시장의 몇 %를 점유할 것인지에 대한 계획은 신뢰하기가 어렵다는 것이다. 서비스를 출시한다고 쉽게 시장을 점유할 수 있는 것도 아니고, 막연히 해당 시장의 모든 구성원들을 대상으로 점유율 몇 %를 달성하겠다는 것은 설득력이 부족하다.</p><p>겨냥한 전체시장 및 유효시장의 크기가 충분히 큼을 보여줌과 동시에, <strong>초기 고객군(Immediate Market)</strong>을 어떻게 보고 있고, 이후 어떤 고객군을 단계적으로 추가 공략하여 수익시장을 키워 나갈 것인지에 대한 논리를 제시하는 것이 중요하다.</p></blockquote><blockquote class="prompt-tip"><p><strong>사업 타이밍</strong></p><ul><li>사업에서는 타이밍도 매우 중요<li>왜 지금 이 사업이 잘 될 수 있고, 지금 투자해야 하는지 투자자들에게 설명할 수 있어야 함<li>기술적 가능성, 사람들의 행동 양상 변화, 사회적 흐름, 환경적 변화 등 지금 이 사업을 실행하기에 적합한 이유를 제시해야 함</ul></blockquote><h3 id="제품서비스-설명-product">제품/서비스 설명 (Product)</h3><ul><li>제품/서비스의 주요 특징과 기능은 무엇인가?<li>구체적인 작동 방식, 예시는 무엇인가?</ul><h3 id="사업-모형-business-model">사업 모형 (Business Model)</h3><ul><li>돈을 어떻게 벌 것인가?<li>누가 돈을 지불하는가? (최종 사용자와 돈을 지불하는 고객이 항상 일치하지는 않으므로, 실질적으로 매출을 발생시키는 고객이 누구인지 명확히 해야 함)<li>어떤 부분을 과금할 것인가? 가격 책정은 어떻게 할 것인가?</ul><h3 id="경쟁-환경-competition">경쟁 환경 (Competition)</h3><ul><li>주요 경쟁자는 누구인가?<li><strong>고객 입장에서</strong> 타사 서비스 및 제품 대비 당사 서비스 및 제품이 어떤 면에서 뛰어나고 장점이 있는가?<li>어떤 서비스를 경쟁 서비스로 정하고, 어떤 고객을 주요 타깃으로 할 것인가?</ul><blockquote class="prompt-tip"><p>경쟁자를 제대로 분석해야 투자자들에게 시장 현황을 잘 파악하고 있음을 효과적으로 어필할 수 있다.</p></blockquote><h3 id="성과-및-시장-진출-전략-go-to-market-strategy">성과 및 시장 진출 전략 (Go-to Market Strategy)</h3><ul><li>사업의 성공에 있어 가장 중요한 핵심 지표가 무엇인가?<ul><li>e.g. 주문 건수, 월간활성사용자(MAU), 월간 거래대금 등</ul><li>해당 지표를 중심으로, 어떤 성과가 있었는가?<li>회사의 주요 마케팅 수단 및 채널은?<li>신규 고객 유치 수단과 비용은 얼마인가?<li>*<strong>고객 생애 가치(LTV)</strong>는 얼마인가?</ul><blockquote class="prompt-info"><p>*<strong>고객 생애 가치(Customer Lifetime Value, LTV)</strong>: 한 사용자가 해당 서비스를 이용하는 전 기간 동안 총 얼마의 이익을 가져다주는가를 수치화한 것</p></blockquote><blockquote class="prompt-tip"><p>핵심 지표 외의 부수적인 지표는 제외하는 것이 좋다.</p></blockquote><blockquote class="prompt-tip"><p><strong>아직 매출이 없는 극초기 단계 스타트업이라면</strong></p><ul><li>제공하고자 하는 서비스의 <strong>손익분기점</strong>을 설정하여 제시<li>이때 수익 관련 지표를 부풀리지 않고, 보수적인 관점에서 현실적으로 설정해야 함<li>수익 발생 첫 해의 수익 시나리오를 제시하고, 향후 몇 년 간의 매출 계획을 덧붙여서 실제로 꾸준히 성장할 수 있다는 확신을 주는 게 좋음<ul><li>1년 단기 예측<li>3년 중기 예측<li>5년 장기 예측</ul><li>내용을 한눈에 확인 가능하도록 그래프와 표를 적극적으로 활용<li><strong>가설 검증 장표</strong>를 포함하여, 어떠한 이유로 핵심 지표와 매출 시나리오를 설정했는지를 설득력 있게 제시함으로써 근거를 강화하는 것이 좋음<ul><li>여러 번의 실험과 가설 검증을 통해 예상 매출 시나리오에 대한 탄탄한 근거를 마련해야 함</ul></ul></blockquote><h3 id="팀-구성-the-team">팀 구성 (The Team)</h3><ul><li>모두를 소개하기보다는, 대표 자신을 포함하여 핵심적인 역할을 수행하는 주요 팀원 위주로 소개<li>경력, 기술은 2-3개 내외로 로고 등을 활용해 가독성 좋게 제시<li>핵심적인 역할을 해 줬거나 해 주고 있는 투자자, 고문이 있다면 같이 포함하는 것도 좋음</ul><h3 id="향후-성장-계획-milestones">향후 성장 계획 (Milestones)</h3><ul><li>시기별, 단계별로 달성하고자 하는 목표 제시<li>다음 투자 단계 전까지의 목표를 설정하는 게 일반적임 (시드라면 시리즈A 전까지, 시리즈A라면 시리즈B 전까지)<li>희망 투자 금액과 사용 계획 제시<li>이때 구분 단위를 반 년 이상으로 너무 길게 잡기보다, 2개월 정도의 단위로 끊어서 제시</ul><h3 id="재무-계획-financials">재무 계획 (Financials)</h3><p>IR 덱의 경우 재무 계획을 포함해야 한다.</p><ul><li>향후 3-5년간의 재무계획표<li><strong>단위 경제</strong>: 사업의 고객 단위당 수입과 비용<li><strong>경비지출속도(Burn rate)</strong>: 신생 기업에서 현금으로 지출한 창업비용, 연구개발비, 기타 비용의 비율<li>총 수입과 비용<li>EBITDA 또는 현금흐름표 등</ul><blockquote class="prompt-warning"><ul><li>너무 비현실적인 재무 계획을 제시하지 않도록 주의해야 함<li>예상 매출액은 과대평가, 소요 비용은 과소평가하는 경우가 잦으므로 예상 매출규모 산정 시 신중해야 함<li>소요 비용은 제품/서비스 개발비, 그리고 운영비 등을 고려하여 가능한 정확히 추산</ul></blockquote><h2 id="투자-단계별-강조해야-하는-지점">투자 단계별 강조해야 하는 지점</h2><h3 id="시드">시드</h3><ul><li>MVP를 개발하고 시장 반응 확인, 사업 모델의 타당성을 검증하는 단계<li>초기 가설과 사업 모델 검증 결과, MVP 실험 결과와 그에 따른 매출을 집중적으로 강조해야 함</ul><h3 id="pre-a">Pre-A</h3><ul><li>성장 잠재력을 입증하고 제품 개발, 마케팅, 채용 등에 필요한 추가 자금을 확보해야 하는 단계<li>사업의 핵심 지표가 무엇이며, 어떤 활동을 통해 얼마나 잘 성장하고 있는지, 향후 성장 가능성에 대한 설명 필요</ul><h3 id="시리즈a">시리즈A</h3><ul><li>본격적으로 성장하며 기업 가치를 높이는 단계<li>이때는 가설 검증은 끝났어야 하는 시점이므로, 사업 성과에 대한 정량적인 결과로 투자자의 신뢰를 확보해야 함</ul><h2 id="몇-가지-팁들">몇 가지 팁들</h2><ul><li>처음 다섯 장은 특히 공을 들여서, 첫 인상을 긍정적으로 남길 수 있도록 해야 함<li>첫 장의 미션/비전은 마지막 장에 다시 한 번 넣는 것도 좋음<li>모든 내용은 두괄식으로 전달<li>투자의 대상은 <strong>회사</strong>이므로, IR자료에서도 서비스명보다 회사명이 우선임<li>IR 자료를 읽는 잠재적인 투자자들은 업계 종사자가 아닐 수 있으므로, 가급적 쉬운 용어들 위주로 풀어서 설명하고 불가피하게 전문 용어 사용 시에는 설명을 덧붙일 것<li>시장문제와 솔루션은 혼용하지 말고 분리할 것<li>텍스트는 키워드 위주로 사용, 이미지 사용 시 캡처 이미지는 지양하여 가독성 높이기<li>정확하고 구체적인 수치 표나 그래프로 기재하기<li>팀원 소개, 희망 투자금액과 사용 계획을 누락하지 않도록 유의해야 함<li>투자금 회수 전략도 함께 제시하면 좋음<li>주주를 어떤 비율로 구성할 것인지에 대한 계획도 완벽하진 않더라도 간략하게나마 제시할 것<li>본문에 너무 많은 자료를 넣지 말고, 필요하다면 별첨 자료로 분리하기<li>마지막 슬라이드에는 연락처(이메일, 전화번호, 이름) 기재<li>글꼴도 상당히 중요하므로 <a href="https://cactus.tistory.com/306">Pretendard</a> 등 가독성 좋은 글꼴을 사용하고, 깨지는 일 없도록 PDF로 준비</ul><h2 id="참고-자료">참고 자료</h2><h3 id="기업공시채널-kind">기업공시채널 KIND</h3><p><a href="https://kind.krx.co.kr/corpgeneral/irschedule.do?method=searchIRScheduleMain&amp;gubun=iRMaterials">https://kind.krx.co.kr/corpgeneral/irschedule.do?method=searchIRScheduleMain&amp;gubun=iRMaterials</a></p><ul><li>한국거래소에서 운영하는 기업공시 채널<li>KOSPI, KOSDAQ, KONEX에 상장한 기업들의 공시 정보 제공<li>상장사들의 IR 자료를 확인할 수 있어, 최근 제작된 다른 IR 자료들의 구성 방식을 확인할 수 있음</ul>]]> </content> </entry> <entry><title xml:lang="ko">암호학의 기본 개념들</title><link href="https://www.yunseo.kim/ko/posts/basic-concepts-of-cryptography/" rel="alternate" type="text/html" hreflang="en" /><link href="https://www.yunseo.kim/ko/posts/basic-concepts-of-cryptography/" rel="alternate" type="text/html" hreflang="ko" /><link href="https://www.yunseo.kim/ja/posts/basic-concepts-of-cryptography/" rel="alternate" type="text/html" hreflang="ja" /><link href="https://www.yunseo.kim/zh-TW/posts/basic-concepts-of-cryptography/" rel="alternate" type="text/html" hreflang="zh-TW" /><link href="https://www.yunseo.kim/es/posts/basic-concepts-of-cryptography/" rel="alternate" type="text/html" hreflang="es" /><link href="https://www.yunseo.kim/pt-BR/posts/basic-concepts-of-cryptography/" rel="alternate" type="text/html" hreflang="pt-BR" /><link href="https://www.yunseo.kim/fr/posts/basic-concepts-of-cryptography/" rel="alternate" type="text/html" hreflang="fr" /><link href="https://www.yunseo.kim/de/posts/basic-concepts-of-cryptography/" rel="alternate" type="text/html" hreflang="de" /><link href="https://www.yunseo.kim/pl/posts/basic-concepts-of-cryptography/" rel="alternate" type="text/html" hreflang="pl" /><link href="https://www.yunseo.kim/cs/posts/basic-concepts-of-cryptography/" rel="alternate" type="text/html" hreflang="cs" /><link href="https://www.yunseo.kim/sw/posts/basic-concepts-of-cryptography/" rel="alternate" type="text/html" hreflang="sw" /><link href="https://www.yunseo.kim/am/posts/basic-concepts-of-cryptography/" rel="alternate" type="text/html" hreflang="am" /><published>2025-11-26T00:00:00+09:00</published> <updated>2025-11-26T00:00:00+09:00</updated> <id>https://www.yunseo.kim/ko/posts/basic-concepts-of-cryptography/</id> <author> <name>Yunseo Kim</name> </author> <category term="Dev" /> <category term="Cryptography" /> <summary xml:lang="ko">암호학이란 무엇인지 이해하고, 대칭 암호학, 비대칭 암호학, 케르크호프스의 원칙 등 기본적인 개념들을 알아본다.</summary> <content type="html" xml:lang="ko"> <![CDATA[<p>암호학이란 무엇인지 이해하고, 대칭 암호학, 비대칭 암호학, 케르크호프스의 원칙 등 기본적인 개념들을 알아본다.</p><em><p>* Mathematical equations and diagrams included in posts may not display properly when viewed with a feed reader.</p></em><h2 id="암호학이란">암호학이란</h2><p><strong>암호학(cryptography)</strong>은 본질적으로, 적대 행위로부터 <strong>프로토콜(protocol)</strong>을 방어하는 것을 목표로 하는 과학의 한 하위 분야이다.</p><p>여기서 프로토콜이라 함은 한 명 이상의 사람이 무언가를 달성하기 위하여 따라야 하는 단계의 목록인데, 가령 기기 간 클립보드 공유를 하고 싶다고 할 때 다음은 클립보드 공유를 위한 프로토콜에 해당한다.</p><ol><li>어느 한 기기에서 클립보드에 변경사항이 있을 시, 해당 클립보드 내용을 복사하여 서버에 업로드한다.<li>서버에서는 공유 클립보드에 변경사항이 발생하였음을 나머지 기기들에 알린다.<li>나머지 기기들에서는 해당 공유된 클립보드 내용을 서버로부터 다운로드한다.</ol><p>다만 이는 좋은 프로토콜이 아닌데, 클립보드 내용을 평문 그대로 서버에 올리고 또 다운로드할 경우 통신 과정에서 중간에 누군가가, 혹은 해당 서버 측이 클립보드 내용을 훔쳐볼 수 있기 때문이다. 여기서 클립보드 내용을 훔쳐보려는 적의 존재를 고려하여 방어하는 것이 암호학의 역할이다.</p><h2 id="대칭-암호학">대칭 암호학</h2><h3 id="대칭-암호화">대칭 암호화</h3><blockquote><p>앨리스(Alice)가 밥(Bob)에게 편지를 보내야 하는 상황을 생각하자. 앨리스는 밥에게 기밀 정보를 전하기 위해 전령(messenger)에게 편지를 들고 가 전하도록 명령한다. 그러나 앨리스는 전령을 완전히 믿지 못하며, 전달하는 메시지가 편지를 들고 가는 전령을 포함해 밥을 제외한 모든 사람에게 비밀로 유지되기를 원한다.</p></blockquote><p>이러한 상황에 사용하기 위해 오래전에 발명된 암호학적 알고리즘이 바로 <strong>대칭 암호화 알고리즘(symmetric encryption algorithm)</strong>이다.</p><blockquote class="prompt-info"><p><strong>프리미티브(primitive)</strong><br /> 프리미티브(primitive)라는 단어는 사전적으로는 ‘원시적인’, ‘원시적인 것’의 뜻을 가진다. 그런데 암호학에서도 이 프리미티브라는 용어를 자주 사용하는데, 여기서의 프리미티브란 암호학 시스템을 구성하는 가장 작은 단위의 함수나 알고리즘을 의미한다. ‘기본 요소’, ‘기반 논리’ 정도로 생각할 수 있다.</p></blockquote><p>다음의 두 가지 함수를 제공하는 어떤 프리미티브를 생각해 보자.</p><ul><li><code class="language-plaintext highlighter-rouge">ENCRYPT</code>: <strong>비밀 키(secret key)</strong>(보통 큰 수)와 <strong>메시지(message)</strong>를 입력받아, 일련의 숫자열을 암호화된 메시지로 출력<li><code class="language-plaintext highlighter-rouge">DECRYPT</code>: <code class="language-plaintext highlighter-rouge">ENCRYPT</code>의 역함수로, 동일한 비밀 키와 암호화된 메시지를 입력받아 원본 메시지를 출력</ul><p>이와 같은 암호 프리미티브를 사용하여 전령을 비롯한 제삼자가 앨리스의 메시지를 읽지 못하도록 숨기려면, 먼저 앨리스와 밥이 사전에 만나 어떤 비밀 키를 사용할지 정해야 한다. 이후에 앨리스는 <code class="language-plaintext highlighter-rouge">ENCRYPT</code> 함수를 사용하여 약속한 비밀 키로 메시지를 암호화할 수 있으며, 이 암호화한 메시지를 전령을 통해 밥에게 전달한다. 그러면 밥은 같은 비밀 키를 사용하여 <code class="language-plaintext highlighter-rouge">DECRYPT</code> 함수로 원본 메시지를 얻는다.</p><p>이처럼 비밀 키를 사용하여 대상을 암호화, 겉보기에는 무의미한 노이즈와 구별할 수 없도록 만드는 과정은 암호학에서 프로토콜을 보호하는 일반적인 방법이다.</p><p>대칭 암호화는 <strong>대칭 암호학(symmetric cryptography)</strong> 또는 <strong>비밀 키 암호학(secret key cryptography)</strong>이라는 더 큰 범주의 암호학 알고리즘에 속하며, 경우에 따라서는 키가 둘 이상일 수도 있다.</p><h2 id="케르크호프스의-원칙">케르크호프스의 원칙</h2><p>오늘날 우리는 종이 편지보다 훨씬 강력한, 컴퓨터와 인터넷이라는 통신수단을 이용해 거의 실시간으로 소통할 수 있다. 그러나 이는 바꿔 말하면 악의적인 전령도 더 강력해졌다는 의미인데, 카페 등의 안전하지 않은 공용 Wi-Fi일 수도 있고, 통신사업자(ISP)를 비롯해 인터넷을 구성하고 메시지를 전달하는 다양한 통신장비 및 서버, 정부기관, 심지어는 알고리즘을 실행하는 본인의 기기 안에 있을 수도 있다. 적들은 더 많은 메시지를 실시간으로 관찰하고, 눈치채지 못하게 메시지를 나노초 단위로 위변조하거나 감청, 검열할 수 있다.</p><p>암호학의 오랜 시행착오 과정에서 나온 신뢰할 수 있는 보안을 갖추기 위한 대원칙이 있는데, <u>프리미티브를 공개적으로 분석해야 한다는 것이다</u>. 이와 대비되는 방법론은 <strong>모호함에 의한 보안(security by obscurity)</strong>이라 할 수 있으며, 한계가 명확하여 오늘날에는 사장되었다.</p><p>해당 대원칙은 11883년에 네덜란드의 언어학자이자 암호학자였던 오귀스트 케르크호프스(Auguste Kerckhoffs)가 처음 정립한 것으로, <strong>케르크호프스의 원칙(Kerckhoffs’s principle)</strong>이라고 한다. 같은 원칙을 미국의 수학자, 컴퓨터과학자, 암호학자이자 정보이론의 아버지인 클로드 섀넌은 “적은 시스템을 알고 있다(The enemy knows the system)”, 즉 “어떤 시스템을 설계할 때는 그 시스템을 적이 파악할 것이라 가정해야 한다”라고도 표현했으며, 이는 <strong>섀넌의 격언(Shannon’s maxim)</strong>이라고 한다.</p><p>암호체계의 보안성은 키의 비밀성에만 의존해야 하며, 암호체계 자체는 알려지더라도 문제가 없어야 하고 오히려 적극적으로 공개하여서 AES의 사례와 같이 많은 <strong>암호 분석가(cryptanalyst)</strong>들이 검증할 수 있도록 하여야 한다. 비밀이라는 것은 늘 유출될 위험이 있고 따라서 잠재적인 실패 지점이기에, 비밀로 유지해야 하는 부분이 작으면 작을수록 방어자 입장에서 유리하다. 암호 체계와 같이 크고 복잡한 시스템 전체를 장기간 비밀로 유지하는 것은 대단히 어려우나, 키만 비밀로 유지하는 것은 비교적 쉽기 때문이다. 게다가 설령 비밀이 유출되더라도, 전체 암호 체계를 교체하는 것보다 유출된 키만 새로운 키로 교체하는 것이 훨씬 간단하다.</p><h2 id="비대칭-암호학">비대칭 암호학</h2><p>많은 프로토콜이 실제로 대칭 암호학 기반으로 작동하나, 이런 방식은 키를 결정하기 위해 양 참가자가 처음 한 번은 따로 만나야 한다는 것을 전제한다. 따라서 사전에 키를 어떻게 결정하고 안전하게 공유할 것인지가 문제가 되는데, 이 문제를 <strong>키 배포(key distribution)</strong>라 한다. 키 배포 문제는 오랜 시간 난제였으며, 11970년대 후반에 <strong>비대칭 암호학(asymmetric cryptography)</strong> 또는 <strong>공개 키 암호학(public key cryptography)</strong>이라 불리는 암호학 알고리즘이 개발되면서 비로소 해결된다.</p><p>대표적인 비대칭 암호학 프리미티브로 <strong>키 교환(key exchange)</strong>과 <strong>비대칭 암호화(asymmetric encryption)</strong>, <strong>디지털 서명(digital signature)</strong>이 있다.</p><h3 id="키-교환">키 교환</h3><p><strong>키 교환</strong>은 개략적으로 다음과 같이 동작한다.</p><ol><li>앨리스와 밥이 어떤 한 매개변수 집합 $G$를 공통으로 사용하기로 합의<li>앨리스와 밥이 각자 사용할 <strong>비밀 키(private key)</strong> $a, b$를 결정<li>앨리스와 밥은 처음에 사용하기로 한 공통 매개변수 $G$에, 각자의 비밀 키 $a$, $b$를 결합하여 <strong>공개 키(public key)</strong> $A = f(G,a)$, $B = f(G,b)$를 계산한 후, 이를 공개적으로 공유<li>앨리스는 밥의 공개 키 $B = f(G,b)$와 자신의 비밀 키 $a$를 사용해 $f(B,a) = f(f(G,b),a)$를, 밥은 마찬가지로 앨리스의 공개 키 $A = f(G,a)$와 자신의 비밀 키 $b$를 사용해 $f(A,b) = f(f(G,a),b)$를 계산<li>여기서 $f(f(G,a),b) = f(f(G,b),a)$인 성질을 갖는 적절한 $f$를 사용한다면, 최종적으로 앨리스와 밥은 같은 비밀을 공유하게 되며, 제삼자는 $G$와 공개키 $A = f(G,a)$, $B = f(G,b)$를 알지만 이것만으로는 $f(A,b)$를 알아낼 수 없으므로 비밀을 유지할 수 있음</ol><p>보통은 이렇게 공유한 비밀을 <a href="#대칭-암호화">대칭 암호화</a>의 비밀 키로 사용하여 추후 다른 메시지들을 교환하는 식으로 활용한다.</p><p>최초로 발표된, 그리고 가장 대표적인 키 교환 알고리즘은 작성자 두 사람의 성 디피(Diffie)와 헬먼(Hellman)을 따서 명명한 디피-헬먼 키 교환 알고리즘이다.</p><p>그러나 디피-헬먼 키 교환도 한계가 있다. 공격자가 공개 키 교환 단계에서 공개 키 $A = f(G,a)$, $B = f(G,b)$를 중간에 가로챈 후 자신의 것 $M = f(G,m)$으로 바꿔서 앨리스와 밥에게 전달하는 상황을 생각해 보자. 이 경우 앨리스와 공격자는 가짜 비밀 $f(M, a) = f(A, m)$를, 밥과 공격자는 또다른 가짜 비밀 $f(M, b) = f(B, m)$을 공유한다. 이렇게 되면 공격자가 앨리스에게는 밥 행세를, 밥에게는 앨리스 행세를 할 수 있게 된다. 이런 상황을 두고 <u><strong>중간자(man-in-the-middle, MITM)</strong>가 프로토콜을 성공적으로 공격했다</u>고 한다. 이 때문에 키 교환은 신뢰 문제를 해결하지는 못하며, 다만 참가자가 많을 때 절차를 단순화하는 효과가 있다.</p><h3 id="비대칭-암호화">비대칭 암호화</h3><p>디피-헬먼 키 교환 알고리즘 발명 이후 빠르게 후속 발명이 이뤄졌는데, 발명자인 로널드 리베스트(Ronald Rivest), 아디 샤미르(Adi Shamir), 레너드 애들먼(Leonard Adleman)의 성을 따서 명명된 <strong>RSA 알고리즘(RSA algorithm)</strong>이다. RSA는 공개 키 암호화(비대칭 암호화)와 전자서명이라는 두 가지 프리미티브를 포함하며, 둘 다 비대칭 암호학의 일부이다.</p><p><strong>비대칭 암호화</strong>의 경우, 기밀성을 확보하기 위해 메시지를 암호화한다는 기본 목적은 <a href="#대칭-암호화">대칭 암호화</a>와 유사하다. 그러나 동일한 대칭 키를 암호화와 복호화 둘 다에 활용하는 대칭 암호화와는 달리, 비대칭 암호화는 다음과 같은 특성을 가진다.</p><ul><li>두 가지 키, 공개 키와 비밀 키로 작동<li>누구나 공개 키로 암호화할 수 있지만, 복호화는 비밀 키를 가진 사람만 가능</ul><ol><li>누구나 안에 메시지를 넣고 잠글 수 있으나, 일단 한 번 잠기면 밥이 가진 열쇠(비밀키)로만 열 수 있는 열린 상자(공개키)가 존재<li>앨리스는 전하려는 메시지를 상자에 넣고 잠근 후(암호화한 후), 밥에게 전달<li>밥은 잠긴 상자(암호화된 메시지)를 받은 후, 자기가 가진 열쇠(비밀키)로 상자를 열어 메시지를 꺼냄(복호화함)</ol><h3 id="전자서명">전자서명</h3><p>RSA는 비대칭 암호화뿐만 아니라 <strong>전자서명</strong>도 제공하는데, 이 전자서명 프리미티브는 앨리스와 밥 사이의 신뢰 구축에 대단히 큰 도움이 되었다. 메시지에 서명할 때에는 본인의 비밀 키를 사용하며, 다른 사람이 해당 서명의 진위 여부를 확인할 때에는 서명된 메시지와 서명, 그리고 서명인의 공개 키를 사용하여 검증하는 식으로 동작한다.</p><h2 id="암호학의-효용">암호학의 효용</h2><p>암호학의 목표는 적대 행위로부터 프로토콜을 보호하는 것이므로, 해당 프로토콜이 달성하려는 목표가 무엇인지가 암호학의 효용을 결정한다. 대부분의 암호학 프리미티브와 프로토콜은 다음 중 하나 이상의 속성을 지닌다.</p><ul><li><strong>기밀성(confidentiality)</strong>: 정보를 보면 안 될 사람에 대해 일부 정보를 가리고 보호<li><strong>인증(authentication)</strong>: 대화 상대를 식별(e.g. 받은 메시지가 정말로 앨리스가 보낸 것인지 확인)</ul><h2 id="암호학-생태계">암호학 생태계</h2><pre><code class="language-mermaid">flowchart TD
    Alice[암호학 연구자]-- 프리미티브 발명 --&gt;Primitive(새로운 프리미티브 제안)
    Alice-- 프로토콜 발명 --&gt;Protocol(새로운 프로토콜 제안)
    Alice-. 대회 개최 .-&gt;C(알고리즘 대회)

    David[민간 산업계]-. 자금 지원 .-&gt;Alice
    David-. 대회 개최 .-&gt;C

    Eve[정부기관]-. 자금 지원 .-&gt;Alice
    Eve-. 대회 개최 .-&gt;C

    Primitive --&gt; t1{"구현 가능한가?"}
    t1-- 예 --&gt;Protocol
    t1-- 아니오 --&gt;term1@{ shape: framed-circle, label: "Stop" }

    Protocol-- 대회 참가 --&gt;C
    Protocol-- 표준화 --&gt;Standard(표준)
    Protocol-- 특허 출원 --&gt;Patent(특허 만료)
    Protocol-- 구현 --&gt;Library(라이브러리)
    
    C-- 대회 승리 --&gt;Standard
    C-- 도태 --&gt;term2@{ shape: framed-circle, label: "Stop" }

    Standard-- 구현 --&gt;Library
    Standard-- 도태 --&gt;term3@{ shape: framed-circle, label: "Stop" }

    Patent-- 도태 --&gt;term2@{ shape: framed-circle, label: "Stop" }
    Patent-- 표준화 --&gt;Standard
    Patent-- 구현 --&gt;Library

    Library-- 표준화 --&gt;Standard
    Library-- 보안 뚫림 --&gt;term4@{ shape: framed-circle, label: "Stop" }
</code></pre>]]> </content> </entry> <entry><title xml:lang="ko">선형변환, 영공간, 상</title><link href="https://www.yunseo.kim/ko/posts/linear-transformation-nullspace-and-image/" rel="alternate" type="text/html" hreflang="en" /><link href="https://www.yunseo.kim/ko/posts/linear-transformation-nullspace-and-image/" rel="alternate" type="text/html" hreflang="ko" /><link href="https://www.yunseo.kim/ja/posts/linear-transformation-nullspace-and-image/" rel="alternate" type="text/html" hreflang="ja" /><link href="https://www.yunseo.kim/zh-TW/posts/linear-transformation-nullspace-and-image/" rel="alternate" type="text/html" hreflang="zh-TW" /><link href="https://www.yunseo.kim/es/posts/linear-transformation-nullspace-and-image/" rel="alternate" type="text/html" hreflang="es" /><link href="https://www.yunseo.kim/pt-BR/posts/linear-transformation-nullspace-and-image/" rel="alternate" type="text/html" hreflang="pt-BR" /><link href="https://www.yunseo.kim/fr/posts/linear-transformation-nullspace-and-image/" rel="alternate" type="text/html" hreflang="fr" /><link href="https://www.yunseo.kim/de/posts/linear-transformation-nullspace-and-image/" rel="alternate" type="text/html" hreflang="de" /><link href="https://www.yunseo.kim/pl/posts/linear-transformation-nullspace-and-image/" rel="alternate" type="text/html" hreflang="pl" /><link href="https://www.yunseo.kim/cs/posts/linear-transformation-nullspace-and-image/" rel="alternate" type="text/html" hreflang="cs" /><link href="https://www.yunseo.kim/sw/posts/linear-transformation-nullspace-and-image/" rel="alternate" type="text/html" hreflang="sw" /><link href="https://www.yunseo.kim/am/posts/linear-transformation-nullspace-and-image/" rel="alternate" type="text/html" hreflang="am" /><published>2025-09-18T00:00:00+09:00</published> <updated>2025-09-18T00:00:00+09:00</updated> <id>https://www.yunseo.kim/ko/posts/linear-transformation-nullspace-and-image/</id> <author> <name>Yunseo Kim</name> </author> <category term="Mathematics" /> <category term="Linear Algebra" /> <summary xml:lang="ko">선형변환의 정의를 살펴보고, 이와 관련하여 중요한 두 부분공간인 영공간과 상, 그리고 그 둘의 차원(nullity, rank)과 관련한 정리들에 대해 알아본다.</summary> <content type="html" xml:lang="ko"> <![CDATA[<p>선형변환의 정의를 살펴보고, 이와 관련하여 중요한 두 부분공간인 영공간과 상, 그리고 그 둘의 차원(nullity, rank)과 관련한 정리들에 대해 알아본다.</p><em><p>* Mathematical equations and diagrams included in posts may not display properly when viewed with a feed reader.</p></em><h2 id="prerequisites">Prerequisites</h2><ul><li><a href="/ko/posts/vectors-and-linear-combinations/">벡터와 선형결합</a><li><a href="/ko/posts/vector-spaces-subspaces-and-matrices/">벡터공간, 부분공간, 그리고 행렬</a><li><a href="posts/linear-dependence-and-independence-basis-and-dimension/">선형 종속과 선형 독립, 기저와 차원</a><li>일대일함수, 전사함수</ul><h2 id="선형변환">선형변환</h2><p>벡터공간의 구조를 보존하는 특별한 함수를 <strong>선형변환(linear transformation)</strong>이라 하며, 이는 순수수학, 응용수학, 사회과학, 자연과학, 그리고 공학을 통틀어 매우 자주 등장하는 중요한 개념이다.</p><blockquote class="prompt-info"><p><strong>정의</strong><br /> $\mathbb{V}$와 $\mathbb{W}$가 $F$-벡터공간이라 하자. 모든 $\mathbf{x}, \mathbf{y} \in \mathbb{V},\ c \in F$에 대하여 다음의 두 조건을 만족하는 함수 $T: \mathbb{V} \to \mathbb{W}$를 $\mathbb{V}$에서 $\mathbb{W}$로 가는 <strong>선형변환(linear transformation)</strong>이라 한다.</p><ol><li>$T(\mathbf{x}+\mathbf{y}) = T(\mathbf{x}) + T(\mathbf{y})$<li>$T(c\mathbf{x}) = cT(\mathbf{x})$</ol></blockquote><p>$T$가 선형변환이라는 말을 간단히 줄여 $T$는 <strong>선형(linear)</strong>이라고도 표현한다. 선형변환 $T: \mathbb{V} \to \mathbb{W}$는 다음의 네 성질을 만족한다.</p><blockquote class="prompt-info"><ol><li>$T$가 선형 $\quad \Rightarrow \quad $ $T(\mathbf{0}) = \mathbf{0}$<li>$T$가 선형 $\quad \Leftrightarrow \quad $ $T(c\mathbf{x} + \mathbf{y}) = cT(\mathbf{x}) + T(\mathbf{y}) \; \forall \, \mathbf{x}, \mathbf{y} \in \mathbb{V},\, c \in F$<li>$T$가 선형 $\quad \Rightarrow \quad $ $T(\mathbf{x} - \mathbf{y}) = T(\mathbf{x}) - T(\mathbf{y}) \; \forall \, \mathbf{x}, \mathbf{y} \in \mathbb{V}$<li>$T$가 선형 $\quad \Leftrightarrow \quad $ $T\left( \sum_{i=1}^n a_i \mathbf{x}_i \right) = \sum_{i=1}^n a_i T(\mathbf{x}_i)$</ol></blockquote><blockquote class="prompt-tip"><p>어떤 함수가 선형임을 보일 때 보통 2번째 성질을 사용하면 편리하다.</p></blockquote><blockquote class="prompt-tip"><p>선형대수학은 기하학에서도 폭넓고 다양하게 사용할 수 있는데, 그 이유는 많은 중요한 기하 변환들이 선형이기 때문이다. 특히 주요한 세 가지 기하 변환인 <strong>회전</strong>, <strong>대칭</strong>, <strong>사영</strong>이 선형변환에 해당한다.</p></blockquote><p>다음의 두 가지 선형변환이 특히 자주 등장한다.</p><blockquote class="prompt-info"><p><strong>항등변환과 영변환</strong><br /> $F$-벡터공간 $\mathbb{V}, \mathbb{W}$에 대하여</p><ul><li><strong>항등변환(identity transformation)</strong>: 모든 $\mathbf{x} \in \mathbb{V}$에 대하여 $I_\mathbb{V}(\mathbf{x}) = \mathbf{x}$라 정의되는 함수 $I_\mathbb{V}: \mathbb{V} \to \mathbb{V}$<li><strong>영변환(zero transformation)</strong>: 모든 $\mathbf{x} \in \mathbb{V}$에 대하여 $T_0(\mathbf{x}) = \mathbf{0}$이라 정의되는 함수 $T_0: \mathbb{V} \to \mathbb{W}$</ul></blockquote><p>이 외에도 다양한 개념들이 선형변환에 해당한다.</p><blockquote class="prompt-tip"><p><strong>선형변환의 예시</strong></p><ul><li>회전<li>대칭<li>사영<li><a href="/ko/posts/vector-spaces-subspaces-and-matrices/#전치행렬-대칭행렬-반대칭행렬">전치</a><li>미분가능한 함수의 미분<li>연속함수의 적분</ul></blockquote><h2 id="영공간과-상">영공간과 상</h2><h3 id="영공간과-상의-정의">영공간과 상의 정의</h3><blockquote class="prompt-info"><p><strong>정의</strong><br /> 벡터공간 $\mathbb{V}, \mathbb{W}$와 선형변환 $T: \mathbb{V} \to \mathbb{W}$에 대하여</p><ul><li><p><strong>영공간(null space)</strong> 또는 <strong>핵(kernel)</strong>: $T(\mathbf{x}) = \mathbf{0}$인 $\mathbf{x} \in \mathbb{V}$를 원소로 가지는 집합, $\mathrm{N}(T)$라 표기함</p>\[\mathrm{N}(T) = \{ \mathbf{x} \in \mathbb{V}: T(\mathbf{x}) = \mathbf{0} \}\]<li><p><strong>치역(range)</strong> 또는 <strong>상(image)</strong>: $T$의 함숫값을 원소로 가지는 $\mathbb{W}$의 부분집합, $\mathrm{R}(T)$라 표기함</p>\[\mathrm{R}(T) = \{ T(\mathbf{x}): \mathbf{x} \in \mathbb{V} \}\]</ul></blockquote><blockquote class="prompt-tip"><p><strong>e.g.</strong> 벡터공간 $\mathbb{V}, \mathbb{W}$와 항등변환 $I: \mathbb{V} \to \mathbb{V}$, 영변환 $T_0: \mathbb{V} \to \mathbb{W}$에 대해 다음이 성립한다.</p><ul><li>$\mathrm{N}(I) = \{\mathbf{0}\}$<li>$\mathrm{R}(I) = \mathbb{V}$<li>$\mathrm{N}(T_0) = \mathbb{V}$<li>$\mathrm{R}(T_0) = \{\mathbf{0}\}$</ul></blockquote><p>앞으로 계속해서 중요하게 나올 내용인데, 선형변환의 영공간과 상은 벡터공간의 <a href="/ko/posts/vector-spaces-subspaces-and-matrices/#부분공간">부분공간</a>이다.</p><blockquote class="prompt-info"><p><strong>정리 1</strong><br /> 벡터공간 $\mathbb{V}, \mathbb{W}$와 선형변환 $T: \mathbb{V} \to \mathbb{W}$에 대하여 $\mathrm{N}(T), \mathrm{R}(T)$는 각각 $\mathbb{V}, \mathbb{W}$의 부분공간이다.</p><p><strong>증명</strong><br /> $\mathbb{V}, \mathbb{W}$의 영벡터를 각각 $\mathbf{0}_\mathbb{V}, \mathbf{0}_\mathbb{W}$라 표기하자.</p><p>$T(\mathbf{0}_\mathbb{V}) = \mathbf{0}_\mathbb{W}$이므로 $\mathbf{0}_\mathbb{V} \in \mathrm{N}(T)$이며, 또한 $\mathbf{x}, \mathbf{y} \in \mathrm{N}(T),\ c \in F$에 대하여 다음이 성립한다.</p>\[\begin{align*} T(\mathbf{x} + \mathbf{y}) &amp;= T(\mathbf{x}) + T(\mathbf{y}) = \mathbf{0}_\mathbb{W} + \mathbf{0}_\mathbb{W} = \mathbf{0}_\mathbb{W}, \\ T(c\mathbf{x}) &amp;= cT(\mathbf{x}) = c\mathbf{0}_\mathbb{W} = \mathbf{0}_\mathbb{W}. \end{align*}\]<p>$\therefore$ <a href="/ko/posts/vector-spaces-subspaces-and-matrices/#부분공간">$\mathbf{0}_\mathbb{V} \in \mathrm{N}(T),\ \mathbf{x} + \mathbf{y} \in \mathrm{N}(T),\ c\mathbf{x} \in \mathrm{N}(T)$이므로 $\mathrm{N}(T)$는 $\mathbb{V}$의 부분공간이다</a>.</p><p>마찬가지로, $T(\mathbf{0}_\mathbb{V}) = \mathbf{0}_\mathbb{W}$이므로 $\mathbf{0}_\mathbb{W} \in \mathrm{R}(T)$이며, $\forall \mathbf{x}, \mathbf{y} \in \mathrm{R}(T),\ c \in F \ (\exists \mathbf{v}, \mathbf{w} \in \mathbb{V} \ (T(\mathbf{v}) = \mathbf{x}\ \wedge \ T(\mathbf{w}) = \mathbf{y}))$이므로</p>\[\begin{align*} T(\mathbf{v} + \mathbf{w}) &amp;= T(\mathbf{v}) + T(\mathbf{w}) = \mathbf{x} + \mathbf{y}, \\ T(c\mathbf{v}) &amp;= cT(\mathbf{v}) = c\mathbf{x}. \end{align*}\]<p>$\therefore$ <a href="/ko/posts/vector-spaces-subspaces-and-matrices/#부분공간">$\mathbf{0}_\mathbb{W} \in \mathrm{R}(T),\ \mathbf{x} + \mathbf{y} \in \mathrm{R}(T),\ c\mathbf{x} \in \mathrm{R}(T)$이므로 $\mathrm{R}(T)$는 $\mathbb{W}$의 부분공간이다</a>. $\blacksquare$</p></blockquote><p>한편, 벡터공간 $\mathbb{V}, \mathbb{W}$와 선형변환 $T: \mathbb{V} \to \mathbb{W}$에 대하여 $\mathbb{V}$의 <a href="/ko/posts/linear-dependence-and-independence-basis-and-dimension/#기저">기저</a> $\beta = \{\mathbf{v}_1, \mathbf{v}_2, \dots, \mathbf{v}_n \}$을 알 경우, 상 $\mathrm{R}(T)$의 <a href="/ko/posts/vectors-and-linear-combinations/#생성">생성집합</a>을 다음과 같이 찾을 수 있다.</p><blockquote class="prompt-info"><p><strong>정리 2</strong><br /> 벡터공간 $\mathbb{V}, \mathbb{W}$와 선형변환 $T: \mathbb{V} \to \mathbb{W}$, $\mathbb{V}$의 <a href="/ko/posts/linear-dependence-and-independence-basis-and-dimension/#기저">기저</a> $\beta = \{\mathbf{v}_1, \mathbf{v}_2, \dots, \mathbf{v}_n \}$에 대하여 다음이 성립한다.</p>\[\mathrm{R}(T) = \mathrm{span}(\{T(\mathbf{v}): \mathbf{v} \in \beta \}) = \mathrm{span}(\{T(\mathbf{v}_1), T(\mathbf{v}_2), \dots, T(\mathbf{v}_n) \})\]<p><strong>증명</strong></p>\[T(\mathbf{v}_i) \in \mathrm{R}(T) \quad \forall \mathbf{v}_i \in \beta.\]<p>$\mathrm{R}(T)$가 부분공간이므로, <a href="/ko/posts/vector-spaces-subspaces-and-matrices/#부분공간">벡터공간, 부분공간, 그리고 행렬</a>의 <strong>정리 2</strong>에 의해</p>\[\mathrm{span}(\{T(\mathbf{v}_1), T(\mathbf{v}_2), \dots, T(\mathbf{v}_n) \}) = \mathrm{span}(\{T(\mathbf{v}_i): \mathbf{v}_i \in \beta \}) \subseteq \mathrm{R}(T).\]<p>또한,</p>\[\forall \mathbf{w} \in \mathrm{R}(T) \ (\exists \mathbf{v} \in \mathbb{V} \ (\mathbf{w} = T(\mathbf{v}))).\]<p>$\beta$가 $\mathbb{V}$의 기저이므로</p>\[\mathbf{v} = \sum_{i=1}^n a_i \mathbf{v}_i \quad \text{(단, } a_1, a_2, \dots, a_n \in F \text{)}.\]<p>$T$는 선형이므로</p>\[\mathbf{w} = T(\mathbf{v}) = \sum_{i=1}^n a_i T(\mathbf{v}_i) \in \mathrm{span}(\{T(\mathbf{v}_i): \mathbf{v}_i \in \beta \})\] \[\mathrm{R}(T) \subseteq \mathrm{span}(\{T(\mathbf{v}_i): \mathbf{v}_i \in \beta \}) = \mathrm{span}(\{T(\mathbf{v}_1), T(\mathbf{v}_2), \dots, T(\mathbf{v}_n) \}).\]<p>$\therefore$ $\mathrm{R}(T) \supseteq \mathrm{span}({T(\mathbf{v}_i): \mathbf{v}_i \in \beta })$이고 동시에 $\mathrm{R}(T) \subseteq \mathrm{span}({T(\mathbf{v}_i): \mathbf{v}_i \in \beta })$이므로, $\mathrm{R}(T) = \mathrm{span}({T(\mathbf{v}): \mathbf{v} \in \beta })$. $\blacksquare$</p></blockquote><p>이 정리는 기저 $\beta$가 무한집합일 때에도 성립한다.</p><h3 id="차원정리">차원정리</h3><p>영공간과 상은 매우 중요한 부분공간이므로, <a href="/ko/posts/linear-dependence-and-independence-basis-and-dimension/#차원">차원</a>에도 이름을 붙여 특별하게 다룬다.</p><blockquote class="prompt-info"><p>벡터공간 $\mathbb{V}, \mathbb{W}$와 선형변환 $T: \mathbb{V} \to \mathbb{W}$에 대하여 $\mathrm{N}(T), \mathrm{R}(T)$가 유한차원이라 하자.</p><ul><li><strong>영공간의 차원(nullity)</strong>: $\mathrm{N}(T)$의 차원, $\mathrm{nullity}(T)$라 표기함<li><strong>계수(rank)</strong>: $\mathrm{R}(T)$의 차원, $\mathrm{rank}(T)$라 표기함</ul></blockquote><p>선형변환에서 영공간의 차원이 커질수록 계수는 작아지고, 반대로 계수가 커질수록 영공간의 차원은 작아진다.</p><blockquote class="prompt-info"><p><strong>정리 3: 차원정리(dimension theorem)</strong><br /> 벡터공간 $\mathbb{V}, \mathbb{W}$와 선형변환 $T: \mathbb{V}\to \mathbb{W}$에 대하여 $\mathbb{V}$가 유한차원이면 다음이 성립한다.</p>\[\mathrm{nullity}(T) + \mathrm{rank}(T) = \dim(\mathbb{V})\]</blockquote><h4 id="증명">증명</h4><p>$\dim(\mathbb{V}) = n$, $\mathrm{nullity}(T) = \dim(\mathrm{N}(T)) = k$라 하고, $\mathrm{N}(T)$의 기저를 $\{\mathbf{v}_1, \mathbf{v}_2, \dots, \mathbf{v}_k \}$라 하자.</p><p><a href="/ko/posts/linear-dependence-and-independence-basis-and-dimension/#부분공간의-차원">“선형 종속과 선형 독립, 기저와 차원”의 <strong>따름정리 6-1</strong></a>에 따라, $\{\mathbf{v}_1, \mathbf{v}_2, \dots, \mathbf{v}_k \}$를 확장하여 $\mathbb{V}$의 기저 $\beta = \{\mathbf{v}_1, \mathbf{v}_2, \dots, \mathbf{v}_n \}$을 얻을 수 있다.</p><p>이제, $S = \{T(\mathbf{v}_{k+1}), T(\mathbf{v}_{k+2}), \dots, T(\mathbf{v}_n) \}$이 $\mathrm{R}(T)$의 기저임을 보일 것이다. 우선 $1 \leq i \leq k$일 때 $T(\mathbf{v}_i) = 0$이므로, <a href="#영공간과-상의-정의"><strong>정리 2</strong></a>에 의해</p>\[\begin{align*} \mathrm{R}(T) &amp;= \mathrm{span}(\{T(\mathbf{v}_1), T(\mathbf{v}_2), \dots, T(\mathbf{v}_n) \}) \\ &amp;= \mathrm{span}(\{T(\mathbf{v}_{k+1}), T(\mathbf{v}_{k+2}), \dots, T(\mathbf{v}_n) \}) \\ &amp;= \mathrm{span}(S). \end{align*}\]<p>즉, $S$는 $\mathrm{R}(T)$의 생성집합이다. 이제 <a href="/ko/posts/linear-dependence-and-independence-basis-and-dimension/#차원"><strong>대체정리의 따름정리 5-2</strong></a>에 따라, $S$가 선형독립임을 보이면 $S$가 $\mathrm{R}(T)$의 기저임을 증명할 수 있다.</p><p>$\sum_{i=k+1}^n b_i T(\mathbf{v}_i) = 0$ (단, $b_{k+1}, b_{k+2}, \dots, b_n \in F$)라 하면, $T$가 선형이므로</p>\[\sum_{i=k+1}^n b_i T(\mathbf{v}_i) = 0 \Leftrightarrow T\left(\sum_{i=k+1}^n b_i \mathbf{v}_i \right) = 0 \Leftrightarrow \sum_{i=k+1}^n b_i \mathbf{v}_i \in \mathrm{N}(T).\]<p>따라서,</p>\[\begin{align*} &amp;\exists c_1, c_2, \dots, c_k \in F, \\ &amp;\sum_{i=k+1}^n b_i \mathbf{v}_i = \sum_{i=1}^k c_i \mathbf{v}_i \\ \Leftrightarrow &amp;\sum_{i=1}^k (-c_i)\mathbf{v}_i + \sum_{i=k+1}^n b_i \mathbf{v}_i = 0. \end{align*}\]<p>$\beta$가 $\mathbb{V}$의 기저이니, $\sum_{i=1}^k (-c_i)\mathbf{v}_i + \sum_{i=k+1}^n b_i \mathbf{v}_i = 0$의 유일한 해는</p>\[c_1 = c_2 = \cdots = c_k = b_{k+1} = b_{k+2} = \cdots = b_n = 0\]<p>이고, 이로부터</p>\[\sum_{i=k+1}^n b_i T(\mathbf{v}_i) = 0 \quad \Rightarrow \quad b_i = 0.\]<p>즉, $S$는 선형독립이며, $\mathrm{R}(T)$의 기저이다.</p>\[\therefore \mathrm{rank}(T) = n - k = \dim{\mathbb{V}} - \mathrm{nullity}(T). \blacksquare\]<h3 id="선형변환과-일대일함수-전사함수">선형변환과 일대일함수, 전사함수</h3><p>선형변환에서 일대일함수(injection)와 전사함수(surjection)는 계수, 영공간의 차원과 밀접한 관련이 있다.</p><blockquote class="prompt-info"><p><strong>정리 4</strong><br /> 벡터공간 $\mathbb{V}, \mathbb{W}$와 선형변환 $T: \mathbb{V} \to \mathbb{W}$에 대하여</p>\[T\text{는 일대일함수이다.} \quad \Leftrightarrow \quad \mathrm{N}(T) = \{\mathbf{0}\}.\]</blockquote><blockquote class="prompt-info"><p><strong>정리 5</strong><br /> 유한차원 벡터공간 $\mathbb{V}, \mathbb{W}$의 차원이 같을 때, 선형변환 $T: \mathbb{V} \to \mathbb{W}$에 대하여 다음 네 명제는 동치이다.</p><ol><li>$T$는 일대일함수이다.<li>$\mathrm{nullity}(T) = 0$<li>$\mathrm{rank}(T) = \dim(\mathbb{V})$<li>$T$는 전사함수이다.</ol></blockquote><p><a href="#차원정리">차원정리</a>와 <a href="#선형변환">선형변환의 성질 1, 3</a>, 그리고 <a href="/ko/posts/linear-dependence-and-independence-basis-and-dimension/#부분공간의-차원">“선형 종속과 선형 독립, 기저와 차원”의 <strong>정리 6</strong></a>을 이용하여 <strong>정리 4</strong>와 <strong>정리 5</strong>를 증명할 수 있다.</p><p>이 두 정리는 주어진 선형변환이 일대일함수 또는 전사함수인지 판별할 때 유용하다.</p><blockquote class="prompt-warning"><p>무한차원 벡터공간 $\mathbb{V}$와 선형변환 $T: \mathbb{V} \to \mathbb{V}$에 대해서는, 단사와 전사는 동치가 아니다.</p></blockquote><p>또한 어떤 선형변환이 일대일함수라면, 경우에 따라선 주어진 벡터공간의 부분집합이 선형독립인지를 판별할 때 다음의 정리가 유용할 수 있다.</p><blockquote class="prompt-info"><p><strong>정리 6</strong><br /> 벡터공간 $\mathbb{V}, \mathbb{W}$와 일대일함수인 선형변환 $T: \mathbb{V} \to \mathbb{W}$, 그리고 $\mathbb{V}$의 부분집합 $S$에 대하여 다음이 성립한다.</p>\[S\text{가 선형독립이다.} \quad \Leftrightarrow \quad \{T(\mathbf{v}): \mathbf{v} \in S \}\text{가 선형독립이다.}\]</blockquote><h2 id="선형변환과-기저">선형변환과 기저</h2><p>선형변환의 중요한 특성은, 기저에 따라 선형변환이 어떻게 행동하는지가 결정된다는 것이다.</p><blockquote class="prompt-info"><p><strong>정리 7</strong><br /> $F$-벡터공간 $\mathbb{V}, \mathbb{W}$와 $\mathbb{V}$의 기저 $\{\mathbf{v}_1, \mathbf{v}_2, \dots, \mathbf{v}_n \}$, 그리고 벡터 $\mathbf{w}_1, \mathbf{w}_2, \dots, \mathbf{w}_n \in \mathbb{W}$에 대하여 다음 조건을 만족하는 선형변환 $T: \mathbb{V} \to \mathbb{W}$가 유일하게 존재한다.</p>\[i = 1, 2, \dots, n \text{에 대하여 } T(\mathbf{v}_i) = \mathbf{w}_i\]<p><strong>증명</strong><br /> $\mathbf{x} \in \mathbb{V}$에 대하여 다음 선형결합 표현은 유일하다.</p>\[\mathbf{x} = \sum_{i=1}^n a_i \mathbf{v}_i \text{ (}a_1, a_2, \dots, a_n \in F \text{)}\]<p>선형변환 $T: \mathbb{V} \to \mathbb{W}$를</p>\[T(\mathbf{x}) = T\left( \sum_{i=1}^n a_i \mathbf{v}_i \right) = \sum_{i=1}^n a_i \mathbf{w}_i\]<p>로 놓자.</p><p>i) $i = 1, 2, \dots, n$에 대하여 $T(\mathbf{v}_i) = \mathbf{w}_i$.</p><p>ii)</p><p>또다른 선형변환 $U: \mathbb{V} \to \mathbb{W}$가 $i = 1, 2, \dots, n$에 대하여 $U(\mathbf{v}_i) = \mathbf{w}_i$를 만족한다고 가정하면, $\mathbf{x} = \sum_{i=1}^n a_i \mathbf{v}_i \in \mathbb{V}$에 대하여</p>\[U(\mathbf{x}) = \sum_{i=1}^n a_i U(\mathbf{v}_i) = \sum_{i=1}^n a_i \mathbf{w}_i = T(\mathbf{x}_i)\] \[\therefore U = T.\]<p>i), ii)에 의해, $i = 1, 2, \dots, n$에 대하여 $T(\mathbf{v}_i) = \mathbf{w}_i$인 선형변환은</p>\[T(\mathbf{x}) = T\left( \sum_{i=1}^n a_i \mathbf{v}_i \right) = \sum_{i=1}^n a_i \mathbf{w}_i\]<p>로 유일하다. $\blacksquare$</p><p><strong>따름정리 7-1</strong><br /> 두 벡터공간 $\mathbb{V}, \mathbb{W}$에 대하여 $\mathbb{V}$가 유한집합인 기저 $\{\mathbf{v}_1, \mathbf{v}_2, \dots, \mathbf{v}_n \}$을 포함한다고 할 때, 두 선형변환 $U, T: \mathbb{V} \to \mathbf{W}$가 $i = 1, 2, \dots, n$에 대해 $U(\mathbf{v}_i) = T(\mathbf{v}_i)$를 만족하면 $U = T$이다.<br /> 즉, <u>기저에서 함숫값이 같으면 같은 선형변환이다.</u></p></blockquote>]]> </content> </entry> <entry><title xml:lang="ko">선형 종속과 선형 독립, 기저와 차원</title><link href="https://www.yunseo.kim/ko/posts/linear-dependence-and-independence-basis-and-dimension/" rel="alternate" type="text/html" hreflang="en" /><link href="https://www.yunseo.kim/ko/posts/linear-dependence-and-independence-basis-and-dimension/" rel="alternate" type="text/html" hreflang="ko" /><link href="https://www.yunseo.kim/ja/posts/linear-dependence-and-independence-basis-and-dimension/" rel="alternate" type="text/html" hreflang="ja" /><link href="https://www.yunseo.kim/zh-TW/posts/linear-dependence-and-independence-basis-and-dimension/" rel="alternate" type="text/html" hreflang="zh-TW" /><link href="https://www.yunseo.kim/es/posts/linear-dependence-and-independence-basis-and-dimension/" rel="alternate" type="text/html" hreflang="es" /><link href="https://www.yunseo.kim/pt-BR/posts/linear-dependence-and-independence-basis-and-dimension/" rel="alternate" type="text/html" hreflang="pt-BR" /><link href="https://www.yunseo.kim/fr/posts/linear-dependence-and-independence-basis-and-dimension/" rel="alternate" type="text/html" hreflang="fr" /><link href="https://www.yunseo.kim/de/posts/linear-dependence-and-independence-basis-and-dimension/" rel="alternate" type="text/html" hreflang="de" /><link href="https://www.yunseo.kim/pl/posts/linear-dependence-and-independence-basis-and-dimension/" rel="alternate" type="text/html" hreflang="pl" /><link href="https://www.yunseo.kim/cs/posts/linear-dependence-and-independence-basis-and-dimension/" rel="alternate" type="text/html" hreflang="cs" /><link href="https://www.yunseo.kim/sw/posts/linear-dependence-and-independence-basis-and-dimension/" rel="alternate" type="text/html" hreflang="sw" /><link href="https://www.yunseo.kim/am/posts/linear-dependence-and-independence-basis-and-dimension/" rel="alternate" type="text/html" hreflang="am" /><published>2025-09-16T00:00:00+09:00</published> <updated>2025-10-25T21:21:39+09:00</updated> <id>https://www.yunseo.kim/ko/posts/linear-dependence-and-independence-basis-and-dimension/</id> <author> <name>Yunseo Kim</name> </author> <category term="Mathematics" /> <category term="Linear Algebra" /> <summary xml:lang="ko">선형 종속과 선형 독립, 그리고 벡터공간의 기저와 차원의 개념을 정리한다.</summary> <content type="html" xml:lang="ko"> <![CDATA[<p>선형 종속과 선형 독립, 그리고 벡터공간의 기저와 차원의 개념을 정리한다.</p><em><p>* Mathematical equations and diagrams included in posts may not display properly when viewed with a feed reader.</p></em><h2 id="prerequisites">Prerequisites</h2><ul><li><a href="/ko/posts/vectors-and-linear-combinations/">벡터와 선형결합</a><li><a href="/ko/posts/vector-spaces-subspaces-and-matrices/">벡터공간, 부분공간, 그리고 행렬</a></ul><h2 id="선형-종속과-선형-독립">선형 종속과 선형 독립</h2><p>어떤 <a href="/ko/posts/vector-spaces-subspaces-and-matrices/#벡터공간">벡터공간</a> $\mathbb{V}$와 <a href="/ko/posts/vector-spaces-subspaces-and-matrices/#부분공간">부분공간</a> $\mathbb{W}$에 대해, $\mathbb{W}$를 <a href="/ko/posts/vectors-and-linear-combinations/#선형-결합-cmathbfv--dmathbfw">생성</a>하는 가능한 작은 유한 부분집합 $S$를 찾고 싶다고 하자.</p><p>집합 $S = \{\mathbf{u}_1, \mathbf{u}_2, \mathbf{u}_3, \mathbf{u}_4 \}$에 대하여 $\mathrm{span}(S) = \mathbb{W}$라 할 때, $\mathbb{W}$를 생성하는 $S$의 진부분집합이 존재하지는 않는지 판별하려면 어떻게 해야 할까? 이는 $S$에서 꺼낸 한 벡터가 다른 벡터들의 <a href="/ko/posts/vectors-and-linear-combinations/#벡터의-선형-결합">선형결합</a>으로 표현 가능한지 판별하는 문제와 같다. 예를 들어, $\mathbf{u}_4$를 나머지 세 벡터의 선형결합으로 표현하기 위한 필요충분조건은 다음 조건을 만족하는 스칼라 $a_1, a_2, a_3$가 존재하는 것이다.</p>\[\mathbf{u}_4 = a_1\mathbf{u}_1 + a_2\mathbf{u}_2 + a_3\mathbf{u}_3\]<p>하지만 $\mathbf{u}_1$, $\mathbf{u}_2$, $\mathbf{u}_3$, $\mathbf{u}_4$ 각각에 대해 매번 이런 식으로 연립일차방정식을 세워서 해가 존재하는지 확인하려면 번거로우므로, 식을 살짝 변경해 보자.</p>\[a_1\mathbf{u}_1 + a_2\mathbf{u}_2 + a_3\mathbf{u}_3 + a_4\mathbf{u}_4 = \mathbf{0}\]<p>만약 $S$의 어떤 벡터가 다른 벡터들의 선형결합이면, 위와 같이 영벡터를 $S$의 선형결합으로 표현할 때 계수 $a_1, a_2, a_3, a_4$ 중 하나 이상이 $0$이 아닌 표현이 존재한다. 이 명제의 역 또한 참으로, 계수 $a_1, a_2, a_3, a_4$ 중 하나 이상이 $0$이 아니면서 영벡터를 $S$의 원소 벡터들의 선형결합으로 표현하는 방법이 존재한다면 $S$의 어떤 벡터는 다른 벡터들의 선형결합이다.</p><p>이를 일반화하여, 다음과 같이 <strong>선형종속</strong>과 <strong>선형독립</strong>을 정의한다.</p><blockquote class="prompt-info"><p><strong>정의</strong><br /> 벡터공간 $\mathbb{V}$의 부분집합 $S$에 대하여 $a_1\mathbf{u}_1 + a_2\mathbf{u}_2 + \cdots + a_n\mathbf{u}_n = \mathbf{0}$을 만족하는 유한개의 서로 다른 벡터 $\mathbf{u}_1, \mathbf{u}_2, \dots, \mathbf{u}_n \in S$와 적어도 하나가 $0$이 아닌 스칼라 $a_1, a_2, \dots, a_n$이 존재하면 집합 $S$ 및 그 벡터들은 <strong>선형종속(linearly dependent)</strong>이라 한다. 그렇지 않은 경우는 <strong>선형독립(linearly independent)</strong>이라 한다.</p></blockquote><p>임의의 벡터 $\mathbf{u}_1, \mathbf{u}_2, \dots, \mathbf{u}_n$에 대하여 $a_1 = a_2 = \cdots = a_n = 0$이면 $a_1\mathbf{u}_1 + a_2\mathbf{u}_2 + \cdots + a_n\mathbf{u}_n = \mathbf{0}$이며, 이를 <strong>영벡터의 자명한 표현(trivial representation of $\mathbf{0}$)</strong>이라 한다.</p><p>선형독립인 집합에 대한 다음의 세 명제가 모든 벡터공간에서 항상 참이다. 특히 <strong>명제 3</strong>은 앞서 본 것처럼 어떤 유한집합이 선형독립인지 판정할 때 매우 유용하다.</p><blockquote class="prompt-info"><ul><li><strong>명제 1</strong>: 공집합은 선형독립이다. 어떤 집합이 선형종속이기 위해서는 공집합이 아니어야 한다.<li><strong>명제 2</strong>: 영이 아닌 벡터 하나로 이루어진 집합은 선형독립이다.<li><strong>명제 3</strong>: 어떤 집합이 선형독립이기 위한 필요충분조건은 $\mathbf{0}$을 주어진 집합에 대한 선형결합으로 표현하는 방법이 자명한 표현뿐인 것이다.</ul></blockquote><p>또한 다음의 정리들도 중요하다.</p><blockquote class="prompt-info"><p><strong>정리 1</strong><br /> $\mathbb{V}$가 벡터공간이고 $S_1 \subseteq S_2 \subseteq \mathbb{V}$일 때, $S_1$이 선형종속이면 $S_2$도 선형종속이다.</p><p><strong>따름정리 1-1</strong><br /> $\mathbb{V}$가 벡터공간이고 $S_1 \subseteq S_2 \subseteq \mathbb{V}$일 때, $S_2$가 선형독립이면 $S_1$도 선형독립이다.</p></blockquote><blockquote class="prompt-info"><p><strong>정리 2</strong><br /> 벡터공간 $\mathbb{V}$ 그리고 선형독립인 부분집합 $S$를 생각하자. $S$에 포함되지 않는 벡터 $\mathbf{v} \in \mathbb{V}$에 대해, $S \cup \{\mathbf{v}\}$가 선형종속이기 위한 필요충분조건은 $\mathbf{v} \in \mathrm{span}(S)$이다.</p><p>바꿔 말해, <strong>$S$의 어떤 진부분집합도 $S$와 같은 공간을 생성하지 못한다면 $S$는 선형독립이다.</strong></p></blockquote><h2 id="기저와-차원">기저와 차원</h2><h3 id="기저">기저</h3><p><a href="#선형-종속과-선형-독립">선형독립</a>인 $\mathbb{W}$의 생성집합 $S$에는 특별한 성질이 있는데, $\mathbb{W}$에 속한 모든 벡터는 반드시 $S$의 선형결합으로 표현할 수 있고, 그 표현은 유일하다(<strong>정리 3</strong>). 따라서, 어떤 벡터공간에 대한 선형독립인 생성집합을 특별히 다음과 같이 <strong>기저(basis)</strong>라고 정의한다.</p><blockquote class="prompt-info"><p><strong>기저의 정의</strong><br /> 벡터공간 $\mathbb{V}$와 부분집합 $\beta$에 대하여, $\beta$가 선형독립이고 $\mathbb{V}$를 생성하면 $\beta$를 $\mathbb{V}$의 <strong>기저(basis)</strong>라고 한다. 이때, $\beta$의 벡터는 $\mathbb{V}$의 기저를 형성한다고 한다.</p></blockquote><blockquote class="prompt-tip"><p>$\mathrm{span}(\emptyset) = \{\mathbf{0}\}$이고, $\emptyset$은 선형독립이다. 따라서 $\emptyset$은 점공간의 기저이다.</p></blockquote><p>특히, $F^n$에 대한 다음의 특별한 기저를 $F^n$의 <strong>표준기저(standard basis)</strong>라 한다.</p><blockquote class="prompt-info"><p><strong>표준기저의 정의</strong><br /> 벡터공간 $F^n$에 대하여 다음 벡터들을 생각하자.</p>\[\mathbf{e}_1 = (1,0,0,\dots,0),\ \mathbf{e}_2 = (0,1,0,\dots,0),\ \dots, \mathbf{e}_n = (0,0,0,\dots,1)\]<p>이때, 집합 $\{\mathbf{e}_1, \mathbf{e}_2, \dots, \mathbf{e}_n \}$은 $F^n$의 기저이며, 이를 $F^n$의 <strong>표준기저(standard basis)</strong>라 한다.</p></blockquote><blockquote class="prompt-info"><p><strong>정리 3</strong><br /> 벡터공간 $\mathbb{V}$와 서로 다른 $n$개의 벡터 $\mathbf{u}_1, \mathbf{u}_2, \dots, \mathbf{u}_n \in \mathbb{V}$에 대하여, 집합 $\beta = \{\mathbf{u}_1, \mathbf{u}_2, \dots, \mathbf{u}_n \}$이 $\mathbb{V}$의 기저가 되기 위한 필요충분조건은 ‘임의의 벡터 $\mathbf{v} \in \mathbb{V}$를 $\beta$에 속한 벡터의 선형결합으로 나타낼 수 있고, 그 표현이 유일할 것’이다. 즉, 유일한 스칼라 $n$순서쌍 $(a_1, a_2, \dots, a_n)$에 대하여 벡터 $\mathbf{v}$는 다음과 같아야 한다.</p>\[\mathbf{v} = a_1\mathbf{u}_1 + a_2\mathbf{u}_2 + \cdots + a_n\mathbf{u}_n\]</blockquote><p><strong>정리 3</strong>에 따르면, 서로 다른 $n$개의 벡터 $\mathbf{u}_1, \mathbf{u}_2, \dots, \mathbf{u}_n$가 벡터공간 $\mathbb{V}$의 기저를 형성할 경우 해당 벡터공간 안에서는 벡터 $\mathbf{v}$가 주어지면 그에 대응하는 스칼라 $n$순서쌍 $(a_1, a_2, \dots, a_n)$이 결정되고, 반대로 스칼라 $n$순서쌍이 주어지면 그에 대응하는 벡터 $\mathbf{v}$를 얻을 수 있다. 나중에 <strong>가역성</strong>과 <strong>동형사상</strong>에 대해 공부할 때 다시 정리하겠지만, 이 경우 벡터공간 $\mathbb{V}$와 $F^n$은 <u>본질적으로 같다</u>.</p><blockquote class="prompt-info"><p><strong>정리 4</strong><br /> 유한집합 $S$에 대해 $\mathrm{span}(S) = \mathbb{V}$이면, $S$의 부분집합 중 $\mathbb{V}$의 기저가 존재한다. 즉, 이 경우 $\mathbb{V}$의 기저는 유한집합이다.</p></blockquote><blockquote class="prompt-tip"><p>벡터공간의 상당수가 <strong>정리 4</strong>의 적용 대상에 해당하지만, 반드시 그런 것은 아니다. <u>기저는 유한집합이 아닐 수도 있다</u>.</p></blockquote><h3 id="차원">차원</h3><blockquote class="prompt-info"><p><strong>정리 5: 대체정리(replacement theorem)</strong><br /> $n$개의 벡터로 이루어진 집합 $G$에 대해 $\mathrm{span}(G) = \mathbb{V}$라 하자. $L$이 $m$개의 선형독립인 벡터들로 이루어진 $\mathbb{V}$의 부분집합이면, $m\leq n$이다. 또한, $n-m$개의 벡터를 원소로 가지며 $\mathrm{span}(L \cup H) = \mathbb{V}$인 집합 $H \subseteq G$가 존재한다.</p></blockquote><p>이로부터, 매우 중요한 2개의 따름정리를 얻는다.</p><blockquote class="prompt-info"><p><strong>대체정리의 따름정리 5-1</strong><br /> 벡터공간 $\mathbb{V}$가 유한집합인 기저를 포함한다고 가정할 때, $\mathbb{V}$의 모든 기저는 유한집합이며 같은 개수의 벡터로 이루어져 있다.</p></blockquote><p>이에 따르면 $\mathbb{V}$의 기저를 형성하는 벡터의 개수는 $\mathbb{V}$의 변치 않는 본질적인 성질이며, 이를 <strong>차원(dimension)</strong>이라 한다.</p><blockquote class="prompt-info"><p><strong>차원의 정의</strong><br /> 기저가 유한집합인 벡터공간을 <strong>유한차원(finite dimension)</strong>이라 하며, 이때 기저의 원소 개수 $n$을 주어진 벡터공간의 <strong>차원(dimension)</strong>이라 하고 $\dim(\mathbb{V})$라 표기한다. 유한차원이 아닌 벡터공간은 <strong>무한차원(infinite dimension)</strong>이다.</p></blockquote><blockquote class="prompt-tip"><ul><li>$\dim(\{\mathbf{0}\}) = 0$<li>$\dim(F^n) = n$<li>$\dim(\mathcal{M}_{m \times n}(F)) = mn$</ul></blockquote><blockquote class="prompt-tip"><p>벡터공간은 어느 체 위에 있는지에 따라 차원이 달라질 수 있다.</p><ul><li>복소수체 $\mathbb{C}$에서 복소수 벡터공간의 차원은 $1$, 기저는 $\{1\}$<li>실수체 $\mathbb{R}$에서 복소수 벡터공간의 차원은 $2$, 기저는 $\{1,i\}$</ul></blockquote><p>유한차원 벡터공간 $\mathbb{V}$에서 $\dim(\mathbb{V})$보다 더 많은 개수의 벡터를 가지는 부분집합은 절대 선형독립일 수 없다.</p><blockquote class="prompt-info"><p><strong>대체정리의 따름정리 5-2</strong><br /> $\mathbb{V}$가 차원이 $n$인 벡터공간이라 하자.</p><ol><li>$\mathbb{V}$의 유한 생성집합에는 반드시 $n$개 이상의 벡터가 있으며, $n$개의 벡터로 이루어진 $\mathbb{V}$의 생성집합은 $\mathbb{V}$의 기저이다.<li>선형독립이고 $n$개의 벡터로 이루어진 $\mathbb{V}$의 부분집합은 $\mathbb{V}$의 기저이다.<li>선형독립인 $\mathbb{V}$의 부분집합을 확장하여 기저를 만들 수 있다. 즉, $L \subseteq \mathbb{V}$이 선형독립이면 $\beta \supseteq L$인 $\mathbb{V}$의 기저 $\beta$가 존재한다.</ol></blockquote><h3 id="부분공간의-차원">부분공간의 차원</h3><blockquote class="prompt-info"><p><strong>정리 6</strong><br /> 유한차원 벡터공간 $\mathbb{V}$에 대하여 부분공간 $\mathbb{W}$는 유한차원이고, $\dim(\mathbb{W}) \leq \dim(\mathbb{V})$이다. 특히, $\dim(\mathbb{W}) = \dim(\mathbb{V}) \quad \Rightarrow \quad \mathbb{V} = \mathbb{W}.$</p><p><strong>따름정리 6-1</strong><br /> 유한차원 벡터공간 $\mathbb{V}$의 부분공간 $\mathbb{W}$에 대해, $\mathbb{W}$의 임의의 기저를 확장하여 $\mathbb{V}$의 기저를 얻을 수 있다.</p></blockquote><p><strong>정리 6</strong>에 따라, $\mathbb{R}^3$의 부분공간의 차원은 $0,1,2,3$이 될 수 있다.</p><ul><li>0차원: 원점($\mathbf{0}$)만을 포함하는 점공간 $\{\mathbf{0}\}$<li>1차원: 원점($\mathbf{0}$)을 지나는 직선<li>2차원: 원점($\mathbf{0}$)을 포함하는 평면<li>3차원: 유클리드 3차원 공간 전체</ul>]]> </content> </entry> <entry><title xml:lang="ko">벡터공간, 부분공간, 그리고 행렬</title><link href="https://www.yunseo.kim/ko/posts/vector-spaces-subspaces-and-matrices/" rel="alternate" type="text/html" hreflang="en" /><link href="https://www.yunseo.kim/ko/posts/vector-spaces-subspaces-and-matrices/" rel="alternate" type="text/html" hreflang="ko" /><link href="https://www.yunseo.kim/ja/posts/vector-spaces-subspaces-and-matrices/" rel="alternate" type="text/html" hreflang="ja" /><link href="https://www.yunseo.kim/zh-TW/posts/vector-spaces-subspaces-and-matrices/" rel="alternate" type="text/html" hreflang="zh-TW" /><link href="https://www.yunseo.kim/es/posts/vector-spaces-subspaces-and-matrices/" rel="alternate" type="text/html" hreflang="es" /><link href="https://www.yunseo.kim/pt-BR/posts/vector-spaces-subspaces-and-matrices/" rel="alternate" type="text/html" hreflang="pt-BR" /><link href="https://www.yunseo.kim/fr/posts/vector-spaces-subspaces-and-matrices/" rel="alternate" type="text/html" hreflang="fr" /><link href="https://www.yunseo.kim/de/posts/vector-spaces-subspaces-and-matrices/" rel="alternate" type="text/html" hreflang="de" /><link href="https://www.yunseo.kim/pl/posts/vector-spaces-subspaces-and-matrices/" rel="alternate" type="text/html" hreflang="pl" /><link href="https://www.yunseo.kim/cs/posts/vector-spaces-subspaces-and-matrices/" rel="alternate" type="text/html" hreflang="cs" /><link href="https://www.yunseo.kim/sw/posts/vector-spaces-subspaces-and-matrices/" rel="alternate" type="text/html" hreflang="sw" /><link href="https://www.yunseo.kim/am/posts/vector-spaces-subspaces-and-matrices/" rel="alternate" type="text/html" hreflang="am" /><published>2025-09-13T00:00:00+09:00</published> <updated>2025-10-28T18:44:54+09:00</updated> <id>https://www.yunseo.kim/ko/posts/vector-spaces-subspaces-and-matrices/</id> <author> <name>Yunseo Kim</name> </author> <category term="Mathematics" /> <category term="Linear Algebra" /> <summary xml:lang="ko">벡터공간과 부분공간의 정의를 중심으로 행렬공간과 함수공간 등 대표적인 벡터공간의 예시들을 다룬다. 특히 행렬공간에 집중하여, 임의의 크기의 행렬공간에 대해 중요한 유형의 부분공간을 이루는 대칭·반대칭행렬, 상삼각·하삼각·대각행렬을 정리한다.</summary> <content type="html" xml:lang="ko"> <![CDATA[<p>벡터공간과 부분공간의 정의를 중심으로 행렬공간과 함수공간 등 대표적인 벡터공간의 예시들을 다룬다. 특히 행렬공간에 집중하여, 임의의 크기의 행렬공간에 대해 중요한 유형의 부분공간을 이루는 대칭·반대칭행렬, 상삼각·하삼각·대각행렬을 정리한다.</p><em><p>* Mathematical equations and diagrams included in posts may not display properly when viewed with a feed reader.</p></em><h2 id="tldr">TL;DR</h2><blockquote class="prompt-info"><ul><li><strong>행렬(matrix)</strong><ul><li>행렬 $A$의 $i$행 $j$열 성분을 $A_{ij}$ 또는 $a_{ij}$로 표기함<li><strong>대각성분(diagonal entry)</strong>: $i=j$인 성분 $a_{ij}$<li>성분 $a_{i1}, a_{i2}, \dots, a_{in}$을 이 행렬의 $i$번째 <strong>행(row)</strong>이라 함<ul><li>행렬의 각 행은 $F^n$의 벡터로 나타낼 수 있음<li>더 나아가, $F^n$의 행벡터를 $1 \times n$의 또다른 행렬로 나타낼 수 있음</ul><li>성분 $a_{1j}, a_{2j}, \dots, a_{mj}$를 이 행렬의 $j$번째 <strong>열(column)</strong>이라 함<ul><li>행렬의 각 열은 $F^m$의 벡터로 나타낼 수 있음<li>더 나아가, $F^m$의 열벡터를 $m \times 1$의 또다른 행렬로 나타낼 수 있음</ul><li><strong>영행렬(zero matrix)</strong>: 모든 성분이 $0$인 행렬, $O$로 표기함<li><strong>정사각행렬(square matrix)</strong>: 행의 개수와 열의 개수가 같은 행렬<li>두 $m \times n$ 행렬 $A, B$에서 모든 $1 \leq i \leq m$, $1 \leq j \leq n$에 대하여 $A_{ij} = B_{ij}$이면(즉, 대응하는 성분이 모두 일치하면) 두 행렬이 <strong>같다</strong>($A=B$)고 정의함<li><strong>전치행렬(transpose matrix)</strong>: $m \times n$ 행렬 $A$에 대해, $A$의 행과 열을 뒤바꾼 $n \times m$ 행렬 $A^T$을 전치행렬이라고 함<li><strong>대칭행렬(symmetric matrix)</strong>: $A^T = A$인 정사각행렬 $A$<li><strong>반대칭행렬(skew-symmetric matrix)</strong>: $B^T = -B$인 정사각행렬 $B$<li><strong>삼각행렬(triangular matrix)</strong><ul><li><strong>상삼각행렬(upper triangular matrix)</strong>: 대각성분 아래의 모든 성분이 $0$인 행렬(즉, $i&gt;j \Rightarrow A_{ij}=0$인 행렬), 보통 $U$로 표기<li><strong>하삼각행렬(lower triangular matrix)</strong>: 대각성분 위의 모든 성분이 $0$인 행렬(즉, $i&lt;j \Rightarrow A_{ij}=0$인 행렬), 보통 $L$로 표기</ul><li><strong>대각행렬(diagonal matrix)</strong>: 대각성분을 제외한 모든 성분이 $0$인 정사각행렬(즉, $i \neq j \Rightarrow M_{ij}=0$인 $n \times n$ 행렬), 보통 $D$로 표기</ul><li>대표적인 벡터공간들<ul><li><strong>n 순서쌍 $F^n$</strong>:<ul><li>체 $F$에서 성분을 가져온 모든 $n$ 순서쌍의 집합<li>$F^n$이라 표기하며, $F$-벡터공간임</ul><li><strong>행렬공간(matrix space)</strong>:<ul><li>성분이 체 $F$의 원소인 모든 $m \times n$ 행렬의 집합<li>$\mathcal{M}_{m \times n}(F)$라 표기하며, 벡터공간임</ul><li><strong>함수공간(function space)</strong>:<ul><li>체 $F$의 공집합이 아닌 집합 $S$에 대해, $S$에서 $F$로 가는 모든 함수의 집합<li>$\mathcal{F}(S,F)$라 표기하며, 벡터공간임</ul></ul><li><strong>부분공간(subspace)</strong><ul><li>$F$-벡터공간 $\mathbb{V}$의 부분집합 $\mathbb{W}$가 $\mathbb{V}$에서 정의한 합과 스칼라배를 동일하게 가지는 $F$-벡터공간일 때, $\mathbb{W}$는 $\mathbb{V}$의 <strong>부분공간(subspace)</strong>이라 정의함<li>모든 벡터공간 $\mathbb{V}$에 대해 $\mathbb{V}$ 자기 자신과 $\{0\}$은 부분공간이며, 특히 $\{0\}$은 <strong>점 부분공간(zero subspace)</strong>이라 함<li>벡터공간의 어떤 부분집합이 영벡터를 원소로 가지며 <a href="/ko/posts/vectors-and-linear-combinations/#벡터의-선형-결합">선형결합</a>에 대해 닫혀 있으면($\mathrm{span}(\mathbb{W})=\mathbb{W}$이면), 그 집합은 부분공간임</ul></ul></blockquote><h2 id="prerequisites">Prerequisites</h2><ul><li><a href="/ko/posts/vectors-and-linear-combinations/">벡터와 선형결합</a></ul><h2 id="벡터공간">벡터공간</h2><p><a href="/ko/posts/vectors-and-linear-combinations/#넓은-의미의-벡터-벡터-공간의-원소">벡터와 선형결합</a>에서도 잠깐 보았듯, 대수적 구조로서의 벡터와 벡터공간의 정의는 다음과 같다.</p><blockquote class="prompt-info"><p><strong>정의</strong><br /> 체 $F$에서의 <strong>벡터공간(vector space)</strong> 또는 <strong>선형공간(linear space)</strong> $\mathbb{V}$는 다음 8가지 조건을 만족하는 두 연산, <strong>합</strong>과 <strong>스칼라배</strong>를 가지는 집합이다. 체 $F$의 원소를 <strong>스칼라(scalar)</strong>, 벡터공간 $\mathbb{V}$의 원소를 <strong>벡터(vector)</strong>라 한다.</p><ul><li><strong>합(sum)</strong>: $\mathbb{V}$의 두 원소 $\mathbf{x}, \mathbf{y}$에 대하여 유일한 원소 $\mathbf{x} + \mathbf{y} \in \mathbb{V}$를 대응하는 연산이다. 이때 $\mathbf{x} + \mathbf{y}$를 $\mathbf{x}$와 $\mathbf{y}$의 <strong>합</strong>이라 한다.<li><strong>스칼라배(scalar multiplication)</strong>: 체 $F$의 원소 $a$와 벡터공간 $\mathbb{V}$의 원소 $\mathbf{x}$마다 유일한 원소 $a\mathbf{x} \in \mathbb{V}$를 대응하는 연산이다. 이때 $a\mathbf{x}$를 $\mathbf{x}$의 <strong>스칼라배(scalar multiple)</strong>라 한다.</ul><ol><li>모든 $\mathbf{x},\mathbf{y} \in \mathbb{V}$에 대하여 $\mathbf{x} + \mathbf{y} = \mathbf{y} + \mathbf{x}$이다. (덧셈에 대한 교환법칙)<li>모든 $\mathbf{x},\mathbf{y},\mathbf{z} \in \mathbb{V}$에 대하여 $(\mathbf{x}+\mathbf{y})+\mathbf{z} = \mathbf{x}+(\mathbf{y}+\mathbf{z})$이다. (덧셈에 대한 결합법칙)<li>모든 $\mathbf{x} \in \mathbb{V}$에 대하여 $\mathbf{x} + \mathbf{0} = \mathbf{x}$인 $\mathbf{0} \in \mathbb{V}$가 존재한다. (영벡터, 덧셈에 대한 항등원)<li>각 $\mathbf{x} \in \mathbb{V}$마다 $\mathbf{x}+\mathbf{y}=\mathbf{0}$인 $\mathbf{y} \in \mathbb{V}$가 존재한다. (덧셈에 대한 역원)<li>각 $\mathbf{x} \in \mathbb{V}$에 대하여 $1\mathbf{x} = \mathbf{x}$이다. (곱셈에 대한 항등원)<li>모든 $a,b \in F$와 모든 $\mathbf{x} \in \mathbb{V}$에 대하여 $(ab)\mathbf{x} = a(b\mathbf{x})$이다. (스칼라배에 대한 결합법칙)<li>모든 $a \in F$와 모든 $\mathbf{x},\mathbf{y} \in \mathbb{V}$에 대하여 $a(\mathbf{x}+\mathbf{y}) = a\mathbf{x} + a\mathbf{y}$이다. (덧셈에 대한 스칼라배의 분배법칙 1)<li>모든 $a,b \in F$와 모든 $\mathbf{x},\mathbf{y} \in \mathbb{V}$에 대하여 $(a+b)\mathbf{x} = a\mathbf{x} + b\mathbf{x}$이다. (덧셈에 대한 스칼라배의 분배법칙 2)</ol></blockquote><p>벡터공간은 정확하게는 ‘$F$-벡터공간 $\mathbb{V}$’라 표기해야 하나, 벡터공간을 다룰 때 체는 크게 중요한 요소는 아니므로 혼란의 여지가 없으면 체 $F$는 생략하고 ‘벡터공간 $\mathbb{V}$’라 적는다.</p><h3 id="행렬공간">행렬공간</h3><h4 id="행벡터와-열벡터">행벡터와 열벡터</h4><p>체 $F$에서 성분을 가져온 모든 $n$ 순서쌍의 집합을 $F^n$이라 표기한다. $u = (a_1, a_2, \dots, a_n) \in F^n$, $v = (b_1, b_2, \dots, b_n) \in F^n$일 때, 합과 스칼라곱을 다음과 같이 정의하면 $F^n$은 $F$-벡터공간이다.</p>\[\begin{align*} u + v &amp;= (a_1+b_1, a_2+b_2, \dots, a_n+b_n), \\ cu &amp;= (ca_1, ca_2, \dots, ca_n) \end{align*}\]<p>$F^n$의 벡터는 단독으로 쓸 때는 보통 <strong>행벡터(row vector)</strong> $(a_1, a_2, \dots, a_n)$보다는 <strong>열벡터(column vector)</strong></p>\[\begin{pmatrix} a_1 \\ a_2 \\ \vdots \\ a_n \end{pmatrix}\]<p>로 표현한다.</p><blockquote class="prompt-tip"><p>다만 이렇게 열벡터로 표기할 때 공간을 많이 차지하다 보니, <a href="#전치행렬-대칭행렬-반대칭행렬">전치</a>를 써서 $(a_1, a_2, \dots, a_n)^T$로 나타내기도 한다.</p></blockquote><h4 id="행렬과-행렬공간">행렬과 행렬공간</h4><p>한편, $F$에서 성분을 가져온 $m \times n$ <strong>행렬(matrix)</strong>은 다음과 같은 직사각형 모양의 배열로, 이탤릭 대문자($A, B, C$ 등)로 나타낸다.</p>\[\begin{pmatrix} a_{11} &amp; a_{12} &amp; \cdots &amp; a_{1n} \\ a_{21} &amp; a_{22} &amp; \cdots &amp; a_{2n} \\ \vdots &amp; \vdots &amp; &amp; \vdots \\ a_{m1} &amp; a_{m2} &amp; \cdots &amp; a_{mn} \end{pmatrix}\]<ul><li>행렬 $A$의 $i$행 $j$열 성분을 $A_{ij}$ 또는 $a_{ij}$로 표기한다.<li>모든 $a_{ij}$ ($1 \leq i \leq m$, $1 \leq j \leq n$)는 $F$의 원소이다.<li>$i=j$인 성분 $a_{ij}$를 이 행렬의 <strong>대각성분(diagonal entry)</strong>이라 한다.<li>성분 $a_{i1}, a_{i2}, \dots, a_{in}$을 이 행렬의 $i$번째 <strong>행(row)</strong>이라 한다. 행렬의 각 행은 $F^n$의 벡터로 나타낼 수 있으며, 더 나아가 $F^n$의 행벡터를 $1 \times n$의 또다른 행렬로 나타낼 수 있다.<li>성분 $a_{1j}, a_{2j}, \dots, a_{mj}$를 이 행렬의 $j$번째 <strong>열(column)</strong>이라 한다. 행렬의 각 열은 $F^m$의 벡터로 나타낼 수 있으며, 더 나아가 $F^m$의 열벡터를 $m \times 1$의 또다른 행렬로 나타낼 수 있다.<li>모든 성분이 $0$인 $m \times n$ 행렬을 <strong>영행렬(zero matrix)</strong>이라 하며 $O$로 표기한다.<li>행의 개수와 열의 개수가 같은 행렬을 <strong>정사각행렬(square matrix)</strong>이라 한다.<li>두 $m \times n$ 행렬 $A, B$에서 모든 $1 \leq i \leq m$, $1 \leq j \leq n$에 대하여 $A_{ij} = B_{ij}$이면(즉, 대응하는 성분이 모두 일치하면) 두 행렬이 <strong>같다</strong>($A=B$)고 정의한다.</ul><p>성분이 체 $F$의 원소인 모든 $m \times n$ 행렬의 집합을 $\mathcal{M}_{m \times n}(F)$라 표기한다. $\mathbf{A},\mathbf{B} \in \mathcal{M}_{m \times n}(F),\ c \in F$일 때, 합과 스칼라배를 다음과 같이 정의하면 $\mathcal{M}_{m \times n}(F)$는 벡터공간이며, 이를 <strong>행렬공간(matrix space)</strong>이라고 한다.</p>\[\begin{align*} (\mathbf{A}+\mathbf{B})_{ij} &amp;= \mathbf{A}_{ij} + \mathbf{B}_{ij}, \\ (c\mathbf{A})_{ij} &amp;= c\mathbf{A}_{ij} \\ \text{(단, }1 \leq i \leq &amp;m, 1 \leq j \leq n \text{)} \end{align*}\]<p>이는 $F^n$과 $F^m$에서 정의한 연산을 자연스럽게 확장한 것이다.</p><h3 id="함수공간">함수공간</h3><p>체 $F$의 공집합이 아닌 집합 $S$에 대해, $\mathcal{F}(S,F)$는 $S$에서 $F$로 가는 모든 함수의 집합이다. $\mathcal{F}(S,F)$에서 모든 $s \in S$에 대하여 $f(s) = g(s)$일 때 두 함수 $f, g$는 <strong>같다</strong>($f=g$)고 한다.</p><p>$f,g \in \mathcal{F}(S,F),\ c \in F,\ s \in S$일 때, 합과 스칼라배를 다음과 같이 정의하면 $\mathcal{F}(S,F)$는 벡터공간이며, 이를 <strong>함수공간(function space)</strong>이라고 한다.</p>\[\begin{align*} (f + g)(s) &amp;= f(s) + g(s), \\ (cf)(s) &amp;= c[f(s)] \end{align*}\]<h2 id="부분공간">부분공간</h2><blockquote class="prompt-info"><p><strong>정의</strong><br /> $F$-벡터공간 $\mathbb{V}$의 부분집합 $\mathbb{W}$가 $\mathbb{V}$에서 정의한 합과 스칼라배를 동일하게 가지는 $F$-벡터공간일 때, $\mathbb{W}$는 $\mathbb{V}$의 <strong>부분공간(subspace)</strong>이라 한다.</p></blockquote><p>모든 벡터공간 $\mathbb{V}$에 대해 $\mathbb{V}$ 자기 자신과 $\{0\}$은 부분공간이며, 특히 $\{0\}$은 <strong>점 부분공간(zero subspace)</strong>이라 한다.</p><p>어떤 부분집합이 부분공간인지는 다음 정리를 이용해 확인할 수 있다.</p><blockquote class="prompt-info"><p><strong>정리 1</strong><br /> 벡터공간 $\mathbb{V}$와 부분집합 $\mathbb{W}$에 대해, $\mathbb{W}$가 $\mathbb{V}$의 부분공간이기 위한 필요충분조건은 다음 3가지 조건을 만족하는 것이다. 이때 연산은 $\mathbb{V}$에서 정의한 것과 같다.</p><ol><li>$\mathbf{0} \in \mathbb{W}$<li>$\mathbf{x}+\mathbf{y} \in \mathbb{W} \quad \forall\ \mathbf{x} \in \mathbb{W},\ \mathbf{y} \in \mathbb{W}$<li>$c\mathbf{x} \in \mathbb{W} \quad \forall\ c \in F,\ \mathbf{x} \in \mathbb{W}$</ol><p>간단히 말해, 영벡터를 원소로 가지며 <a href="/ko/posts/vectors-and-linear-combinations/#벡터의-선형-결합">선형결합</a>에 대해 닫혀 있으면($\mathrm{span}(\mathbb{W})=\mathbb{W}$이면) 부분공간이다.</p></blockquote><p>또한 다음의 정리들이 성립한다.</p><blockquote class="prompt-info"><p><strong>정리 2</strong></p><ul><li><p>벡터공간 $\mathbb{V}$의 임의의 부분집합 $S$의 생성공간 $\mathrm{span}(S)$는 $S$를 포함하는 $\mathbb{V}$의 부분공간이다.</p>\[S \subset \mathrm{span}(S) \leq \mathbb{V} \quad \forall\ S \subset \mathbb{V}.\]<li><p>$S$를 포함하는 $\mathbb{V}$의 부분공간은 반드시 $S$의 생성공간을 포함한다.</p>\[\mathbb{W}\supset \mathrm{span}(S) \quad \forall\ S \subset \mathbb{W} \leq \mathbb{V}.\]</ul></blockquote><blockquote class="prompt-info"><p><strong>정리 3</strong><br /> 벡터공간 $\mathbb{V}$의 부분공간들에 대해, 이 부분공간들의 임의의 교집합은 마찬가지로 $\mathbb{V}$의 부분공간이다.</p></blockquote><h3 id="전치행렬-대칭행렬-반대칭행렬">전치행렬, 대칭행렬, 반대칭행렬</h3><p>$m \times n$ 행렬 $A$의 <strong>전치행렬(transpose matrix)</strong> $A^T$는 $A$의 행과 열을 뒤바꾼 $n \times m$ 행렬이다.</p>\[(A^T)_{ij} = A_{ji}\] \[\begin{pmatrix} 1 &amp; 2 &amp; 3 \\ 4 &amp; 5 &amp; 6 \end{pmatrix}^T = \begin{pmatrix} 1 &amp; 4 \\ 2 &amp; 5 \\ 3 &amp; 6 \end{pmatrix}\]<p>$A^T = A$인 행렬 $A$를 <strong>대칭행렬(symmetric matrix)</strong>, $B^T = -B$인 행렬 $B$를 <strong>반대칭행렬(skew-symmetric matrix)</strong>이라 한다. 대칭행렬과 반대칭행렬은 반드시 정사각행렬이어야 한다.</p><p>각각 $\mathcal{M}_{n \times n}(F)$의 모든 대칭행렬, 반대칭행렬을 원소로 하는 두 집합 $\mathbb{W}_1, \mathbb{W}_2$는 $\mathcal{M}_{n \times n}(F)$의 부분공간이다. 즉, $\mathbb{W}_1, \mathbb{W}_2$는 합과 스칼라곱에 대해 닫혀 있다.</p><h3 id="삼각행렬-대각행렬">삼각행렬, 대각행렬</h3><p>이 두 종류의 행렬도 특히 중요하다.</p><p>우선, 다음 두 종류의 행렬을 묶어 <strong>삼각행렬(triangular matrix)</strong>이라 한다.</p><ul><li><strong>상삼각행렬(upper triangular matrix)</strong>: 대각성분 아래의 모든 성분이 $0$인 행렬(즉, $i&gt;j \Rightarrow A_{ij}=0$인 행렬), 보통 $U$로 표기<li><strong>하삼각행렬(lower triangular matrix)</strong>: 대각성분 위의 모든 성분이 $0$인 행렬(즉, $i&lt;j \Rightarrow A_{ij}=0$인 행렬), 보통 $L$로 표기</ul><p>대각성분을 제외한 모든 성분이 $0$인 정사각행렬, 즉 $i \neq j \Rightarrow M_{ij}=0$인 $n \times n$ 행렬을 <strong>대각행렬(diagonal matrix)</strong>이라 하며 보통 $D$로 표기한다. 대각행렬은 상삼각행렬인 동시에 하삼각행렬이다.</p><p>상삼각행렬의 집합, 하삼각행렬의 집합, 대각행렬의 집합은 모두 $\mathcal{M}_{m \times n}(F)$의 부분공간이다.</p>]]> </content> </entry> <entry><title xml:lang="ko">내적과 노름</title><link href="https://www.yunseo.kim/ko/posts/inner-product-and-norm/" rel="alternate" type="text/html" hreflang="en" /><link href="https://www.yunseo.kim/ko/posts/inner-product-and-norm/" rel="alternate" type="text/html" hreflang="ko" /><link href="https://www.yunseo.kim/ja/posts/inner-product-and-norm/" rel="alternate" type="text/html" hreflang="ja" /><link href="https://www.yunseo.kim/zh-TW/posts/inner-product-and-norm/" rel="alternate" type="text/html" hreflang="zh-TW" /><link href="https://www.yunseo.kim/es/posts/inner-product-and-norm/" rel="alternate" type="text/html" hreflang="es" /><link href="https://www.yunseo.kim/pt-BR/posts/inner-product-and-norm/" rel="alternate" type="text/html" hreflang="pt-BR" /><link href="https://www.yunseo.kim/fr/posts/inner-product-and-norm/" rel="alternate" type="text/html" hreflang="fr" /><link href="https://www.yunseo.kim/de/posts/inner-product-and-norm/" rel="alternate" type="text/html" hreflang="de" /><link href="https://www.yunseo.kim/pl/posts/inner-product-and-norm/" rel="alternate" type="text/html" hreflang="pl" /><link href="https://www.yunseo.kim/cs/posts/inner-product-and-norm/" rel="alternate" type="text/html" hreflang="cs" /><link href="https://www.yunseo.kim/sw/posts/inner-product-and-norm/" rel="alternate" type="text/html" hreflang="sw" /><link href="https://www.yunseo.kim/am/posts/inner-product-and-norm/" rel="alternate" type="text/html" hreflang="am" /><published>2025-09-10T00:00:00+09:00</published> <updated>2025-10-15T05:48:53+09:00</updated> <id>https://www.yunseo.kim/ko/posts/inner-product-and-norm/</id> <author> <name>Yunseo Kim</name> </author> <category term="Mathematics" /> <category term="Linear Algebra" /> <summary xml:lang="ko">벡터의 내적(inner product) 및 점곱(dot product)의 정의를 알아보고, 이로부터 벡터의 길이/노름, 그리고 벡터들 사이의 각을 어떻게 정의하는지 살펴본다.</summary> <content type="html" xml:lang="ko"> <![CDATA[<p>벡터의 내적(inner product) 및 점곱(dot product)의 정의를 알아보고, 이로부터 벡터의 길이/노름, 그리고 벡터들 사이의 각을 어떻게 정의하는지 살펴본다.</p><em><p>* Mathematical equations and diagrams included in posts may not display properly when viewed with a feed reader.</p></em><h2 id="prerequisites">Prerequisites</h2><ul><li><a href="/ko/posts/vectors-and-linear-combinations/">벡터와 선형결합</a></ul><h2 id="내적">내적</h2><p>일반적인 $F$-벡터공간에서의 <strong>내적(inner product)</strong>의 정의는 다음과 같다.</p><blockquote class="prompt-info"><p><strong>내적(inner product)과 내적공간(inner product space)의 정의</strong><br /> $F$-벡터공간 $\mathbb{V}$를 생각하자. $\mathbb{V}$에서의 <strong>내적(inner product)</strong> $\langle \mathbf{x},\mathbf{y} \rangle$는 $\mathbb{V}$의 임의의 벡터 $\mathbf{x}$와 $\mathbf{y}$의 순서쌍을 $F$에 속한 스칼라에 대응시키는, 다음 조건을 만족하는 함수로 정의한다.</p><p>임의의 $\mathbf{x},\mathbf{y},\mathbf{z} \in \mathbb{V}$와 임의의 $c \in F$에 대하여</p><ol><li>$\langle \mathbf{x}+\mathbf{z}, \mathbf{y} \rangle = \langle \mathbf{x}, \mathbf{y} \rangle + \langle \mathbf{z}, \mathbf{y} \rangle$<li>$\langle c\mathbf{x}, \mathbf{y} \rangle = c \langle \mathbf{x}, \mathbf{y} \rangle$<li>$\overline{\langle \mathbf{x}, \mathbf{y} \rangle} = \langle \mathbf{y}, \mathbf{x} \rangle$ ($\overline{\mathbf{z}}$는 $\mathbf{z}$의 복소 켤레)<li>$\mathbf{x} \neq \mathbf{0}$일 때, $\langle \mathbf{x}, \mathbf{x} \rangle$는 양수이다.</ol><p>내적이 주어진 $F$-벡터공간 $\mathbb{V}$를 <strong>내적공간(inner product space)</strong>이라 한다. 특히 $F=\mathbb{C}$인 경우 <strong>복소내적공간(complex inner product space)</strong>, $F=\mathbb{R}$인 경우 <strong>실내적공간(real inner product space)</strong>이라 한다.</p></blockquote><p>특히 다음의 내적을 <strong>표준 내적(standard inner product)</strong>이라고 한다. 표준 내적이 앞선 내적의 조건 4가지를 모두 만족함을 확인할 수 있다.</p><blockquote class="prompt-info"><p><strong>표준 내적(standard inner product)의 정의</strong><br /> $F^n$의 두 벡터 $\mathbf{x}=(a_1, a_2, \dots, a_n)$, $\mathbf{y}=(b_1, b_2, \dots, b_n)$에 대하여, $F^n$의 <strong>표준 내적(standard inner product)</strong>을 다음과 같이 정의한다.</p>\[\langle \mathbf{x}, \mathbf{y} \rangle = \sum_{i=1}^n a_i \overline{b_i}\]</blockquote><p>여기서 $F=\mathbb{R}$이면, 실수의 켤레복소수는 자기 자신이기 때문에 이때의 표준 내적은 $\sum_{i=1}^n a_i b_i$가 된다. 특별히 이 경우의 표준 내적을 $\langle \mathbf{x}, \mathbf{y} \rangle$ 대신 $\mathbf{x} \cdot \mathbf{y}$로 표기하고, <strong>점곱(dot product)</strong> 또는 <strong>스칼라곱(scalar product)</strong>이라고 한다.</p><blockquote class="prompt-info"><p><strong>점곱(dot product)/스칼라곱(scalar product)의 정의</strong><br /> $\mathbb{R}^n$의 $\mathbf{v}=(v_1, v_2, \dots, v_n)$, $\mathbf{w}=(w_1, w_2, \dots, w_n)$에 대하여, $\mathbb{R}^n$의 <strong>점곱(dot product)</strong> 또는 <strong>스칼라곱(scalar product)</strong>을 다음과 같이 정의한다.</p>\[\mathbf{v} \cdot \mathbf{w} = \sum_{i=1}^n v_i w_i = v_1 w_1 + v_2 w_2 + \cdots + v_n w_n\]</blockquote><blockquote class="prompt-warning"><p>여기서 말하는 ‘스칼라곱(<strong>scalar product</strong>)’은 벡터와 벡터 간의 연산으로, <a href="/ko/posts/vectors-and-linear-combinations/">벡터와 선형결합</a>에서 다뤘던 스칼라와 벡터 간 연산인 ‘스칼라배(<strong>scalar multiplication</strong>)’과는 별개의 연산이다. 영문 표현도 비슷한 편인 데다, <a href="https://www.kms.or.kr/mathdict/list.html?key=kname&amp;keyword=%EC%8A%A4%EC%B9%BC%EB%9D%BC%EA%B3%B1">대한수학회 기준 한국어 번역 표현은 아예 동일하기 때문에</a> 혼동하지 않도록 주의하자.</p><p>혼동을 방지하기 위해, 앞으로는 가급적 <strong>점곱(dot product)</strong>으로 지칭하겠다.</p></blockquote><blockquote class="prompt-tip"><p>유클리드 공간에서의 내적(inner product)이 곧 점곱(dot product)이므로, 맥락상 혼동의 여지가 없다면 점곱을 그냥 내적이라고 표현하는 경우도 흔하다. 다만 엄밀히는 내적이 점곱을 포함하는 더 일반적인 개념이다.</p></blockquote><pre><code class="language-mermaid">flowchart TD
    A["내적(Inner Product)"] --&gt;|포함함| B["표준 내적(Standard Inner Product)"]
    B --&gt;|"F = R(실수체)인 경우"| C["점곱/스칼라곱(Dot/Scalar Product)"]

    %% 포함(포함 관계) 표기
    C -. 포함됨 .-&gt; B
    B -. 포함됨 .-&gt; A
</code></pre><h2 id="벡터의-길이노름">벡터의 길이/노름</h2><p>$\mathbb{R}^n$에서의 벡터 $\mathbf{v}=(v_1, v_2, \dots, v_n)$에 대하여 $\mathbf{v}$의 유클리드 길이는 다음과 같이 점곱을 통해 정의한다.</p>\[\| \mathbf{v} \| = \sqrt{\mathbf{v} \cdot \mathbf{v}} = \left[ \sum_{i=1}^n |v_i|^2 \right]^{1/2} = \sqrt{v_1^2 + v_2^2 + \cdots + v_n^2}\]<p>보다 일반적으로는, 임의의 내적공간에서의 벡터의 <strong>길이(length)</strong> 또는 <strong>노름(norm)</strong>을 다음과 같이 정의한다.</p>\[\| \mathbf{x} \| = \sqrt{\langle \mathbf{x}, \mathbf{x} \rangle}\]<p>일반적인 내적공간에서, 벡터의 노름에 대해 다음의 중요한 성질들이 성립한다.</p><blockquote class="prompt-info"><p><strong>정리</strong><br /> $F$-내적공간 $\mathbb{V}$와 임의의 벡터 $\mathbf{x}, \mathbf{y} \in \mathbb{V}$, 스칼라 $c \in F$에 대하여 다음이 성립한다.</p><ol><li>$\|c\mathbf{x}\| = |c| \cdot \|\mathbf{x}\|$<li>다음의 둘이 성립한다.<ul><li>$\|\mathbf{x}\| = 0 \iff \mathbf{x}=\mathbf{0}$<li>$\|\mathbf{x}\| \geq 0 \ \forall \mathbf{x}$</ul><li><strong>코시-슈바르츠 부등식(Cauchy-Schwarz inequality)</strong>: $| \langle \mathbf{x}, \mathbf{y} \rangle | \leq \|\mathbf{x}\| \cdot \|\mathbf{y}\|$ (등호는 $\mathbf{x}$와 $\mathbf{y}$ 둘 중 하나가 다른 하나의 상수배일 때 성립)<li><strong>삼각 부등식(triangle inequality)</strong>: $\| \mathbf{x} + \mathbf{y} \| \leq \|\mathbf{x}\| + \|\mathbf{y}\|$ (등호는 $\mathbf{x}$와 $\mathbf{y}$ 둘 중 하나가 다른 하나의 상수배이고, 둘의 방향이 같을 때 성립)</ol></blockquote><h2 id="벡터들-사이의-각과-단위벡터">벡터들 사이의 각과 단위벡터</h2><p>길이가 $1$인 벡터를 <strong>단위벡터(unit vector)</strong>라고 한다. 또한 $\mathbb{R}^n$에서의 두 벡터 $\mathbf{v}=(v_1, v_2, \dots, v_n)$, $\mathbf{w}=(w_1, w_2, \dots, w_n)$에 대하여 $\mathbf{v} \cdot \mathbf{w} = \|\mathbf{v}\| \cdot \|\mathbf{w}\| \cos\theta$가 성립하며, 이로부터 $\mathbf{v}$와 $\mathbf{w}$ 사이의 각 $\theta$ ($0 \leq \theta \leq \pi$)를 구할 수 있다.</p>\[\theta = \arccos{\frac{\mathbf{v} \cdot \mathbf{w}}{\|\mathbf{v}\| \cdot \|\mathbf{w}\|}}\]<p>$\mathbf{v} \cdot \mathbf{w} = 0$인 경우, 두 벡터는 <strong>수직(perpendicular)</strong> 또는 <strong>직교(orthogonal)</strong>한다고 한다.</p><blockquote class="prompt-tip"><p>두 벡터 $\mathbf{v}$와 $\mathbf{w}$가 수직인 경우,</p>\[\begin{align*} \| \mathbf{v} + \mathbf{w} \|^2 &amp;= (\mathbf{v} + \mathbf{w}) \cdot (\mathbf{v} + \mathbf{w}) \\ &amp;= \mathbf{v} \cdot \mathbf{v} + \mathbf{v} \cdot \mathbf{w} + \mathbf{w} \cdot \mathbf{v} + \mathbf{w} \cdot \mathbf{w} \\ &amp;= \mathbf{v} \cdot \mathbf{v} + \mathbf{w} \cdot \mathbf{w} \\ &amp;= \|\mathbf{v}\|^2 + \|\mathbf{w}\|^2. \end{align*}\]</blockquote><p>이를 임의의 내적공간으로 일반화하면 다음과 같다.</p><blockquote class="prompt-info"><p><strong>정의</strong><br /> 내적공간 $\mathbb{V}$를 생각하자. $\mathbb{V}$의 벡터 $\mathbf{x}, \mathbf{y}$에 대하여 $\langle \mathbf{x}, \mathbf{y} \rangle = 0$이면 두 벡터는 <strong>직교(orthogonal)</strong> 또는 <strong>수직(perpendicular)</strong>이라고 정의한다. 또한,</p><ol><li>$\mathbb{V}$의 부분집합 $S$에 대하여 $S$에 속하는 서로 다른 임의의 두 벡터가 직교할 때, 집합 $S$를 <strong>직교집합(orthogonal set)</strong>이라 한다.<li>$\|\mathbf{x}\|=1$인 벡터 $\mathbf{x} \in \mathbb{V}$를 <strong>단위벡터(unit vector)</strong>라 한다.<li>$\mathbb{V}$의 부분집합 $S$가 직교집합이고 단위벡터로만 이루어져 있을 때, 집합 $S$를 <strong>정규직교집합(orthonormal set)</strong>이라 한다.</ol></blockquote><p>집합 $S = { \mathbf{v}_1, \mathbf{v}_2, \dots }$가 정규직교집합이기 위한 필요충분조건은 $\langle \mathbf{v}_i, \mathbf{v}_j \rangle = \delta_{ij}$이다. 벡터에 영이 아닌 스칼라를 곱해도 직교성에 영향을 주지 않는다.</p><p>영이 아닌 임의의 벡터 $\mathbf{x}$에 대하여 $\cfrac{\mathbf{x}}{\|\mathbf{x}\|}$는 단위벡터이며, 이렇게 영이 아닌 벡터에 길이의 역수만큼의 스칼라를 곱하여 단위벡터를 얻는 과정을 <strong>정규화(normalizing)</strong>라 한다.</p>]]> </content> </entry> <entry><title xml:lang="ko">벡터와 선형결합</title><link href="https://www.yunseo.kim/ko/posts/vectors-and-linear-combinations/" rel="alternate" type="text/html" hreflang="en" /><link href="https://www.yunseo.kim/ko/posts/vectors-and-linear-combinations/" rel="alternate" type="text/html" hreflang="ko" /><link href="https://www.yunseo.kim/ja/posts/vectors-and-linear-combinations/" rel="alternate" type="text/html" hreflang="ja" /><link href="https://www.yunseo.kim/zh-TW/posts/vectors-and-linear-combinations/" rel="alternate" type="text/html" hreflang="zh-TW" /><link href="https://www.yunseo.kim/es/posts/vectors-and-linear-combinations/" rel="alternate" type="text/html" hreflang="es" /><link href="https://www.yunseo.kim/pt-BR/posts/vectors-and-linear-combinations/" rel="alternate" type="text/html" hreflang="pt-BR" /><link href="https://www.yunseo.kim/fr/posts/vectors-and-linear-combinations/" rel="alternate" type="text/html" hreflang="fr" /><link href="https://www.yunseo.kim/de/posts/vectors-and-linear-combinations/" rel="alternate" type="text/html" hreflang="de" /><link href="https://www.yunseo.kim/pl/posts/vectors-and-linear-combinations/" rel="alternate" type="text/html" hreflang="pl" /><link href="https://www.yunseo.kim/cs/posts/vectors-and-linear-combinations/" rel="alternate" type="text/html" hreflang="cs" /><link href="https://www.yunseo.kim/sw/posts/vectors-and-linear-combinations/" rel="alternate" type="text/html" hreflang="sw" /><link href="https://www.yunseo.kim/am/posts/vectors-and-linear-combinations/" rel="alternate" type="text/html" hreflang="am" /><published>2025-09-07T00:00:00+09:00</published> <updated>2025-10-28T20:47:49+09:00</updated> <id>https://www.yunseo.kim/ko/posts/vectors-and-linear-combinations/</id> <author> <name>Yunseo Kim</name> </author> <category term="Mathematics" /> <category term="Linear Algebra" /> <summary xml:lang="ko">벡터란 무엇인지와 기본 연산(상수배, 덧셈)을 알아보고, 이를 바탕으로 벡터의 선형 결합과 생성공간의 개념을 이해한다.</summary> <content type="html" xml:lang="ko"> <![CDATA[<p>벡터란 무엇인지와 기본 연산(상수배, 덧셈)을 알아보고, 이를 바탕으로 벡터의 선형 결합과 생성공간의 개념을 이해한다.</p><em><p>* Mathematical equations and diagrams included in posts may not display properly when viewed with a feed reader.</p></em><h2 id="tldr">TL;DR</h2><blockquote class="prompt-info"><ul><li><strong>벡터의 정의</strong><ul><li><strong>좁은 의미의 벡터(유클리드 벡터)</strong>: 크기와 방향을 함께 갖는 물리량<li><strong>넓은 의미의, 선형대수학에서의 벡터</strong>: 벡터공간의 원소</ul><li><strong>벡터의 표현법</strong><ul><li><strong>화살표 표현법</strong>: 벡터의 크기는 화살표의 길이로, 벡터의 방향은 화살표의 방향으로 나타냄. 시각화하기 용이하고 직관적이라는 장점이 있으나, 4차원 이상의 고차원 벡터나 비유클리드 벡터는 표현하기 곤란함.<li><strong>성분 표현법</strong>: 벡터의 시점을 좌표공간의 원점으로 놓고, 종점의 좌표로 벡터를 표현하는 방법.</ul><li><strong>벡터의 기본 연산</strong><ul><li><strong>합</strong>: $(a_1, a_2, \cdots, a_n) + (b_1, b_2, \cdots, b_n) := (a_1+b_1, a_2+b_2, \cdots, a_n+b_n)$<li><strong>스칼라 곱</strong>: $c(a_1, a_2, \cdots, a_n) := (ca_1, ca_2, \cdots, ca_n)$</ul><li><strong>벡터의 선형 결합</strong><ul><li>유한 개의 벡터 $\mathbf{u}_1, \mathbf{u}_2, \dots, \mathbf{u}_n$과 스칼라 $a_1, a_2, \dots, a_n$에 대하여, $\mathbf{v} = a_1\mathbf{u}_1 + a_2\mathbf{u}_2 + \cdots + a_n\mathbf{u}_n$인 벡터 $\mathbf{v}$를 $\mathbf{u}_1, \mathbf{u}_2, \dots, \mathbf{u}_n$의 <strong>선형 결합(linear combination)</strong>이라고 함<li>이때 $a_1, a_2, \dots, a_n$을 이 선형 결합의 <strong>계수(coefficient)</strong>라고 함</ul><li><strong>생성공간</strong><ul><li>벡터공간 $\mathbb{V}$의 공집합이 아닌 부분집합 $S$에 대하여, $S$의 벡터를 사용하여 만든 모든 선형결합의 집합 $\mathrm{span}(S)$<li>$\mathrm{span}(\emptyset) = \{0\}$으로 정의<li>벡터공간 $\mathbb{V}$의 부분집합 $S$에 대하여 $\mathrm{span}(S) = \mathbb{V}$이면 $S$가 $\mathbb{V}$를 생성한다(generate 또는 span)고 함</ul></ul></blockquote><h2 id="prerequisites">Prerequisites</h2><ul><li>좌표평면/좌표공간<li>체(field)</ul><h2 id="벡터란-무엇인가">벡터란 무엇인가?</h2><h3 id="좁은-의미의-벡터-유클리드-벡터">좁은 의미의 벡터: 유클리드 벡터</h3><blockquote class="prompt-info"><p>힘, 속도, 가속도 등 많은 물리량은 크기뿐만 아니라 방향 정보를 함께 가진다. 이처럼 크기와 방향을 모두 가진 물리량을 <strong>벡터(vector)</strong>라고 한다.</p></blockquote><p>위의 정의가 물리학의 역학이나 고등학교 수준 수학에서 다루던 벡터의 정의이다. 이와 같이 ‘유향선분의 크기와 방향’이라는 기하학적인 의미를 지닌, 물리적 직관에 기반한 좁은 의미의 벡터를 엄밀히는 <strong>유클리드 벡터(Euclidean vector)</strong>라고 한다.</p><h3 id="넓은-의미의-벡터-벡터-공간의-원소">넓은 의미의 벡터: 벡터 공간의 원소</h3><p>선형대수학에서는 위의 유클리드 벡터의 정의보다 넓은 의미를 지닌, 보다 추상적인 대수적 구조로서 벡터를 다음과 같이 정의한다.</p><blockquote class="prompt-info"><p><strong>정의</strong><br /> 체 $F$에서의 <strong>벡터공간(vector space)</strong> 또는 <strong>선형공간(linear space)</strong> $\mathbb{V}$는 다음 8가지 조건을 만족하는 두 연산, <strong>합</strong>과 <strong>스칼라배</strong>를 가지는 집합이다. 체 $F$의 원소를 <strong>스칼라(scalar)</strong>, 벡터공간 $\mathbb{V}$의 원소를 <strong>벡터(vector)</strong>라 한다.</p><ul><li><strong>합(sum)</strong>: $\mathbb{V}$의 두 원소 $\mathbf{x}, \mathbf{y}$에 대하여 유일한 원소 $\mathbf{x} + \mathbf{y} \in \mathbb{V}$를 대응하는 연산이다. 이때 $\mathbf{x} + \mathbf{y}$를 $\mathbf{x}$와 $\mathbf{y}$의 <strong>합</strong>이라 한다.<li><strong>스칼라배(scalar multiplication)</strong>: 체 $F$의 원소 $a$와 벡터공간 $\mathbb{V}$의 원소 $\mathbf{x}$마다 유일한 원소 $a\mathbf{x} \in \mathbb{V}$를 대응하는 연산이다. 이때 $a\mathbf{x}$를 $\mathbf{x}$의 <strong>스칼라배(scalar multiple)</strong>라 한다.</ul><ol><li>모든 $\mathbf{x},\mathbf{y} \in \mathbb{V}$에 대하여 $\mathbf{x} + \mathbf{y} = \mathbf{y} + \mathbf{x}$이다. (덧셈에 대한 교환법칙)<li>모든 $\mathbf{x},\mathbf{y},\mathbf{z} \in \mathbb{V}$에 대하여 $(\mathbf{x}+\mathbf{y})+\mathbf{z} = \mathbf{x}+(\mathbf{y}+\mathbf{z})$이다. (덧셈에 대한 결합법칙)<li>모든 $\mathbf{x} \in \mathbb{V}$에 대하여 $\mathbf{x} + \mathbf{0} = \mathbf{x}$인 $\mathbf{0} \in \mathbb{V}$가 존재한다. (영벡터, 덧셈에 대한 항등원)<li>각 $\mathbf{x} \in \mathbb{V}$마다 $\mathbf{x}+\mathbf{y}=\mathbf{0}$인 $\mathbf{y} \in \mathbb{V}$가 존재한다. (덧셈에 대한 역원)<li>각 $\mathbf{x} \in \mathbb{V}$에 대하여 $1\mathbf{x} = \mathbf{x}$이다. (곱셈에 대한 항등원)<li>모든 $a,b \in F$와 모든 $\mathbf{x} \in \mathbb{V}$에 대하여 $(ab)\mathbf{x} = a(b\mathbf{x})$이다. (스칼라배에 대한 결합법칙)<li>모든 $a \in F$와 모든 $\mathbf{x},\mathbf{y} \in \mathbb{V}$에 대하여 $a(\mathbf{x}+\mathbf{y}) = a\mathbf{x} + a\mathbf{y}$이다. (덧셈에 대한 스칼라배의 분배법칙 1)<li>모든 $a,b \in F$와 모든 $\mathbf{x},\mathbf{y} \in \mathbb{V}$에 대하여 $(a+b)\mathbf{x} = a\mathbf{x} + b\mathbf{x}$이다. (덧셈에 대한 스칼라배의 분배법칙 2)</ol></blockquote><p>이러한 선형대수학에서의 벡터의 정의는 앞서 언급한 <a href="#좁은-의미의-벡터-유클리드-벡터">유클리드 벡터</a>까지 포괄하는 보다 넓은 범위의 정의이다. <a href="#좁은-의미의-벡터-유클리드-벡터">유클리드 벡터</a>도 위의 8가지 성질을 만족함을 확인할 수 있다.</p><p>벡터의 기원과 발전 과정은 물리학에서 제기한 여러 실용적인 문제들, 가령 힘이나 물체의 운동, 회전, 장과 같은 개념들을 정량적으로 기술하려는 시도와 밀접하게 연관되어 있다. 자연현상을 수학적으로 표현하기 위한 물리학적 필요에 의해 처음에 <a href="#좁은-의미의-벡터-유클리드-벡터">유클리드 벡터</a>로 벡터의 개념이 처음 제시되었고, 이후 수학이 이러한 물리적 개념을 일반화하고 이론화하는 과정에서 벡터 공간, 내적, 외적 등의 형식적 구조를 정립하여 지금의 벡터의 정의를 이루게 된다. 즉 벡터는 물리학이 요구하고 수학이 정립한 개념으로, 순수 수학만의 산물이라기보다는 수학계와 물리학계가 긴밀히 교류하며 발전시켜 온 학제 간 산물이라 할 수 있다.</p><p>고전적인 역학에서 다루던 <a href="#좁은-의미의-벡터-유클리드-벡터">유클리드 벡터</a>는 수학적으로 <a href="#넓은-의미의-벡터-벡터-공간의-원소">보다 일반화된 틀</a>로 표현할 수 있으며, 오늘날 물리학에서는 <a href="#좁은-의미의-벡터-유클리드-벡터">유클리드 벡터</a>뿐만 아니라 벡터 공간, 함수 공간 등 수학에서 정의한 보다 추상적인 개념들도 적극적으로 활용하여 물리적인 의미를 부여한다. 따라서 벡터에 대한 두 정의를 단순히 ‘물리학적 정의’, ‘수학적 정의’로 이해하는 것은 부적절하다.</p><p>벡터공간에 대해서는 나중에 더 알아보기로 하고, 우선은 좌표공간 상에서 기하학적으로 표현 가능한 좁은 의미의 벡터, 유클리드 벡터에 집중한다. 직관적인 유클리드 벡터의 예시를 먼저 살펴보는 것은 추후 그 외의 다른 벡터들로 일반화할 때에도 이해에 도움이 된다.</p><h2 id="벡터의-표현법">벡터의 표현법</h2><h3 id="화살표-표현법">화살표 표현법</h3><p>기하학적인 직관을 가장 잘 살린, 흔히 볼 수 있는 표현법이다. 벡터의 크기는 화살표의 길이로, 벡터의 방향은 화살표의 방향으로 나타낸다.</p><p><img src="https://upload.wikimedia.org/wikipedia/commons/9/95/Vector_from_A_to_B.svg" alt="Euclidean Vector from A to B" width="972" /></p><blockquote><p><em>이미지 출처</em></p><ul><li>저작자: 위키피디아 유저 <a href="https://en.wikipedia.org/wiki/User:Nguyenthephuc">Nguyenthephuc</a><li>라이선스: <a href="https://creativecommons.org/licenses/by-sa/3.0/deed.en">CC BY-SA 3.0</a></ul></blockquote><p>이러한 표현법은 직관적이긴 하나, 4차원 이상의 고차원 벡터에 대해서는 이러한 화살표 표현법은 한계가 명확하다. 뿐만 아니라, 나중에 가서는 애초에 기하학적으로 표현하기 곤란한 비유클리드 벡터들도 다뤄야 하기 때문에 후술할 성분 표현법에 익숙해질 필요가 있다.</p><h3 id="성분-표현법">성분 표현법</h3><p>벡터가 어디에 위치했는지와 무관하게 크기와 방향이 같으면 동일한 벡터로 생각한다. 따라서 어떤 좌표공간이 주어졌을 때, 벡터의 시점을 해당 좌표공간의 원점으로 고정하면 <u>$n$차원 벡터는 $n$차원 공간상의 임의의 점에 대응</u>하며, 이 경우 종점의 좌표로 벡터를 표현할 수 있다. 이와 같은 표현법을 벡터의 <strong>성분 표현법</strong>이라고 한다.</p>\[(a_1, a_2, \cdots, a_n) \in \mathbb{R}^n \text{ or } \mathbb{C}^n\]<p><img src="https://upload.wikimedia.org/wikipedia/commons/5/5d/Position_vector.svg" alt="Position vector" /></p><blockquote><p><em>이미지 출처</em></p><ul><li>저작자: 위키미디어 유저 <a href="https://commons.wikimedia.org/wiki/User:Acdx">Acdx</a><li>라이선스: <a href="https://creativecommons.org/licenses/by-sa/3.0/deed.en">CC BY-SA 3.0</a></ul></blockquote><h2 id="벡터의-기본-연산">벡터의 기본 연산</h2><p>벡터의 기본 연산은 <strong>합</strong>과 <strong>스칼라배</strong> 두 가지이다. 모든 벡터 연산은 이 두 가지 기본 연산의 조합으로 표현할 수 있다.</p><h3 id="벡터의-합">벡터의 합</h3><p>두 벡터의 합은 마찬가지로 벡터이며, 이때 합성벡터의 성분들은 두 벡터의 성분들끼리 각각 더한 것과 같다.</p>\[(a_1, a_2, \cdots, a_n) + (b_1, b_2, \cdots, b_n) := (a_1+b_1, a_2+b_2, \cdots, a_n+b_n)\]<h3 id="벡터의-스칼라배">벡터의 스칼라배</h3><p>벡터는 크기를 확대하거나 축소할 수 있으며, 이를 벡터에 상수(스칼라)를 곱하는 스칼라배라는 연산으로 나타낸다. 어떤 벡터에 스칼라배를 한 결과물은 각각의 성분에 스칼라배를 한 것과 같다.</p>\[c(a_1, a_2, \cdots, a_n) := (ca_1, ca_2, \cdots, ca_n)\]<p><img src="https://upload.wikimedia.org/wikipedia/commons/1/1b/Scalar_multiplication_of_vectors2.svg" alt="Scalar multiplication of vectors" /></p><blockquote><p><em>이미지 출처</em></p><ul><li>저작자: 위키피디아 유저 <a href="https://en.wikipedia.org/wiki/User:Silly_rabbit">Silly rabbit</a><li>라이선스: <a href="https://creativecommons.org/licenses/by-sa/3.0/deed.en">CC BY-SA 3.0</a></ul></blockquote><h2 id="벡터의-선형-결합">벡터의 선형 결합</h2><p>미적분학이 수 $x$와 함수 $f(x)$로부터 출발하듯, 선형대수학은 벡터 $\mathbf{v}, \mathbf{w}, \dots$와 선형 결합 $c\mathbf{v} + d\mathbf{w} + \cdots$로부터 출발한다. 그리고 벡터들의 모든 선형 결합은 위의 두 기본 연산, <a href="#벡터의-합">합</a>과 <a href="#벡터의-스칼라배">스칼라배</a>의 조합으로 구성된다.</p><blockquote class="prompt-info"><p>유한 개의 벡터 $\mathbf{u}_1, \mathbf{u}_2, \dots, \mathbf{u}_n$과 스칼라 $a_1, a_2, \dots, a_n$에 대하여 다음을 만족하는 벡터 $\mathbf{v}$는 $\mathbf{u}_1, \mathbf{u}_2, \dots, \mathbf{u}_n$의 <strong>선형 결합(linear combination)</strong>이라 한다.</p>\[\mathbf{v} = a_1\mathbf{u}_1 + a_2\mathbf{u}_2 + \cdots + a_n\mathbf{u}_n\]<p>이때, $a_1, a_2, \dots, a_n$을 이 선형 결합의 <strong>계수(coefficient)</strong>라고 한다.</p></blockquote><p>그렇다면 이러한 선형 결합이 왜 중요한가? 다음과 같이 <strong>$m$차원 공간 상의 벡터 $n$개가 $m \times n$ 행렬의 $n$개 열을 이루는 상황</strong>을 생각해 보자.</p>\[\begin{gather*} \mathbf{v}_1 = (a_{11}, a_{21}, \dots, a_{m1}), \\ \mathbf{v}_2 = (a_{12}, a_{22}, \dots, a_{m2}), \\ \vdots \\ \mathbf{v}_n = (a_{1n}, a_{2n}, \dots, a_{mn}) \\ \\ A = \Bigg[ \mathbf{v}_1 \quad \mathbf{v}_2 \quad \cdots \quad \mathbf{v}_n \Bigg] \end{gather*}\]<p>여기서 핵심은 다음의 두 가지이다.</p><ol><li><strong>모든 가능한 선형 결합 $Ax = x_1\mathbf{v}_1 + x_2\mathbf{v}_2 + \cdots x_n\mathbf{v}_n$을 표현해 보라.</strong> 무엇을 이루는가?<li>원하는 출력 벡터 $Ax = b$를 만들어 내는 <strong>수 $x_1, x_2, \dots, x_n$을 찾아라.</strong></ol><p>두 번째 질문에 대한 답은 나중에 다시 알아볼 것이며, 일단 지금은 첫 번째 질문에 집중하자. 논의를 간단하게 하기 위해, $\mathbf{0}$이 아닌 2차원($m=2$) 벡터 2개($n=2$)의 경우를 예시로 살펴보자.</p><h3 id="선형-결합-cmathbfv--dmathbfw">선형 결합 $c\mathbf{v} + d\mathbf{w}$</h3><p>2차원 공간 상의 벡터 $\mathbf{v}$는 2개의 성분을 가진다. 모든 스칼라 $c$에 대하여, <u>벡터 $c\mathbf{v}$는 원래의 벡터 $\mathbf{v}$와 평행하고 원점을 지나는 $xy$ 평면 상의 무한히 긴 직선을 이룬다.</u></p><p>여기서 주어진 두 번째 벡터 $\mathbf{w}$가 이 직선 위에 있지 않다면(벡터 $\mathbf{v}$와 $\mathbf{w}$가 평행하지 않다면), 벡터 $d\mathbf{w}$는 또다른 두 번째 직선을 이룬다. 이제 이 두 직선을 조합해 보면, <strong>선형 결합 $c\mathbf{v} + d\mathbf{w}$는 원점을 포함하는 하나의 평면을 이룬다</strong>는 것을 알 수 있다.</p><p><img src="https://upload.wikimedia.org/wikipedia/commons/6/6f/Linjcomb.png" alt="Linear combinations of two vectors" /></p><blockquote><p><em>이미지 출처</em></p><ul><li>저작자: 위키미디어 유저 <a href="https://commons.wikimedia.org/wiki/User:Svjo">Svjo</a><li>라이선스: <a href="https://creativecommons.org/licenses/by-sa/4.0/deed.en">CC BY-SA 4.0</a></ul></blockquote><h3 id="생성">생성</h3><p>이처럼 벡터들의 선형 결합은 곧 벡터공간을 이루며, 이를 공간 <strong>생성(span)</strong>이라고 한다.</p><blockquote class="prompt-info"><p><strong>정의</strong><br /> 벡터공간 $\mathbb{V}$의 공집합이 아닌 부분집합 $S$에 대하여, $S$의 벡터를 사용하여 만든 모든 선형결합의 집합을 $S$의 <strong>생성공간(span)</strong>이라 하며 $\mathrm{span}(S)$라 표기한다. 단, $\mathrm{span}(\emptyset) = \{0\}$으로 정의한다.</p></blockquote><blockquote class="prompt-info"><p><strong>정의</strong><br /> 벡터공간 $\mathbb{V}$의 부분집합 $S$에 대하여 $\mathrm{span}(S) = \mathbb{V}$이면 $S$가 $\mathbb{V}$를 생성한다(generate 또는 span)고 한다.</p></blockquote><p>아직 부분공간, 기저와 같은 개념들은 알아보지 않았으나, 지금의 이 예시를 떠올리면 벡터공간의 개념을 이해하는 데 도움이 된다.</p>]]> </content> </entry> <entry><title xml:lang="ko">Kaggle 'Pandas' 교육과정 내용 정리 (2) - Lesson 4-6</title><link href="https://www.yunseo.kim/ko/posts/summary-of-kaggle-pandas-course-2/" rel="alternate" type="text/html" hreflang="en" /><link href="https://www.yunseo.kim/ko/posts/summary-of-kaggle-pandas-course-2/" rel="alternate" type="text/html" hreflang="ko" /><link href="https://www.yunseo.kim/ja/posts/summary-of-kaggle-pandas-course-2/" rel="alternate" type="text/html" hreflang="ja" /><link href="https://www.yunseo.kim/zh-TW/posts/summary-of-kaggle-pandas-course-2/" rel="alternate" type="text/html" hreflang="zh-TW" /><link href="https://www.yunseo.kim/es/posts/summary-of-kaggle-pandas-course-2/" rel="alternate" type="text/html" hreflang="es" /><link href="https://www.yunseo.kim/pt-BR/posts/summary-of-kaggle-pandas-course-2/" rel="alternate" type="text/html" hreflang="pt-BR" /><link href="https://www.yunseo.kim/fr/posts/summary-of-kaggle-pandas-course-2/" rel="alternate" type="text/html" hreflang="fr" /><link href="https://www.yunseo.kim/de/posts/summary-of-kaggle-pandas-course-2/" rel="alternate" type="text/html" hreflang="de" /><link href="https://www.yunseo.kim/pl/posts/summary-of-kaggle-pandas-course-2/" rel="alternate" type="text/html" hreflang="pl" /><link href="https://www.yunseo.kim/cs/posts/summary-of-kaggle-pandas-course-2/" rel="alternate" type="text/html" hreflang="cs" /><link href="https://www.yunseo.kim/sw/posts/summary-of-kaggle-pandas-course-2/" rel="alternate" type="text/html" hreflang="sw" /><link href="https://www.yunseo.kim/am/posts/summary-of-kaggle-pandas-course-2/" rel="alternate" type="text/html" hreflang="am" /><published>2025-08-24T00:00:00+09:00</published> <updated>2025-08-24T00:00:00+09:00</updated> <id>https://www.yunseo.kim/ko/posts/summary-of-kaggle-pandas-course-2/</id> <author> <name>Yunseo Kim</name> </author> <category term="AI & Data" /> <category term="Machine Learning" /> <summary xml:lang="ko">데이터를 정제, 가공하기 위한 Pandas 라이브러리의 활용법을 정리한다. Kaggle의 &apos;Pandas&apos; 공개 교육과정의 내용을 요약하고, 필요에 따라 일부 보강하였다. 이 포스트는 해당 교육과정의 후반부(Lesson 4-6)의 내용을 다룬다.</summary> <content type="html" xml:lang="ko"> <![CDATA[<p>데이터를 정제, 가공하기 위한 Pandas 라이브러리의 활용법을 정리한다. Kaggle의 'Pandas' 공개 교육과정의 내용을 요약하고, 필요에 따라 일부 보강하였다. 이 포스트는 해당 교육과정의 후반부(Lesson 4-6)의 내용을 다룬다.</p><em><p>* Mathematical equations and diagrams included in posts may not display properly when viewed with a feed reader.</p></em><p>Kaggle의 <a href="https://www.kaggle.com/learn/pandas">Pandas</a> 교육과정을 통해 공부한 내용을 여기에 정리한다.<br /> 분량이 제법 되기 때문에 2편으로 분리하였다.</p><ul><li><a href="/ko/posts/summary-of-kaggle-pandas-course-1/">1편: Lesson 1-3</a><li>2편: Lesson 4-6 (본문)</ul><p><img src="/assets/img/kaggle-pandas/certificate.png" alt="Certificate of Completion" /></p><h2 id="lesson-4-grouping-and-sorting">Lesson 4. Grouping and Sorting</h2><p>종종 데이터를 분류하고 집단별로 어떤 조작을 가해야 하거나, 특정 기준에 따라 정렬해야 할 때가 있다.</p><h3 id="집단별-분석">집단별 분석</h3><p><a href="https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.groupby.html"><code class="language-plaintext highlighter-rouge">groupby()</code></a> 메서드를 사용하면 특정 열의 값이 같은 데이터끼리 묶고, 이후 각 집단별로 개요 확인 또는 조작을 수행할 수 있다.</p><p>앞서 <a href="/ko/posts/summary-of-kaggle-pandas-course-1/#데이터-개요-확인"><code class="language-plaintext highlighter-rouge">value_counts()</code> 메서드</a>를 알아보았는데, 동일한 동작을 <code class="language-plaintext highlighter-rouge">groupby()</code> 메서드로는 다음과 같이 구현할 수 있다.</p><div class="language-python highlighter-rouge"><div class="highlight">class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre><td class="rouge-code"><pre><span class="n">reviews</span><span class="p">.</span><span class="nf">groupby</span><span class="p">(</span><span class="sh">'</span><span class="s">taster_name</span><span class="sh">'</span><span class="p">).</span><span class="nf">size</span><span class="p">()</span>
</pre></div></div><ol><li><code class="language-plaintext highlighter-rouge">reviews</code> 데이터프레임을 <code class="language-plaintext highlighter-rouge">taster_name</code> 열의 값이 같은 데이터들끼리 묶음<li>그렇게 묶은 각 집단의 크기(속한 데이터 수)를 시리즈로 반환</ol><p>또는</p><div class="language-python highlighter-rouge"><div class="highlight">class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre><td class="rouge-code"><pre><span class="n">reviews</span><span class="p">.</span><span class="nf">groupby</span><span class="p">(</span><span class="sh">'</span><span class="s">taster_name</span><span class="sh">'</span><span class="p">).</span><span class="n">taster_name</span><span class="p">.</span><span class="nf">count</span><span class="p">()</span>
</pre></div></div><ol><li><code class="language-plaintext highlighter-rouge">reviews</code> 데이터프레임을 <code class="language-plaintext highlighter-rouge">taster_name</code> 열의 값이 같은 데이터들끼리 묶음<li>그렇게 묶은 각 집단별로 <code class="language-plaintext highlighter-rouge">taster_name</code> 열에 해당하는 데이터를 선택<li>해당하는 결측치를 제외한 데이터 수를 시리즈로 반환</ol><p>즉, <code class="language-plaintext highlighter-rouge">value_counts()</code> 메서드는 사실 위와 같은 동작에 대한 단축어인 것이다. <a href="https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.count.html"><code class="language-plaintext highlighter-rouge">count()</code></a> 메서드 이외에도 어떤 개요 함수든지 이런 식으로 활용할 수 있다. 가령, 와인 데이터로부터 평점별 최저가를 확인하려면 다음과 같이 할 수 있다.</p><div class="language-python highlighter-rouge"><div class="highlight">class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre><td class="rouge-code"><pre><span class="n">reviews</span><span class="p">.</span><span class="nf">groupby</span><span class="p">(</span><span class="sh">'</span><span class="s">points</span><span class="sh">'</span><span class="p">).</span><span class="n">price</span><span class="p">.</span><span class="nf">min</span><span class="p">()</span>
</pre></div></div><div class="language-plaintext highlighter-rouge"><div class="highlight">class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
</pre><td class="rouge-code"><pre>points
80      5.0
81      5.0
       ... 
99     44.0
100    80.0
Name: price, Length: 21, dtype: float64
</pre></div></div><ol><li><code class="language-plaintext highlighter-rouge">reviews</code> 데이터프레임을 <code class="language-plaintext highlighter-rouge">points</code> 열의 값이 같은 데이터들끼리 묶음<li>그렇게 묶은 각 집단별로 <code class="language-plaintext highlighter-rouge">price</code> 열에 해당하는 데이터를 선택<li>해당하는 데이터 중 최소값을 시리즈로 반환</ol><p>둘 이상의 열을 기준으로 데이터를 분류하는 것도 가능하다. 국가별, 주별로 평점이 가장 높은 와인의 정보만을 선택하려면 다음과 같이 할 수 있다.</p><div class="language-python highlighter-rouge"><div class="highlight">class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre><td class="rouge-code"><pre><span class="n">reviews</span><span class="p">.</span><span class="nf">groupby</span><span class="p">([</span><span class="sh">'</span><span class="s">country</span><span class="sh">'</span><span class="p">,</span> <span class="sh">'</span><span class="s">province</span><span class="sh">'</span><span class="p">]).</span><span class="nf">apply</span><span class="p">(</span><span class="k">lambda</span> <span class="n">df</span><span class="p">:</span> <span class="n">df</span><span class="p">.</span><span class="n">loc</span><span class="p">[</span><span class="n">df</span><span class="p">.</span><span class="n">points</span><span class="p">.</span><span class="nf">idxmax</span><span class="p">()])</span>
</pre></div></div><p>또다른 알아두면 좋을 DataFrameGroupBy 객체의 메서드는 <a href="https://pandas.pydata.org/docs/reference/api/pandas.core.groupby.DataFrameGroupBy.agg.html"><code class="language-plaintext highlighter-rouge">agg()</code></a>이다. 이를 사용하면 데이터를 묶은 후에 각 집단별로 여러 개의 함수를 동시에 실행하는 것이 가능하다.</p><blockquote class="prompt-tip"><p>이때 인자로는</p><ul><li>함수<li>함수명을 담은 문자열<li>함수 또는 함수명 문자열을 담은 리스트<li>축 레이블을 키, 해당 축에 대해 적용할 함수 또는 함수 목록을 값으로 갖는 딕셔너리</ul><p>를 전달할 수 있으며, 여기서 함수는</p><ul><li>데이터프레임을 입력으로 받을 수 있거나<li><a href="/ko/posts/summary-of-kaggle-pandas-course-1/#사상-maps">앞서 다뤘던</a> <a href="https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.apply.html"><code class="language-plaintext highlighter-rouge">DataFrame.apply()</code></a> 메서드에 인자로 전달 가능한</ul><p>함수여야 한다. 원래의 Kaggle 교육과정에는 나와 있지 않던 설명으로, 판다스 공식 문서를 참고하여 보강 서술하였다.</p></blockquote><p>예를 들어 다음과 같이 국가별 가격 통계량을 산출할 수 있다.</p><div class="language-python highlighter-rouge"><div class="highlight">class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre><td class="rouge-code"><pre><span class="n">reviews</span><span class="p">.</span><span class="nf">groupby</span><span class="p">([</span><span class="sh">'</span><span class="s">country</span><span class="sh">'</span><span class="p">]).</span><span class="n">price</span><span class="p">.</span><span class="nf">agg</span><span class="p">([</span><span class="nb">len</span><span class="p">,</span> <span class="nb">min</span><span class="p">,</span> <span class="nb">max</span><span class="p">])</span>
</pre></div></div><blockquote class="prompt-tip"><p>여기서 <code class="language-plaintext highlighter-rouge">len</code>은 파이썬 내장 함수 <a href="https://docs.python.org/3/library/functions.html#len"><code class="language-plaintext highlighter-rouge">len()</code></a>을 의미하며, 지금의 예시에서는 <u>결측치를 포함한</u> 묶음(<code class="language-plaintext highlighter-rouge">country</code>)별 가격(<code class="language-plaintext highlighter-rouge">price</code>) 데이터 수를 출력하기 위해 사용하였다. 데이터프레임 또는 시리즈를 입력으로 받아 동작 가능한 함수이기 때문에 이와 같이 사용이 가능하다.</p><p>판다스에서 제공하는 <a href="https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.count.html"><code class="language-plaintext highlighter-rouge">count()</code></a> 메서드는 <u>결측치를 제외한 유효한 값들의 수만</u> 세서 반환한다는 점에서 동작에 차이가 있다.</p><p>원래의 Kaggle 교육과정에는 나와 있지 않던 설명으로, 파이썬과 판다스 공식 문서를 참고하여 보강 서술하였다.</p></blockquote><h3 id="다중-인덱스">다중 인덱스</h3><p><code class="language-plaintext highlighter-rouge">groupby()</code> 메서드를 활용한 데이터 가공 및 분석을 하다 보면, 단일 레이블이 아니라 둘 이상의 단계로 구성된 다중 인덱스를 갖는 데이터프레임을 반환받을 때가 있다.</p><div class="language-python highlighter-rouge"><div class="highlight">class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
</pre><td class="rouge-code"><pre><span class="n">countries_reviewed</span> <span class="o">=</span> <span class="n">reviews</span><span class="p">.</span><span class="nf">groupby</span><span class="p">([</span><span class="sh">'</span><span class="s">country</span><span class="sh">'</span><span class="p">,</span> <span class="sh">'</span><span class="s">province</span><span class="sh">'</span><span class="p">]).</span><span class="n">description</span><span class="p">.</span><span class="nf">agg</span><span class="p">([</span><span class="nb">len</span><span class="p">])</span>
<span class="n">countries_reviewed</span>
</pre></div></div><table><tr><th><th><th>len<tr><th>Country<th>province<th><tr><td rowspan="2">Argentina<td>Mendoza Province<td>3264<tr><td>Other<td>536<tr><td>...<td>...<td>...<tr><td rowspan="2">Uruguay<td>San Jose<td>3<tr><td>Uruguay<td>24</table><div class="language-python highlighter-rouge"><div class="highlight">class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
</pre><td class="rouge-code"><pre><span class="n">mi</span> <span class="o">=</span> <span class="n">countries_reviewed</span><span class="p">.</span><span class="n">index</span>
<span class="nf">type</span><span class="p">(</span><span class="n">mi</span><span class="p">)</span>
</pre></div></div><div class="language-plaintext highlighter-rouge"><div class="highlight">class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre><td class="rouge-code"><pre>pandas.core.indexes.multi.MultiIndex
</pre></div></div><p>다중 인덱스는 계층 구조를 다루기 위한, 단일 인덱스에는 없는 몇몇 메서드들을 지닌다. 다중 인덱스에 대한 자세한 사용례와 지침은 <a href="https://pandas.pydata.org/pandas-docs/stable/user_guide/advanced.html">pandas User Guide의 MultiIndex / advanced indexing 섹션</a>에 자세히 나와 있다.</p><p>다만, 보통 다중 인덱스에 대해 제일 자주 사용하게 될 메서드는 아래와 같이 보통의 인덱스로 되돌리기 위한 <a href="https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.reset_index.html"><code class="language-plaintext highlighter-rouge">reset_index()</code></a>일 것이다.</p><div class="language-python highlighter-rouge"><div class="highlight">class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre><td class="rouge-code"><pre><span class="n">countries_reviewed</span><span class="p">.</span><span class="nf">reset_index</span><span class="p">()</span>
</pre></div></div><table><thead><tr><th> <th>country<th>province<th>len<tbody><tr><td>0<td>Argentina<td>Mendoza Province<td>3264<tr><td>1<td>Argentina<td>Other<td>536<tr><td>…<td>…<td>…<td>…<tr><td>423<td>Uruguay<td>San Jose<td>3<tr><td>424<td>Uruguay<td>Uruguay<td>24</table><h3 id="정렬">정렬</h3><p>계속해서 예시로 살펴보고 있는 <code class="language-plaintext highlighter-rouge">countries_reviewed</code>를 가만히 보면 데이터를 묶은 결과물은 인덱스 순서로 반환됨을 알 수 있다. 즉 <code class="language-plaintext highlighter-rouge">groupby</code> 결과물의 행 순서는 데이터 내용물이 아닌 인덱스 값에 의해 결정된다.</p><p>필요에 따라 데이터를 다른 방식으로 직접 정렬할 수 있다. 이럴 때는 <a href="https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.sort_values.html"><code class="language-plaintext highlighter-rouge">sort_values()</code></a> 메서드를 사용하면 편리하다. 예를 들어 아래와 같이 포함한 데이터 수(‘len’) 기준으로 국가와 주 정보를 오름차순 정렬할 수 있다.</p><div class="language-python highlighter-rouge"><div class="highlight">class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
</pre><td class="rouge-code"><pre><span class="n">countries_reviewed</span> <span class="o">=</span> <span class="n">countries_reviewed</span><span class="p">.</span><span class="nf">reset_index</span><span class="p">()</span>
<span class="n">countries_reviewed</span><span class="p">.</span><span class="nf">sort_values</span><span class="p">(</span><span class="n">by</span><span class="o">=</span><span class="sh">'</span><span class="s">len</span><span class="sh">'</span><span class="p">)</span>
</pre></div></div><table><thead><tr><th> <th>country<th>province<th>len<tbody><tr><td>179<td>Greece<td>Muscat of Kefallonian<td>1<tr><td>192<td>Greece<td>Sterea Ellada<td>1<tr><td>…<td>…<td>…<td>…<tr><td>415<td>US<td>Washington<td>8639<tr><td>392<td>US<td>California<td>36247</table><p><code class="language-plaintext highlighter-rouge">sort_values()</code>는 기본적으로 오름차순 정렬(낮은 값부터 높아지는 순서)을 수행하나, 다음과 같이 옵션을 지정하면 내림차순 정렬(높은 값부터 낮아지는 순서)도 가능하다.</p><div class="language-python highlighter-rouge"><div class="highlight">class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre><td class="rouge-code"><pre><span class="n">countries_reviewed</span><span class="p">.</span><span class="nf">sort_values</span><span class="p">(</span><span class="n">by</span><span class="o">=</span><span class="sh">'</span><span class="s">len</span><span class="sh">'</span><span class="p">,</span> <span class="n">ascending</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span>
</pre></div></div><table><thead><tr><th> <th>country<th>province<th>len<tbody><tr><td>392<td>US<td>California<td>36247<tr><td>415<td>US<td>Washington<td>8639<tr><td>…<td>…<td>…<td>…<tr><td>63<td>Chile<td>Coelemu<td>1<tr><td>149<td>Greece<td>Beotia<td>1</table><p>인덱스 기준으로 정렬하려면 <a href="https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.sort_index.html"><code class="language-plaintext highlighter-rouge">sort_index()</code></a> 메서드를 사용하면 된다. <code class="language-plaintext highlighter-rouge">sort_values()</code>와 동일한 인자 및 기본 정렬 순서(내림차순)를 가지므로 사용법은 동일하다.</p><div class="language-python highlighter-rouge"><div class="highlight">class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre><td class="rouge-code"><pre><span class="n">countries_reviewed</span><span class="p">.</span><span class="nf">sort_index</span><span class="p">()</span>
</pre></div></div><table><thead><tr><th> <th>country<th>province<th>len<tbody><tr><td>0<td>Argentina<td>Mendoza Province<td>3264<tr><td>1<td>Argentina<td>Other<td>536<tr><td>…<td>…<td>…<td>…<tr><td>423<td>Uruguay<td>San Jose<td>3<tr><td>424<td>Uruguay<td>Uruguay<td>24</table><p>마지막으로, 다음과 같이 한번에 둘 이상의 열을 기준으로 정렬하는 것도 가능하다.</p><div class="language-python highlighter-rouge"><div class="highlight">class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre><td class="rouge-code"><pre><span class="n">countries_reviewed</span><span class="p">.</span><span class="nf">sort_values</span><span class="p">(</span><span class="n">by</span><span class="o">=</span><span class="p">[</span><span class="sh">'</span><span class="s">country</span><span class="sh">'</span><span class="p">,</span> <span class="sh">'</span><span class="s">len</span><span class="sh">'</span><span class="p">])</span>
</pre></div></div><h2 id="lesson-5-data-types-and-missing-values">Lesson 5. Data Types and Missing Values</h2><p>현실적으로 다루어야 하는 데이터가 항상 잘 정제되어 있으리란 보장은 없으며, 오히려 자료형이 원하는 것과 달라 변환해 주어야 하거나 결측값이 중간중간에 있어 누락된 부분을 적절히 처리해 줘야 하는 경우가 대부분이다. 데이터를 가공하고 분석할 때 거의 대부분 최대 난관이 바로 이 단계이다.</p><h3 id="자료형">자료형</h3><p>데이터프레임의 특정 열, 또는 시리즈의 자료형을 <strong>dtype</strong>이라고 한다. <code class="language-plaintext highlighter-rouge">dtype</code> 속성을 통해 주어진 데이터프레임의 특정 열의 자료형을 확인할 수 있다. 다음은 <code class="language-plaintext highlighter-rouge">reviews</code> 데이터프레임의 <code class="language-plaintext highlighter-rouge">price</code> 열의 <code class="language-plaintext highlighter-rouge">dtype</code>을 확인하는 예시이다.</p><div class="language-python highlighter-rouge"><div class="highlight">class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre><td class="rouge-code"><pre><span class="n">reviews</span><span class="p">.</span><span class="n">price</span><span class="p">.</span><span class="n">dtype</span>
</pre></div></div><div class="language-plaintext highlighter-rouge"><div class="highlight">class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre><td class="rouge-code"><pre>dtype('float64')
</pre></div></div><p>혹은 <code class="language-plaintext highlighter-rouge">dtypes</code> 속성을 통해 다음과 같이 데이터프레임 내 모든 열의 <code class="language-plaintext highlighter-rouge">dtype</code>을 한번에 확인할 수 있다.</p><div class="language-python highlighter-rouge"><div class="highlight">class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre><td class="rouge-code"><pre><span class="n">reviews</span><span class="p">.</span><span class="n">dtypes</span>
</pre></div></div><div class="language-plaintext highlighter-rouge"><div class="highlight">class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
</pre><td class="rouge-code"><pre>country        object
description    object
                ...  
variety        object
winery         object
Length: 13, dtype: object
</pre></div></div><p>자료형은 판다스가 내부적으로 해당 데이터를 어떻게 저장하고 있는지를 나타낸다. 가령 <code class="language-plaintext highlighter-rouge">float64</code>는 64비트 부동소수점 실수, <code class="language-plaintext highlighter-rouge">int64</code>는 64비트 정수를 의미한다.</p><p>또한 한 가지 특이한 점은, 문자열로만 구성된 열은 자체적인 자료형을 갖지 않고 단지 객체(<code class="language-plaintext highlighter-rouge">object</code>)로 간주된다.</p><p><a href="https://pandas.pydata.org/docs/reference/api/pandas.Series.astype.html"><code class="language-plaintext highlighter-rouge">astype()</code></a>을 사용하면 어느 한 자료형의 열을 다른 자료형으로 변환할 수 있다. 예를 들어, 앞선 예시에서 <code class="language-plaintext highlighter-rouge">int64</code> 자료형이었던 <code class="language-plaintext highlighter-rouge">points</code> 열을 <code class="language-plaintext highlighter-rouge">float64</code> 자료형으로 변환할 수 있다.</p><div class="language-python highlighter-rouge"><div class="highlight">class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre><td class="rouge-code"><pre><span class="n">reviews</span><span class="p">.</span><span class="n">points</span><span class="p">.</span><span class="nf">astype</span><span class="p">(</span><span class="sh">'</span><span class="s">float64</span><span class="sh">'</span><span class="p">)</span>
</pre></div></div><div class="language-plaintext highlighter-rouge"><div class="highlight">class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
</pre><td class="rouge-code"><pre>0         87.0
1         87.0
          ... 
129969    90.0
129970    90.0
Name: points, Length: 129971, dtype: float64
</pre></div></div><p>데이터프레임 혹은 시리즈의 인덱스 역시 마찬가지로 자료형을 가진다.</p><div class="language-python highlighter-rouge"><div class="highlight">class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre><td class="rouge-code"><pre><span class="n">reviews</span><span class="p">.</span><span class="n">index</span><span class="p">.</span><span class="n">dtype</span>
</pre></div></div><div class="language-plaintext highlighter-rouge"><div class="highlight">class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre><td class="rouge-code"><pre>dtype('int64')
</pre></div></div><p>판다스는 이 외에도 범주형 데이터나 시계열 데이터와 같은 외부 자료형 역시 지원한다.</p><h3 id="결측값">결측값</h3><p>값이 없는, 비어 있는 엔트리들은 <code class="language-plaintext highlighter-rouge">NaN</code>(“Not a Number”의 축약어) 값을 부여받는다. 기술적인 이유로 <code class="language-plaintext highlighter-rouge">NaN</code>은 항상 <code class="language-plaintext highlighter-rouge">float64</code> 자료형이다.</p><p>판다스는 결측값에 특화된 몇몇 함수들을 지원한다. <a href="/ko/posts/summary-of-kaggle-pandas-course-1/#조건부-선택">이전에도 비슷한 걸 잠깐 본 적 있는데</a>, 메서드가 아닌 판다스 내 독립적인 함수로도 <a href="https://pandas.pydata.org/docs/reference/api/pandas.isna.html"><code class="language-plaintext highlighter-rouge">pd.isna</code></a>와 <a href="https://pandas.pydata.org/docs/reference/api/pandas.notna.html"><code class="language-plaintext highlighter-rouge">pd.notna</code></a>가 존재한다. 이들 함수는 주어진 엔트리가 결측값인지(혹은 결측값이 아닌지)를 단일 불리언 값 또는 불리언 배열로 반환하며, 다음과 같이 응용할 수 있다.</p><div class="language-python highlighter-rouge"><div class="highlight">class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre><td class="rouge-code"><pre><span class="n">reviews</span><span class="p">[</span><span class="n">pd</span><span class="p">.</span><span class="nf">isna</span><span class="p">(</span><span class="n">reviews</span><span class="p">.</span><span class="n">country</span><span class="p">)]</span>
</pre></div></div><p>보통은 주어진 데이터에 결측값이 있는지 확인하고, 있다면 이를 적절히 채워 넣을 필요가 있다. 이럴 때 쓸 수 있는 전략은 여러 가지가 있는데, 우선 <a href="https://pandas.pydata.org/docs/reference/api/pandas.Series.fillna.html"><code class="language-plaintext highlighter-rouge">fillna()</code></a> 메서드를 사용하면 결측값을 어떤 적당한 값으로 대체하여 채워 넣을 수 있다. 다음은 주어진 <code class="language-plaintext highlighter-rouge">reviews</code> 데이터프레임의 <code class="language-plaintext highlighter-rouge">region_2</code> 열에서 모든 <code class="language-plaintext highlighter-rouge">NaN</code>을 <code class="language-plaintext highlighter-rouge">"Unknown"</code>으로 바꿔 넣는 예시이다.</p><div class="language-python highlighter-rouge"><div class="highlight">class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre><td class="rouge-code"><pre><span class="n">reviews</span><span class="p">.</span><span class="n">region_2</span><span class="p">.</span><span class="nf">fillna</span><span class="p">(</span><span class="sh">"</span><span class="s">Unknown</span><span class="sh">"</span><span class="p">)</span>
</pre></div></div><p>혹은, 결측값이 있을 때 그 앞쪽이나 뒤쪽에서 가장 가까운 유효한 값을 가져와 채워 넣는 forward fill 또는 backward fill 전략을 사용할 수 있다. 각각 <a href="https://pandas.pydata.org/docs/reference/api/pandas.Series.ffill.html"><code class="language-plaintext highlighter-rouge">ffill()</code></a>, <a href="https://pandas.pydata.org/docs/reference/api/pandas.Series.bfill.html"><code class="language-plaintext highlighter-rouge">bfill()</code></a> 메서드로 구현할 수 있다.</p><blockquote class="prompt-danger"><p>예전에는 <code class="language-plaintext highlighter-rouge">fillna()</code> 메서드에 <code class="language-plaintext highlighter-rouge">method</code> 인자로 <code class="language-plaintext highlighter-rouge">'ffill'</code>, <code class="language-plaintext highlighter-rouge">'bfill'</code> 문자열을 전달하여 사용할 수도 있었으나, 판다스 2.1.0 버전부터 해당 방법은 deprecated되어 사용을 권장하지 않으므로 대신 <code class="language-plaintext highlighter-rouge">ffill()</code>이나 <code class="language-plaintext highlighter-rouge">bfill()</code> 메서드를 상황에 맞게 사용해야 한다.</p></blockquote><p>그리고 경우에 따라서는 결측값이 아니더라도 어떤 값을 다른 값으로 일괄 대치해야 할 수 있다. 원래의 Kaggle 교육과정에서는 리뷰 데이터셋에서 특정 리뷰어의 트위터 핸들이 변경된 상황을 예시로 들고 있는데, 이것도 훌륭한 예시지만 한국인들 입장에서 좀 더 와닿을 다른 예시를 생각해보자면 다음과 같다.</p><p>대한민국에서 경기도 북부를 분할하여 <strong>경기북도</strong>라는 새로운 행정구역을 설치하였고 해당 명칭을 반영한 데이터셋이 있는데, 여기서 누군가가 갑자기 <strong>경기북도</strong>라는 멀쩡한 이름을 <strong>평화누리특별자치도</strong>로 바꾸자는 정신나간 발상을 해내고 그걸 기어이 관철해 버린 가상의 상황을 생각해 보자. <del>가상의 상황이지만, 자칫 이 비슷한 상황이 진짜 일어날 수도 있었다는 게 참 무서운 부분이다.</del> 그렇다면 이를 반영하여 기존 데이터셋에서 <code class="language-plaintext highlighter-rouge">"Gyeonggibuk-do"</code>를 <code class="language-plaintext highlighter-rouge">"Pyeonghwanuri State"</code> 내지는 <code class="language-plaintext highlighter-rouge">"Pyeonghwanuri Special Self-Governing Province"</code> 같은 새로운 값으로 대치해야 할 것이다. 판다스로 이러한 작업을 수행하는 한 가지 방법은 바로 <a href="https://pandas.pydata.org/docs/reference/api/pandas.Series.replace.html"><code class="language-plaintext highlighter-rouge">replace()</code></a> 메서드를 사용하는 것이다.</p><div class="language-python highlighter-rouge"><div class="highlight">class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre><td class="rouge-code"><pre><span class="n">rok_2030_census</span><span class="p">.</span><span class="n">province</span><span class="p">.</span><span class="nf">replace</span><span class="p">(</span><span class="sh">"</span><span class="s">Gyeonggibuk-do</span><span class="sh">"</span><span class="p">,</span> <span class="sh">"</span><span class="s">Pyeonghwanuri Special Self-Governing Province</span><span class="sh">"</span><span class="p">)</span>
</pre></div></div><p>위의 예제 코드를 활용하면 <code class="language-plaintext highlighter-rouge">rok_2030_census</code> 데이터셋의 <code class="language-plaintext highlighter-rouge">province</code> 열에서 모든 <code class="language-plaintext highlighter-rouge">"Gyeonggibuk-do"</code> 문자열을 효과적으로 ‘그 긴 거’로 일괄 대치할 수 있다. <del>이딴 코드를 누군가가 진짜로 돌려야만 했을 상황이 현실에서 벌어지지 않았다는 사실에 다시금 그저 안도하게 된다.</del></p><p>이와 같은 문자열 대치는 결측값 처리 및 데이터 정제 과정에서도 유효한데, 결측값이 <code class="language-plaintext highlighter-rouge">NaN</code>이 아니라 <code class="language-plaintext highlighter-rouge">"Unknown"</code>, <code class="language-plaintext highlighter-rouge">"Undisclosed"</code>, <code class="language-plaintext highlighter-rouge">"Invalid"</code> 같은 문자열로 주어지는 경우도 흔하기 때문이다. 현실에서 과거 작성된 공문서 등을 OCR 스캔하여 데이터셋으로 만드는 것과 같은 작업에서는 오히려 이런 경우가 대부분일 수 있다.</p><h2 id="lesson-6-renaming-and-combining">Lesson 6. Renaming and Combining</h2><p>때로는 데이터셋 내 특정 열이나 인덱스의 이름을 변경해야 할 수 있다. 또한 여러 개의 데이터프레임이나 시리즈를 결합해야 하는 상황도 자주 있다.</p><h3 id="이름-변경">이름 변경</h3><p><a href="https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.rename.html"><code class="language-plaintext highlighter-rouge">rename()</code></a> 메서드를 사용하면 데이터셋 내 특정 열 또는 인덱스의 이름을 변경할 수 있다. <code class="language-plaintext highlighter-rouge">rename()</code> 메서드는 다양한 입력 형식을 지원하지만, 대개 파이썬 딕셔너리를 이용하는 것이 제일 편리하다. 다음은 각각 <code class="language-plaintext highlighter-rouge">reviews</code> 데이터프레임에서 <code class="language-plaintext highlighter-rouge">points</code> 열의 이름을 <code class="language-plaintext highlighter-rouge">score</code>로 변경하고, 인덱스 중 <code class="language-plaintext highlighter-rouge">0</code>, <code class="language-plaintext highlighter-rouge">1</code>을 <code class="language-plaintext highlighter-rouge">firstEntry</code>, <code class="language-plaintext highlighter-rouge">secondEntry</code>로 변경하는 예시이다.</p><div class="language-python highlighter-rouge"><div class="highlight">class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre><td class="rouge-code"><pre><span class="n">reviews</span><span class="p">.</span><span class="nf">rename</span><span class="p">(</span><span class="n">columns</span><span class="o">=</span><span class="p">{</span><span class="sh">'</span><span class="s">points</span><span class="sh">'</span><span class="p">:</span> <span class="sh">'</span><span class="s">score</span><span class="sh">'</span><span class="p">})</span>
</pre></div></div><div class="language-python highlighter-rouge"><div class="highlight">class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre><td class="rouge-code"><pre><span class="n">reviews</span><span class="p">.</span><span class="nf">rename</span><span class="p">(</span><span class="n">index</span><span class="o">=</span><span class="p">{</span><span class="mi">0</span><span class="p">:</span> <span class="sh">'</span><span class="s">firstEntry</span><span class="sh">'</span><span class="p">,</span> <span class="mi">1</span><span class="p">:</span> <span class="sh">'</span><span class="s">secondEntry</span><span class="sh">'</span><span class="p">})</span>
</pre></div></div><p>사실 열 이름을 변경할 일은 자주 있지만, 인덱스 값의 이름을 변경할 일은 거의 없다. 그리고 그런 용도로는 보통 <a href="/ko/posts/summary-of-kaggle-pandas-course-1/#인덱스-조작하기">전에 본 것처럼</a> <a href="https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.set_index.html"><code class="language-plaintext highlighter-rouge">set_index()</code></a> 메서드를 사용하는 게 더 편하다.</p><p>행 인덱스와 열 인덱스는 스스로도 <code class="language-plaintext highlighter-rouge">name</code> 속성을 가지며, <code class="language-plaintext highlighter-rouge">rename_axis()</code> 메서드를 사용하면 이 축 이름을 변경하는 것도 가능하다. 가령 주어진 데이터셋의 인덱스 축에는 <code class="language-plaintext highlighter-rouge">wines</code>, 열 축에는 <code class="language-plaintext highlighter-rouge">fields</code>라고 이름을 붙일 수 있다.</p><div class="language-python highlighter-rouge"><div class="highlight">class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre><td class="rouge-code"><pre><span class="n">reviews</span><span class="p">.</span><span class="nf">rename_axis</span><span class="p">(</span><span class="sh">"</span><span class="s">wines</span><span class="sh">"</span><span class="p">,</span> <span class="n">axis</span><span class="o">=</span><span class="sh">'</span><span class="s">index</span><span class="sh">'</span><span class="p">).</span><span class="nf">rename_axis</span><span class="p">(</span><span class="sh">"</span><span class="s">fields</span><span class="sh">"</span><span class="p">,</span> <span class="n">axis</span><span class="o">=</span><span class="sh">'</span><span class="s">columns</span><span class="sh">'</span><span class="p">)</span>
</pre></div></div><h3 id="데이터셋-결합하기">데이터셋 결합하기</h3><p>때로는 데이터프레임들끼리, 혹은 시리즈들끼리 결합해야 하는 경우가 있다. 판다스는 이러한 작업을 위해 세 가지 핵심 함수를 제공하는데, 단순한 것부터 복잡해지는 순서대로 쓰면 <a href="https://pandas.pydata.org/docs/reference/api/pandas.concat.html"><code class="language-plaintext highlighter-rouge">concat()</code></a>, <a href="https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.join.html"><code class="language-plaintext highlighter-rouge">join()</code></a>, 그리고 <a href="https://pandas.pydata.org/docs/reference/api/pandas.merge.html"><code class="language-plaintext highlighter-rouge">merge()</code></a>이다. Kaggle 교육과정에서는 <code class="language-plaintext highlighter-rouge">merge()</code>로 할 수 있는 일의 대부분은 <code class="language-plaintext highlighter-rouge">join()</code>으로 더 간단하게 할 수 있으므로 앞의 둘에만 집중하겠다고 밝히고 있다.</p><p><code class="language-plaintext highlighter-rouge">concat()</code> 함수는 제일 단순한데, 여러 개의 데이터프레임 혹은 시리즈를 어느 한 축을 따라서 그대로 이어붙인다. 병합 대상인 데이터프레임 혹은 시리즈들이 같은 필드(열)들을 가지는 경우에 유용하다. 기본적으로는 인덱스 축을 따라 이어붙이며, <code class="language-plaintext highlighter-rouge">axis=1</code> 또는 <code class="language-plaintext highlighter-rouge">axis='columns'</code> 옵션을 지정하면 열 축을 따라 이어붙일 수도 있다.</p><div class="language-python highlighter-rouge"><div class="highlight">class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
</pre><td class="rouge-code"><pre><span class="o">&gt;&gt;&gt;</span> <span class="n">s1</span> <span class="o">=</span> <span class="n">pd</span><span class="p">.</span><span class="nc">Series</span><span class="p">([</span><span class="sh">'</span><span class="s">a</span><span class="sh">'</span><span class="p">,</span> <span class="sh">'</span><span class="s">b</span><span class="sh">'</span><span class="p">])</span>
<span class="o">&gt;&gt;&gt;</span> <span class="n">s2</span> <span class="o">=</span> <span class="n">pd</span><span class="p">.</span><span class="nc">Series</span><span class="p">([</span><span class="sh">'</span><span class="s">c</span><span class="sh">'</span><span class="p">,</span> <span class="sh">'</span><span class="s">d</span><span class="sh">'</span><span class="p">])</span>
<span class="o">&gt;&gt;&gt;</span> <span class="n">pd</span><span class="p">.</span><span class="nf">concat</span><span class="p">([</span><span class="n">s1</span><span class="p">,</span> <span class="n">s2</span><span class="p">])</span>
<span class="mi">0</span>    <span class="n">a</span>
<span class="mi">1</span>    <span class="n">b</span>
<span class="mi">0</span>    <span class="n">c</span>
<span class="mi">1</span>    <span class="n">d</span>
<span class="n">dtype</span><span class="p">:</span> <span class="nb">object</span>
</pre></div></div><div class="language-python highlighter-rouge"><div class="highlight">class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">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
</pre><td class="rouge-code"><pre><span class="o">&gt;&gt;&gt;</span> <span class="n">df1</span> <span class="o">=</span> <span class="n">pd</span><span class="p">.</span><span class="nc">DataFrame</span><span class="p">([[</span><span class="sh">'</span><span class="s">a</span><span class="sh">'</span><span class="p">,</span> <span class="mi">1</span><span class="p">],</span> <span class="p">[</span><span class="sh">'</span><span class="s">b</span><span class="sh">'</span><span class="p">,</span> <span class="mi">2</span><span class="p">]],</span>
<span class="p">...</span>                    <span class="n">columns</span><span class="o">=</span><span class="p">[</span><span class="sh">'</span><span class="s">letter</span><span class="sh">'</span><span class="p">,</span> <span class="sh">'</span><span class="s">number</span><span class="sh">'</span><span class="p">])</span>
<span class="o">&gt;&gt;&gt;</span> <span class="n">df1</span>
  <span class="n">letter</span>  <span class="n">number</span>
<span class="mi">0</span>      <span class="n">a</span>       <span class="mi">1</span>
<span class="mi">1</span>      <span class="n">b</span>       <span class="mi">2</span>
<span class="o">&gt;&gt;&gt;</span> <span class="n">df2</span> <span class="o">=</span> <span class="n">pd</span><span class="p">.</span><span class="nc">DataFrame</span><span class="p">([[</span><span class="sh">'</span><span class="s">c</span><span class="sh">'</span><span class="p">,</span> <span class="mi">3</span><span class="p">],</span> <span class="p">[</span><span class="sh">'</span><span class="s">d</span><span class="sh">'</span><span class="p">,</span> <span class="mi">4</span><span class="p">]],</span>
<span class="p">...</span>                    <span class="n">columns</span><span class="o">=</span><span class="p">[</span><span class="sh">'</span><span class="s">letter</span><span class="sh">'</span><span class="p">,</span> <span class="sh">'</span><span class="s">number</span><span class="sh">'</span><span class="p">])</span>
<span class="o">&gt;&gt;&gt;</span> <span class="n">df2</span>
  <span class="n">letter</span>  <span class="n">number</span>
<span class="mi">0</span>      <span class="n">c</span>       <span class="mi">3</span>
<span class="mi">1</span>      <span class="n">d</span>       <span class="mi">4</span>
<span class="o">&gt;&gt;&gt;</span> <span class="n">pd</span><span class="p">.</span><span class="nf">concat</span><span class="p">([</span><span class="n">df1</span><span class="p">,</span> <span class="n">df2</span><span class="p">])</span>
  <span class="n">letter</span>  <span class="n">number</span>
<span class="mi">0</span>      <span class="n">a</span>       <span class="mi">1</span>
<span class="mi">1</span>      <span class="n">b</span>       <span class="mi">2</span>
<span class="mi">0</span>      <span class="n">c</span>       <span class="mi">3</span>
<span class="mi">1</span>      <span class="n">d</span>       <span class="mi">4</span>
<span class="o">&gt;&gt;&gt;</span> <span class="n">df4</span> <span class="o">=</span> <span class="n">pd</span><span class="p">.</span><span class="nc">DataFrame</span><span class="p">([[</span><span class="sh">'</span><span class="s">bird</span><span class="sh">'</span><span class="p">,</span> <span class="sh">'</span><span class="s">polly</span><span class="sh">'</span><span class="p">],</span> <span class="p">[</span><span class="sh">'</span><span class="s">monkey</span><span class="sh">'</span><span class="p">,</span> <span class="sh">'</span><span class="s">george</span><span class="sh">'</span><span class="p">]],</span>
<span class="p">...</span>                    <span class="n">columns</span><span class="o">=</span><span class="p">[</span><span class="sh">'</span><span class="s">animal</span><span class="sh">'</span><span class="p">,</span> <span class="sh">'</span><span class="s">name</span><span class="sh">'</span><span class="p">])</span>
<span class="o">&gt;&gt;&gt;</span> <span class="n">df4</span>
   <span class="n">animal</span>    <span class="n">name</span>
<span class="mi">0</span>    <span class="n">bird</span>   <span class="n">polly</span>
<span class="mi">1</span>  <span class="n">monkey</span>  <span class="n">george</span>
<span class="o">&gt;&gt;&gt;</span> <span class="n">pd</span><span class="p">.</span><span class="nf">concat</span><span class="p">([</span><span class="n">df1</span><span class="p">,</span> <span class="n">df4</span><span class="p">],</span> <span class="n">axis</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
  <span class="n">letter</span>  <span class="n">number</span>  <span class="n">animal</span>    <span class="n">name</span>
<span class="mi">0</span>      <span class="n">a</span>       <span class="mi">1</span>    <span class="n">bird</span>   <span class="n">polly</span>
<span class="mi">1</span>      <span class="n">b</span>       <span class="mi">2</span>  <span class="n">monkey</span>  <span class="n">george</span>
</pre></div></div><blockquote class="prompt-tip"><p><a href="(https://pandas.pydata.org/docs/reference/api/pandas.concat.html)">판다스 공식 문서</a>에 따르면 여러 개의 행을 합쳐서 하나의 데이터프레임으로 만들어야 하는 경우 반복문 안에서 개별 행을 하나씩 더하는 것은 권장하지 않으며, 합쳐야 하는 행들을 리스트로 만든 다음 단일 <code class="language-plaintext highlighter-rouge">concat()</code>로 한번에 합쳐야 한다.</p></blockquote><p><code class="language-plaintext highlighter-rouge">join()</code> 메서드는 좀 더 복잡한데, 인덱스를 기준으로 한 데이터프레임에 또다른 데이터프레임을 이어붙인다. 이때 이름이 겹치는 열이 있을 경우, <code class="language-plaintext highlighter-rouge">lsuffix</code>와 <code class="language-plaintext highlighter-rouge">rsuffix</code> 인자로 두 데이터프레임의 겹치는 열 이름 뒤에 구분을 위해 붙일 접미사를 각각 지정해 주어야 한다.</p><div class="language-python highlighter-rouge"><div class="highlight">class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">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
</pre><td class="rouge-code"><pre><span class="o">&gt;&gt;&gt;</span> <span class="n">df</span> <span class="o">=</span> <span class="n">pd</span><span class="p">.</span><span class="nc">DataFrame</span><span class="p">({</span><span class="sh">'</span><span class="s">key</span><span class="sh">'</span><span class="p">:</span> <span class="p">[</span><span class="sh">'</span><span class="s">K0</span><span class="sh">'</span><span class="p">,</span> <span class="sh">'</span><span class="s">K1</span><span class="sh">'</span><span class="p">,</span> <span class="sh">'</span><span class="s">K2</span><span class="sh">'</span><span class="p">,</span> <span class="sh">'</span><span class="s">K3</span><span class="sh">'</span><span class="p">,</span> <span class="sh">'</span><span class="s">K4</span><span class="sh">'</span><span class="p">,</span> <span class="sh">'</span><span class="s">K5</span><span class="sh">'</span><span class="p">],</span>
<span class="p">...</span>                    <span class="sh">'</span><span class="s">A</span><span class="sh">'</span><span class="p">:</span> <span class="p">[</span><span class="sh">'</span><span class="s">A0</span><span class="sh">'</span><span class="p">,</span> <span class="sh">'</span><span class="s">A1</span><span class="sh">'</span><span class="p">,</span> <span class="sh">'</span><span class="s">A2</span><span class="sh">'</span><span class="p">,</span> <span class="sh">'</span><span class="s">A3</span><span class="sh">'</span><span class="p">,</span> <span class="sh">'</span><span class="s">A4</span><span class="sh">'</span><span class="p">,</span> <span class="sh">'</span><span class="s">A5</span><span class="sh">'</span><span class="p">]})</span>
<span class="o">&gt;&gt;&gt;</span> <span class="n">df</span>
  <span class="n">key</span>   <span class="n">A</span>
<span class="mi">0</span>  <span class="n">K0</span>  <span class="n">A0</span>
<span class="mi">1</span>  <span class="n">K1</span>  <span class="n">A1</span>
<span class="mi">2</span>  <span class="n">K2</span>  <span class="n">A2</span>
<span class="mi">3</span>  <span class="n">K3</span>  <span class="n">A3</span>
<span class="mi">4</span>  <span class="n">K4</span>  <span class="n">A4</span>
<span class="mi">5</span>  <span class="n">K5</span>  <span class="n">A5</span>
<span class="o">&gt;&gt;&gt;</span> <span class="n">other</span> <span class="o">=</span> <span class="n">pd</span><span class="p">.</span><span class="nc">DataFrame</span><span class="p">({</span><span class="sh">'</span><span class="s">key</span><span class="sh">'</span><span class="p">:</span> <span class="p">[</span><span class="sh">'</span><span class="s">K0</span><span class="sh">'</span><span class="p">,</span> <span class="sh">'</span><span class="s">K1</span><span class="sh">'</span><span class="p">,</span> <span class="sh">'</span><span class="s">K2</span><span class="sh">'</span><span class="p">],</span>
<span class="p">...</span>                       <span class="sh">'</span><span class="s">B</span><span class="sh">'</span><span class="p">:</span> <span class="p">[</span><span class="sh">'</span><span class="s">B0</span><span class="sh">'</span><span class="p">,</span> <span class="sh">'</span><span class="s">B1</span><span class="sh">'</span><span class="p">,</span> <span class="sh">'</span><span class="s">B2</span><span class="sh">'</span><span class="p">]})</span>
<span class="o">&gt;&gt;&gt;</span> <span class="n">other</span>
  <span class="n">key</span>   <span class="n">B</span>
<span class="mi">0</span>  <span class="n">K0</span>  <span class="n">B0</span>
<span class="mi">1</span>  <span class="n">K1</span>  <span class="n">B1</span>
<span class="mi">2</span>  <span class="n">K2</span>  <span class="n">B2</span>
<span class="o">&gt;&gt;&gt;</span> <span class="n">df</span><span class="p">.</span><span class="nf">join</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="n">lsuffix</span><span class="o">=</span><span class="sh">'</span><span class="s">_caller</span><span class="sh">'</span><span class="p">,</span> <span class="n">rsuffix</span><span class="o">=</span><span class="sh">'</span><span class="s">_other</span><span class="sh">'</span><span class="p">)</span>
  <span class="n">key_caller</span>   <span class="n">A</span> <span class="n">key_other</span>    <span class="n">B</span>
<span class="mi">0</span>         <span class="n">K0</span>  <span class="n">A0</span>        <span class="n">K0</span>   <span class="n">B0</span>
<span class="mi">1</span>         <span class="n">K1</span>  <span class="n">A1</span>        <span class="n">K1</span>   <span class="n">B1</span>
<span class="mi">2</span>         <span class="n">K2</span>  <span class="n">A2</span>        <span class="n">K2</span>   <span class="n">B2</span>
<span class="mi">3</span>         <span class="n">K3</span>  <span class="n">A3</span>       <span class="n">NaN</span>  <span class="n">NaN</span>
<span class="mi">4</span>         <span class="n">K4</span>  <span class="n">A4</span>       <span class="n">NaN</span>  <span class="n">NaN</span>
<span class="mi">5</span>         <span class="n">K5</span>  <span class="n">A5</span>       <span class="n">NaN</span>  <span class="n">NaN</span>
</pre></div></div>]]> </content> </entry> <entry><title xml:lang="ko">웹 성능 지표 (Web Vitals)</title><link href="https://www.yunseo.kim/ko/posts/about-web-vitals/" rel="alternate" type="text/html" hreflang="en" /><link href="https://www.yunseo.kim/ko/posts/about-web-vitals/" rel="alternate" type="text/html" hreflang="ko" /><link href="https://www.yunseo.kim/ja/posts/about-web-vitals/" rel="alternate" type="text/html" hreflang="ja" /><link href="https://www.yunseo.kim/zh-TW/posts/about-web-vitals/" rel="alternate" type="text/html" hreflang="zh-TW" /><link href="https://www.yunseo.kim/es/posts/about-web-vitals/" rel="alternate" type="text/html" hreflang="es" /><link href="https://www.yunseo.kim/pt-BR/posts/about-web-vitals/" rel="alternate" type="text/html" hreflang="pt-BR" /><link href="https://www.yunseo.kim/fr/posts/about-web-vitals/" rel="alternate" type="text/html" hreflang="fr" /><link href="https://www.yunseo.kim/de/posts/about-web-vitals/" rel="alternate" type="text/html" hreflang="de" /><link href="https://www.yunseo.kim/pl/posts/about-web-vitals/" rel="alternate" type="text/html" hreflang="pl" /><link href="https://www.yunseo.kim/cs/posts/about-web-vitals/" rel="alternate" type="text/html" hreflang="cs" /><link href="https://www.yunseo.kim/sw/posts/about-web-vitals/" rel="alternate" type="text/html" hreflang="sw" /><link href="https://www.yunseo.kim/am/posts/about-web-vitals/" rel="alternate" type="text/html" hreflang="am" /><published>2025-08-05T00:00:00+09:00</published> <updated>2025-08-28T18:22:07+09:00</updated> <id>https://www.yunseo.kim/ko/posts/about-web-vitals/</id> <author> <name>Yunseo Kim</name> </author> <category term="Dev" /> <category term="Web Dev" /> <summary xml:lang="ko">웹 성능 지표(Web Vitals)와 Lighthouse 측정 및 평가 기준을 정리하고, 각 성능 지표가 무엇을 의미하는지 알아본다.</summary> <content type="html" xml:lang="ko"> <![CDATA[<p>웹 성능 지표(Web Vitals)와 Lighthouse 측정 및 평가 기준을 정리하고, 각 성능 지표가 무엇을 의미하는지 알아본다.</p><em><p>* Mathematical equations and diagrams included in posts may not display properly when viewed with a feed reader.</p></em><h2 id="웹-성능을-결정하는-요소">웹 성능을 결정하는 요소</h2><p>웹 성능 최적화 시 고려해야 할 웹 성능을 결정하는 요소는 크게는 로딩 성능, 렌더링 성능의 두 가지로 분류할 수 있다.</p><h3 id="html-로딩-성능">HTML 로딩 성능</h3><ul><li>네트워크를 통해 서버에 최초로 웹페이지를 요청한 후, HTML 문서를 받아 와 브라우저가 렌더링을 시작할 때까지의 시간<li>얼마나 빨리 페이지가 표시되기 시작하는가를 결정<li>리다이렉트 최소화, HTML 응답 캐싱, 리소스 압축, 적절한 CDN 활용 등의 방법으로 최적화</ul><h3 id="렌더링-성능">렌더링 성능</h3><ul><li>브라우저가 사용자가 보는 화면을 그리고 상호작용 가능하게끔 하는 데 걸리는 시간<li>얼마나 부드럽고 빠르게 화면이 그려지는가를 결정<li>불필요한 CSS 및 JS 제거, 폰트 및 썸네일 지연 로딩 방지, 무거운 연산은 별도의 Web Worker로 분리하여 메인 쓰레드 점유 최소화, 애니메이션 최적화 등의 방법으로 최적화</ul><h2 id="웹-성능-지표-web-vitals">웹 성능 지표 (Web Vitals)</h2><p>구글의 <a href="https://web.dev/performance?hl=ko">web.dev</a>와 <a href="https://developer.chrome.com/docs/lighthouse/performance/performance-scoring?hl=ko">Chrome 개발자 문서</a>를 기준으로 서술한다. 특별한 이유가 있는 게 아니라면 어느 한 성능 지표에만 집중하기보다는 전체적인 개선을 목표로 하는 것이 좋으며, 최적화하고자 하는 웹페이지에서 어떤 부분이 성능에 병목으로 작용하는지 파악하는 것이 중요하다. 또한 실제 사용자 데이터 통계가 있는 경우, 상위권이나 평균에 해당하는 값보다는 Q1 정도의 하위권 값에 주목하여 그 경우에도 목표 기준을 달성하는지 확인하고 개선하는 것이 좋다.</p><h3 id="주요-웹-성능-지표-core-web-vitals">주요 웹 성능 지표 (Core Web Vitals)</h3><p>잠시 후 다루겠지만 웹 성능 지표(Web Vitals)에는 여러 가지가 있다. 그러나 그 중에서도 특히 사용자 경험에 밀접한 연관이 있고, 모의 환경이 아닌 실제 환경에서 측정이 가능한 다음 3가지 지표를 구글에서는 특히 중요하게 간주하며, 이를 <a href="https://web.dev/articles/vitals?hl=ko#core-web-vitals">주요 웹 성능 지표(Core Web Vitals)</a>라고 한다. 구글은 자사 검색엔진의 검색 결과 순서에도 대상 사이트의 주요 웹 성능 지표를 반영하기 때문에 사이트 운영자 입장에서도 이들 지표는 검색엔진 최적화(SEO)의 측면에서 유의 깊게 살펴야 한다.</p><ul><li><a href="#lcp-largest-contentful-paint">Large Contentful Paint (LCP)</a>: <em>로딩 성능</em> 반영, 2.5초 이내여야 함<li><a href="https://web.dev/articles/inp?hl=ko">Interaction to Next Paint (INP)</a>: <em>응답성</em> 반영, 200ms 이하여야 함<li><a href="#cls-cumulative-layout-shift">Cummulative Layout Shift (CLS)</a>: <em>시각적 안정성</em> 반영, 0.1 이하로 유지해야 함</ul><p>주요 웹 성능 지표는 기본적으로 실제 환경에서 측정하기 위한 것이지만, INP를 제외한 나머지 둘은 Chrome 개발자 도구나 Lighthouse와 같은 모의 환경에서도 측정할 수 있다. INP의 경우에는 실제 사용자 입력이 주어져야 측정 가능하므로 모의 환경에서는 측정할 수 없으나, 이런 경우 <a href="#tbt-total-blocking-time">TBT</a>가 INP와 매우 상관관계가 높고 유사한 성능 지표이므로 대신 참고할 수 있으며 <a href="https://web.dev/articles/vitals?hl=ko#lab_tools_to_measure_core_web_vitals">보통은 TBT를 개선하면 INP도 함께 개선된다</a>.</p><h3 id="lighthouse-10의-성능-점수-가중치">Lighthouse 10의 성능 점수 가중치</h3><p><a href="https://developer.chrome.com/docs/lighthouse/performance/performance-scoring?hl=ko">Lighthouse의 성능 점수는 각 측정항목 점수의 가중 평균으로 계산하며, 이때 다음 표의 가중치를 따른다</a>.</p><table><thead><tr><th>측정항목<th>가중치<tbody><tr><td><a href="#fcp-first-contentful-paint">First Contentful Paint</a><td>10%<tr><td><a href="#si-speed-index">Speed Index</a><td>10%<tr><td><a href="#lcp-largest-contentful-paint">Largest Contentful Paint</a><td>25%<tr><td><a href="#tbt-total-blocking-time">Total Blocking Time</a><td>30%<tr><td><a href="#cls-cumulative-layout-shift">Cumulative Layout Shift</a><td>25%</table><h3 id="fcp-first-contentful-paint">FCP (First Contentful Paint)</h3><ul><li>페이지 요청 후 첫 DOM 콘텐츠를 렌더링하는 데까지의 소요 시간을 측정<li>페이지 내 이미지, 흰색이 아닌 <code class="language-plaintext highlighter-rouge">&lt;canvas&gt;</code> 요소, SVG 등을 DOM 콘텐츠로 간주하며, <code class="language-plaintext highlighter-rouge">iframe</code> 내 콘텐츠는 고려하지 않음</ul><blockquote class="prompt-tip"><p>FCP에 특히 중요하게 영향을 미치는 요소 중 하나는 글꼴 로딩 시간으로, 이에 관한 최적화는 <a href="https://developer.chrome.com/docs/lighthouse/performance/font-display?hl=ko">관련 포스트</a>를 참고해 볼 것을 <a href="https://developer.chrome.com/docs/lighthouse/performance/first-contentful-paint/?hl=ko">Chrome 개발자 문서</a>에서는 권고하고 있다.</p></blockquote><h4 id="lighthouse-평가-기준">Lighthouse 평가 기준</h4><p><a href="https://developer.chrome.com/docs/lighthouse/performance/first-contentful-paint/?hl=ko">Chrome 개발자 문서</a>에 따르면, Lighthouse의 평가 기준은 다음 표와 같다.</p><table><thead><tr><th>색상 등급<th>모바일 FCP (초)<th>데스크탑 FCP (초)<tbody><tr><td>녹색 (빠름)<td>0-1.8<td>0-0.9<tr><td>주황색 (중간)<td>1.8-3<td>0.9-1.6<tr><td>빨간색 (느림)<td>3 초과<td>1.6 초과</table><h3 id="lcp-largest-contentful-paint">LCP (Largest Contentful Paint)</h3><ul><li>웹페이지를 처음 열었을 때 제일 먼저 화면에 보이는 표시 영역(viewport)을 기준으로, 해당 영역 내에서 가장 크게 표시되는 요소(이미지, 텍스트 블록, 영상 등)를 렌더링하기까지의 소요 시간을 측정<li>화면상에서 차지하는 면적이 넓을수록 사용자 입장에서 주요 콘텐츠로 체감할 가능성이 높을 것임<li>LCP가 이미지일 경우, 소요 시간을 4개의 하위 구간으로 나눌 수 있으며 이 중 병목이 발생하는 부분이 어디인지를 파악하는 것이 중요함<ol><li>Time to first byte (TTFB): 페이지 로드 시작 시점부터 HTML 문서 응답의 첫 바이트를 수신한 시점까지의 시간<li>로드 지연(Load delay): 브라우저가 LCP 리소스를 로드하기 시작한 시점과 TTFB 사이의 차<li>로드 시간(Load time): LCP 리소스 자체를 로드하는 데 걸린 시간<li>렌더링 지연(Render delay): LCP 리소스 로드를 완료한 시점부터 LCP 요소를 완전히 렌더링 완료할 때까지의 시간</ol></ul><h4 id="lighthouse-평가-기준-1">Lighthouse 평가 기준</h4><p><a href="https://developer.chrome.com/docs/lighthouse/performance/lighthouse-largest-contentful-paint/?hl=ko">Chrome 개발자 문서</a>에 따르면, Lighthouse의 평가 기준은 다음 표와 같다.</p><table><thead><tr><th>색상 등급<th>모바일 LCP (초)<th>데스크탑 LCP (초)<tbody><tr><td>녹색 (빠름)<td>0-2.5<td>0-1.2<tr><td>주황색 (중간)<td>2.5-4<td>1.2-2.4<tr><td>빨간색 (느림)<td>4 초과<td>2.4 초과</table><h3 id="tbt-total-blocking-time">TBT (Total Blocking Time)</h3><ul><li>웹페이지가 마우스 클릭, 화면 터치, 키보드 입력과 같은 사용자 입력에 반응하지 못하는 총 시간을 측정<li>FCP와 <a href="https://developer.chrome.com/docs/lighthouse/performance/interactive?hl=ko">TTI(상호작용 시작 시점, Time to Interactive)</a>* 사이의 작업들 중 50ms 이상 실행된 작업들을 <a href="https://web.dev/articles/long-tasks-devtools?hl=ko">긴 작업</a>으로 간주, 이러한 긴 작업들 각각에 소요된 시간에서 50ms를 뺀 초과분을 <em>차단 부분(blocking portion)</em>이라 하고 모든 차단 부분들의 합계를 TBT로 정의함</ul><blockquote class="prompt-info"><p>* TTI 자체는 네트워크 응답 이상치와 긴 작업들에 지나치게 민감하여 일관성이 낮고 높은 변동성을 가지며, 이에 따라 <a href="https://developer.chrome.com/blog/lighthouse-10-0#scoring-changes">Lighthouse 10부터는 성능 평가 항목에서 제외하였다</a>.</p></blockquote><blockquote class="prompt-tip"><p>일반적으로 긴 작업을 유발하는 가장 흔한 원인은 불필요하거나 비효율적인 자바스크립트 로딩, 파싱 및 실행이며, <a href="https://web.dev/articles/reduce-javascript-payloads-with-code-splitting?hl=ko">코드 분할</a>을 통해 각각이 50ms 이내에 실행 가능하도록 자바스크립트 페이로드 크기를 줄이고 필요하다면 메인 쓰레드가 아닌 별도의 서비스 worker로 분리하여 멀티쓰레드로 실행하는 것을 고려하라고 <a href="https://developer.chrome.com/docs/lighthouse/performance/lighthouse-total-blocking-time/?hl=ko">Chrome 개발자 문서</a>와 <a href="https://web.dev/articles/long-tasks-devtools#what_is_causing_my_long_tasks?hl=ko">구글의 web.dev</a>는 권고하고 있다.</p></blockquote><h4 id="lighthouse-평가-기준-2">Lighthouse 평가 기준</h4><p><a href="https://developer.chrome.com/docs/lighthouse/performance/lighthouse-total-blocking-time/?hl=ko">Chrome 개발자 문서</a>에 따르면, Lighthouse의 평가 기준은 다음 표와 같다.</p><table><thead><tr><th>색상 등급<th>모바일 TBT (밀리초)<th>데스크탑 TBT (밀리초)<tbody><tr><td>녹색 (빠름)<td>0-200<td>0-150<tr><td>주황색 (중간)<td>200-600<td>150-350<tr><td>빨간색 (느림)<td>600 초과<td>350 초과</table><h3 id="cls-cumulative-layout-shift">CLS (Cumulative Layout Shift)</h3><p> <video class="embed-video file" controls="" autoplay="" loop=""> <source src="https://web.dev/static/articles/cls/video/web-dev-assets/layout-instability-api/layout-instability2.webm" type="video/webm" /> Your browser does not support the video tag. Here is a <a href="https://web.dev/static/articles/cls/video/web-dev-assets/layout-instability-api/layout-instability2.webm">link to the video file</a> instead. </video> <em>갑작스러운 레이아웃 변경의 예시</em></p><blockquote><p>영상 출처: <a href="https://web.dev/articles/cls?hl=ko">Cumulative Layout Shift (CLS) | Articles | web.dev</a></p></blockquote><p><del>커서 움직임에서 깊은 분노가 느껴진다</del></p><ul><li>예기치 않은 레이아웃 변경은 텍스트가 갑자기 이동하여 읽던 위치를 놓치거나, 링크 혹은 버튼을 잘못 클릭하게 하는 등 여러 방식으로 사용자 경험을 저해함<li>CLS 점수를 산정하는 구체적인 방식은 <a href="https://web.dev/articles/cls">구글의 web.dev</a>에 기술되어 있음<li>아래 이미지에서 확인할 수 있듯, 0.1 이하를 목표로 해야 함</ul><p><img src="https://web.dev/static/articles/cls/image/good-cls-values.svg" alt="What is a good CLS score?" width="640" height="480" /></p><blockquote><p>이미지 출처: <a href="https://web.dev/articles/cls#what-is-a-good-cls-score?hl=ko">Cumulative Layout Shift (CLS) | Articles | web.dev</a></p></blockquote><h3 id="si-speed-index">SI (Speed Index)</h3><ul><li>페이지를 로드하는 동안 콘텐츠가 얼마나 빨리 시각적으로 표시되는지를 측정<li>Lighthouse는 브라우저에서 페이지를 로드하는 과정을 영상으로 녹화하고, 해당 영상을 분석하여 프레임 간의 진행을 계산한 뒤 <a href="https://github.com/paulirish/speedline">Speedline Node.js 모듈</a>을 사용하여 SI 점수를 산정함</ul><blockquote class="prompt-tip"><p>앞서 <a href="#fcp-first-contentful-paint">FCP</a>, <a href="#lcp-largest-contentful-paint">LCP</a>, <a href="#tbt-total-blocking-time">TBT</a>에 대해 정리하면서 언급했던 것들을 비롯해, 페이지 로딩 속도를 개선하는 조치라면 무엇이든 SI 점수에도 긍정적으로 작용한다. 페이지 로딩의 어느 한 과정만 대표하기보다는 전체 로딩 과정을 일정 수준 반영하는 성능 지표라고 볼 수 있다.</p></blockquote><h4 id="lighthouse-평가-기준-3">Lighthouse 평가 기준</h4><p><a href="https://developer.chrome.com/docs/lighthouse/performance/speed-index/?hl=ko">Chrome 개발자 문서</a>에 따르면, Lighthouse의 평가 기준은 다음 표와 같다.</p><table><thead><tr><th>색상 등급<th>모바일 SI (초)<th>데스크탑 SI (초)<tbody><tr><td>녹색 (빠름)<td>0-3.4<td>0-1.3<tr><td>주황색 (중간)<td>3.4-5.8<td>1.3-2.3<tr><td>빨간색 (느림)<td>5.8 초과<td>2.3 초과</table>]]> </content> </entry> <entry><title xml:lang="ko">중력장과 중력 퍼텐셜</title><link href="https://www.yunseo.kim/ko/posts/gravitational-field-and-potential/" rel="alternate" type="text/html" hreflang="en" /><link href="https://www.yunseo.kim/ko/posts/gravitational-field-and-potential/" rel="alternate" type="text/html" hreflang="ko" /><link href="https://www.yunseo.kim/ja/posts/gravitational-field-and-potential/" rel="alternate" type="text/html" hreflang="ja" /><link href="https://www.yunseo.kim/zh-TW/posts/gravitational-field-and-potential/" rel="alternate" type="text/html" hreflang="zh-TW" /><link href="https://www.yunseo.kim/es/posts/gravitational-field-and-potential/" rel="alternate" type="text/html" hreflang="es" /><link href="https://www.yunseo.kim/pt-BR/posts/gravitational-field-and-potential/" rel="alternate" type="text/html" hreflang="pt-BR" /><link href="https://www.yunseo.kim/fr/posts/gravitational-field-and-potential/" rel="alternate" type="text/html" hreflang="fr" /><link href="https://www.yunseo.kim/de/posts/gravitational-field-and-potential/" rel="alternate" type="text/html" hreflang="de" /><link href="https://www.yunseo.kim/pl/posts/gravitational-field-and-potential/" rel="alternate" type="text/html" hreflang="pl" /><link href="https://www.yunseo.kim/cs/posts/gravitational-field-and-potential/" rel="alternate" type="text/html" hreflang="cs" /><link href="https://www.yunseo.kim/sw/posts/gravitational-field-and-potential/" rel="alternate" type="text/html" hreflang="sw" /><link href="https://www.yunseo.kim/am/posts/gravitational-field-and-potential/" rel="alternate" type="text/html" hreflang="am" /><published>2025-05-17T00:00:00+09:00</published> <updated>2025-11-03T20:50:45+09:00</updated> <id>https://www.yunseo.kim/ko/posts/gravitational-field-and-potential/</id> <author> <name>Yunseo Kim</name> </author> <category term="Physics" /> <category term="Classical Dynamics" /> <summary xml:lang="ko">뉴턴의 만유인력 법칙에 따른 중력장 벡터와 중력 퍼텐셜의 정의를 알아보고, 이에 관련된 중요한 두 예제로 구각 정리와 은하 회전 곡선을 다룬다.</summary> <content type="html" xml:lang="ko"> <![CDATA[<p>뉴턴의 만유인력 법칙에 따른 중력장 벡터와 중력 퍼텐셜의 정의를 알아보고, 이에 관련된 중요한 두 예제로 구각 정리와 은하 회전 곡선을 다룬다.</p><em><p>* Mathematical equations and diagrams included in posts may not display properly when viewed with a feed reader.</p></em><h2 id="tldr">TL;DR</h2><blockquote class="prompt-info"><ul><li>뉴턴의 만유인력 법칙: $\mathbf{F} = -G\cfrac{mM}{r^2}\mathbf{e}_r$<li>연속적인 질량 분포와 크기를 갖는 물체의 경우: $\mathbf{F} = -Gm\int_V \cfrac{dM}{r^2}\mathbf{e}_r = -Gm\int_V \cfrac{\rho(\mathbf{r^\prime})\mathbf{e}_r}{r^2} dv^{\prime}$<ul><li>$\rho(\mathbf{r^{\prime}})$: 임의의 원점으로부터 위치 벡터 $\mathbf{r^{\prime}}$에 위치한 점에서의 질량 밀도<li>$dv^{\prime}$: 임의의 원점으로부터 위치 벡터 $\mathbf{r^{\prime}}$에 위치한 점에서의 부피 요소</ul><li><strong>중력장 벡터(gravitational field vector)</strong>:<ul><li>질량 $M$의 물체에 의해 생긴 장 안에서 어떤 하나의 입자가 단위질량당 받는 힘을 나타내는 벡터<li>$\mathbf{g} = \cfrac{\mathbf{F}}{m} = - G \cfrac{M}{r^2}\mathbf{e}_r = - G \int_V \cfrac{\rho(\mathbf{r^\prime})\mathbf{e}_r}{r^2}dv^\prime$<li><em>단위질량당 힘</em> 또는 <em>가속도</em>의 차원을 가짐</ul><li><strong>중력 퍼텐셜(gravitational potential)</strong>:<ul><li>$\mathbf{g} \equiv -\nabla \Phi$<li>$($<em>단위질량당 힘</em> $) \times ($<em>거리</em> $)$ 또는 <em>단위질량당 에너지</em>의 차원을 가짐<li>$\Phi = -G\cfrac{M}{r}$<li>중력 퍼텐셜은 그 상대적인 차이만이 의미가 있을 뿐, 특정한 값 자체는 의미가 없음<li>보통 $r \to \infty$일 때 $\Phi \to 0$인 조건을 임의로 설정하여 불확실성(ambiguity)을 제거함<li>$U = m\Phi, \quad \mathbf{F} = -\nabla U$</ul><li><strong>구면 껍질 내부와 외부의 중력 퍼텐셜(구각 정리)</strong><ul><li>$R&gt;a$일 때:<ul><li>$\Phi(R&gt;a) = -\cfrac{GM}{R}$<li>물질의 구대칭 분포(spherical symmetric distribution)에 의한 외부의 어떤 점에서의 중력 퍼텐셜을 구할 때, 해당 물체를 질점(point mass)으로 간주하고 계산할 수 있음</ul><li>$R&lt;b$일 때:<ul><li>$\Phi(R&lt;b) = -2\pi\rho G(a^2 - b^2)$<li>구대칭인 질량 껍질 안에서 중력 퍼텐셜은 위치와 무관하게 일정하며, 작용하는 중력은 $0$</ul><li>$b&lt;R&lt;a$일 때: $\Phi(b&lt;R&lt;a) = -4\pi\rho G \left( \cfrac{a^2}{2} - \cfrac{b^3}{3R} - \cfrac{R^2}{6} \right)$</ul></ul></blockquote><h2 id="중력장">중력장</h2><h3 id="뉴턴의-만유인력-법칙">뉴턴의 만유인력 법칙</h3><p>뉴턴은 11666 HE 이전에 이미 만유인력의 법칙을 체계화하고 수치적으로도 검증하였다. 그럼에도 불구하고 11687 HE에 저서 <em>Principia</em>로 자신의 결과를 출판하기까지는 20년이나 더 걸렸는데, 그 이유는 지구와 달을 크기를 갖지 않는 질점(point mass)으로 가정하고 수행한 계산법을 정당화할 수가 없었기 때문이다. 다행히도 <a href="#ra일-때">뉴턴 자신이 그 이후에 발명한 미적분학을 사용하면, 11600년대 당시 뉴턴에게는 쉽지 않았던 그 문제를 우리는 훨씬 쉽게 증명할 수 있다</a>.</p><p>뉴턴의 만유인력 법칙(Newton’s law of universal gravitation)에 따르면, <em>각 질량입자는 우주 내의 다른 모든 입자를 잡아당기는데 그 힘은 두 개의 질량의 곱에 비례하고 그 사이 거리의 제곱에 반비례한다.</em> 수학적으로 나타내면 다음과 같다.</p>\[\mathbf{F} = -G\frac{mM}{r^2}\mathbf{e}_r \label{eqn:law_of_gravitation}\tag{1}\]<p><img src="https://upload.wikimedia.org/wikipedia/commons/0/0e/NewtonsLawOfUniversalGravitation.svg" alt="Newton's law of universal gravitation" /></p><blockquote><p><em>이미지 출처</em></p><ul><li>저작자: 위키미디어 유저 <a href="https://commons.wikimedia.org/wiki/User:Dna-webmaster">Dennis Nilsson</a><li>라이선스: <a href="https://creativecommons.org/licenses/by/3.0/">CC BY 3.0</a></ul></blockquote><p>단위벡터 $\mathbf{e}_r$은 $M$에서 $m$ 방향을 향하며, 음부호는 힘이 인력임을 나타낸다. 즉, $m$은 $M$ 쪽으로 당겨진다.</p><h3 id="캐번디시의-실험">캐번디시의 실험</h3><p>이 법칙의 실험적인 검증과 $G$ 값의 결정은 11798 HE에 영국의 물리학자 헨리 캐번디시(Henry Cavendish)에 의해 이뤄졌다. 캐번디시의 실험은 가벼운 막대의 양쪽 끝 부분에 고정된 두 개의 작은 구로 이뤄진 비틀림 저울을 사용한다. 그 두 개의 구는 각각 그 근처에 위치한 다른 두 개의 큰 구 쪽으로 당겨진다. 지금까지 구해진 공식적인 $G$ 값은 $6.673 \pm 0.010 \times 10^{-11} \mathrm{N\cdot m^2/kg^2}$이다.</p><blockquote class="prompt-tip"><p>$G$는 가장 오래전부터 알려져 있던 기본 상수임에도 불구하고, $e$, $c$, $\hbar$와 같은 대부분의 다른 기본 상수들보다 낮은 정밀도(precision)로밖에 알고 있지 못하다. 오늘날에도 $G$ 값을 더 높은 정밀도로 알아내고자 하는 많은 연구가 이뤄지고 있다.</p></blockquote><h3 id="크기를-갖는-물체의-경우">크기를 갖는 물체의 경우</h3><p>식 ($\ref{eqn:law_of_gravitation}$)의 법칙은 엄밀하게는 <em>점입자(point particle)</em>에 대해서만 적용할 수 있다. 만약 어느 한 쪽 혹은 양쪽이 어떤 크기를 갖는 물체인 경우에는 힘을 계산하기 위해 중력장(gravitational force field)이 <em>선형장(linear field)</em>이라는 가정을 추가로 해야 한다. 즉, 질량이 $m$인 한 개의 입자가 다른 여러 입자들로부터 받는 총 중력은 각 힘의 벡터를 합함으로써 구할 수 있다고 가정한다. 물질이 연속적으로 분포하는 물체의 경우에는 합을 다음과 같이 적분으로 바꾼다.</p>\[\mathbf{F} = -Gm\int_V \frac{dM}{r^2}\mathbf{e}_r = -Gm\int_V \frac{\rho(\mathbf{r^\prime})\mathbf{e}_r}{r^2} dv^{\prime} \label{eqn:integral_form}\tag{2}\]<ul><li>$\rho(\mathbf{r^{\prime}})$: 임의의 원점으로부터 위치 벡터 $\mathbf{r^{\prime}}$에 위치한 점에서의 질량 밀도<li>$dv^{\prime}$: 임의의 원점으로부터 위치 벡터 $\mathbf{r^{\prime}}$에 위치한 점에서의 부피 요소</ul><p>만약 질량 $M$의 물체와 질량 $m$의 물체가 모두 크기를 갖는 경우에 전체 중력을 구하려고 할 경우 $m$에 대한 두 번째 부피 적분도 필요하다.</p><h3 id="중력장-벡터">중력장 벡터</h3><p><strong>중력장 벡터(gravitational field vector)</strong> $\mathbf{g}$는 질량 $M$의 물체에 의해 생긴 장 안에서 어떤 하나의 입자가 단위질량당 받는 힘을 나타내는 벡터라고 정의하여</p>\[\mathbf{g} = \frac{\mathbf{F}}{m} = - G \frac{M}{r^2}\mathbf{e}_r \label{eqn:g_vector}\tag{3}\]<p>또는</p>\[\boxed{\mathbf{g} = - G \int_V \frac{\rho(\mathbf{r^\prime})\mathbf{e}_r}{r^2}dv^\prime} \tag{4}\]<p>으로 나타낸다. 여기서 $\mathbf{e}_r$의 방향은 $\mathbf{r^\prime}$에 따라 달라진다.</p><p>이 양 $\mathbf{g}$는 <em>단위질량당 힘</em> 또는 <em>가속도</em>의 차원을 갖는다. 지구 표면 근처에서의 중력장 벡터 $\mathbf{g}$의 크기는 곧 우리가 <strong>중력가속도 상수(gravitational acceleration constant)</strong>라고 부르는 양과 같으며, $|\mathbf{g}| \approx 9.80\mathrm{m/s^2}$이다.</p><h2 id="중력-퍼텐셜">중력 퍼텐셜</h2><h3 id="정의">정의</h3><p>중력장 벡터 $\mathbf{g}$는 $1/r^2$로 변화하며, 따라서 어떤 스칼라 함수(퍼텐셜)의 기울기(gradient)로 표현하기 위한 조건($\nabla \times \mathbf{g} \equiv 0$)을 만족한다. 그러므로 다음과 같이 쓸 수 있다.</p>\[\mathbf{g} \equiv -\nabla \Phi \label{eqn:gradient_phi}\tag{5}\]<p>여기서 $\Phi$를 <strong>중력 퍼텐셜(gravitational potential)</strong>이라 하며, $($<em>단위질량당 힘</em> $) \times ($<em>거리</em> $)$ 또는 <em>단위질량당 에너지</em>의 차원을 갖는다.</p><p>$\mathbf{g}$는 반지름에만 의존하므로, $\Phi$ 역시 $r$에 따라 변한다. 식 ($\ref{eqn:g_vector}$)과 ($\ref{eqn:gradient_phi}$)로부터</p>\[\nabla\Phi = \frac{d\Phi}{dr}\mathbf{e}_r = G\frac{M}{r^2}\mathbf{e}_r\]<p>이 되고, 이를 적분하면</p>\[\boxed{\Phi = -G\frac{M}{r}} \label{eqn:g_potential}\tag{6}\]<p>을 얻는다. 중력 퍼텐셜은 그 상대적인 차이만이 의미가 있을 뿐, 절대적인 값의 크기는 의미가 없기 때문에 적분 상수는 생략할 수 있다. 보통 $r \to \infty$일 때 $\Phi \to 0$인 조건을 임의로 설정하여 불확실성(ambiguity)을 제거하며, 식 ($\ref{eqn:g_potential}$) 또한 이 조건을 만족한다.</p><p>물질이 연속적으로 분포할 경우의 중력 퍼텐셜은 다음과 같다.</p>\[\Phi = -G\int_V \frac{\rho(\mathbf{r\prime})}{r}dv^\prime \label{eqn:g_potential_v}\tag{7}\]<p>질량이 얇은 껍질에 표면 분포할 경우에는</p>\[\Phi = -G\int_S \frac{\rho_s}{r}da^\prime. \label{eqn:g_potential_s}\tag{8}\]<p>그리고 선밀도 $\rho_l$인 선형 질량원의 경우에는 다음과 같이 쓸 수 있다.</p>\[\Phi = -G\int_\Gamma \frac{\rho_l}{r}ds^\prime. \label{eqn:g_potential_l}\tag{9}\]<h3 id="물리적-의미">물리적 의미</h3><p>물체가 중력장 안에서 $d\mathbf{r}$만큼 이동할 때 그 물체가 행하는 단위질량당 일 $dW^\prime$을 생각해보자.</p>\[\begin{align*} dW^\prime &amp;= -\mathbf{g}\cdot d\mathbf{r} = (\nabla \Phi)\cdot d\mathbf{r} \\ &amp;= \sum_i \frac{\partial \Phi}{\partial x_i}dx_i = d\Phi \label{eqn:work}\tag{10} \end{align*}\]<p>이 식에서 $\Phi$는 위치 좌표만의 함수로, $\Phi=\Phi(x_1, x_2, x_3) = \Phi(x_i)$로 표현된다. 따라서 중력장 안에서 물체를 어떤 한 점에서 다른 한 점까지 이동시킬 때 그 물체가 행하는 단위질량당 일의 양은 그 두 점의 퍼텐셜 차이와 같음을 알 수 있다.</p><p>무한히 먼 곳에서의 중력 퍼텐셜을 $0$으로 정의하면, 임의의 점에서의 $\Phi$는 그 물체를 무한히 먼 곳으로부터 그 점까지 이동시키는 데 필요한 단위질량당의 일로 해석할 수 있다. 물체의 퍼텐셜 에너지는 그 물체의 질량과 중력 퍼텐셜 $\Phi$의 곱과 같으므로, $U$를 퍼텐셜 에너지라 할 때</p>\[U = m\Phi. \label{eqn:potential_e}\tag{11}\]<p>따라서 물체가 받는 중력은 그 물체의 퍼텐셜 에너지의 기울기에 음부호를 붙여 얻는다.</p>\[\mathbf{F} = -\nabla U \label{eqn:force_and_potential}\tag{12}\]<p>물체가 어떤 질량에 의해 생긴 중력장 속에 놓여 있을 때는 항상 어떤 퍼텐셜 에너지가 생긴다. 이 퍼텐셜 에너지는 엄밀히는 장 자체에 있는 것이지만, 관례적으로 이를 그 물체의 퍼텐셜 에너지라고 표현하곤 한다.</p><h2 id="예제-구면-껍질-내부와-외부의-중력-퍼텐셜-구각-정리">예제: 구면 껍질 내부와 외부의 중력 퍼텐셜 (구각 정리)</h2><h3 id="좌표-설정--적분식으로-중력-퍼텐셜-표현하기">좌표 설정 &amp; 적분식으로 중력 퍼텐셜 표현하기</h3><p>안쪽 반지름이 $b$, 바깥쪽 반지름이 $a$인 균일한 구면 껍질(spherical shell)의 내부와 외부의 중력 퍼텐셜을 구해 보자. 구면 껍질에 의한 중력은 장 속의 단위질량에 작용하는 힘 성분들을 직접 계산하여 얻을 수도 있지만, 퍼텐셜 방법을 쓰는 것이 더 간단하다.</p><p><img src="/assets/img/gravitational-field-and-potential/spherical-shell.png" alt="Spherical shell" /></p><p>위의 그림에서 중심으로부터 거리 $R$인 $P$ 점에서의 퍼텐셜을 계산하자. 껍질의 균일 질량 분포를 가정하면 $\rho(r^\prime)=\rho$이고, 구의 중심과 점 $P$를 잇는 선을 기준으로 방위각 $\phi$에 대해서는 대칭이므로</p>\[\begin{align*} \Phi &amp;= -G\int_V \frac{\rho(r^\prime)}{r}dv^\prime \\ &amp;= -\rho G \int_0^{2\pi} \int_0^\pi \int_b^a \frac{1}{r}(dr^\prime)(r^\prime d\theta)(r^\prime \sin\theta\, d\phi) \\ &amp;= -\rho G \int_0^{2\pi} d\phi \int_b^a {r^\prime}^2 dr^\prime \int_0^\pi \frac{\sin\theta}{r}d\theta \\ &amp;= -2\pi\rho G \int_b^a {r^\prime}^2 dr^\prime \int_0^\pi \frac{\sin\theta}{r}d\theta. \label{eqn:spherical_shell_1}\tag{13} \end{align*}\]<p>코사인 법칙에 따르면</p>\[r^2 = {r^\prime}^2 + R^2 - 2r^\prime R \cos\theta \label{eqn:law_of_cosines}\tag{14}\]<p>이고 $R$은 일정하므로, $r^\prime$에 대해 이 식을 미분하면</p>\[2rdr = 2r^\prime R \sin\theta d\theta\] \[\frac{\sin\theta}{r}d\theta = \frac{dr}{r^\prime R} \tag{15}\]<p>을 얻는다. 이를 식 ($\ref{eqn:spherical_shell_1}$)에 대입하면</p>\[\Phi = -\frac{2\pi\rho G}{R} \int_b^a r^\prime dr^\prime \int_{r_\mathrm{min}}^{r_\mathrm{max}} dr. \label{eqn:spherical_shell_2}\tag{16}\]<p>여기서 $r_\mathrm{max}$와 $r_\mathrm{min}$은 점 $P$의 위치에 따라 정해진다.</p><h3 id="ra일-때">$R&gt;a$일 때</h3>\[\begin{align*} \Phi(R&gt;a) &amp;= -\frac{2\pi\rho G}{R} \int_b^a r^\prime dr^\prime \int_{R-r^\prime}^{R+r^\prime} dr \\ &amp;= - \frac{4\pi\rho G}{R} \int_b^a {r^\prime}^2 dr^\prime \\ &amp;= - \frac{4}{3}\frac{\pi\rho G}{R}(a^3 - b^3). \label{eqn:spherical_shell_outside_1}\tag{17} \end{align*}\]<p>구면 껍질의 질량 $M$은</p>\[M = \frac{4}{3}\pi\rho(a^3 - b^3) \label{eqn:mass_of_shell}\tag{18}\]<p>으로 주어지므로, 퍼텐셜은 다음과 같다.</p>\[\boxed{\Phi(R&gt;a) = -\frac{GM}{R}} \label{eqn:spherical_shell_outside_2}\tag{19}\]<blockquote class="prompt-info"><p>질량이 $M$인 질점에 의한 중력 퍼텐셜 식 ($\ref{eqn:g_potential}$)과 방금 얻은 결과 ($\ref{eqn:spherical_shell_outside_2}$)를 비교해 보면 동일함을 알 수 있다. 이는 곧, 물질의 구대칭 분포(spherical symmetric distribution)에 의한 외부의 어떤 점에서의 중력 퍼텐셜을 구할 때, 모든 질량이 중심에 집중되어 있다고 생각해도 무방하다는 의미이다. 지구나 달과 같은 일정 크기 이상의 구형 천체 대부분이 이에 해당하는데, 이들은 <a href="https://en.wikipedia.org/wiki/Matryoshka_doll">마트료시카</a>처럼 중심이 같고 서로 다른 직경을 갖는 무수히 많은 구면 껍질들이 겹쳐져 있는 것으로 간주할 수 있다. 이는 이 글의 첫 부분에서 언급한 <a href="#뉴턴의-만유인력-법칙">지구나 달과 같은 천체들을 크기를 갖지 않는 질점으로 가정하고 계산해도 타당한 근거</a>가 된다.</p></blockquote><h3 id="rb일-때">$R&lt;b$일 때</h3>\[\begin{align*} \Phi(R&lt;b) &amp;= -\frac{2\pi\rho G}{R} \int_b^a r^\prime dr^\prime \int_{r^\prime - R}^{r^\prime + R}dr \\ &amp;= -4\pi\rho G \int_b^a r^\prime dr^\prime \\ &amp;= -2\pi\rho G(a^2 - b^2). \label{eqn:spherical_shell_inside}\tag{20} \end{align*}\]<blockquote class="prompt-info"><p>구대칭인 질량 껍질 안에서 중력 퍼텐셜은 위치와 무관하게 일정하며, 작용하는 중력은 $0$이다.</p></blockquote><blockquote class="prompt-tip"><p>그리고 이는 대표적인 유사과학 중 하나인 ‘지구공동설’이 헛소리인 주요 근거이기도 하다. 지구공동설에서 주장하는 것과 같이 지구가 구면 껍질 형태이고 내부가 비어 있다면, 해당 공동 내부에 있는 모든 물체에 대해 지구 중력이 작용하지 않는다. 지구의 질량과 부피를 생각해 보면 지구공동이 있을 수도 없거니와, 설령 있다 한들 그곳의 생명체는 구면 껍질 안쪽을 땅바닥 삼아 생활하는 게 아니라 우주정거장과 같이 무중량 상태로 떠다닐 것이다.<br /> <a href="https://youtu.be/VD6xJq8NguY?si=szgtuLkuk6rPJag3">지하 수 km 정도의 지층 깊숙한 곳에 미생물들이 살고 있을 수는 있지만</a>, 적어도 지구공동설에서 주장하는 것과 같은 형태로는 불가능하다. 쥘 베른의 소설 《지구 속 여행(Voyage au centre de la Terre)》과 영화 ‘잃어버린 세계를 찾아서(Journey to the Center of the Earth)’는 나도 참 좋아하지만, 창작물은 창작물로 즐겨야지 그걸 진지하게 믿진 말자.</p></blockquote><h3 id="bra일-때">$b&lt;R&lt;a$일 때</h3>\[\begin{align*} \Phi(b&lt;R&lt;a) &amp;= -\frac{4\pi\rho G}{3R}(R^3 - b^3) - 2\pi\rho G(a^2 - R^2) \\ &amp;= -4\pi\rho G \left( \frac{a^2}{2} - \frac{b^3}{3R} - \frac{R^2}{6} \right) \label{eqn:within_spherical_shell}\tag{21} \end{align*}\]<h3 id="결과">결과</h3><p>앞서 구한 세 영역에서의 중력 퍼텐셜 $\Phi$, 그리고 그에 따른 중력장 벡터의 크기 $|\mathbf{g}|$를 거리 $R$의 함수로서 그래프로 나타내면 다음과 같다.</p><p><img src="/physics-visualizations/figs/shell-theorem-gravitational-potential.png" alt="Gravitational Potential as a Function of R" /><br /> <img src="/physics-visualizations/figs/shell-theorem-field-vector.png" alt="Magnitude of the Field Vector as a Function of R" /></p><blockquote><ul><li>Python 시각화 코드: <a href="https://github.com/yunseo-kim/physics-visualizations/blob/main/src/shell_theorem.py">yunseo-kim/physics-visualizations 리포지터리</a><li>라이선스: <a href="https://github.com/yunseo-kim/physics-visualizations?tab=readme-ov-file#license">See here</a></ul></blockquote><p>중력 퍼텐셜과 중력장 벡터의 크기는 연속적임을 알 수 있다. 만약 중력 퍼텐셜이 어떤 점에서 불연속이면 그 점에서 퍼텐셜의 기울기, 즉 중력의 크기가 무한대가 되는데, 이는 물리적으로 타당하지 않으므로 퍼텐셜 함수는 모든 점에서 연속이어야 한다. 그러나 중력장 벡터의 <em>미분계수</em>는 껍질의 안쪽 면과 바깥쪽 면에서 불연속이다.</p><h2 id="예제-은하-회전-곡선">예제: 은하 회전 곡선</h2><p>천문학적 관측에 따르면, 우리은하나 안드로메다 은하와 같이 중심에 대해 회전하는 많은 나선형 은하 속 관측 가능한 질량들은 대부분이 중심부 근처에 집중적으로 분포한다. 그러나 이러한 나선형 은하 속 질량들의 궤도 속력은, 다음 그래프에서 확인할 수 있듯 관측 가능한 질량 분포로부터 이론적으로 예측한 값과 크게 불일치하며 일정 거리 이상에서는 거의 일정하다.</p><p><img src="https://upload.wikimedia.org/wikipedia/commons/b/b9/GalacticRotation2.svg" alt="Galactic Rotation" width="972" /></p><blockquote><p><em>이미지 출처</em></p><ul><li>저작자: 위키피디아 유저 <a href="https://en.wikipedia.org/wiki/User:PhilHibbs">PhilHibbs</a><li>라이선스: Public Domain</ul></blockquote><p> <video class="embed-video file" controls="" autoplay="" loop=""> <source src="https://cdn.jsdelivr.net/gh/yunseo-kim/yunseo-kim.github.io/assets/video/gravitational-field-and-potential/Galaxy_rotation_under_the_influence_of_dark_matter.webm" type="video/webm" /> <source src="https://cdn.jsdelivr.net/gh/yunseo-kim/yunseo-kim.github.io/assets/video/gravitational-field-and-potential/Galaxy_rotation_under_the_influence_of_dark_matter.ogg" type="video/ogg" /> Your browser does not support the video tag. Here is a <a href="https://cdn.jsdelivr.net/gh/yunseo-kim/yunseo-kim.github.io/assets/video/gravitational-field-and-potential/Galaxy_rotation_under_the_influence_of_dark_matter.webm">link to the video file</a> instead. </video> <em>좌: 관측 가능 질량으로부터 예측한 은하 회전 | 우: 실제 관측한 은하 회전.</em></p><blockquote><p><em>영상 출처</em></p><ul><li>원본 파일(Ogg Theora video) 링크: <a href="https://commons.wikimedia.org/wiki/File:Galaxy_rotation_under_the_influence_of_dark_matter.ogv">https://commons.wikimedia.org/wiki/File:Galaxy_rotation_under_the_influence_of_dark_matter.ogv</a><li>저작자: <a href="https://beltoforion.de/en/index.php">Ingo Berg</a><li>라이선스: <a href="https://creativecommons.org/licenses/by-sa/3.0/deed.en">CC BY-SA 3.0</a><li>사용된 시뮬레이션 방법 및 코드: <a href="https://beltoforion.de/en/spiral_galaxy_renderer/">https://beltoforion.de/en/spiral_galaxy_renderer/</a></ul></blockquote><blockquote class="prompt-danger"><p>기존에 이 페이지에 삽입하였던 <code class="language-plaintext highlighter-rouge">Rotation curve of spiral galaxy Messier 33 (Triangulum).png</code> 이미지 파일은 <a href="https://markwhittle.uvacreate.virginia.edu/">버지니아 대학교 Mark Whittle 교수</a>의 비자유 저작물을 위키미디어 유저 <a href="https://commons.wikimedia.org/wiki/User:Accrama">Mario De Leo</a>가 <a href="https://commons.wikimedia.org/wiki/Commons:Deletion_requests/File:Rotation_curve_of_spiral_galaxy_Messier_33_(Triangulum).png">적절한 인용 없이 표절한 파생 저작물인 것으로 판명됨에 따라 위키미디어 공용에서 삭제되었으며</a>, 이에 본 페이지에서도 삭제하였음을 밝힘.</p></blockquote><p>은하의 질량이 중심부에 집중되어 있을 경우의 거리에 따른 궤도 속력을 예측하여 해당 예측값은 이러한 관측 결과와 일치하지 않음을 확인하고, 은하 중심으로부터 거리 $R$ 이내에 분포하는 질량 $M(R)$이 $R$에 비례하여야 관측 결과를 설명할 수 있음을 보이자.</p><p>우선 은하 질량 $M$이 중심부에 집중되어 있을 경우, 거리 $R$에서의 궤도 속력을 구하면 다음과 같다.</p>\[\frac{GMm}{R^2} = \frac{mv^2}{R}\] \[v = \sqrt{\frac{GM}{R}} \propto \frac{1}{\sqrt{R}}.\]<p>이 경우 위의 두 그래프에 표시된 점선과 같이 $1/\sqrt{R}$로 감소하는 궤도 속력이 예측되나, 관측 결과에 따르면 궤도 속력 $v$는 거리 $R$과 무관하게 거의 일정하므로 예측과 관측 결과가 일치하지 않는다. 이러한 관측 결과는 $M(R)\propto R$이어야만 설명할 수 있다.</p><p>비례 상수 $k$를 써서 $M(R) = kR$로 놓으면,</p>\[v = \sqrt{\frac{GM(R)}{R}} = \sqrt{Gk}\ \text{(상수)}.\]<p>이로부터 천체물리학자들은, 많은 은하에는 발견되지 않은 ‘암흑 물질(dark matter)’이 반드시 있고, 이러한 암흑 물질이 우주 질량의 90% 이상을 차지해야 한다는 결론을 내린다. 다만 암흑 물질의 정체는 아직까지 명확히 밝혀지지 않았으며, 주류 이론은 아니지만 암흑 물질의 존재를 가정하지 않고 관측 결과를 설명하려는 수정 뉴턴 역학(Modified Newtonian Dynamics, MOND) 같은 시도도 존재한다. 오늘날 이러한 연구 분야는 천체물리학의 최전선에 맞닿아 있다.</p>]]> </content> </entry> <entry><title xml:lang="ko">미정계수법</title><link href="https://www.yunseo.kim/ko/posts/method-of-undetermined-coefficients/" rel="alternate" type="text/html" hreflang="en" /><link href="https://www.yunseo.kim/ko/posts/method-of-undetermined-coefficients/" rel="alternate" type="text/html" hreflang="ko" /><link href="https://www.yunseo.kim/ja/posts/method-of-undetermined-coefficients/" rel="alternate" type="text/html" hreflang="ja" /><link href="https://www.yunseo.kim/zh-TW/posts/method-of-undetermined-coefficients/" rel="alternate" type="text/html" hreflang="zh-TW" /><link href="https://www.yunseo.kim/es/posts/method-of-undetermined-coefficients/" rel="alternate" type="text/html" hreflang="es" /><link href="https://www.yunseo.kim/pt-BR/posts/method-of-undetermined-coefficients/" rel="alternate" type="text/html" hreflang="pt-BR" /><link href="https://www.yunseo.kim/fr/posts/method-of-undetermined-coefficients/" rel="alternate" type="text/html" hreflang="fr" /><link href="https://www.yunseo.kim/de/posts/method-of-undetermined-coefficients/" rel="alternate" type="text/html" hreflang="de" /><link href="https://www.yunseo.kim/pl/posts/method-of-undetermined-coefficients/" rel="alternate" type="text/html" hreflang="pl" /><link href="https://www.yunseo.kim/cs/posts/method-of-undetermined-coefficients/" rel="alternate" type="text/html" hreflang="cs" /><link href="https://www.yunseo.kim/sw/posts/method-of-undetermined-coefficients/" rel="alternate" type="text/html" hreflang="sw" /><link href="https://www.yunseo.kim/am/posts/method-of-undetermined-coefficients/" rel="alternate" type="text/html" hreflang="am" /><published>2025-04-20T00:00:00+09:00</published> <updated>2025-07-09T19:24:14+09:00</updated> <id>https://www.yunseo.kim/ko/posts/method-of-undetermined-coefficients/</id> <author> <name>Yunseo Kim</name> </author> <category term="Mathematics" /> <category term="Differential Equation" /> <summary xml:lang="ko">특정한 형태의 상수계수 비동차 선형 상미분방정식에 대한 초기값 문제를 간단하게 풀 수 있어, 공학에서 진동계, RLC 전기회로 모델 등에 대해 유용하게 자주 사용하는 해법인 미정계수법을 알아보자.</summary> <content type="html" xml:lang="ko"> <![CDATA[<p>특정한 형태의 상수계수 비동차 선형 상미분방정식에 대한 초기값 문제를 간단하게 풀 수 있어, 공학에서 진동계, RLC 전기회로 모델 등에 대해 유용하게 자주 사용하는 해법인 미정계수법을 알아보자.</p><em><p>* Mathematical equations and diagrams included in posts may not display properly when viewed with a feed reader.</p></em><h2 id="tldr">TL;DR</h2><blockquote class="prompt-info"><ul><li><strong>미정계수법</strong>의 적용 대상:<ul><li><strong>상수 계수 $a$와 $b$</strong>를 갖고<li>입력 $r(x)$가 지수함수, $x$의 거듭제곱, $\cos$ 또는 $\sin$, 또는 이와 같은 함수들의 합과 곱으로 이루어진<li>선형 상미분방정식 $y^{\prime\prime} + ay^{\prime} + by = r(x)$</ul><li><strong>미정계수법에 대한 선택 규칙</strong><ul><li><strong>(a) 기본규칙(basic rule)</strong>: 식 ($\ref{eqn:linear_ode_with_constant_coefficients}$)에서 $r(x)$가 표의 첫 번째 열에 있는 함수들 중 하나라면 같은 행의 $y_p$를 선택하고, $y_p$와 그 도함수들을 식 ($\ref{eqn:linear_ode_with_constant_coefficients}$)에 대입함으로써 미정계수를 결정한다.<li><strong>(b) 변형규칙(modification rule)</strong>: $y_p$로 선택한 항이 식 ($\ref{eqn:linear_ode_with_constant_coefficients}$)에 대응하는 동차 상미분방정식 $y^{\prime\prime} + ay^{\prime} + by = 0$의 해가 된다면, 이 항에 $x$(또는 만약 이 해가 동차 상미분방정식의 특성방정식의 이중근에 해당한다면 $x^2$)를 곱한다.<li><strong>(c) 합규칙(sum rule)</strong>: $r(x)$가 표의 첫 번째 열에 있는 함수들의 합이라면, 두 번째 열의 대응하는 행에 있는 함수들의 합을 $y_p$로 선택한다.</ul></ul><table><thead><tr><th style="text-align: left">$r(x)$의 항<th style="text-align: left">$y_p(x)$에 대한 선택<tbody><tr><td style="text-align: left">$ke^{\gamma x}$<td style="text-align: left">$Ce^{\gamma x}$<tr><td style="text-align: left">$kx^n\ (n=0,1,\cdots)$<td style="text-align: left">$K_nx^n + K_{n-1}x^{n-1} + \cdots + K_1x + K_0$<tr><td style="text-align: left">$k\cos{\omega x}$<br />$k\sin{\omega x}$<td style="text-align: left">$K\cos{\omega x} + M\sin{\omega x}$<tr><td style="text-align: left">$ke^{\alpha x}\cos{\omega x}$<br />$ke^{\alpha x}\sin{\omega x}$<td style="text-align: left">$e^{\alpha x}(K\cos{\omega x} + M\sin{\omega x})$</table></blockquote><h2 id="prerequisites">Prerequisites</h2><ul><li><a href="/ko/posts/homogeneous-linear-odes-of-second-order/">2계 동차 선형 상미분방정식 (Homogeneous Linear ODEs of Second Order)</a><li><a href="/ko/posts/homogeneous-linear-odes-with-constant-coefficients/">상수계수를 갖는 2계 동차 선형 상미분방정식</a><li><a href="/ko/posts/euler-cauchy-equation/">오일러-코시 방정식</a><li><a href="/ko/posts/wronskian-existence-and-uniqueness-of-solutions/">브론스키언(Wronskian), 해의 존재와 유일성</a><li><a href="/ko/posts/nonhomogeneous-linear-odes-of-second-order/">2계 비동차 선형 상미분방정식 (Nonhomogeneous Linear ODEs of Second Order)</a><li>벡터공간, 선형생성(선형대수학)</ul><h2 id="미정계수법">미정계수법</h2><p>$r(x) \not\equiv 0$인 2계 비동차 선형 상미분방정식</p>\[y^{\prime\prime} + p(x)y^{\prime} + q(x)y = r(x) \label{eqn:nonhomogeneous_linear_ode}\tag{1}\]<p>와 이 비동차 상미분방정식에 대응하는 동차 상미분방정식</p>\[y^{\prime\prime} + p(x)y^{\prime} + q(x)y = 0 \label{eqn:homogeneous_linear_ode}\tag{2}\]<p>을 생각하자.</p><p>앞서 <a href="/ko/posts/nonhomogeneous-linear-odes-of-second-order/">2계 비동차 선형 상미분방정식 (Nonhomogeneous Linear ODEs of Second Order)</a>에서 살펴본 바에 따르면, 비동차 선형 상미분방정식 ($\ref{eqn:nonhomogeneous_linear_ode}$)에 대한 초기값 문제를 풀기 위해서는 동차 상미분방정식 ($\ref{eqn:homogeneous_linear_ode}$)를 풀어 $y_h$를 구한 후 방정식 ($\ref{eqn:nonhomogeneous_linear_ode}$)의 한 해 $y_p$를 찾아서 일반해</p>\[y(x) = y_h(x) + y_p(x) \label{eqn:general_sol}\tag{3}\]<p>를 얻어야 한다. 그렇다면 $y_p$는 어떻게 찾을 수 있는가? $y_p$를 찾는 일반적인 방법은 <strong>매개변수변환법(method of variation of parameters)</strong>이지만, 경우에 따라선 그보다 훨씬 간단한 <strong>미정계수법(method of undetermined coefficients)</strong>을 적용할 수 있다. 특히, 진동계와 RLC 전기회로 모델에 적용할 수 있어 공학에서 자주 사용하는 방법이다.</p><p>미정계수법은 <strong>상수 계수 $a$와 $b$</strong>를 갖고, 입력 $r(x)$가 지수함수, $x$의 거듭제곱, $\cos$ 또는 $\sin$, 또는 이와 같은 함수들의 합과 곱으로 이루어진 선형 상미분방정식</p>\[y^{\prime\prime} + ay^{\prime} + by = r(x) \label{eqn:linear_ode_with_constant_coefficients}\tag{4}\]<p>에 적합하다. 이와 같은 형태의 $r(x)$는 자기 자신과 유사한 형태의 도함수들을 갖는다는 점이 미정계수법의 핵심이다. 미정계수법을 적용하기 위해서는 $r(x)$와 유사한 형태이되, 자기 자신과 그 도함수들을 주어진 상미분방정식에 대입함으로써 결정되는 미지의 계수를 갖는 $y_p$를 선택한다. 공학에서 실용적으로 중요한 형태의 $r(x)$에 대하여 적절한 $y_p$를 선택하기 위한 규칙은 다음과 같다.</p><blockquote class="prompt-info"><p><strong>미정계수법에 대한 선택 규칙</strong><br /> <strong>(a) 기본규칙(basic rule)</strong>: 식 ($\ref{eqn:linear_ode_with_constant_coefficients}$)에서 $r(x)$가 표의 첫 번째 열에 있는 함수들 중 하나라면 같은 행의 $y_p$를 선택하고, $y_p$와 그 도함수들을 식 ($\ref{eqn:linear_ode_with_constant_coefficients}$)에 대입함으로써 미정계수를 결정한다.<br /> <strong>(b) 변형규칙(modification rule)</strong>: $y_p$로 선택한 항이 식 ($\ref{eqn:linear_ode_with_constant_coefficients}$)에 대응하는 동차 상미분방정식 $y^{\prime\prime} + ay^{\prime} + by = 0$의 해가 된다면, 이 항에 $x$(또는 만약 이 해가 동차 상미분방정식의 특성방정식의 이중근에 해당한다면 $x^2$)를 곱한다.<br /> <strong>(c) 합규칙(sum rule)</strong>: $r(x)$가 표의 첫 번째 열에 있는 함수들의 합이라면, 두 번째 열의 대응하는 행에 있는 함수들의 합을 $y_p$로 선택한다.</p><table><thead><tr><th style="text-align: left">$r(x)$의 항<th style="text-align: left">$y_p(x)$에 대한 선택<tbody><tr><td style="text-align: left">$ke^{\gamma x}$<td style="text-align: left">$Ce^{\gamma x}$<tr><td style="text-align: left">$kx^n\ (n=0,1,\cdots)$<td style="text-align: left">$K_nx^n + K_{n-1}x^{n-1} + \cdots + K_1x + K_0$<tr><td style="text-align: left">$k\cos{\omega x}$<br />$k\sin{\omega x}$<td style="text-align: left">$K\cos{\omega x} + M\sin{\omega x}$<tr><td style="text-align: left">$ke^{\alpha x}\cos{\omega x}$<br />$ke^{\alpha x}\sin{\omega x}$<td style="text-align: left">$e^{\alpha x}(K\cos{\omega x} + M\sin{\omega x})$</table></blockquote><p>이 방법은 간편할 뿐만 아니라 자기교정성을 지닌다는 장점이 있다. $y_p$를 잘못 선택하거나 너무 적은 수의 항들을 선택하면 모순에 이르게 되며, 너무 많은 항을 선택할 경우 불필요한 항들의 계수는 $0$이 되어 옳은 결과를 얻는다. 미정계수법을 적용했다가 뭔가가 잘못되더라도 풀이 과정에서 자연스럽게 알아차리게 되므로, 위의 선택 규칙에 따라 어느 정도 적당한 $y_p$를 선택했다면 부담 없이 시도해 볼 수 있다.</p><h3 id="합규칙의-증명">합규칙의 증명</h3><p>$r(x) = r_1(x) + r_2(x)$ 꼴인 비동차 선형 상미분방정식</p>\[y^{\prime\prime} + ay^{\prime} + by = r_1(x) + r_2(x)\]<p>를 생각하자. 이제 동일한 좌변에 입력으로는 $r_1$, $r_2$를 갖는 다음의 두 방정식</p>\[\begin{gather*} y^{\prime\prime} + ay^{\prime} + by = r_1(x) \\ y^{\prime\prime} + ay^{\prime} + by = r_2(x) \end{gather*}\]<p>가 각각 ${y_p}_1$, ${y_p}_2$를 해로 가진다고 하자. 주어진 방정식의 좌변을 $L[y]$로 표기하면, $L[y]$의 선형성에 의해 $y_p = {y_p}_1 + {y_p}_2$에 대해 다음을 만족하므로 합규칙이 성립한다.</p>\[L[y_p] = L[{y_p}_1 + {y_p}_2] = L[{y_p}_1] + L[{y_p}_2] = r_1 + r_2 = r. \ \blacksquare\]<h2 id="예제-yprimeprime--ayprime--by--kegamma-x">예제: $y^{\prime\prime} + ay^{\prime} + by = ke^{\gamma x}$</h2><p>기본규칙 (a)에 따라 $y_p = Ce^{\gamma x}$으로 놓고 주어진 방정식 $y^{\prime\prime} + ay^{\prime} + by = ke^{\gamma x}$에 대입하면</p>\[\gamma^2 Ce^{\gamma x} + \gamma aCe^{\gamma x} + bCe^{\gamma x} = ke^{\gamma x}\] \[C(\gamma^2 + a\gamma + b)e^{\gamma x} = ke^{\gamma x}\] \[C(\gamma^2 + a\gamma + b) = k.\]<h3 id="gamma2--agamma--b-neq-0인-경우">$\gamma^2 + a\gamma + b \neq 0$인 경우</h3><p>다음과 같이 미정계수 $C$를 결정하고 $y_p$를 구할 수 있다.</p>\[C = \frac{k}{\gamma^2 + a\gamma + b}\] \[y_p = Ce^{\gamma x} = \frac{k}{\gamma^2 + a\gamma + b} e^{\gamma x}.\]<h3 id="gamma2--agamma--b--0인-경우">$\gamma^2 + a\gamma + b = 0$인 경우</h3><p>이 경우 변형규칙 (b)를 적용해야 한다. 우선 $b = -\gamma^2 - a\gamma = -\gamma(a + \gamma)$임을 이용하여 동차 상미분방정식 $y^{\prime\prime} + ay^{\prime} + by = 0$의 특성방정식의 근을 구하자.</p>\[y^{\prime\prime} + ay^{\prime} - \gamma(a + \gamma)y = 0\] \[\lambda^2 + a\lambda - \gamma(a + \gamma) = 0\] \[(\lambda + (a + \gamma))(\lambda - \gamma) = 0\] \[\lambda = \gamma, -a -\gamma.\]<p>이로부터 동차 상미분방정식의 기저</p>\[y_1 = e^{\gamma x}, \quad y_2 = e^{(-a - \gamma)x}\]<p>을 얻는다.</p><h4 id="gamma-neq--a-gamma인-경우">$\gamma \neq -a-\gamma$인 경우</h4><p>$y_p$로 선택했던 $Ce^{\gamma x}$이 주어진 방정식에 대응하는 동차 상미분방정식의 이중근이 아닌 해이므로, 변형규칙 (b)에 따라 이 항에 $x$를 곱하여 $y_p = Cxe^{\gamma x}$으로 놓는다.</p><p>이제 변형한 $y_p$를 다시 주어진 방정식 $y^{\prime\prime} + ay^{\prime} - \gamma(a + \gamma)y = ke^{\gamma x}$에 대입하면</p>\[C(2\gamma + \gamma^2 x)e^{\gamma x} + aC(1 + \gamma x)e^{\gamma x} - \gamma(a + \gamma)Cxe^{\gamma x} = ke^{\gamma x}\] \[C \left[\left\{\gamma^2 + a\gamma -\gamma(a + \gamma)\right\}x + 2\gamma + a \right]e^{\gamma x} = ke^{\gamma x}\] \[C(2\gamma + a)e^{\gamma x} = ke^{\gamma x}\] \[C(2\gamma + a) = k\] \[\therefore C = \frac{k}{2\gamma + a}, \quad y_p = Cxe^{\gamma x} = \frac{k}{2\gamma + a}xe^{\gamma x}.\]<h4 id="gamma---a-gamma인-경우">$\gamma = -a-\gamma$인 경우</h4><p>이 경우 $y_p$로 선택했던 $Ce^{\gamma x}$이 주어진 방정식에 대응하는 동차 상미분방정식의 이중근이므로, 변형규칙 (b)에 따라 이 항에 $x^2$을 곱하여 $y_p = Cx^2 e^{\gamma x}$으로 놓는다.</p><p>이제 변형한 $y_p$를 다시 주어진 방정식 $y^{\prime\prime} - 2\gamma y^{\prime} + \gamma^2 y = ke^{\gamma x}$에 대입하면</p>\[C(2 + 4\gamma x + \gamma^2 x^2)e^{\gamma x} + C(-4\gamma x - 2\gamma^2 x^2)e^{\gamma x} + C(\gamma^2 x^2)e^{\gamma x} = ke^{\gamma x}\] \[2Ce^{\gamma x} = ke^{\gamma x}\] \[2C = k\] \[\therefore C = \frac{k}{2}, \quad y_p = Cx^2 e^{\gamma x} = \frac{k}{2}x^2 e^{\gamma x}.\]<h2 id="미정계수법의-확장-함수들의-곱-형태인-rx">미정계수법의 확장: 함수들의 곱 형태인 $r(x)$</h2><p>$r(x) = k x^n e^{\alpha x}\cos(\omega x)$ 꼴인 비동차 선형 상미분방정식</p>\[y^{\prime\prime} + ay^{\prime} + by = C x^n e^{\alpha x}\cos(\omega x)\]<p>를 생각하자. $r(x)$를 이와 같이 지수함수 $e^{\alpha x}$, $x$의 거듭제곱 $x^m$, $\cos{\omega x}$ 또는 $\sin{\omega x}$(여기서는 $\cos$이라 가정하며, 이렇게 해도 일반성을 잃지 않는다), 또는 이와 같은 함수들의 합과 곱이라고 하면(즉, 앞선 표의 첫 번째 열에 있는 함수들의 합과 곱으로 표현할 수 있다고 하면), 동일한 표의 두 번째 열에 있는 함수들의 합과 곱인 방정식의 해 $y_p$가 존재함을 보일 것이다.</p><blockquote class="prompt-tip"><p>엄밀한 증명을 위해 선형대수학을 사용하여 기술한 부분이 있는데, 그러한 부분은 *로 표시하였다. 해당 부분을 건너뛰고 나머지 부분만 읽어도 개략적인 이해에는 문제가 없다.</p></blockquote><h3 id="벡터공간-v-정의">벡터공간 $V$ 정의*</h3><p>\(\begin{align*} r(x) &amp;= C_1x^{n_1}e^{\alpha_1 x} \times C_2x^{n_2}e^{\alpha_2 x}\cos(\omega x) \times \cdots \\ &amp;= C x^n e^{\alpha x}\cos(\omega x) \end{align*}\)</p><p>인 $r(x)$에 대하여, $r(x) \in V$인 벡터공간 $V$를 다음과 같이 잡을 수 있다.</p>\[V = \mathrm{span}\left\{x^k e^{\alpha x}\cos(\omega x), \; x^k e^{\alpha x}\sin(\omega x) \bigm| k=0,1,\dots,n \right\}\]<h3 id="지수함수-다항함수-삼각함수의-도함수-형태">지수함수, 다항함수, 삼각함수의 도함수 형태</h3><p>앞선 표의 첫 열로 제시된 기본 함수들의 도함수 형태는 다음과 같다.</p><ul><li>지수함수: $\cfrac{d}{dx}e^{\alpha x} = \alpha e^{\alpha x}$<li>다항함수: $\cfrac{d}{dx}x^m = mx^{m-1}$<li>삼각함수: $\cfrac{d}{dx}\cos\omega x = -\omega\sin\omega x, \quad \cfrac{d}{dx}\sin\omega x = \omega\cos\omega x$</ul><p>이들 함수들을 미분하여 얻는 도함수 역시 <u>같은 종류의 함수들의 합</u>으로 표현된다.</p><p>따라서, 함수 $f$와 $g$가 위의 함수들 또는 이들의 합이라고 할 때, $r(x) = f(x)g(x)$에 대해 곱의 미분법을 적용하면</p>\[\begin{align*} (fg)^{\prime} &amp;= f^{\prime}g + fg^{\prime}, \\ (fg)^{\prime\prime} &amp;= f^{\prime\prime}g + 2f^{\prime}g^{\prime} + fg^{\prime\prime} \end{align*}\]<p>이고 여기서 $f$, $f^{\prime}$, $f^{\prime\prime}$과 $g$, $g^{\prime}$, $g^{\prime\prime}$은 모두 지수함수, 다항함수, 삼각함수의 합 또는 상수배 형태로 쓸 수 있다. 따라서 $r^{\prime}(x) = (fg)^{\prime}$, $r^{\prime\prime}(x) = (fg)^{\prime\prime}$ 역시 $r(x)$와 마찬가지로 이들 함수의 합과 곱으로 표현할 수 있다.</p><h3 id="v의-미분-연산-d-선형-변환-l에-대한-불변">$V$의 미분 연산 $D$, 선형 변환 $L$에 대한 불변*</h3><p>즉, $r(x)$ 자기 자신뿐만 아니라 $r^{\prime}(x)$, $r^{\prime\prime}(x)$ 역시 $x^k e^{\alpha x}\cos(\omega x)$꼴 항들과 $x^k e^{\alpha x}\sin(\omega x)$꼴 항들의 선형 결합이므로</p>\[r(x) \in V \implies r^{\prime}(x) \in V,\ r^{\prime\prime}(x) \in V.\]<p>$r(x)$로 한정하지 않고 앞서 정의한 벡터공간 $V$의 모든 원소에 대해 미분 연산자 $D$를 도입하여 보다 일반적으로 표현하면, <em>벡터공간 $V$는 미분 연산 $D$에 대해 닫혀 있다</em>. 따라서 주어진 방정식의 좌변 $y^{\prime\prime} + ay^{\prime} + by$를 $L[y]$로 표기하면, <em>$V$는 $L$에 대해 불변(invariant)이다</em>.</p>\[D^2(V)\subseteq V,\quad aD(V)\subseteq V,\quad b\,V\subseteq V \implies L(V)\subseteq V.\]<p>$r(x) \in V$이고 $V$가 $L$에 대해 불변이므로, $L[y_p] = r$을 만족하는 $V$의 또다른 원소 $y_p$가 존재한다.</p>\[\exists y_p \in V: L[y_p] = r\]<h3 id="ansatz">Ansatz</h3><p>따라서, 모든 가능한 곱꼴 항들의 합이 되도록 적절한 $y_p$를 미정계수 $A_0, A_1, \dots, A_n$과 $K$, $M$을 이용하여 다음과 같이 선택하면, 기본규칙 (a)와 변형규칙 (b)에 따라 $y_p$(또는 $xy_p$, $x^2y_p$)와 그 도함수들을 주어진 방정식에 대입함으로써 미정계수를 결정할 수 있다. 이때 $n$은 $r(x)$의 $x$에 대한 차수에 따라 결정하면 된다.</p>\[y_p = e^{\alpha x}(A_nx^n + A_{n-1}x^{n-1} + \cdots + A_1x + A_0)(K\cos{\omega x} + M \sin{\omega x}).\]<p>$\blacksquare$</p><blockquote class="prompt-warning"><p>만약 주어진 입력 $r(x)$가 서로 다른 여러 $\alpha_i$, $\omega_j$ 값들을 포함한다면, 각 $\alpha_i$와 $\omega_j$ 값에 대해서도 가능한 모든 $x^{k}e^{\alpha_i x}\cos(\omega_j x)$, $x^{k}e^{\alpha_i x}\sin(\omega_j x)$꼴 항들을 빠짐없이 포함할 수 있게 $y_p$를 선택해야 한다.<br /> 미정계수법의 장점은 간편하다는 것이므로, 가설 풀이(ansatz)가 너무 복잡해져서 이러한 장점이 퇴색되는 경우라면 차라리 추후 다룰 매개변수변환법을 적용하는 게 더 나을 수 있다.</p></blockquote><h2 id="미정계수법의-확장-오일러-코시-방정식">미정계수법의 확장: 오일러-코시 방정식</h2><p><a href="/ko/posts/homogeneous-linear-odes-with-constant-coefficients/">상수계수를 갖는 2계 동차 선형 상미분방정식</a>뿐만 아니라, <a href="/ko/posts/euler-cauchy-equation/">오일러-코시 방정식</a></p>\[x^2y^{\prime\prime} + axy^{\prime} + by = r(x) \label{eqn:euler_cauchy}\tag{5}\]<p>에 대해서도 미정계수법을 활용할 수 있다.</p><h3 id="변수-치환">변수 치환</h3><p><a href="/ko/posts/euler-cauchy-equation/#상수계수를-갖는-2계-동차-선형-상미분방정식으로의-변환">$x = e^t$로 치환하여 상수계수를 갖는 2계 동차 선형 상미분방정식으로 변환</a>하면</p>\[\frac{d}{dx} = \frac{1}{x}\frac{d}{dt}, \quad \frac{d^2}{dx^2} = \frac{1}{x^2}\left(\frac{d^2}{dt^2} - \frac{d}{dt} \right)\]<p>이 되어, 오일러-코시 방정식을 다음과 같이 $t$에 대한 상수계수 동차 선형 상미분방정식으로 바꿀 수 있음을 앞서 알아본 바 있다.</p>\[y^{\prime\prime} + (a-1)y^{\prime} + by = r(e^t). \label{eqn:substituted}\tag{6}\]<p>이제 식 ($\ref{eqn:substituted}$)에 대해 <a href="#미정계수법">앞서 살펴본 미정계수법</a>을 동일하게 적용하여 $t$에 대해 풀고, 마지막에 $t = \ln x$임을 이용하여 $x$에 대한 해를 구하면 된다.</p><h3 id="rx가-x의-거듭제곱-자연로그-또는-이와-같은-함수들의-합과-곱인-경우">$r(x)$가 $x$의 거듭제곱, 자연로그, 또는 이와 같은 함수들의 합과 곱인 경우</h3><p>특히 입력 $r(x)$가 $x$의 거듭제곱, 자연로그, 또는 이와 같은 함수들의 합과 곱으로 이루어진 경우, 다음의 오일러-코시 방정식용 선택 규칙에 따라 적절한 $y_p$를 곧바로 선택할 수 있다.</p><blockquote class="prompt-info"><p><strong>미정계수법에 대한 선택 규칙: 오일러-코시 방정식용</strong><br /> <strong>(a) 기본규칙(basic rule)</strong>: 식 ($\ref{eqn:euler_cauchy}$)에서 $r(x)$가 표의 첫 번째 열에 있는 함수들 중 하나라면 같은 행의 $y_p$를 선택하고, $y_p$와 그 도함수들을 식 ($\ref{eqn:euler_cauchy}$)에 대입함으로써 미정계수를 결정한다.<br /> <strong>(b) 변형규칙(modification rule)</strong>: $y_p$로 선택한 항이 식 ($\ref{eqn:euler_cauchy}$)에 대응하는 동차 상미분방정식 $x^2y^{\prime\prime} + axy^{\prime} + by = 0$의 해가 된다면, 이 항에 $\ln{x}$(또는 만약 이 해가 동차 상미분방정식의 특성방정식의 이중근에 해당한다면 $(\ln{x})^2$)를 곱한다.<br /> <strong>(c) 합규칙(sum rule)</strong>: $r(x)$가 표의 첫 번째 열에 있는 함수들의 합이라면, 두 번째 열의 대응하는 행에 있는 함수들의 합을 $y_p$로 선택한다.</p><table><thead><tr><th style="text-align: left">$r(x)$의 항<th style="text-align: left">$y_p(x)$에 대한 선택<tbody><tr><td style="text-align: left">$kx^m\ (m=0,1,\cdots)$<td style="text-align: left">$Ax^m$<tr><td style="text-align: left">$kx^m \ln{x}\ (m=0,1,\cdots)$<td style="text-align: left">$x^m(B\ln x + C)$<tr><td style="text-align: left">$k(\ln{x})^s\ (s=0,1,\cdots)$<td style="text-align: left">$D_0 + D_1\ln{x} + \cdots + D_{s-1}(\ln{x})^{s-1} + D_s(\ln{x})^s$<tr><td style="text-align: left">$kx^m (\ln{x})^s$<br />$(m=0,1,\cdots ;\; s=0,1,\cdots)$<td style="text-align: left">$x^m \left( D_0 + D_1\ln{x} + \cdots + D_{s-1}(\ln{x})^{s-1} + D_s(\ln{x})^s \right)$</table></blockquote><p>이렇게 하면 실용적으로 중요한 형태의 입력 $r(x)$에 대하여 <a href="#변수-치환">변수 치환</a>으로 얻는 것과 동일한 $y_p$를 보다 빠르고 간편하게 찾을 수 있다. 앞서 살펴본 <a href="#미정계수법">원래의 선택 규칙</a>에서 $x$ 자리에 $\ln{x}$를 대신 넣으면 이 오일러-코시 방정식용 선택 규칙을 유도할 수 있다.</p>]]> </content> </entry> <entry><title xml:lang="ko">2계 비동차 선형 상미분방정식 (Nonhomogeneous Linear ODEs of Second Order)</title><link href="https://www.yunseo.kim/ko/posts/nonhomogeneous-linear-odes-of-second-order/" rel="alternate" type="text/html" hreflang="en" /><link href="https://www.yunseo.kim/ko/posts/nonhomogeneous-linear-odes-of-second-order/" rel="alternate" type="text/html" hreflang="ko" /><link href="https://www.yunseo.kim/ja/posts/nonhomogeneous-linear-odes-of-second-order/" rel="alternate" type="text/html" hreflang="ja" /><link href="https://www.yunseo.kim/zh-TW/posts/nonhomogeneous-linear-odes-of-second-order/" rel="alternate" type="text/html" hreflang="zh-TW" /><link href="https://www.yunseo.kim/es/posts/nonhomogeneous-linear-odes-of-second-order/" rel="alternate" type="text/html" hreflang="es" /><link href="https://www.yunseo.kim/pt-BR/posts/nonhomogeneous-linear-odes-of-second-order/" rel="alternate" type="text/html" hreflang="pt-BR" /><link href="https://www.yunseo.kim/fr/posts/nonhomogeneous-linear-odes-of-second-order/" rel="alternate" type="text/html" hreflang="fr" /><link href="https://www.yunseo.kim/de/posts/nonhomogeneous-linear-odes-of-second-order/" rel="alternate" type="text/html" hreflang="de" /><link href="https://www.yunseo.kim/pl/posts/nonhomogeneous-linear-odes-of-second-order/" rel="alternate" type="text/html" hreflang="pl" /><link href="https://www.yunseo.kim/cs/posts/nonhomogeneous-linear-odes-of-second-order/" rel="alternate" type="text/html" hreflang="cs" /><link href="https://www.yunseo.kim/sw/posts/nonhomogeneous-linear-odes-of-second-order/" rel="alternate" type="text/html" hreflang="sw" /><link href="https://www.yunseo.kim/am/posts/nonhomogeneous-linear-odes-of-second-order/" rel="alternate" type="text/html" hreflang="am" /><published>2025-04-16T00:00:00+09:00</published> <updated>2025-07-09T19:24:14+09:00</updated> <id>https://www.yunseo.kim/ko/posts/nonhomogeneous-linear-odes-of-second-order/</id> <author> <name>Yunseo Kim</name> </author> <category term="Mathematics" /> <category term="Differential Equation" /> <summary xml:lang="ko">2계 비동차 선형 상미분방정식의 일반해의 형태를 대응하는 동차 선형 상미분방정식의 해와의 관계를 중심으로 살펴보고, 일반해의 존재와 특이해의 비존재를 보인다.</summary> <content type="html" xml:lang="ko"> <![CDATA[<p>2계 비동차 선형 상미분방정식의 일반해의 형태를 대응하는 동차 선형 상미분방정식의 해와의 관계를 중심으로 살펴보고, 일반해의 존재와 특이해의 비존재를 보인다.</p><em><p>* Mathematical equations and diagrams included in posts may not display properly when viewed with a feed reader.</p></em><h2 id="tldr">TL;DR</h2><blockquote class="prompt-info"><ul><li>2계 비동차 선형 상미분방정식 $y^{\prime\prime} + p(x)y^{\prime} + q(x)y = r(x)$의 <strong>일반해</strong>:<ul><li>$y(x) = y_h(x) + y_p(x)$<li>$y_h$: 동차 상미분방정식 $y^{\prime\prime} + p(x)y^{\prime} + q(x)y = 0$의 일반해 $y_h = c_1y_1 + c_2y_2$<li>$y_p$: 해당 비동차 상미분방정식의 특수해</ul><li>응답 항 $y_p$는 입력 $r(x)$에 의해서만 결정되며, 동일한 비동차 상미분방정식에 대해서는 초기조건이 달라져도 $y_p$는 달라지지 않음. 비동차 상미분방정식의 두 특수해의 차는 대응하는 동차 상미분방정식의 해가 됨.<li><strong>일반해의 존재</strong>: 비동차 상미분방정식의 계수 $p(x)$, $q(x)$와 입력 함수 $r(x)$가 연속이면 일반해가 항상 존재함<li><strong>특이해의 비존재</strong>: 일반해는 방정식의 모든 해를 포함함(즉, 특이해가 존재하지 않음)</ul></blockquote><h2 id="prerequisites">Prerequisites</h2><ul><li><a href="/ko/posts/homogeneous-linear-odes-of-second-order/">2계 동차 선형 상미분방정식 (Homogeneous Linear ODEs of Second Order)</a><li><a href="/ko/posts/wronskian-existence-and-uniqueness-of-solutions/">브론스키언(Wronskian), 해의 존재와 유일성</a></ul><h2 id="2계-비동차-선형-상미분방정식의-일반해와-특수해">2계 비동차 선형 상미분방정식의 일반해와 특수해</h2><p>2계 비동차 선형 상미분방정식</p>\[y^{\prime\prime} + p(x)y^{\prime} + q(x)y = r(x) \label{eqn:nonhomogeneous_linear_ode}\tag{1}\]<p>를 생각하자. 여기서 $r(x) \not\equiv 0$이다. 열린 구간 $I$에서 방정식 ($\ref{eqn:nonhomogeneous_linear_ode}$)의 <strong>일반해</strong>는 이 비동차 상미분방정식에 대응하는 동차 상미분방정식</p>\[y^{\prime\prime} + p(x)y^{\prime} + q(x)y = 0 \label{eqn:homogeneous_linear_ode}\tag{2}\]<p>의 일반해 $y_h = c_1y_1 + c_2y_2$와 식 ($\ref{eqn:nonhomogeneous_linear_ode}$)의 특수해 $y_p$의 합</p>\[y(x) = y_h(x) + y_p(x) \label{eqn:general_sol}\tag{3}\]<p>의 형태이다. 또한 구간 $I$에서 방정식 ($\ref{eqn:nonhomogeneous_linear_ode}$)의 <strong>특수해</strong>는 $y_h$의 임의의 상수 $c_1$과 $c_2$에 특정한 값을 지정하여 식 ($\ref{eqn:general_sol}$)으로부터 얻는 해이다.</p><p>즉, 동차 상미분방정식 ($\ref{eqn:homogeneous_linear_ode}$)에 독립변수 $x$에만 의존하는 입력 $r(x)$를 추가하면 그에 대응하는 항 $y_p$가 응답에 추가되며, 이 추가된 응답 항 $y_p$는 초기조건과 무관하게 오직 입력 $r(x)$에 의해 결정된다. 뒤에서 보겠지만 식 ($\ref{eqn:nonhomogeneous_linear_ode}$)의 임의의 두 해 $y_1$과 $y_2$의 차를 구하면(즉, 서로 다른 두 초기조건에 대한 각각의 특수해의 차를 구하면) 초기조건에 무관한 $y_p$ 부분은 지워져 ${y_h}_1$과 ${y_h}_2$의 차만 남으며, 이는 <a href="/ko/posts/homogeneous-linear-odes-of-second-order/#중첩의-원리">중첩의 원리</a>에 의해 식 ($\ref{eqn:homogeneous_linear_ode}$)의 해가 된다.</p><h2 id="비동차-상미분방정식의-해와-그에-대응하는-동차-상미분방정식의-해의-관계">비동차 상미분방정식의 해와, 그에 대응하는 동차 상미분방정식의 해의 관계</h2><blockquote class="prompt-info"><p><strong>정리 1: 비동차 상미분방정식 ($\ref{eqn:nonhomogeneous_linear_ode}$)의 해와 동차 상미분방정식 ($\ref{eqn:homogeneous_linear_ode}$)의 해의 관계</strong><br /> <strong>(a)</strong> 어떤 열린 구간 $I$에서 비동차 상미분방정식 ($\ref{eqn:nonhomogeneous_linear_ode}$)의 해 $y$와 동차 상미분방정식 ($\ref{eqn:homogeneous_linear_ode}$)의 해 $\tilde{y}$의 합은 구간 $I$에서 방정식 ($\ref{eqn:nonhomogeneous_linear_ode}$)의 해이다. 특히 식 ($\ref{eqn:general_sol}$)은 구간 $I$에서 방정식 ($\ref{eqn:nonhomogeneous_linear_ode}$)의 해이다.<br /> <strong>(b)</strong> 구간 $I$에서 비동차 상미분방정식 ($\ref{eqn:nonhomogeneous_linear_ode}$)의 두 해의 차는 구간 $I$에서 동차 상미분방정식 ($\ref{eqn:homogeneous_linear_ode}$)의 해이다.</p></blockquote><h3 id="증명">증명</h3><h4 id="a">(a)</h4><p>방정식 ($\ref{eqn:nonhomogeneous_linear_ode}$)과 ($\ref{eqn:homogeneous_linear_ode}$)의 좌변을 $L[y]$라고 표기하자. 그러면 구간 $I$에서 식 ($\ref{eqn:nonhomogeneous_linear_ode}$)의 임의의 해 $y$와 식 ($\ref{eqn:homogeneous_linear_ode}$)의 임의의 해 $\tilde{y}$에 대해서도 다음을 만족한다.</p>\[L[y + \tilde{y}] = L[y] + L[\tilde{y}] = r + 0 = r.\]<h4 id="b">(b)</h4><p>구간 $I$에서 식 ($\ref{eqn:nonhomogeneous_linear_ode}$)의 임의의 두 해 $y$와 $y^*$에 대하여 다음을 만족한다.</p>\[L[y - y^*] = L[y] - L[y^*] = r - r = 0.\ \blacksquare\]<h2 id="비동차-상미분방정식의-일반해는-모든-해를-포함한다">비동차 상미분방정식의 일반해는 모든 해를 포함한다</h2><p>동차 상미분방정식 ($\ref{eqn:homogeneous_linear_ode}$)에 대하여 <a href="/ko/posts/wronskian-existence-and-uniqueness-of-solutions/#일반해는-모든-해를-포함한다">일반해가 모든 해를 포함한다는 것을 알고 있다</a>. 비동차 상미분방정식 ($\ref{eqn:nonhomogeneous_linear_ode}$)에 대해서도 같은 것이 성립함을 보이자.</p><blockquote class="prompt-info"><p><strong>정리 2: 비동차 상미분방정식의 일반해는 모든 해를 포함한다</strong><br /> 방정식 ($\ref{eqn:nonhomogeneous_linear_ode}$)의 계수 $p(x)$, $q(x)$와 입력 함수 $r(x)$가 어떤 열린 구간 $I$에서 연속이라면, 구간 $I$에서 식 ($\ref{eqn:nonhomogeneous_linear_ode}$)의 모든 해는 구간 $I$에서 식 ($\ref{eqn:nonhomogeneous_linear_ode}$)의 일반해 ($\ref{eqn:general_sol}$)의 $y_h$의 임의의 상수 $c_1$과 $c_2$에 적당한 값을 지정함으로써 얻을 수 있다.</p></blockquote><h3 id="증명-1">증명</h3><p>$y^*$을 $I$에서 방정식 ($\ref{eqn:nonhomogeneous_linear_ode}$)의 어떤 해라고 하고, $x_0$를 구간 $I$ 내의 어떤 $x$라 하자. <a href="/ko/posts/wronskian-existence-and-uniqueness-of-solutions/#일반해의-존재">연속인 변수계수를 갖는 동차 상미분방정식의 일반해의 존재 정리</a>에 의해 $y_h = c_1y_1 + c_2y_2$가 존재하고, 추후 알아볼 <strong>매개변수변환법(method of variation of parameters)</strong>에 의해 $y_p$ 또한 존재하기에 구간 $I$에서 방정식 ($\ref{eqn:nonhomogeneous_linear_ode}$)의 일반해 ($\ref{eqn:general_sol}$)은 존재한다. 이제 앞서 증명한 정리 <a href="#비동차-상미분방정식의-해와-그에-대응하는-동차-상미분방정식의-해의-관계">1(b)</a>에 의해 $Y = y^* - y_p$는 구간 $I$에서 동차 상미분방정식 ($\ref{eqn:homogeneous_linear_ode}$)의 해이며, $x_0$에서</p>\[\begin{gather*} Y(x_0) = y^*(x_0) - y_p(x_0) \\ Y^{\prime}(x_0) = {y^*}^{\prime}(x_0) - y_p^{\prime}(x_0) \end{gather*}\]<p>이다. <a href="/ko/posts/wronskian-existence-and-uniqueness-of-solutions/#초기값-문제의-해의-존재성과-유일성의-정리">초기값 문제의 해의 존재성과 유일성의 정리</a>에 의하면 구간 $I$에서 위의 초기조건에 대하여 $y_h$의 $c_1$, $c_2$에 적당한 값을 지정하여 얻을 수 있는 동차 상미분방정식 ($\ref{eqn:homogeneous_linear_ode}$)의 특수해 $Y$가 유일하게 존재한다. $y^* = Y + y_p$이므로 비동차 상미분방정식 ($\ref{eqn:nonhomogeneous_linear_ode}$)의 임의의 특수해 $y^*$을 일반해 ($\ref{eqn:general_sol}$)으로부터 얻을 수 있음을 보였다. $\blacksquare$</p>]]> </content> </entry> <entry><title xml:lang="ko">브론스키언(Wronskian), 해의 존재와 유일성</title><link href="https://www.yunseo.kim/ko/posts/wronskian-existence-and-uniqueness-of-solutions/" rel="alternate" type="text/html" hreflang="en" /><link href="https://www.yunseo.kim/ko/posts/wronskian-existence-and-uniqueness-of-solutions/" rel="alternate" type="text/html" hreflang="ko" /><link href="https://www.yunseo.kim/ja/posts/wronskian-existence-and-uniqueness-of-solutions/" rel="alternate" type="text/html" hreflang="ja" /><link href="https://www.yunseo.kim/zh-TW/posts/wronskian-existence-and-uniqueness-of-solutions/" rel="alternate" type="text/html" hreflang="zh-TW" /><link href="https://www.yunseo.kim/es/posts/wronskian-existence-and-uniqueness-of-solutions/" rel="alternate" type="text/html" hreflang="es" /><link href="https://www.yunseo.kim/pt-BR/posts/wronskian-existence-and-uniqueness-of-solutions/" rel="alternate" type="text/html" hreflang="pt-BR" /><link href="https://www.yunseo.kim/fr/posts/wronskian-existence-and-uniqueness-of-solutions/" rel="alternate" type="text/html" hreflang="fr" /><link href="https://www.yunseo.kim/de/posts/wronskian-existence-and-uniqueness-of-solutions/" rel="alternate" type="text/html" hreflang="de" /><link href="https://www.yunseo.kim/pl/posts/wronskian-existence-and-uniqueness-of-solutions/" rel="alternate" type="text/html" hreflang="pl" /><link href="https://www.yunseo.kim/cs/posts/wronskian-existence-and-uniqueness-of-solutions/" rel="alternate" type="text/html" hreflang="cs" /><link href="https://www.yunseo.kim/sw/posts/wronskian-existence-and-uniqueness-of-solutions/" rel="alternate" type="text/html" hreflang="sw" /><link href="https://www.yunseo.kim/am/posts/wronskian-existence-and-uniqueness-of-solutions/" rel="alternate" type="text/html" hreflang="am" /><published>2025-04-06T00:00:00+09:00</published> <updated>2025-07-11T21:22:11+09:00</updated> <id>https://www.yunseo.kim/ko/posts/wronskian-existence-and-uniqueness-of-solutions/</id> <author> <name>Yunseo Kim</name> </author> <category term="Mathematics" /> <category term="Differential Equation" /> <summary xml:lang="ko">연속인 임의의 변수계수를 갖는 2계 동차 선형 상미분방정식에 대하여, 초기값 문제의 해의 존재성과 유일성의 정리, 브론스키언(Wronskian)을 이용한 해의 선형종속/선형독립 판별법을 알아본다. 또한 이를 이용하여 이러한 형태의 방정식은 항상 일반해를 가지며, 이 일반해는 방정식의 모든 해를 포함함을 보인다.</summary> <content type="html" xml:lang="ko"> <![CDATA[<p>연속인 임의의 변수계수를 갖는 2계 동차 선형 상미분방정식에 대하여, 초기값 문제의 해의 존재성과 유일성의 정리, 브론스키언(Wronskian)을 이용한 해의 선형종속/선형독립 판별법을 알아본다. 또한 이를 이용하여 이러한 형태의 방정식은 항상 일반해를 가지며, 이 일반해는 방정식의 모든 해를 포함함을 보인다.</p><em><p>* Mathematical equations and diagrams included in posts may not display properly when viewed with a feed reader.</p></em><h2 id="tldr">TL;DR</h2><blockquote class="prompt-info"><p>구간 $I$에서 연속인 임의의 변수계수 $p$와 $q$를 갖는 2계 동차 선형 상미분방정식</p>\[y^{\prime\prime} + p(x)y^{\prime} + q(x)y = 0\]<p>과 초기조건</p>\[y(x_0)=K_0, \qquad y^{\prime}(x_0)=K_1\]<p>에 대하여, 다음 4개의 정리가 성립한다.</p><ol><li><strong>초기값 문제의 해의 존재성과 유일성의 정리</strong>: 주어진 방정식 및 초기조건으로 구성되는 초기값 문제는 구간 $I$에서 유일한 해 $y(x)$를 갖는다.<li><strong>브론스키언(Wronskian)을 이용한 해의 선형종속/선형독립 판별</strong>: 방정식의 두 해 $y_1$과 $y_2$에 대하여, 구간 $I$ 내에 <strong>브론스키언(Wronskian)</strong> $W(y_1, y_2) = y_1y_2^{\prime} - y_2y_1^{\prime}$의 값이 $0$이 되는 $x_0$가 존재한다면 두 해는 선형종속이다. 또한, 구간 $I$ 내에 $W\neq 0$이 되는 $x_1$이 존재한다면 두 해는 선형독립이다.<li><strong>일반해의 존재</strong>: 주어진 방정식은 구간 $I$에서 일반해를 가진다.<li><strong>특이해의 비존재</strong>: 이 일반해는 방정식의 모든 해를 포함한다(즉, 특이해가 존재하지 않는다).</ol></blockquote><h2 id="prerequisites">Prerequisites</h2><ul><li><a href="/ko/posts/Solution-of-First-Order-Linear-ODE/">1계 선형 상미분방정식의 풀이</a><li><a href="/ko/posts/homogeneous-linear-odes-of-second-order/">2계 동차 선형 상미분방정식 (Homogeneous Linear ODEs of Second Order)</a><li><a href="/ko/posts/homogeneous-linear-odes-with-constant-coefficients/">상수계수를 갖는 2계 동차 선형 상미분방정식</a><li><a href="/ko/posts/euler-cauchy-equation/">오일러-코시 방정식</a><li>역행렬과 특이행렬, 행렬식</ul><h2 id="연속인-임의의-변수계수를-갖는-동차-선형-상미분방정식">연속인 임의의 변수계수를 갖는 동차 선형 상미분방정식</h2><p>앞서 <a href="/ko/posts/homogeneous-linear-odes-with-constant-coefficients/">상수계수를 갖는 2계 동차 선형 상미분방정식</a>과 <a href="/ko/posts/euler-cauchy-equation/">오일러-코시 방정식</a>의 일반해를 알아보았다. 이 글에서는 논의를 보다 일반적인 경우로 확장하여, 연속인 임의의 <strong>변수계수(variable coefficient)</strong> $p$와 $q$를 갖는 2계 동차 선형 상미분방정식</p>\[y^{\prime\prime} + p(x)y^{\prime} + q(x)y = 0 \label{eqn:homogeneous_linear_ode_with_var_coefficients}\tag{1}\]<p>의 일반해의 존재성과 형태를 알아본다. 또한 이에 더하여, 상미분방정식 ($\ref{eqn:homogeneous_linear_ode_with_var_coefficients}$)과 다음의 두 가지 초기조건</p>\[y(x_0)=K_0, \qquad y^{\prime}(x_0)=K_1 \label{eqn:initial_conditions}\tag{2}\]<p>로 구성된 <a href="/ko/posts/homogeneous-linear-odes-of-second-order/#초기값-문제와-초기조건">초기값 문제</a>의 유일성도 알아볼 것이다.</p><p>미리 결론부터 이야기하자면, 연속인 계수를 갖는 <u>선형</u>상미분방정식은 <em>특이해(singular solution)</em>(일반해로부터 얻을 수 없는 해)를 갖지 않는다는 것이 여기서 다루는 내용의 핵심이다.</p><h2 id="초기값-문제의-해의-존재성과-유일성의-정리">초기값 문제의 해의 존재성과 유일성의 정리</h2><blockquote class="prompt-info"><p><strong>초기값 문제의 해의 존재성과 유일성의 정리(Existence and Uniqueness Theorem for Initial Value Problems)</strong><br /> 만약 $p(x)$와 $q(x)$가 어떤 열린 구간 $I$에서 연속함수이고, $x_0$가 구간 $I$ 내에 있다면, 식 ($\ref{eqn:homogeneous_linear_ode_with_var_coefficients}$)과 ($\ref{eqn:initial_conditions}$)로 구성되는 초기값 문제는 구간 $I$에서 유일한 해 $y(x)$를 갖는다.</p></blockquote><p>존재성에 대한 증명은 여기서는 다루지 않으며, 유일성의 증명만 살펴볼 것이다. 통상적으로 유일성을 증명하는 것이 존재성을 증명하는 것보다 간단하다.<br /> 증명에 관심이 없다면 이 부분은 건너뛰고 <a href="#해의-선형종속과-선형독립">해의 선형종속과 선형독립</a>으로 넘어가도 좋다.</p><h3 id="유일성의-증명">유일성의 증명</h3><p>상미분방정식 ($\ref{eqn:homogeneous_linear_ode_with_var_coefficients}$)과 초기조건 ($\ref{eqn:initial_conditions}$)로 구성된 초기값 문제가 구간 $I$에서 두 개의 해 $y_1(x)$와 $y_2(x)$를 가진다고 가정하자. 이 두 해의 차</p>\[y(x) = y_1(x) - y_2(x)\]<p>가 구간 $I$에서 항등적으로 $0$이 됨을 보일 수 있다면, 이는 곧 구간 $I$에서 $y_1 \equiv y_2$라는 것이므로 해의 유일성을 의미한다.</p><p>방정식 ($\ref{eqn:homogeneous_linear_ode_with_var_coefficients}$)이 동차 선형 상미분방정식이므로, $y_1$과 $y_2$의 선형결합인 $y$는 $I$에서 방정식의 해가 된다. $y_1$과 $y_2$가 동일한 초기조건 ($\ref{eqn:initial_conditions}$)를 만족하므로, $y$는 조건</p>\[\begin{align*} &amp; y(x_0) = y_1(x_0) - y_2(x_0) = 0, \\ &amp; y^{\prime}(x_0) = y_1^{\prime}(x_0) - y_2^{\prime}(x_0) = 0 \end{align*} \label{eqn:initial_conditions_*}\tag{3}\]<p>을 만족한다. 이제 함수</p>\[z(x) = y(x)^2 + y^{\prime}(x)^2\]<p>과 그 도함수</p>\[z^{\prime} = 2yy^{\prime} + 2y^{\prime}y^{\prime\prime}\]<p>을 생각하자. 상미분방정식으로부터</p>\[y^{\prime\prime} = -py^{\prime} - qy\]<p>를 얻으며, 이를 $z^{\prime}$에 대한 식에 대입하면</p>\[z^{\prime} = 2yy^{\prime} - 2p{y^{\prime}}^2 - 2qyy^{\prime} \label{eqn:z_prime}\tag{4}\]<p>을 얻는다. 이제 $y$와 $y^{\prime}$이 실수이므로</p>\[(y\pm y^{\prime})^2 = y^2 \pm 2yy^{\prime} + {y^{\prime}}^2 \geq 0\]<p>이 된다. 이것과 $z$의 정의로부터 두 개의 부등식</p>\[(a)\ 2yy^{\prime} \leq y^2 + {y^{\prime}}^2 = z, \qquad (b)\ 2yy^{\prime} \geq -(y^2 + {y^{\prime}}^2) = -z \label{eqn:inequalities}\tag{5}\]<p>를 얻을 수 있다. 이 두 부등식으로부터 $|2yy^{\prime}|\leq z$임을 알 수 있고, 그렇다면 식 ($\ref{eqn:z_prime}$)의 마지막 항에 대해서는 다음 부등식이 성립한다.</p>\[\pm2qyy^{\prime} \leq |\pm 2qyy^{\prime}| = |q||2yy^{\prime}| \leq |q|z.\]<p>이 결과와 함께 $-p \leq |p|$임을 이용하고, 식 ($\ref{eqn:z_prime}$)의 항 $2yy^{\prime}$에 식 ($\ref{eqn:inequalities}$a)를 적용하면</p>\[z^{\prime} \leq z + 2|p|{y^{\prime}}^2 + |q|z\]<p>가 된다. ${y^{\prime}}^2 \leq y^2 + {y^{\prime}}^2 = z$이므로 이로부터</p>\[z^{\prime} \leq (1 + 2|p| + |q|)z\]<p>를 얻으며, 괄호 안의 함수를 $h = 1 + 2|p| + |q|$로 놓으면</p>\[z^{\prime} \leq hz \quad \forall x \in I \label{eqn:inequality_6a}\tag{6a}\]<p>이다. 같은 방법으로, 식 ($\ref{eqn:z_prime}$)와 ($\ref{eqn:inequalities}$)로부터</p>\[\begin{align*} -z^{\prime} &amp;= -2yy^{\prime} + 2p{y^{\prime}}^2 + 2qyy^{\prime} \\ &amp;\leq z + 2|p|z + |q|z = hz \end{align*} \label{eqn:inequality_6b}\tag{6b}\]<p>를 얻는다. 이 두 부등식 ($\ref{eqn:inequality_6a}$), ($\ref{eqn:inequality_6b}$)는 다음 부등식</p>\[z^{\prime} - hz \leq 0, \qquad z^{\prime} + hz \geq 0 \label{eqn:inequalities_7}\tag{7}\]<p>과 동등하며, 두 식의 좌변에 대한 <a href="/ko/posts/Solution-of-First-Order-Linear-ODE/#비동차-선형-상미분방정식">적분인자</a>는</p>\[F_1 = e^{-\int h(x)\ dx} \qquad \text{와} \qquad F_2 = e^{\int h(x)\ dx}\]<p>이다. $h$가 연속이므로 부정적분 $\int h(x)\ dx$는 존재하며, $F_1$과 $F_2$가 양수이므로 식 ($\ref{eqn:inequalities_7}$)로부터</p>\[F_1(z^{\prime} - hz) = (F_1 z)^{\prime} \leq 0, \qquad F_2(z^{\prime} + hz) = (F_2 z)^{\prime} \geq 0\]<p>을 얻는다. 이는 구간 $I$에서 $F_1 z$가 증가하지 않으며 $F_2 z$가 감소하지 않음을 의미한다. 식 ($\ref{eqn:initial_conditions_*}$)에 의해 $z(x_0) = 0$이므로,</p>\[\begin{cases} \left(F_1 z \geq (F_1 z)_{x_0} = 0\right)\ \&amp; \ \left(F_2 z \leq (F_2 z)_{x_0} = 0\right) &amp; (x \leq x_0) \\ \left(F_1 z \leq (F_1 z)_{x_0} = 0\right)\ \&amp; \ \left(F_2 z \geq (F_2 z)_{x_0} = 0\right) &amp; (x \geq x_0) \end{cases}\]<p>이다. 마지막으로 부등식의 양변을 양수 $F_1$과 $F_2$로 나누면 다음과 같이 해의 유일성을 보일 수 있다.</p>\[(z \leq 0) \ \&amp; \ (z \geq 0) \quad \forall x \in I\] \[z = y^2 + {y^{\prime}}^2 = 0 \quad \forall x \in I\] \[\therefore y \equiv y_1 - y_2 \equiv 0 \quad \forall x \in I. \ \blacksquare\]<h2 id="해의-선형종속과-선형독립">해의 선형종속과 선형독립</h2><p><a href="/ko/posts/homogeneous-linear-odes-of-second-order/#기저와-일반해">2계 동차 선형 상미분방정식</a>에서 다뤘던 내용을 잠시 다시 떠올려보자. 열린 구간 $I$에서의 일반해는 $I$에서의 <strong>기저(basis)</strong> $y_1$, $y_2$, 즉 선형독립인 해들의 쌍으로부터 만들어진다. 여기서 $y_1$과 $y_2$가 구간 $I$에서 <strong>선형 독립(linearly independent)</strong>이라는 것은 곧 구간 내 모든 $x$에 대하여 다음을 만족함을 의미한다.</p>\[k_1y_1(x) + k_2y_2(x) = 0 \Leftrightarrow k_1=0\text{이고 }k_2=0 \label{eqn:linearly_independent}\tag{8}\]<p>만약 위를 만족하지 않고, 적어도 하나의 $0$이 아닌 $k_1$, $k_2$에 대하여 $k_1y_1(x) + k_2y_2(x) = 0$이 성립할 경우 $y_1$과 $y_2$는 구간 $I$에서 <strong>선형 종속(linearly dependent)</strong>이다. 이 경우 구간 $I$의 모든 $x$에 대해</p>\[\text{(a) } y_1 = ky_2 \quad \text{또는} \quad \text{(b) } y_2 = ly_1 \label{eqn:linearly_dependent}\tag{9}\]<p>이 되어 $y_1$과 $y_2$는 비례한다.</p><p>이제 다음의 해의 선형독립/선형종속 판별법을 알아보자.</p><blockquote class="prompt-info"><p><strong>브론스키언(Wronskian)을 이용한 해의 선형종속/선형독립 판별</strong><br /> <strong>i.</strong> 상미분방정식 ($\ref{eqn:homogeneous_linear_ode_with_var_coefficients}$)이 열린 구간 $I$에서 연속인 계수 $p(x)$와 $q(x)$를 갖는다면, 구간 $I$에서 방정식 ($\ref{eqn:homogeneous_linear_ode_with_var_coefficients}$)의 두 해 $y_1$과 $y_2$가 선형종속이 되기 위한 필요충분조건은 이 해들의 <em>브론스키 행렬식(Wronski determinant)</em>, 줄여서 <strong>브론스키언(Wronskian)</strong>이라고 부르는 다음의 행렬식</p>\[W(y_1, y_2) = \begin{vmatrix} y_1 &amp; y_2 \\ y_1^{\prime} &amp; y_2^{\prime} \\ \end{vmatrix} = y_1y_2^{\prime} - y_2y_1^{\prime} \label{eqn:wronskian}\tag{10}\]<p>이 구간 $I$ 내의 어떤 $x_0$에서 $0$이 되는 것이다.</p>\[\exists x_0 \in I: W(x_0)=0 \iff y_1 \text{과 } y_2 \text{는 선형종속}\]<p><strong>ii.</strong> 구간 $I$ 내의 한 점 $x=x_0$에서 $W=0$이라면 구간 $I$ 안의 모든 $x$에서 $W=0$이다.</p>\[\exists x_0 \in I: W(x_0)=0 \implies \forall x \in I: W(x)=0\]<p>다시 말해, $W\neq 0$인 $x_1$이 구간 $I$에 존재한다면 해당 구간 $I$에서는 $y_1$, $y_2$는 선형독립이다.</p>\[\begin{align*} \exists x_1 \in I: W(x_1)\neq 0 &amp;\implies \forall x \in I: W(x)\neq 0 \\ &amp;\implies y_1 \text{과 } y_2 \text{는 선형독립} \end{align*}\]</blockquote><blockquote class="prompt-tip"><p>브론스키언은 폴란드의 수학자 유제프 마리아 호에네-브론스키(Józef Maria Hoene-Wroński)가 처음 도입하였고, 그의 사후인 11882 HE에 스코틀랜드 수학자 토머스 뮤어(Sir Thomas Muir)에 의해 지금의 이름이 붙었다.</p></blockquote><h3 id="증명">증명</h3><h4 id="i-a">i. (a)</h4><p>구간 $I$에서 $y_1$과 $y_2$가 선형종속이라 하자. 그러면 구간 $I$에서 식 ($\ref{eqn:linearly_dependent}$a) 또는 ($\ref{eqn:linearly_dependent}$b)가 성립한다. 만약 식 ($\ref{eqn:linearly_dependent}$a)가 성립한다면</p>\[W(y_1, y_2) = y_1y_2^{\prime} - y_2y_1^{\prime} = ky_2ky_2^{\prime} - y_2ky_2^{\prime} = 0\]<p>이며, 마찬가지로 식 ($\ref{eqn:linearly_dependent}$b)가 성립하는 경우에도</p>\[W(y_1, y_2) = y_1y_2^{\prime} - y_2y_1^{\prime} = y_1ly_1^{\prime} - ly_1y_1^{\prime} = 0\]<p>이므로 <u>구간 $I$ 내의 모든 $x$에 대해</u> 브론스키언 $W(y_1, y_2)=0$임을 확인할 수 있다.</p><h4 id="i-b">i. (b)</h4><p>역으로 어떤 $x = x_0$에 대해 $W(y_1, y_2)=0$이라 할 때, 구간 $I$에서 $y_1$과 $y_2$가 선형종속이 됨을 보일 것이다. 미지수 $k_1$, $k_2$에 대한 선형연립방정식</p>\[\begin{gather*} k_1y_1(x_0) + k_2y_2(x_0) = 0 \\ k_1y_1^{\prime}(x_0) + k_2y_2^{\prime}(x_0) = 0 \end{gather*} \label{eqn:linear_system}\tag{11}\]<p>을 생각하자. 이는 다음과 같은 벡터방정식 꼴로 표현할 수 있다.</p>\[\left[\begin{matrix} y_1(x_0) &amp; y_2(x_0) \\ y_1^{\prime}(x_0) &amp; y_2^{\prime}(x_0) \end{matrix}\right] \left[\begin{matrix} k_1 \\ k_2 \end{matrix}\right] = 0 \label{eqn:vector_equation}\tag{12}\]<p>이 벡터방정식의 계수행렬은</p>\[A = \left[\begin{matrix} y_1(x_0) &amp; y_2(x_0) \\ y_1^{\prime}(x_0) &amp; y_2^{\prime}(x_0) \end{matrix}\right]\]<p>이고, 이 행렬의 행렬식은 곧 $W(y_1(x_0), y_2(x_0))$이다. $\det(A) = W=0$이므로 $A$는 <strong>역행렬(inverse matrix)</strong>이 존재하지 않는 <strong>특이행렬(singular matrix)</strong>이고, 따라서 연립방정식 ($\ref{eqn:linear_system}$)은 $k_1$과 $k_2$ 중 적어도 하나는 $0$이 아닌 영벡터 $(0,0)$ 이외의 해 $(c_1, c_2)$를 가진다. 이제 함수</p>\[y(x) = c_1y_1(x) + c_2y_2(x)\]<p>를 도입하자. 방정식 ($\ref{eqn:homogeneous_linear_ode_with_var_coefficients}$)이 동차 선형이므로 <a href="/ko/posts/homogeneous-linear-odes-of-second-order/#중첩의-원리">중첩의 원리</a>에 의해 이 함수는 구간 $I$에서 ($\ref{eqn:homogeneous_linear_ode_with_var_coefficients}$)의 해가 된다. 식 ($\ref{eqn:linear_system}$)로부터 이 해는 초기조건 $y(x_0)=0$, $y^{\prime}(x_0)=0$을 만족함을 알 수 있다.</p><p>한편, 동일한 초기조건 $y^*(x_0)=0$, ${y^*}^{\prime}(x_0)=0$을 만족하는 자명해 $y^* \equiv 0$이 존재한다. 방정식 ($\ref{eqn:homogeneous_linear_ode_with_var_coefficients}$)의 계수 $p$와 $q$가 연속이기 때문에 <a href="#초기값-문제의-해의-존재성과-유일성의-정리">초기값 문제의 해의 존재성과 유일성의 정리</a>에 의해 해의 유일성이 보장되며, 따라서 $y \equiv y^*$이다. 즉, 구간 $I$에서</p>\[c_1y_1 + c_2y_2 \equiv 0\]<p>이다. $c_1$과 $c_2$ 둘 중 적어도 하나는 $0$이 아니기 때문에 ($\ref{eqn:linearly_independent}$)을 만족하지 않으므로, 이는 구간 $I$에서 $y_1$, $y_2$가 선형종속임을 의미한다.</p><h4 id="ii">ii.</h4><p>만약 구간 $I$ 내의 어떤 한 점 $x_0$에서 $W(x_0)=0$라면, <a href="#i-b">i.(b)</a>에 의해 구간 $I$에서 $y_1$, $y_2$는 선형종속이고, 그러면 <a href="#i-a">i.(a)</a>에 의해 $W\equiv 0$이다. 그러므로 $W(x_1)\neq 0$인 $x_1$이 구간 $I$ 내에 하나라도 존재한다면 $y_1$과 $y_2$는 선형독립이다. $\blacksquare$</p><h2 id="일반해는-모든-해를-포함한다">일반해는 모든 해를 포함한다</h2><h3 id="일반해의-존재">일반해의 존재</h3><blockquote class="prompt-info"><p>만약 $p(x)$와 $q(x)$가 열린 구간 $I$에서 연속이라면, 방정식 ($\ref{eqn:homogeneous_linear_ode_with_var_coefficients}$)은 구간 $I$에서 일반해를 가진다.</p></blockquote><h4 id="증명-1">증명</h4><p><a href="#초기값-문제의-해의-존재성과-유일성의-정리">초기값 문제의 해의 존재성과 유일성의 정리</a>에 의해, 상미분방정식 ($\ref{eqn:homogeneous_linear_ode_with_var_coefficients}$)은 구간 $I$에서 초기조건</p>\[y_1(x_0) = 1, \qquad y_1^{\prime}(x_0) = 0\]<p>을 만족하는 해 $y_1(x)$와 구간 $I$에서 초기조건</p>\[y_2(x_0) = 0, \qquad y_2^{\prime}(x_0) = 1\]<p>을 만족하는 해 $y_2(x)$를 가진다. 이 두 해의 브론스키언은 $x=x_0$에서 0이 아닌 값</p>\[W(y_1(x_0), y_2(x_0)) = y_1(x_0)y_2^{\prime}(x_0) - y_2(x_0)y_1^{\prime}(x_0) = 1\cdot 1 - 0\cdot 0 = 1\]<p>을 가지므로, <a href="#해의-선형종속과-선형독립">브론스키언(Wronskian)을 이용한 해의 선형종속/선형독립 판별</a>에 의해 구간 $I$에서 $y_1$과 $y_2$는 선형독립이다. 따라서 이 두 해는 구간 $I$에서 방정식 ($\ref{eqn:homogeneous_linear_ode_with_var_coefficients}$)의 해의 기저를 형성하며, 임의의 상수 $c_1$, $c_2$를 갖는 일반해 $y = c_1y_1 + c_2y_2$가 구간 $I$에서 반드시 존재한다. $\blacksquare$</p><h3 id="특이해의-부존재">특이해의 부존재</h3><blockquote class="prompt-info"><p>상미분방정식 ($\ref{eqn:homogeneous_linear_ode_with_var_coefficients}$)이 어떤 열린 구간 $I$에서 연속인 계수 $p(x)$와 $q(x)$를 갖는다면, 구간 $I$에서 방정식 ($\ref{eqn:homogeneous_linear_ode_with_var_coefficients}$)의 모든 해 $y=Y(x)$는</p>\[Y(x) = C_1y_1(x) + C_2y_2(x) \label{eqn:particular_solution}\tag{13}\]<p>의 형태이며, 여기서 $y_1$, $y_2$는 구간 $I$에서 방정식 ($\ref{eqn:homogeneous_linear_ode_with_var_coefficients}$)의 해의 기저이고 $C_1$, $C_2$는 적당한 상수이다.<br /> 즉, 방정식 ($\ref{eqn:homogeneous_linear_ode_with_var_coefficients}$)은 일반해로부터 얻을 수 없는 해인 <strong>특이해(singular solution)</strong>를 갖지 않는다.</p></blockquote><h4 id="증명-2">증명</h4><p>$y=Y(x)$를 구간 $I$에서 방정식 ($\ref{eqn:homogeneous_linear_ode_with_var_coefficients}$)의 어떤 해라고 하자. 이제 <a href="#일반해의-존재">일반해의 존재 정리</a>에 의해서 상미분방정식 ($\ref{eqn:homogeneous_linear_ode_with_var_coefficients}$)은 구간 $I$에서 일반해</p>\[y(x) = c_1y_1(x) + c_2y_2(x) \label{eqn:general_solution}\tag{14}\]<p>를 갖는다. 이제 임의의 $Y(x)$에 대하여 구간 $I$에서 $y(x)=Y(x)$가 되게 하는 상수 $c_1$, $c_2$가 존재함을 보여야 한다. 구간 $I$에서 임의의 $x_0$를 선택했을 때 $y(x_0)=Y(x_0)$이고 $y^{\prime}(x_0)=Y^{\prime}(x_0)$가 되게 하는 $c_1$, $c_2$의 값을 찾을 수 있음을 먼저 보이자. 식 ($\ref{eqn:general_solution}$)로부터</p>\[\begin{gather*} \left[\begin{matrix} y_1(x_0) &amp; y_2(x_0) \\ y_1^{\prime}(x_0) &amp; y_2^{\prime}(x_0) \end{matrix}\right] \left[\begin{matrix} c_1 \\ c_2 \end{matrix}\right] = \left[\begin{matrix} Y(x_0) \\ Y^{\prime}(x_0) \end{matrix}\right] \end{gather*} \label{eqn:vector_equation_2}\tag{15}\]<p>가 된다. $y_1$과 $y_2$가 기저이므로 계수행렬의 행렬식인 $W(y_1(x_0), y_2(x_0))\neq 0$이고, 따라서 방정식 ($\ref{eqn:vector_equation_2}$)는 $c_1$과 $c_2$에 대해 풀 수 있다. 그 해를 $(c_1, c_2) = (C_1, C_2)$라고 하자. 이를 식 ($\ref{eqn:general_solution}$)에 대입하면 다음의 특수해를 얻는다.</p>\[y^*(x) = C_1y_1(x) + C_2y_2(x).\]<p>$C_1$, $C_2$가 방정식 ($\ref{eqn:vector_equation_2}$)의 해이므로,</p>\[y^*(x_0) = Y(x_0), \qquad {y^*}^{\prime}(x_0) = Y^{\prime}(x_0)\]<p>이다. <a href="#초기값-문제의-해의-존재성과-유일성의-정리">초기값 문제의 해의 존재성과 유일성의 정리</a>의 유일성에 의헤, 구간 $I$ 내의 모든 $x$에 대하여 $y^* \equiv Y$이다. $\blacksquare$</p>]]> </content> </entry> <entry><title xml:lang="ko">오일러-코시 방정식</title><link href="https://www.yunseo.kim/ko/posts/euler-cauchy-equation/" rel="alternate" type="text/html" hreflang="en" /><link href="https://www.yunseo.kim/ko/posts/euler-cauchy-equation/" rel="alternate" type="text/html" hreflang="ko" /><link href="https://www.yunseo.kim/ja/posts/euler-cauchy-equation/" rel="alternate" type="text/html" hreflang="ja" /><link href="https://www.yunseo.kim/zh-TW/posts/euler-cauchy-equation/" rel="alternate" type="text/html" hreflang="zh-TW" /><link href="https://www.yunseo.kim/es/posts/euler-cauchy-equation/" rel="alternate" type="text/html" hreflang="es" /><link href="https://www.yunseo.kim/pt-BR/posts/euler-cauchy-equation/" rel="alternate" type="text/html" hreflang="pt-BR" /><link href="https://www.yunseo.kim/fr/posts/euler-cauchy-equation/" rel="alternate" type="text/html" hreflang="fr" /><link href="https://www.yunseo.kim/de/posts/euler-cauchy-equation/" rel="alternate" type="text/html" hreflang="de" /><link href="https://www.yunseo.kim/pl/posts/euler-cauchy-equation/" rel="alternate" type="text/html" hreflang="pl" /><link href="https://www.yunseo.kim/cs/posts/euler-cauchy-equation/" rel="alternate" type="text/html" hreflang="cs" /><link href="https://www.yunseo.kim/sw/posts/euler-cauchy-equation/" rel="alternate" type="text/html" hreflang="sw" /><link href="https://www.yunseo.kim/am/posts/euler-cauchy-equation/" rel="alternate" type="text/html" hreflang="am" /><published>2025-03-28T00:00:00+09:00</published> <updated>2025-07-09T19:24:14+09:00</updated> <id>https://www.yunseo.kim/ko/posts/euler-cauchy-equation/</id> <author> <name>Yunseo Kim</name> </author> <category term="Mathematics" /> <category term="Differential Equation" /> <summary xml:lang="ko">보조방정식의 판별식의 부호에 따라, 각각의 경우에 오일러-코시 방정식의 일반해가 어떤 형태를 띄는지 살펴본다.</summary> <content type="html" xml:lang="ko"> <![CDATA[<p>보조방정식의 판별식의 부호에 따라, 각각의 경우에 오일러-코시 방정식의 일반해가 어떤 형태를 띄는지 살펴본다.</p><em><p>* Mathematical equations and diagrams included in posts may not display properly when viewed with a feed reader.</p></em><h2 id="tldr">TL;DR</h2><blockquote class="prompt-info"><ul><li>오일러-코시 방정식: $x^2y^{\prime\prime} + axy^{\prime} + by = 0$<li><strong>보조방정식(auxiliary equation)</strong>: $m^2 + (a-1)m + b = 0$<li>보조방정식의 판별식 $(1-a)^2 - 4b$의 부호에 따라 일반해의 형태를 표와 같이 세 가지 경우로 나눌 수 있음</ul><table><thead><tr><th style="text-align: center">경우<th style="text-align: center">보조방정식의 해<th style="text-align: center">오일러-코시 방정식의 해의 기저<th style="text-align: center">오일러-코시 방정식의 일반해<tbody><tr><td style="text-align: center">I<td style="text-align: center">서로 다른 실근<br />$m_1$, $m_2$<td style="text-align: center">$x^{m_1}$, $x^{m_2}$<td style="text-align: center">$y = c_1 x^{m_1} + c_2 x^{m_2}$<tr><td style="text-align: center">II<td style="text-align: center">실이중근<br /> $m = \cfrac{1-a}{2}$<td style="text-align: center">$x^{(1-a)/2}$, $x^{(1-a)/2}\ln{x}$<td style="text-align: center">$y = (c_1 + c_2 \ln x)x^m$<tr><td style="text-align: center">III<td style="text-align: center">켤레복소근<br /> $m_1 = \cfrac{1}{2}(1-a) + i\omega$, <br /> $m_2 = \cfrac{1}{2}(1-a) - i\omega$<td style="text-align: center">$x^{(1-a)/2}\cos{(\omega \ln{x})}$, <br /> $x^{(1-a)/2}\sin{(\omega \ln{x})}$<td style="text-align: center">$y = x^{(1-a)/2}[A\cos{(\omega \ln{x})} + B\sin{(\omega \ln{x})}]$</table></blockquote><h2 id="prerequisites">Prerequisites</h2><ul><li><a href="/ko/posts/homogeneous-linear-odes-of-second-order/">2계 동차 선형 상미분방정식 (Homogeneous Linear ODEs of Second Order)</a><li><a href="/ko/posts/homogeneous-linear-odes-with-constant-coefficients/">상수계수를 갖는 2계 동차 선형 상미분방정식</a><li>오일러 공식</ul><h2 id="보조방정식-auxiliary-equation">보조방정식 (auxiliary equation)</h2><p><strong>오일러-코시 방정식(Euler-Cauchy equation)</strong>은 주어진 상수 $a$와 $b$, 그리고 미지의 함수 $y(x)$를 갖는</p>\[x^2y^{\prime\prime} + axy^{\prime} + by = 0 \label{eqn:euler_cauchy_eqn}\tag{1}\]<p>형태의 상미분방정식이다. 식 ($\ref{eqn:euler_cauchy_eqn}$)에</p>\[y=x^m, \qquad y^{\prime}=mx^{m-1}, \qquad y^{\prime\prime}=m(m-1)x^{m-2}\]<p>을 대입하면</p>\[x^2m(m-1)x^{m-2} + axmx^{m-1} + bx^m = 0,\]<p>즉</p>\[[m(m-1) + am + b]x^m = 0\]<p>을 얻는다. 이로부터 보조방정식</p>\[m^2 + (a-1)m + b = 0 \label{eqn:auxiliary_eqn}\tag{2}\]<p>을 얻으며, $y=x^m$이 오일러-코시 방정식 ($\ref{eqn:euler_cauchy_eqn}$)의 해가 되기 위한 필요충분조건은 $m$이 보조방정식 ($\ref{eqn:auxiliary_eqn}$)의 해가 되는 것이다.</p><p>이차방정식 ($\ref{eqn:auxiliary_eqn}$)의 해를 구하면</p>\[\begin{align*} m_1 &amp;= \frac{1}{2}\left[(1-a) + \sqrt{(1-a)^2 - 4b} \right], \\ m_2 &amp;= \frac{1}{2}\left[(1-a) - \sqrt{(1-a)^2 - 4b} \right] \end{align*}\label{eqn:m1_and_m2}\tag{3}\]<p>이고, 이로부터 두 함수</p>\[y_1 = x^{m_1}, \quad y_2 = x^{m_2}\]<p>이 방정식 ($\ref{eqn:euler_cauchy_eqn}$)의 해가 된다.</p><p><a href="/ko/posts/homogeneous-linear-odes-with-constant-coefficients/">상수계수를 갖는 2계 동차 선형 상미분방정식</a>에서와 마찬가지로, 보조방정식 ($\ref{eqn:auxiliary_eqn}$)의 판별식 $(1-a)^2 - 4b$의 부호에 따라 경우를 세 가지로 나눌 수 있다.</p><ul><li>$(1-a)^2 - 4b &gt; 0$: 서로 다른 두 실근<li>$(1-a)^2 - 4b = 0$: 실이중근<li>$(1-a)^2 - 4b &lt; 0$: 켤레복소근</ul><h2 id="보조방정식의-판별식의-부호에-따른-일반해의-형태">보조방정식의 판별식의 부호에 따른 일반해의 형태</h2><h3 id="i-서로-다른-두-실근-m_1과-m_2">I. 서로 다른 두 실근 $m_1$과 $m_2$</h3><p>이 경우 임의의 구간에서 방정식 ($\ref{eqn:euler_cauchy_eqn}$)의 해의 기저는</p>\[y_1 = x^{m_1}, \quad y_2 = x^{m_2}\]<p>이며, 이에 따른 일반해는</p>\[y = c_1 x^{m_1} + c_2 x^{m_2} \label{eqn:general_sol_1}\tag{4}\]<p>이다.</p><h3 id="ii-실이중근-m--cfrac1-a2">II. 실이중근 $m = \cfrac{1-a}{2}$</h3><p>$(1-a)^2 - 4b = 0$, 즉 $b=\cfrac{(1-a)^2}{4}$일 경우 이차방정식 ($\ref{eqn:auxiliary_eqn}$)는 한 개의 해 $m = m_1 = m_2 = \cfrac{1-a}{2}$만을 얻게 되며, 따라서 이로부터 얻을 수 있는 $y = x^m$ 형태의 한 해는</p>\[y_1 = x^{(1-a)/2}\]<p>이고, 오일러-코시 방정식 ($\ref{eqn:euler_cauchy_eqn}$)은</p>\[y^{\prime\prime} + \frac{a}{x}y^{\prime} + \frac{(1-a)^2}{4x^2}y = 0 \label{eqn:standard_form}\tag{5}\]<p>의 형태가 된다. 이제 선형독립인 또다른 해 $y_2$를 <a href="/ko/posts/homogeneous-linear-odes-of-second-order/#계수내림-reduction-of-order">계수내림</a>을 이용하여 구하자.</p><p>찾고자 하는 두 번째 해를 $y_2=uy_1$으로 놓으면</p>\[u = \int U, \qquad U = \frac{1}{y_1^2}\exp\left(-\int \frac{a}{x}\ dx \right)\]<p>를 얻는다.</p><p>$\exp \left(-\int \cfrac{a}{x}\ dx \right) = \exp (-a\ln x) = \exp(\ln{x^{-a}}) = x^{-a}$이므로,</p>\[U = \frac{x^{-a}}{y_1^2} = \frac{x^{-a}}{x^{(1-a)}} = \frac{1}{x}\]<p>이고 적분하면 $u = \ln x$를 얻는다.</p><p>따라서 $y_2 = uy_1 = y_1 \ln x$이고, $y_1$과 $y_2$는 그 몫이 상수가 아니므로 선형독립이다. 기저 $y_1$과 $y_2$에 대응하는 일반해는</p>\[y = (c_1 + c_2 \ln x)x^m \label{eqn:general_sol_2}\tag{6}\]<p>이다.</p><h3 id="iii-켤레복소근">III. 켤레복소근</h3><p>이 경우 보조방정식 ($\ref{eqn:auxiliary_eqn}$)의 해는 $m = \cfrac{1}{2}(1-a) \pm i\sqrt{b - \frac{1}{4}(1-a)^2}$이 되며, 이에 대응하는 방정식 ($\ref{eqn:euler_cauchy_eqn}$)의 두 복소해는 $x=e^{\ln x}$임을 이용하여 다음과 같이 쓸 수 있다.</p>\[\begin{align*} x^{m_1} &amp;= x^{(1-a)/2 + i\sqrt{b - \frac{1}{4}(1-a)^2}} \\ &amp;= x^{(1-a)/2}(e^{\ln x})^{i\sqrt{b - \frac{1}{4}(1-a)^2}} \\ &amp;= x^{(1-a)/2}e^{i(\sqrt{b - \frac{1}{4}(1-a)^2}\ln x)}, \\ x^{m_2} &amp;= x^{(1-a)/2 - i\sqrt{b - \frac{1}{4}(1-a)^2}} \\ &amp;= x^{(1-a)/2}(e^{\ln x})^{-i\sqrt{b - \frac{1}{4}(1-a)^2}} \\ &amp;= x^{(1-a)/2}e^{i(-\sqrt{b - \frac{1}{4}(1-a)^2}\ln x)}. \end{align*} \tag{7}\]<p>$t=\sqrt{b - \frac{1}{4}(1-a)^2}\ln x$로 놓고 오일러 공식 $e^{it} = \cos{t} + i\sin{t}$를 이용하면</p>\[\begin{align*} x^{m_1} &amp;= x^{(1-a)/2}\left[\cos\left(\sqrt{b - \tfrac{1}{4}(1-a)^2}\ln x \right) + i\sin\left(\sqrt{b - \tfrac{1}{4}(1-a)^2}\ln x \right) \right], \\ x^{m_2} &amp;= x^{(1-a)/2}\left[\cos\left(\sqrt{b - \tfrac{1}{4}(1-a)^2}\ln x \right) - i\sin\left(\sqrt{b - \tfrac{1}{4}(1-a)^2}\ln x \right) \right] \end{align*} \tag{8}\]<p>임을 알 수 있고, 이로부터 다음의 두 실수해</p>\[\begin{align*} \frac{x^{m_1} + x^{m_2}}{2} &amp;= x^{(1-a)/2}\cos\left(\sqrt{b - \tfrac{1}{4}(1-a)^2}\ln x \right), \\ \frac{x^{m_1} - x^{m_2}}{2i} &amp;= x^{(1-a)/2}\sin\left(\sqrt{b - \tfrac{1}{4}(1-a)^2}\ln x \right) \end{align*} \tag{9}\]<p>를 얻는다.</p><p>이들의 몫 $\cos\left(\sqrt{b - \frac{1}{4}(1-a)^2}\ln x \right)$가 상수가 아니므로 위의 두 해는 선형독립이며, 따라서 <a href="/ko/posts/homogeneous-linear-odes-of-second-order/#중첩의-원리">중첩의 원리</a>에 의해 오일러-코시 방정식 ($\ref{eqn:euler_cauchy_eqn}$)의 기저를 형성한다. 이로부터 다음의 실수 일반해를 얻는다.</p>\[y = x^{(1-a)/2} \left[ A\cos\left(\sqrt{b - \tfrac{1}{4}(1-a)^2}\ln x \right) + B\sin\left(\sqrt{b - \tfrac{1}{4}(1-a)^2}\ln x \right) \right]. \label{eqn:general_sol_3}\tag{10}\]<p>다만, 오일러-코시 방정식에서 보조방정식이 켤레복소근을 갖는 경우는 실질적인 중요성이 그리 크진 않다.</p><h2 id="상수계수를-갖는-2계-동차-선형-상미분방정식으로의-변환">상수계수를 갖는 2계 동차 선형 상미분방정식으로의 변환</h2><p>오일러-코시 방정식은 변수 치환을 통해 <a href="/ko/posts/homogeneous-linear-odes-with-constant-coefficients/">상수계수를 갖는 2계 동차 선형 상미분방정식</a>으로 변환할 수 있다.</p><p>$x = e^t$으로 치환하면</p>\[\frac{d}{dx} = \frac{1}{x}\frac{d}{dt}, \quad \frac{d^2}{dx^2} = \frac{1}{x^2}\left(\frac{d^2}{dt^2} - \frac{d}{dt} \right)\]<p>가 되어, 오일러-코시 방정식 ($\ref{eqn:euler_cauchy_eqn}$)은 다음과 같이 $t$에 대한 상수계수 동차 선형 상미분방정식으로 바뀐다.</p>\[y^{\prime\prime}(t) + (a-1)y^{\prime}(t) + by(t) = 0. \label{eqn:substituted}\tag{11}\]<p>방정식 ($\ref{eqn:substituted}$)을 <a href="/ko/posts/homogeneous-linear-odes-with-constant-coefficients/">상수계수를 갖는 2계 동차 선형 상미분방정식</a>의 해법을 적용하여 $t$에 대해 풀고, 그렇게 얻은 해를 $t = \ln{x}$임을 이용하여 다시 $x$에 대한 해로 변환하면 <a href="#보조방정식의-판별식의-부호에-따른-일반해의-형태">앞서 살펴본 것과 동일한 결과</a>를 얻는다.</p>]]> </content> </entry> <entry><title xml:lang="ko">급수의 수렴/발산 판정(Testing for Convergence or Divergence of a Series)</title><link href="https://www.yunseo.kim/ko/posts/testing-for-convergence-or-divergence-of-a-series/" rel="alternate" type="text/html" hreflang="en" /><link href="https://www.yunseo.kim/ko/posts/testing-for-convergence-or-divergence-of-a-series/" rel="alternate" type="text/html" hreflang="ko" /><link href="https://www.yunseo.kim/ja/posts/testing-for-convergence-or-divergence-of-a-series/" rel="alternate" type="text/html" hreflang="ja" /><link href="https://www.yunseo.kim/zh-TW/posts/testing-for-convergence-or-divergence-of-a-series/" rel="alternate" type="text/html" hreflang="zh-TW" /><link href="https://www.yunseo.kim/es/posts/testing-for-convergence-or-divergence-of-a-series/" rel="alternate" type="text/html" hreflang="es" /><link href="https://www.yunseo.kim/pt-BR/posts/testing-for-convergence-or-divergence-of-a-series/" rel="alternate" type="text/html" hreflang="pt-BR" /><link href="https://www.yunseo.kim/fr/posts/testing-for-convergence-or-divergence-of-a-series/" rel="alternate" type="text/html" hreflang="fr" /><link href="https://www.yunseo.kim/de/posts/testing-for-convergence-or-divergence-of-a-series/" rel="alternate" type="text/html" hreflang="de" /><link href="https://www.yunseo.kim/pl/posts/testing-for-convergence-or-divergence-of-a-series/" rel="alternate" type="text/html" hreflang="pl" /><link href="https://www.yunseo.kim/cs/posts/testing-for-convergence-or-divergence-of-a-series/" rel="alternate" type="text/html" hreflang="cs" /><link href="https://www.yunseo.kim/sw/posts/testing-for-convergence-or-divergence-of-a-series/" rel="alternate" type="text/html" hreflang="sw" /><link href="https://www.yunseo.kim/am/posts/testing-for-convergence-or-divergence-of-a-series/" rel="alternate" type="text/html" hreflang="am" /><published>2025-03-18T00:00:00+09:00</published> <updated>2025-05-13T16:24:07+09:00</updated> <id>https://www.yunseo.kim/ko/posts/testing-for-convergence-or-divergence-of-a-series/</id> <author> <name>Yunseo Kim</name> </author> <category term="Mathematics" /> <category term="Calculus" /> <summary xml:lang="ko">급수의 수렴/발산을 판정하는 여러 방법들을 종합하여 살펴본다.</summary> <content type="html" xml:lang="ko"> <![CDATA[<p>급수의 수렴/발산을 판정하는 여러 방법들을 종합하여 살펴본다.</p><em><p>* Mathematical equations and diagrams included in posts may not display properly when viewed with a feed reader.</p></em><h2 id="tldr">TL;DR</h2><blockquote class="prompt-info"><ul><li><strong>일반항 판정법($n$th-term test for divergence)</strong>: $\lim_{n\to\infty} a_n \neq 0 \Rightarrow \text{급수 }\sum a_n \text{은 발산}$<li><strong>기하급수의 수렴/발산</strong>: 기하급수 $\sum ar^{n-1}$은<ul><li>$|r| &lt; 1$이면 수렴<li>$|r| \geq 1$이면 발산</ul><li><strong>$p$-급수의 수렴/발산</strong>: $p$-급수 $\sum \cfrac{1}{n^p}$은<ul><li>$p&gt;1$이면 수렴<li>$p\leq 1$이면 발산</ul><li><strong>비교판정법(Comparison Test)</strong>: $0 \leq a_n \leq b_n$일 때,<ul><li>$\sum b_n &lt; \infty \ \Rightarrow \ \sum a_n &lt; \infty$<li>$\sum a_n = \infty \ \Rightarrow \ \sum b_n = \infty$</ul><li><strong>극한비교판정법(Limit Comparison Test)</strong>: 만약 $\lim_{n\to\infty} \frac{a_n}{b_n} = c \text{ (}c\text{는 유한한 양수)}$라면, 두 급수 $\sum a_n$과 $\sum b_n$은 둘 다 수렴하거나 둘 다 발산<li>양항급수 $\sum a_n$과 양수 $\epsilon &lt; 1$에 대하여<ul><li>모든 $n$에 대하여 $\sqrt[n]{a_n}&lt; 1-\epsilon$이면 급수 $\sum a_n$은 수렴<li>모든 $n$에 대하여 $\sqrt[n]{a_n}&gt; 1+\epsilon$이면 급수 $\sum a_n$은 발산</ul><li><strong>거듭제곱근 판정법(Root Test)</strong>: 양항급수 $\sum a_n$에서 극한값 $\lim_{n\to\infty} \sqrt[n]{a_n} =: r$이 존재할 경우,<ul><li>$r&lt;1$이면 급수 $\sum a_n$은 수렴<li>$r&gt;1$이면 급수 $\sum a_n$은 발산</ul><li><strong>비율판정법(Ratio Test)</strong>: 양수의 수열 $(a_n)$과 $0 &lt; r &lt; 1$에 대하여<ul><li>모든 $n$에 대하여 $a_{n+1}/a_n \leq r$이면, 급수 $\sum a_n$은 수렴<li>모든 $n$에 대하여 $a_{n+1}/a_n \geq 1$이면, 급수 $\sum a_n$은 발산</ul><li>양수의 수열 $(a_n)$에서 극한값 $\rho := \lim_{n\to\infty} \cfrac{a_{n+1}}{a_n}$이 존재한다고 하면,<ul><li>$\rho &lt; 1$이면 급수 $\sum a_n$은 수렴<li>$\rho &gt; 1$이면 급수 $\sum a_n$은 발산</ul><li><strong>적분판정법(Integral Test)</strong>: 연속함수 $f: \left[1,\infty \right) \rightarrow \mathbb{R}$이 감소함수이고 항상 $f(x)&gt;0$일 때, 급수 $\sum f(n)$이 수렴할 필요충분조건은 적분 $\int_1^\infty f(x)\ dx := \lim_{b\to\infty} \int_1^b f(x)\ dx$가 수렴하는 것<li><strong>교대급수 판정법(Alternating Series Test)</strong>: 다음 조건을 만족하는 경우 교대급수 $\sum a_n$은 수렴<ol><li>모든 $n$에 대하여 $a_n$과 $a_{n+1}$의 부호가 다름<li>모든 $n$에 대하여 $|a_n| \geq |a_{n+1}|$<li>$\lim_{n\to\infty} a_n = 0$</ol><li>절대수렴하는 급수는 수렴함. 역은 성립하지 않음.</ul></blockquote><h2 id="prerequisites">Prerequisites</h2><ul><li><a href="/ko/posts/sequences-and-series/">수열과 급수</a></ul><h2 id="들어가며">들어가며</h2><p>앞서 <a href="/ko/posts/sequences-and-series/#급수의-수렴과-발산">수열과 급수</a>에서 급수의 수렴과 발산에 대한 정의를 알아보았다. 이 글에서는 급수의 수렴/발산을 판정할 때 사용할 수 있는 여러 가지 방법들을 정리한다. 일반적으로 급수의 수렴/발산 판정은 급수의 합을 정확하게 구하는 것보다는 훨씬 쉽다.</p><h2 id="일반항-판정법">일반항 판정법</h2><p>급수 $\sum a_n$에 대하여, $a_n$을 해당 급수의 <strong>일반항</strong>이라고 한다.</p><p>다음 정리에 의해 어떤 급수는 명백하게 발산함을 쉽게 알 수 있으며, 따라서 어떤 급수의 수렴/발산을 판정할 때는 이를 제일 먼저 확인해 보는 것이 시간 낭비를 막을 수 있는 현명한 방법이다.</p><blockquote class="prompt-info"><p><strong>일반항 판정법($n$th-term test for divergence)</strong><br /> 급수 $\sum a_n$이 수렴하면,</p>\[\lim_{n\to\infty} a_n=0\]<p>이다. 즉,</p>\[\lim_{n\to\infty} a_n \neq 0 \Rightarrow \text{급수 }\sum a_n \text{은 발산}\]<p>이다.</p></blockquote><h3 id="증명">증명</h3><p>수렴하는 어떤 급수 $\sum a_n$의 합을 $l$이라 하고 처음 $n$항까지의 합을</p>\[s_n := a_1 + a_2 + \cdots + a_n\]<p>으로 두면,</p>\[\forall \epsilon &gt; 0,\, \exists N \in \mathbb{N}\ (n &gt; N \Rightarrow |s_n - l| &lt; \epsilon).\]<p>따라서 충분히 큰($&gt;N$) $n$에 대하여</p>\[|a_n| = |s_n - s_{n-1}| = |(s_n - l) - (s_{n-1} - l)| \leq |s_n - l| + |s_{n-1} - l| \leq \epsilon + \epsilon = 2\epsilon\]<p>이므로, 수열의 수렴의 정의로부터</p>\[\lim_{n\to\infty} |a_n| = 0. \quad \blacksquare\]<h3 id="주의사항">주의사항</h3><p>이 정리의 역은 일반적으로 참이 아니다. 이를 보여주는 대표적인 예시는 <strong>조화급수(harmonic series)</strong>이다.</p><p>조화급수는 각 항이 <strong>등차수열</strong>의 역수로 주어진 수열, 즉 <strong>조화수열</strong>에서 얻은 급수이다. 대표적인 조화급수는</p>\[H_n := 1 + \frac{1}{2} + \cdots + \frac{1}{n} \quad (n=1,2,3,\dots)\]<p>이다. 이 급수는 발산함을 다음과 같이 보일 수 있다.</p>\[\begin{align*} \lim_{n\to\infty} H_n &amp;= 1 + \frac{1}{2} + \frac{1}{3} + \frac{1}{4} + \frac{1}{5} + \frac{1}{6} + \frac{1}{7} + \frac{1}{8} + \frac{1}{9} + \cdots + \frac{1}{16} + \cdots \\ &amp;&gt; 1 + \frac{1}{2} + \frac{1}{4} + \frac{1}{4} + \frac{1}{8} + \frac{1}{8} + \frac{1}{8} + \frac{1}{8} + \frac{1}{16} + \cdots + \frac{1}{16} + \cdots \\ &amp;= 1 + \frac{1}{2} \qquad\, + \frac{1}{2} \qquad\qquad\qquad\ \ + \frac{1}{2} \qquad\qquad\quad + \frac{1}{2} + \cdots \\ &amp;= \infty. \end{align*}\]<p>이처럼 급수 $H_n$이 발산함에도 불구하고, 일반항 $1/n$은 $0$에 수렴함을 알 수 있다.</p><blockquote class="prompt-danger"><p>$\lim_{n\to\infty} a_n \neq 0$이면 급수 $\sum a_n$은 반드시 발산하지만, $\lim_{n\to\infty} a_n = 0$이라고 해서 급수 $\sum a_n$이 수렴할 거라고 생각하는 것은 위험하며 이 경우 다른 방법들을 사용하여 수렴/발산을 판정해야 한다.</p></blockquote><h2 id="기하급수">기하급수</h2><p>첫항이 1이고 <strong>공비</strong>가 $r$인 등비수열에서 얻은 <strong>기하급수(geometric series)</strong></p>\[1 + r + r^2 + r^3 + \cdots \label{eqn:geometric_series}\tag{5}\]<p>는 <u>가장 중요하고, 기본적인 급수</u>이다. 이때 등식</p>\[(1-r)(1+r+\cdots + r^{n-1}) = 1 - r^n\]<p>에서</p>\[1 + r + \cdots + r^{n-1} = \frac{1-r^n}{1-r} = \frac{1}{1-r} - \frac{r^n}{1-r} \qquad (r \neq 1) \label{eqn:sum_of_geometric_series}\tag{6}\]<p>을 얻는다. 한편</p>\[\lim_{n\to\infty} r^n = 0 \quad \Leftrightarrow \quad |r| &lt; 1\]<p>이므로, 기하급수 ($\ref{eqn:geometric_series}$)가 수렴할 필요충분조건은 $|r| &lt; 1$임을 안다.</p><blockquote class="prompt-info"><p><strong>기하급수의 수렴/발산</strong><br /> 기하급수 $\sum ar^{n-1}$은</p><ul><li>$|r| &lt; 1$이면 수렴<li>$|r| \geq 1$이면 발산</ul></blockquote><p>이로부터</p>\[1 + r + r^2 + r^3 + \cdots = \frac{1}{1-r} \qquad (|r| &lt; 1) \label{eqn:sum_of_inf_geometric_series}\tag{7}\]<p>을 얻는다.</p><h3 id="기하급수와-근삿값">기하급수와 근삿값</h3><p>항등식 ($\ref{eqn:sum_of_geometric_series}$)은 $|r| &lt; 1$일 때 $\cfrac{1}{1-r}$의 근삿값을 구하는 데에 유용하게 쓰인다.</p><p>이 식에 $r=-\epsilon$, $n=2$를 대입하면</p>\[\frac{1}{1+\epsilon} - (1 - \epsilon) = \frac{\epsilon^2}{1 + \epsilon}\]<p>을 얻는다. 따라서 $0 &lt; \epsilon &lt; 1$이면</p>\[0 &lt; \frac{1}{1 + \epsilon} - (1 - \epsilon) &lt; \epsilon^2\]<p>이므로</p>\[\frac{1}{1 + \epsilon} \approx (1 - \epsilon) \pm \epsilon^2 \qquad (0 &lt; \epsilon &lt; 1)\]<p>을 얻는다. 이로부터, 충분히 작은 양수 $\epsilon$에 대하여 $\cfrac{1}{1 + \epsilon}$은 $1 - \epsilon$으로 근사할 수 있음을 알 수 있다.</p><h2 id="p-급수-판정법-p-series-test">$p$-급수 판정법 ($p$-Series Test)</h2><p>양의 실수 $p$에 대하여, 다음과 같은 형태의 급수를 <strong>$p$-급수</strong>라고 한다.</p>\[\sum_{n=1}^{\infty} \frac{1}{n^p}\]<blockquote class="prompt-info"><p><strong>$p$-급수의 수렴/발산</strong><br /> $p$-급수 $\sum \cfrac{1}{n^p}$은</p><ul><li>$p&gt;1$이면 수렴<li>$p\leq 1$이면 발산</ul></blockquote><p>$p$-급수에서 $p=1$인 경우 조화급수가 되며, 이는 발산함을 앞서 보였다.<br /> $p=2$인 경우의 $p$-급수, 즉 $\sum \cfrac{1}{n^2}$의 값을 구하는 문제는, 이 급수가 수렴함을 처음 보였으며 여러 대에 걸쳐 유명한 수학자 여럿을 배출해 낸 가문이기도 한 베르누이 집안의 근거지 이름을 따서 ‘바젤(Basel) 문제’라고 부른다. 이 문제의 답은 $\cfrac{\pi^2}{6}$임이 알려져 있다.</p><p>또한 더 일반적으로는, $p$-급수에서 $p&gt;1$인 경우를 <strong>제타 함수(zeta function)</strong>라고 한다. 이는 레온하르트 오일러(Leonhard Euler)가 <a href="https://en.wikipedia.org/wiki/Holocene_calendar">인류력</a> 11740년에 도입하고 이후 리만이 이름을 지은 특수함수의 하나로,</p>\[\zeta(s) := \sum_{n=1}^{\infty} \frac{1}{n^s} \qquad (s&gt;1)\]<p>로 정의한다.</p><p>이 글의 주제에서 다소 벗어나는 데다, 솔직히 말해서 난 공대생이지 수학자는 아니므로 나도 잘 모르기 때문에 여기서 다루진 않으나, 레온하르트 오일러는 <strong>오일러 곱(Euler Product)</strong>이라는 소수(prime number)의 무한곱 형태로도 제타 함수를 표현할 수 있음을 보였으며 이후 제타 함수는 해석적 정수론 하위의 여러 분야에서 핵심적인 위치를 차지한다. 제타 함수의 정의역을 복소수로 확장한 <strong>리만 제타 함수(Riemann zeta function)</strong>와 그에 관한 중요한 미해결 난제인 <strong>리만 가설(Riemann hypothesis)</strong>도 그 중 하나이다.</p><p>원래의 주제로 돌아와서, $p$-급수 판정법의 증명을 위해서는 후술할 <a href="#비교판정법">비교판정법</a>과 <a href="#적분판정법">적분판정법</a>이 필요하다. 그러나 $p$-급수의 수렴/발산은 기하급수와 함께 바로 뒤에 다룰 <a href="#비교판정법">비교판정법</a>에서 유용하게 쓰일 수 있기 때문에 의도적으로 앞쪽에 배치하였다.</p><h3 id="증명-1">증명</h3><h4 id="i-p1일-때">i) $p&gt;1$일 때</h4><p>적분</p>\[\int_1^\infty \frac{1}{x^p}\ dx = \left[\frac{1}{-p+1}\frac{1}{x^{p-1}} \right]^\infty_1 = \frac{1}{p-1}\]<p>이 수렴하므로, <a href="#적분판정법">적분판정법</a>에 의해 급수 $\sum \cfrac{1}{n^p}$도 수렴함을 알 수 있다.</p><h4 id="ii-pleq-1일-때">ii) $p\leq 1$일 때</h4><p>이 경우</p>\[0 \leq \frac{1}{n} \leq \frac{1}{n^p}\]<p>이다. 여기서 조화급수 $\sum \cfrac{1}{n}$은 발산함을 알고 있으므로, <a href="#비교판정법">비교판정법</a>에 의해 $\sum \cfrac{1}{n^p}$ 또한 발산함을 알 수 있다.</p><h4 id="결론">결론</h4><p>i), ii)에 의하여, $p$-급수 $\sum \cfrac{1}{n^p}$은 $p&gt;1$이면 수렴, $p \leq 1$이면 발산한다. $\blacksquare$</p><h2 id="비교판정법">비교판정법</h2><p>일반항이 $0$ 이상의 실수로 이루어진 급수인 <strong>양항급수(series of positive terms)</strong>의 수렴/발산을 판정할 때는 야코프 베르누이(Jakob Bernoulli)의 <strong>비교판정법(Comparison Test)</strong>이 유용하다.</p><p>양항급수 $\sum a_n$은 증가하는 수열이므로, 무한대로 발산하는 경우($\sum a_n = \infty$)가 아니라면 반드시 수렴하는 것이다. 그러므로 양항급수에서</p>\[\sum a_n &lt; \infty\]<p>와 같은 표현은 <u>수렴한다</u>는 의미이다.</p><blockquote class="prompt-info"><p><strong>비교판정법(Comparison Test)</strong><br /> $0 \leq a_n \leq b_n$일 때,</p><ul><li>$\sum b_n &lt; \infty \ \Rightarrow \ \sum a_n &lt; \infty$<li>$\sum a_n = \infty \ \Rightarrow \ \sum b_n = \infty$</ul></blockquote><p>특히, 양항급수 중에서도 $\sum \cfrac{1}{n^2 + n}$, $\sum \cfrac{\log n}{n^3}$, $\sum \cfrac{1}{2^n + 3^n}$, $\sum \cfrac{1}{\sqrt{n}}$, $\sum \sin{\cfrac{1}{n}}$ 등과 같이 앞서 살펴본 등비급수 $\sum ar^{n-1}$이나 $p$-급수 $\sum \cfrac{1}{n^p}$과 유사한 형태를 가진 급수의 수렴/발산을 판정할 때는 비교판정법을 적극적으로 시도해 보는 것이 좋다.</p><p>후술하는 다른 여러 수렴/발산 판정법들은 모두 이 <strong>비교판정법</strong>으로부터 유도할 수 있으며, 그런 의미에서 비교판정법이 가장 중요하다고 할 수 있다.</p><h3 id="극한비교판정법">극한비교판정법</h3><p>양항급수 $\sum a_n$과 $\sum b_n$에 대하여, 두 급수의 일반항의 비 $a_n/b_n$에서 분자와 분모의 우세한 항(dominant term)이 상쇄되어 $\lim_{n\to\infty} \cfrac{a_n}{b_n}=c \text{ (}c\text{는 유한한 양수)}$라고 하자. 이때 급수 $\sum b_n$의 수렴/발산 여부를 알고 있다면 다음의 <strong>극한비교판정법(Limit Comparison Test)</strong>을 활용할 수 있다.</p><blockquote class="prompt-info"><p><strong>극한비교판정법(Limit Comparison Test)</strong><br /> 만약</p>\[\lim_{n\to\infty} \frac{a_n}{b_n} = c \text{ (}c\text{는 유한한 양수)}\]<p>라면, 두 급수 $\sum a_n$과 $\sum b_n$은 둘 다 수렴하거나 둘 다 발산한다. 즉, $ \sum a_n &lt; \infty \ \Leftrightarrow \ \sum b_n &lt; \infty$이다.</p></blockquote><h2 id="거듭제곱근-판정법">거듭제곱근 판정법</h2><blockquote class="prompt-info"><p><strong>정리</strong><br /> 양항급수 $\sum a_n$과 양수 $\epsilon &lt; 1$에 대하여</p><ul><li>모든 $n$에 대하여 $\sqrt[n]{a_n}&lt; 1-\epsilon$이면 급수 $\sum a_n$은 수렴<li>모든 $n$에 대하여 $\sqrt[n]{a_n}&gt; 1+\epsilon$이면 급수 $\sum a_n$은 발산</ul></blockquote><blockquote class="prompt-info"><p><strong>따름정리: 거듭제곱근 판정법(Root Test)</strong><br /> 양항급수 $\sum a_n$에서 극한값</p>\[\lim_{n\to\infty} \sqrt[n]{a_n} =: r\]<p>이 존재한다고 하자. 이때</p><ul><li>$r&lt;1$이면 급수 $\sum a_n$은 수렴<li>$r&gt;1$이면 급수 $\sum a_n$은 발산</ul></blockquote><blockquote class="prompt-warning"><p>위의 따름정리에서 $r=1$일 경우에는 수렴/발산을 판정할 수 없으므로 다른 방법을 사용해야 한다.</p></blockquote><h2 id="비율판정법">비율판정법</h2><blockquote class="prompt-info"><p><strong>비율판정법(Ratio Test)</strong><br /> 양수의 수열 $(a_n)$과 $0 &lt; r &lt; 1$에 대하여</p><ul><li>모든 $n$에 대하여 $a_{n+1}/a_n \leq r$이면, 급수 $\sum a_n$은 수렴<li>모든 $n$에 대하여 $a_{n+1}/a_n \geq 1$이면, 급수 $\sum a_n$은 발산</ul></blockquote><blockquote class="prompt-info"><p><strong>따름정리</strong><br /> 양수의 수열 $(a_n)$에서 극한값 $\rho := \lim_{n\to\infty} \cfrac{a_{n+1}}{a_n}$이 존재한다고 하자. 이때</p><ul><li>$\rho &lt; 1$이면 급수 $\sum a_n$은 수렴<li>$\rho &gt; 1$이면 급수 $\sum a_n$은 발산</ul></blockquote><h2 id="적분판정법">적분판정법</h2><p>적분법을 이용하면 감소하는 양의 수열로 이루어진 급수의 수렴/발산을 판정할 수 있다.</p><blockquote class="prompt-info"><p><strong>적분판정법(Integral Test)</strong><br /> 연속함수 $f: \left[1,\infty \right) \rightarrow \mathbb{R}$이 감소함수이고 항상 $f(x)&gt;0$일 때, 급수 $\sum f(n)$이 수렴할 필요충분조건은 적분</p>\[\int_1^\infty f(x)\ dx := \lim_{b\to\infty} \int_1^b f(x)\ dx\]<p>가 수렴하는 것이다.</p></blockquote><h3 id="증명-2">증명</h3><p>함수 $f(x)$가 연속이고 감소함수이면서 부호는 항상 양수이므로, 부등식</p>\[f(n+1) \leq \int_n^{n+1} f(x)\ dx \leq f(n)\]<p>가 성립한다. 이 부등식을 $n=1$부터 일반항까지 변끼리 더하면 부등식</p>\[f(2) + \cdots + f(n+1) \leq \int_1^{n+1} f(x)\ dx \leq f(1) + \cdots + f(n)\]<p>을 얻는다. 이제 <a href="#비교판정법">비교판정법</a>을 쓰면 원하는 결과를 얻는다. $\blacksquare$</p><h2 id="교대급수">교대급수</h2><p>일반항이 $0$이 아니면서 각 항 $a_n$의 부호가 그 다음 항 $a_{n+1}$의 부호와 다른, 즉 양항과 음항이 번갈아 가며 나타나는 급수 $\sum a_n$을 <strong>교대급수(alternating series)</strong>라고 한다.</p><p>교대급수에 대하여, 독일의 수학자 고트프리트 빌헬름 라이프니츠(Gottfried Wilhelm Leibniz)가 발견한 다음 정리를 수렴/발산 판정에 유용하게 활용할 수 있다.</p><blockquote class="prompt-info"><p><strong>교대급수 판정법(Alternating Series Test)</strong></p><ol><li>모든 $n$에 대하여 $a_n$과 $a_{n+1}$의 부호가 다르고,<li>모든 $n$에 대하여 $|a_n| \geq |a_{n+1}|$이며,<li>$\lim_{n\to\infty} a_n = 0$이면,</ol><p>교대급수 $\sum a_n$은 수렴한다.</p></blockquote><h2 id="절대수렴급수">절대수렴급수</h2><p>급수 $\sum a_n$에 대하여 급수 $\sum |a_n|$이 수렴하면, “급수 $\sum a_n$은 <strong>절대수렴</strong>한다(<strong>converge absolutely</strong>)”라고 한다.</p><p>이때 다음 정리가 성립한다.</p><blockquote class="prompt-info"><p><strong>정리</strong><br /> 절대수렴하는 급수는 수렴한다.</p></blockquote><blockquote class="prompt-warning"><p>위 정리의 역은 성립하지 않는다.<br /> 급수가 수렴하지만 절대수렴하지는 않는 경우 “<strong>조건수렴</strong>한다(<strong>converge conditionally</strong>)”라고 한다.</p></blockquote><h3 id="증명-3">증명</h3><p>실수 $a$에 대하여</p>\[\begin{align*} a^+ &amp;:= \max\{a,0\} = \frac{1}{2}(|a| + a), \\ a^- &amp;:= -\min\{a,0\} = \frac{1}{2}(|a| - a) \end{align*}\]<p>로 두면,</p>\[a = a^+ - a^-, \qquad |a| = a^+ + a^-\]<p>를 얻는다. 그러면 $0 \leq a^\pm \leq |a|$이므로, <a href="#비교판정법">비교판정법</a>에 의하여 급수 $\sum |a_n|$이 수렴할 경우 급수 $\sum a_n^+$와 $\sum a_n^-$도 모두 수렴하고, 따라서 <a href="/ko/posts/sequences-and-series/#수렴하는-급수의-기본-성질">수렴하는 급수의 기본 성질</a>에 의해</p>\[\sum a_n = \sum (a_n^+ - a_n^-) = \sum a_n^+ - \sum a_n^-\]<p>도 수렴한다. $\blacksquare$</p>]]> </content> </entry> <entry><title xml:lang="ko">수열과 급수</title><link href="https://www.yunseo.kim/ko/posts/sequences-and-series/" rel="alternate" type="text/html" hreflang="en" /><link href="https://www.yunseo.kim/ko/posts/sequences-and-series/" rel="alternate" type="text/html" hreflang="ko" /><link href="https://www.yunseo.kim/ja/posts/sequences-and-series/" rel="alternate" type="text/html" hreflang="ja" /><link href="https://www.yunseo.kim/zh-TW/posts/sequences-and-series/" rel="alternate" type="text/html" hreflang="zh-TW" /><link href="https://www.yunseo.kim/es/posts/sequences-and-series/" rel="alternate" type="text/html" hreflang="es" /><link href="https://www.yunseo.kim/pt-BR/posts/sequences-and-series/" rel="alternate" type="text/html" hreflang="pt-BR" /><link href="https://www.yunseo.kim/fr/posts/sequences-and-series/" rel="alternate" type="text/html" hreflang="fr" /><link href="https://www.yunseo.kim/de/posts/sequences-and-series/" rel="alternate" type="text/html" hreflang="de" /><link href="https://www.yunseo.kim/pl/posts/sequences-and-series/" rel="alternate" type="text/html" hreflang="pl" /><link href="https://www.yunseo.kim/cs/posts/sequences-and-series/" rel="alternate" type="text/html" hreflang="cs" /><link href="https://www.yunseo.kim/sw/posts/sequences-and-series/" rel="alternate" type="text/html" hreflang="sw" /><link href="https://www.yunseo.kim/am/posts/sequences-and-series/" rel="alternate" type="text/html" hreflang="am" /><published>2025-03-16T00:00:00+09:00</published> <updated>2025-05-13T16:24:07+09:00</updated> <id>https://www.yunseo.kim/ko/posts/sequences-and-series/</id> <author> <name>Yunseo Kim</name> </author> <category term="Mathematics" /> <category term="Calculus" /> <summary xml:lang="ko">수열과 급수의 정의, 수열의 수렴과 발산, 급수의 수렴과 발산, 자연로그의 밑 e의 정의 등 미적분학의 기초 개념들을 살펴본다.</summary> <content type="html" xml:lang="ko"> <![CDATA[<p>수열과 급수의 정의, 수열의 수렴과 발산, 급수의 수렴과 발산, 자연로그의 밑 e의 정의 등 미적분학의 기초 개념들을 살펴본다.</p><em><p>* Mathematical equations and diagrams included in posts may not display properly when viewed with a feed reader.</p></em><h2 id="수열">수열</h2><p>미적분학에서 다루는 <strong>수열(sequence)</strong>은 주로 무한수열을 뜻한다. 즉, 수열이란 <strong>자연수(natural number)</strong> 전체집합</p>\[\mathbb{N} := \{1,2,3,\dots\}\]<p>에서 정의된 함수이다.* 이 함수의 값들이 실수(real number)이면 ‘실수열’, 복소수(complex number)이면 ‘복소수열’, 점(point)이면 ‘점렬’, 행렬(matrix)이면 ‘행렬렬’, 함수(function)이면 ‘함수열’, 집합(set)이면 ‘집합렬’ 등으로 부를 수 있지만, 이들 모두를 간단하게 ‘열’ 또는 ‘수열’로 지칭할 수 있다.</p><p>보통 <strong>실수체(the field of real numbers)</strong> $\mathbb{R}$에 대하여, 수열 $\mathbf{a}: \mathbb{N} \to \mathbb{R}$에서</p>\[a_1 := \mathbf{a}(1), \quad a_2 := \mathbf{a}(2), \quad a_3 := \mathbf{a}(3)\]<p>등으로 두고, 이 수열을</p>\[a_1,\, a_2,\, a_3,\, \dots\]<p>또는</p>\[\begin{gather*} (a_1,a_2,a_3,\dots), \\ (a_n: n=1,2,3,\dots), \\ (a_n)_{n=1}^{\infty}, \qquad (a_n) \end{gather*}\]<p>등으로 나타낸다.</p><blockquote class="prompt-info"><p>*수열을 정의하는 과정에서 정의역을 자연수 전체집합 $\mathbb{N}$ 대신 $0$ 이상의 정수 집합</p>\[\mathbb{N}_0 := \{0\} \cup \mathbb{N} = \{0,1,2,\dots\}\]<p>또는</p>\[\{2,3,4,\dots \}\]<p>등으로 잡을 수도 있다. 예를 들어, 거듭제곱급수 이론을 다룰 때는 정의역이 $\mathbb{N}_0$인 것이 더 자연스럽다.</p></blockquote><h2 id="수렴과-발산">수렴과 발산</h2><p>수열 $(a_n)$이 실수 $l$에 수렴하면</p>\[\lim_{n\to \infty} a_n = l\]<p>로 쓰고, 이때 $l$을 수열 $(a_n)$의 <strong>극한값</strong>이라 한다.</p><blockquote class="prompt-info"><p><strong>엡실론-델타 논법(epsilon-delta argument)</strong>을 이용한 엄밀한 정의는 다음과 같다.</p>\[\lim_{n\to \infty} a_n = l \overset{def}\Longleftrightarrow \forall \epsilon &gt; 0,\, \exists N \in \mathbb{N}\ (n &gt; N \Rightarrow |a_n - l| &lt; \epsilon)\]<p>즉, 아무리 작은 양수 $\epsilon$에 대해서도 $n&gt;N$일 때 $|a_n - l | &lt; \epsilon$을 만족하는 자연수 $N$이 항상 존재한다면, 충분히 큰 $n$에 대하여 $a_n$과 $l$의 차가 한없이 작아진다는 의미이므로 이를 만족하는 수열 $(a_n)$은 실수 $l$로 수렴한다고 정의한다.</p></blockquote><p>수렴하지 않는 수열은 <strong>발산</strong>한다고 한다. <em>수열의 수렴 혹은 발산 여부는 그 수열의 유한 개의 항이 바뀌어도 변하지 않는다.</em></p><p>만약 수열 $(a_n)$의 각 항이 한없이 커지면</p>\[\lim_{n\to \infty} a_n = \infty\]<p>라고 쓰고 <em>양의 무한대로 발산한다</em>고 한다. 마찬가지로, 수열 $(a_n)$의 각 항이 한없이 작아지면</p>\[\lim_{n\to \infty} a_n = -\infty\]<p>라고 쓰고 <em>음의 무한대로 발산한다</em>고 한다.</p><h2 id="수렴하는-수열의-기본-성질">수렴하는 수열의 기본 성질</h2><p>수열 $(a_n)$과 $(b_n)$이 모두 수렴하면(즉 극한값을 가지면), 수열 $(a_n + b_n)$과 $(a_n \cdot b_n)$도 마찬가지로 수렴하며, 이때</p>\[\lim_{n\to \infty} (a_n + b_n) = \lim_{n\to \infty} a_n + \lim_{n\to \infty} b_n \label{eqn:props_of_conv_series_1}\tag{1}\] \[\lim_{n\to \infty} (a_n \cdot b_n) = \left(\lim_{n\to \infty} a_n \right) \cdot \left(\lim_{n\to \infty} b_n \right) \label{eqn:props_of_conv_series_2}\tag{2}\]<p>이다. 또한 임의의 실수 $t$에 대하여</p>\[\lim_{n\to \infty} (t a_n) = t\left(\lim_{n\to \infty} a_n \right) \label{eqn:props_of_conv_series_3}\tag{3}\]<p>이다. 이러한 성질을 <strong>수렴하는 수열의 기본 성질</strong> 또는 <strong>극한의 기본 성질</strong>이라 한다.</p><h2 id="자연로그의-밑-e">자연로그의 밑 $e$</h2><p><strong>자연로그의 밑</strong>은</p>\[e := \lim_{n\to \infty} \left(1+\frac{1}{n} \right)^n \approx 2.718\]<p>로 정의한다. 이는 수학에서 가장 중요한 상수 중 하나라고 할 수 있다.</p><blockquote class="prompt-tip"><p>유독 한국에서만 ‘자연상수’라는 표현이 꽤 널리 쓰이고 있으나, 이는 표준 용어가 아니다. 대한수학회에서 수학용어집에 등재한 공식 용어는 <a href="https://www.kms.or.kr/mathdict/list.html?key=kname&amp;keyword=%EC%9E%90%EC%97%B0%EB%A1%9C%EA%B7%B8%EC%9D%98+%EB%B0%91">‘자연로그의 밑’</a>이며, ‘자연상수’라는 표현은 해당 용어집에서 찾아볼 수 없다. 심지어 국립국어원 표준국어대사전에서도 ‘자연상수’라는 단어는 찾아볼 수 없으며, <a href="https://stdict.korean.go.kr/search/searchView.do?pageSize=10&amp;searchKeyword=%EC%9E%90%EC%97%B0%EB%A1%9C%EA%B7%B8">‘자연로그’에 대한 사전 풀이</a>에서 “흔히 e로 표시하는 특정한 수”라고만 언급하고 있다.<br /> 영어권과 일본에서도 이에 대응하는 용어는 존재하지 않으며, 영어 기준으로 ‘the base of the natural logarithm’이나 줄여서 ‘natural base’, 혹은 ‘Euler’s number’나 ‘the number $e$’ 정도로 주로 지칭하는 듯 하다.<br /> 출처도 불분명하고 대한수학회에서 공식 용어로 인정한 적도 없을 뿐더러, 한국을 제외하면 전 세계 어디에서도 쓰지 않는 이러한 용어를 고집할 이유가 전혀 없으므로, 앞으로 여기서는 나도 ‘자연로그의 밑’이라고 지칭하거나 그냥 $e$라고 표기하겠다.</p></blockquote><h2 id="급수">급수</h2><p>수열</p>\[\mathbf{a} = (a_1, a_2, a_3, \dots)\]<p>에 대하여, 이 수열의 부분합들로 이루어진 또다른 수열</p>\[a_1, \quad a_1 + a_2, \quad a_1 + a_2 + a_3, \quad \dots\]<p>를 수열 $\mathbf{a}$의 <strong>급수</strong>라고 한다. 수열 $(a_n)$의 급수는</p>\[\begin{gather*} a_1 + a_2 + a_3 + \cdots, \qquad \sum_{n=1}^{\infty}a_n, \\ \sum_{n\geq 1} a_n, \qquad \sum_n a_n, \qquad \sum a_n \end{gather*}\]<p>등으로 나타낸다.</p><h2 id="급수의-수렴과-발산">급수의 수렴과 발산</h2><p>수열 $(a_n)$에서 얻은 급수</p>\[a_1, \quad a_1 + a_2, \quad a_1 + a_2 + a_3, \quad \dots\]<p>가 어떤 실수 $l$에 수렴하면</p>\[\sum_{n=1}^{\infty} a_n = l\]<p>로 나타낸다. 이때 극한값 $l$을 급수 $\sum a_n$의 <strong>합</strong>이라고 부른다. 기호</p>\[\sum a_n\]<p>은 상황에 따라서 <u>급수</u>를 나타내기도 하고, 그 <u>급수의 합</u>을 나타내기도 한다.</p><p>수렴하지 않는 급수는 <strong>발산</strong>한다고 한다.</p><h2 id="수렴하는-급수의-기본-성질">수렴하는 급수의 기본 성질</h2><p><a href="#수렴하는-수열의-기본-성질">수렴하는 수열의 기본 성질</a>로부터 다음과 같이 수렴하는 급수의 기본 성질을 얻는다. 실수 $t$와 수렴하는 두 급수 $\sum a_n$, $\sum b_n$에 대하여</p>\[\sum(a_n + b_n) = \sum a_n + \sum b_n, \qquad \sum ta_n = t\sum a_n \tag{4}\]<p>이 성립한다.</p><p>급수의 수렴성은 유한개의 항의 변화에 영향을 받지 않는다. 즉, 두 수열 $(a_n)$, $(b_n)$에서 유한 개의 $n$을 제외하고 $a_n=b_n$이면, 급수 $\sum a_n$이 수렴할 필요충분조건은 급수 $\sum b_n$이 수렴하는 것이다.</p>]]> </content> </entry> <entry><title xml:lang="ko">뉴턴의 운동 법칙</title><link href="https://www.yunseo.kim/ko/posts/newtons-laws-of-motion/" rel="alternate" type="text/html" hreflang="en" /><link href="https://www.yunseo.kim/ko/posts/newtons-laws-of-motion/" rel="alternate" type="text/html" hreflang="ko" /><link href="https://www.yunseo.kim/ja/posts/newtons-laws-of-motion/" rel="alternate" type="text/html" hreflang="ja" /><link href="https://www.yunseo.kim/zh-TW/posts/newtons-laws-of-motion/" rel="alternate" type="text/html" hreflang="zh-TW" /><link href="https://www.yunseo.kim/es/posts/newtons-laws-of-motion/" rel="alternate" type="text/html" hreflang="es" /><link href="https://www.yunseo.kim/pt-BR/posts/newtons-laws-of-motion/" rel="alternate" type="text/html" hreflang="pt-BR" /><link href="https://www.yunseo.kim/fr/posts/newtons-laws-of-motion/" rel="alternate" type="text/html" hreflang="fr" /><link href="https://www.yunseo.kim/de/posts/newtons-laws-of-motion/" rel="alternate" type="text/html" hreflang="de" /><link href="https://www.yunseo.kim/pl/posts/newtons-laws-of-motion/" rel="alternate" type="text/html" hreflang="pl" /><link href="https://www.yunseo.kim/cs/posts/newtons-laws-of-motion/" rel="alternate" type="text/html" hreflang="cs" /><link href="https://www.yunseo.kim/sw/posts/newtons-laws-of-motion/" rel="alternate" type="text/html" hreflang="sw" /><link href="https://www.yunseo.kim/am/posts/newtons-laws-of-motion/" rel="alternate" type="text/html" hreflang="am" /><published>2025-03-10T00:00:00+09:00</published> <updated>2026-02-16T05:09:10+09:00</updated> <id>https://www.yunseo.kim/ko/posts/newtons-laws-of-motion/</id> <author> <name>Yunseo Kim</name> </author> <category term="Physics" /> <category term="Classical Dynamics" /> <summary xml:lang="ko">뉴턴의 운동 법칙 및 해당 3가지 법칙이 갖는 의미, 그리고 관성 질량과 중력 질량의 정의에 대해 알아보고, 고전 역학뿐 아니라 이후의 일반 상대성 이론에서도 중요한 의미를 갖는 등가의 원리를 살펴본다.</summary> <content type="html" xml:lang="ko"> <![CDATA[<p>뉴턴의 운동 법칙 및 해당 3가지 법칙이 갖는 의미, 그리고 관성 질량과 중력 질량의 정의에 대해 알아보고, 고전 역학뿐 아니라 이후의 일반 상대성 이론에서도 중요한 의미를 갖는 등가의 원리를 살펴본다.</p><em><p>* Mathematical equations and diagrams included in posts may not display properly when viewed with a feed reader.</p></em><h2 id="tldr">TL;DR</h2><blockquote class="prompt-info"><p><strong>뉴턴의 운동 법칙(Newton’s laws of motion)</strong></p><ol><li>외부에서 힘이 작용하지 않는 한, 물체는 정지 또는 등속 직선 운동을 계속한다.<li>물체의 운동량의 시간적 변화율은 그 물체가 받은 힘과 같다.<ul><li>$\vec{F} = \cfrac{d\vec{p}}{dt} = \cfrac{d}{dt}(m\vec{v}) = m\vec{a}$</ul><li>두 물체가 서로 힘을 미칠 때 이 두 힘은 크기가 같고 방향이 반대이다.<ul><li>$\vec{F_1} = -\vec{F_2}$</ul></ol></blockquote><blockquote class="prompt-info"><p><strong>등가의 원리(principle of equivalence)</strong></p><ul><li>관성 질량: 주어진 힘이 작용한 경우에 물체의 가속도를 결정하는 질량<li>중력 질량: 어떤 물체와 다른 물체 사이에 작용하는 중력을 결정하는 질량<li>현재 관성 질량과 중력 질량은 $10^{-12}$ 정도의 오차 범위로 명백히 일치함이 알려져 있음<li>관성 질량과 중력 질량은 정확하게 같다는 주장을 <strong>등가의 원리</strong>라고 함</ul></blockquote><h2 id="뉴턴의-운동-법칙">뉴턴의 운동 법칙</h2><p>뉴턴의 운동 법칙은 아이작 뉴턴(Issac Newton)이 <a href="https://en.wikipedia.org/wiki/Holocene_calendar">인류력</a> 11687년에 저서 Philosophiæ Naturalis Principia Mathematica(자연철학의 수학적 원리, 약칭 ‘프린키피아’)를 통해 발표한 3가지 법칙으로, 뉴턴 역학(Newtonian mechanics)의 근간을 이룬다.</p><ol><li>외부에서 힘이 작용하지 않는 한, 물체는 정지 또는 등속 직선 운동을 계속한다.<li>물체의 운동량의 시간적 변화율은 그 물체가 받은 힘과 같다.<li>두 물체가 서로 힘을 미칠 때 이 두 힘은 크기가 같고 방향이 반대이다.</ol><h3 id="뉴턴의-제1법칙">뉴턴의 제1법칙</h3><blockquote><p>I. 외부에서 힘이 작용하지 않는 한, 물체는 정지 또는 등속 직선 운동을 계속한다.</p></blockquote><p>이처럼 외부에서 힘이 작용하지 않는 상태의 물체를 <strong>자유 물체(free body)</strong> 또는 <strong>자유 입자(free particle)</strong>라고 한다. 다만, 제1법칙 단독으로는 힘에 대한 정성적인 개념밖에 주지 않는다.</p><h3 id="뉴턴의-제2법칙">뉴턴의 제2법칙</h3><blockquote><p>II. 물체의 운동량의 시간적 변화율은 그 물체가 받은 힘과 같다.</p></blockquote><p>뉴턴은 <strong>운동량(momentum)</strong>을 질량과 속도의 곱</p>\[\vec{p} \equiv m\vec{v} \label{eqn:momentum}\tag{1}\]<p>로 정의하였다. 이로부터 뉴턴의 제2법칙은 다음과 같이 표현할 수 있다.</p>\[\vec{F} = \frac{d\vec{p}}{dt} = \frac{d}{dt}(m\vec{v}) = m\vec{a}. \label{eqn:2nd_law}\tag{2}\]<p>뉴턴의 제1법칙과 제2법칙은, 이름과는 달리 사실 ‘법칙’보다는 오히려 힘에 대한 ‘정의’에 가깝다. 또한 힘의 정의는 ‘질량’의 정의에 의존한다는 점을 알 수 있다.</p><h3 id="뉴턴의-제3법칙">뉴턴의 제3법칙</h3><blockquote><p>III. 두 물체가 서로 힘을 미칠 때 이 두 힘은 크기가 같고 방향이 반대이다.</p></blockquote><p>‘작용과 반작용의 법칙’으로도 알려져 있는 물리 법칙이며, 한 물체가 다른 물체에 미치는 힘이 두 작용점 사이를 잇는 직선의 방향을 향하는 경우에 적용된다. 이와 같은 힘을 <strong>중심력(central force)</strong>이라 하며, 제3법칙은 중심력이 인력이든 척력이든 상관없이 성립한다. 정지한 두 물체 사이의 중력 또는 정전기력, 그리고 탄성력 등이 이러한 중심력에 해당한다. 반면 움직이는 전하 사이의 힘, 움직이는 물체 사이의 중력 등 상호작용하는 두 물체의 속도에 의존하는 힘은 비중심력에 속하며, 이러한 경우 제3법칙은 적용할 수 없다.</p><p>앞서 살펴본 질량의 정의를 반영하면 제3법칙을 다음과 같이 바꿔 표현할 수 있다.</p><blockquote><p>III$^\prime$. 두 물체가 이상적인 고립계를 구성할 경우, 이 두 물체의 가속도는 방향이 반대이고 그 크기의 비는 두 물체의 질량의 역 비와 같다.</p></blockquote><p>뉴턴의 제3법칙에 의해서</p>\[\vec{F_1} = -\vec{F_2} \label{eqn:3rd_law}\tag{3}\]<p>이고, 여기에 앞서 살펴본 제2법칙 ($\ref{eqn:2nd_law}$)를 대입하면</p>\[\frac{d\vec{p_1}}{dt} = -\frac{d\vec{p_2}}{dt} \label{eqn:3rd-1_law}\tag{4}\]<p>이다. 이로부터 두 입자의 고립된 상호작용에서 운동량은 보존됨을 알 수 있다.</p>\[\frac{d}{dt}(\vec{p_1}+\vec{p_2}) = 0 \label{eqn:conservation_of_momentum}\tag{5}\]<p>또한 식 ($\ref{eqn:3rd-1_law}$)에서 $\vec{p}=m\vec{v}$이고 질량 $m$은 상수이기 때문에,</p>\[m_1\left(\frac{d\vec{v_1}}{dt} \right) = m_2\left(-\frac{d\vec{v_2}}{dt} \right) \tag{6a}\] \[m_1(\vec{a_1}) = m_2(-\vec{a_2}) \tag{6b}\]<p>이 되어 다음을 얻는다.</p>\[\frac{m_2}{m_1} = -\frac{a_1}{a_2}. \tag{7}\]<p>그런데 뉴턴의 제3법칙은 두 물체가 고립계를 구성할 경우에 대해 기술하고 있으나, 실제로는 그러한 이상적인 조건을 실현하는 것은 불가능하기에 제3법칙에서의 뉴턴의 주장은 어찌 보면 꽤 무모했다고도 볼 수 있다. 이처럼 제한된 관찰로부터 얻은 결론임에도 불구하고 뉴턴의 깊이 있는 물리적 통찰력 덕에 뉴턴 역학은 거의 300년 동안 각종 실험을 통한 검증에서 오류가 발견되지 않고 굳건한 지위를 차지하였으며, 11900년대에 들어서야 뉴턴 이론의 예측과 실제와의 차이를 보일 수 있을 정도의 정밀한 측정이 가능해져 이로부터 상대성 이론과 양자역학이 태동하였다.</p><h2 id="관성-질량과-중력-질량">관성 질량과 중력 질량</h2><p>물체의 질량을 정하는 방법 중 하나는, 천칭과 같은 도구를 사용하여 해당 물체의 무게를 표준 무게와 비교하는 것이다. 이 방법은 중력장에서의 물체의 무게가 그 물체에 작용하는 중력의 크기와 같다는 사실을 이용하는 것으로, 이 경우 제2법칙 $\vec{F}=m\vec{a}$는 $\vec{W}=m\vec{g}$의 형태가 된다. 이 방법은 III$^\prime$에서 정의하는 질량 $m$이 중력 방정식에 나타나는 질량 $m$과 같다는 기본 가정에 의한다. 이 두 질량을 각각 <strong>관성 질량(inertial mass)</strong>과 <strong>중력 질량(gravitational mass)</strong>이라 하고, 다음과 같이 정의한다.</p><ul><li>관성 질량: 주어진 힘이 작용한 경우에 물체의 가속도를 결정하는 질량<li>중력 질량: 어떤 물체와 다른 물체 사이에 작용하는 중력을 결정하는 질량</ul><p>비록 갈릴레오 갈릴레이(Galileo Galilei)와는 무관한 후대에 지어낸 이야기이긴 하나, 피사의 사탑 낙하 실험은 최초로 관성 질량과 중력 질량이 같을 것임을 보인 사고실험이다. 뉴턴 또한 길이가 같고 추의 질량이 다른 진자들의 주기를 측정하여 두 질량 사이에 차이는 발견되지 않음을 보이고자 했으나, 실험 방법과 정확도는 조잡한 수준이었기에 정확한 입증에는 실패하였다.</p><p>이후 11800년대 말, 헝가리의 물리학자 외트뵈시 로란드 아고슈톤(Eötvös Loránd Ágoston)이 관성 질량과 중력 질량 사이의 차이를 정확하게 측정하기 위한 외트뵈시 실험을 수행하여 관성 질량과 중력 질량이 동일함을 상당한 정확도(2000만 분의 1 이내의 오차)로 입증하였다.</p><p>이후 로버트 헨리 딕(Robert Henry Dicke) 등이 수행한 더욱 최근의 실험에서는 정확도를 더욱 높였으며, 현재 관성 질량과 중력 질량은 $10^{-12}$ 정도의 오차 범위로 명백히 일치함이 알려져 있다. 이러한 결과는 일반 상대성 이론에서 대단히 중요한 의미를 가지며, 관성 질량과 중력 질량이 정확하게 같다는 주장을 <strong>등가의 원리(principle of equivalence)</strong>라고 한다.</p>]]> </content> </entry> <entry><title xml:lang="ko">상수계수를 갖는 2계 동차 선형 상미분방정식</title><link href="https://www.yunseo.kim/ko/posts/homogeneous-linear-odes-with-constant-coefficients/" rel="alternate" type="text/html" hreflang="en" /><link href="https://www.yunseo.kim/ko/posts/homogeneous-linear-odes-with-constant-coefficients/" rel="alternate" type="text/html" hreflang="ko" /><link href="https://www.yunseo.kim/ja/posts/homogeneous-linear-odes-with-constant-coefficients/" rel="alternate" type="text/html" hreflang="ja" /><link href="https://www.yunseo.kim/zh-TW/posts/homogeneous-linear-odes-with-constant-coefficients/" rel="alternate" type="text/html" hreflang="zh-TW" /><link href="https://www.yunseo.kim/es/posts/homogeneous-linear-odes-with-constant-coefficients/" rel="alternate" type="text/html" hreflang="es" /><link href="https://www.yunseo.kim/pt-BR/posts/homogeneous-linear-odes-with-constant-coefficients/" rel="alternate" type="text/html" hreflang="pt-BR" /><link href="https://www.yunseo.kim/fr/posts/homogeneous-linear-odes-with-constant-coefficients/" rel="alternate" type="text/html" hreflang="fr" /><link href="https://www.yunseo.kim/de/posts/homogeneous-linear-odes-with-constant-coefficients/" rel="alternate" type="text/html" hreflang="de" /><link href="https://www.yunseo.kim/pl/posts/homogeneous-linear-odes-with-constant-coefficients/" rel="alternate" type="text/html" hreflang="pl" /><link href="https://www.yunseo.kim/cs/posts/homogeneous-linear-odes-with-constant-coefficients/" rel="alternate" type="text/html" hreflang="cs" /><link href="https://www.yunseo.kim/sw/posts/homogeneous-linear-odes-with-constant-coefficients/" rel="alternate" type="text/html" hreflang="sw" /><link href="https://www.yunseo.kim/am/posts/homogeneous-linear-odes-with-constant-coefficients/" rel="alternate" type="text/html" hreflang="am" /><published>2025-02-22T00:00:00+09:00</published> <updated>2025-07-11T21:22:11+09:00</updated> <id>https://www.yunseo.kim/ko/posts/homogeneous-linear-odes-with-constant-coefficients/</id> <author> <name>Yunseo Kim</name> </author> <category term="Mathematics" /> <category term="Differential Equation" /> <summary xml:lang="ko">특성방정식의 판별식의 부호에 따라, 각각의 경우에 상수계수 동차 선형 상미분방정식의 일반해가 어떤 형태를 띄는지 살펴본다.</summary> <content type="html" xml:lang="ko"> <![CDATA[<p>특성방정식의 판별식의 부호에 따라, 각각의 경우에 상수계수 동차 선형 상미분방정식의 일반해가 어떤 형태를 띄는지 살펴본다.</p><em><p>* Mathematical equations and diagrams included in posts may not display properly when viewed with a feed reader.</p></em><h2 id="tldr">TL;DR</h2><blockquote class="prompt-info"><ul><li>상수계수를 갖는 2계 동차 선형 상미분방정식: $y^{\prime\prime} + ay^{\prime} + by = 0$<li><strong>특성방정식(characteristic equation)</strong>: $\lambda^2 + a\lambda + b = 0$<li>특성방정식의 판별식 $a^2 - 4b$의 부호에 따라 일반해의 형태를 표와 같이 세 가지 경우로 나눌 수 있음</ul><table><thead><tr><th style="text-align: center">경우<th style="text-align: center">특성방정식의 해<th style="text-align: center">상미분방정식의 해의 기저<th style="text-align: center">상미분방정식의 일반해<tbody><tr><td style="text-align: center">I<td style="text-align: center">서로 다른 실근<br />$\lambda_1$, $\lambda_2$<td style="text-align: center">$e^{\lambda_1 x}$, $e^{\lambda_2 x}$<td style="text-align: center">$y = c_1e^{\lambda_1 x} + c_2e^{\lambda_2 x}$<tr><td style="text-align: center">II<td style="text-align: center">실이중근<br /> $\lambda = -\cfrac{1}{2}a$<td style="text-align: center">$e^{-ax/2}$, $xe^{-ax/2}$<td style="text-align: center">$y = (c_1 + c_2 x)e^{-ax/2}$<tr><td style="text-align: center">III<td style="text-align: center">켤레복소근<br /> $\lambda_1 = -\cfrac{1}{2}a + i\omega$, <br /> $\lambda_2 = -\cfrac{1}{2}a - i\omega$<td style="text-align: center">$e^{-ax/2}\cos{\omega x}$, <br /> $e^{-ax/2}\sin{\omega x}$<td style="text-align: center">$y = e^{-ax/2}(A\cos{\omega x} + B\sin{\omega x})$</table></blockquote><h2 id="prerequisites">Prerequisites</h2><ul><li><a href="/ko/posts/Bernoulli-Equation/">베르누이 방정식(Bernoulli Equation)</a><li><a href="/ko/posts/homogeneous-linear-odes-of-second-order/">2계 동차 선형 상미분방정식 (Homogeneous Linear ODEs of Second Order)</a><li>오일러 공식</ul><h2 id="특성방정식-characteristic-equation">특성방정식 (characteristic equation)</h2><p>계수 $a$와 $b$가 상수인 2계 동차 선형 상미분방정식</p>\[y^{\prime\prime} + ay^{\prime} + by = 0 \label{eqn:ode_with_constant_coefficients}\tag{1}\]<p>을 살펴보자. 이러한 형태의 방정식은 기계적, 전기적 진동에서 중요하게 응용된다.</p><p>앞서 <a href="/ko/posts/Bernoulli-Equation/">베르누이 방정식(Bernoulli Equation)</a>에서 로지스틱 방정식의 일반해를 구한 바 있으며, 그에 따르면 상수계수 $k$를 갖는 1계 선형 상미분방정식</p>\[y^\prime + ky = 0\]<p>의 해는 지수함수 $y = ce^{-kx}$이다. (해당 글의 식 (4)에서 $A=-k$, $B=0$인 경우)</p><p>따라서, 비슷한 형태의 방정식인 ($\ref{eqn:ode_with_constant_coefficients}$)에 대해서도</p>\[y=e^{\lambda x}\label{eqn:general_sol}\tag{2}\]<p>형태의 해를 우선 시도해 볼 수 있다.</p><blockquote class="prompt-info"><p>물론 이는 어디까지나 추측에 불과하며, 정말로 일반해가 이런 형태일 거라는 보장은 전혀 없다. 하지만 뭐가 되었든 선형 독립인 두 해를 일단 구하기만 한다면, <a href="/ko/posts/homogeneous-linear-odes-of-second-order/#기저와-일반해">2계 동차 선형 상미분방정식</a>에서 살펴봤다시피 <a href="/ko/posts/homogeneous-linear-odes-of-second-order/#중첩의-원리">중첩의 원리</a>에 의해 일반해를 구할 수 있다.<br /> 잠시 뒤에 보겠지만, <a href="#ii-실이중근-lambda---cfraca2">다른 형태의 해를 구해야 하는 경우</a>도 있다.</p></blockquote><p>식 ($\ref{eqn:general_sol}$)와 그 도함수</p>\[y^\prime = \lambda e^{\lambda x}, \quad y^{\prime\prime} = \lambda^2 e^{\lambda x}\]<p>을 식 ($\ref{eqn:ode_with_constant_coefficients}$)에 대입하면</p>\[(\lambda^2 + a\lambda + b)e^{\lambda x} = 0\]<p>을 얻는다. 따라서, 만약 $\lambda$가 <strong>특성방정식(characteristic equation)</strong></p>\[\lambda^2 + a\lambda + b = 0 \label{eqn:characteristic_eqn}\tag{3}\]<p>의 해라면 지수함수 ($\ref{eqn:general_sol}$)는 상미분방정식 ($\ref{eqn:ode_with_constant_coefficients}$)의 해이다. 이차방정식 ($\ref{eqn:characteristic_eqn}$)의 해를 구하면</p>\[\begin{align*} \lambda_1 &amp;= \frac{1}{2}\left(-a + \sqrt{a^2 - 4b}\right), \\ \lambda_2 &amp;= \frac{1}{2}\left(-a - \sqrt{a^2 - 4b}\right) \end{align*}\label{eqn:lambdas}\tag{4}\]<p>이고, 이로부터 두 함수</p>\[y_1 = e^{\lambda_1 x}, \quad y_2 = e^{\lambda_2 x} \tag{5}\]<p>이 방정식 ($\ref{eqn:ode_with_constant_coefficients}$)의 해가 된다.</p><blockquote class="prompt-tip"><p><strong>특성방정식(characteristic equation)</strong>과 <strong>보조방정식(auxiliary equation)</strong> 두 용어가 자주 혼용되곤 하는데, 둘은 완전히 같은 의미이다. 어느 쪽으로 지칭해도 상관없다.</p></blockquote><p>이제, 특성방정식 ($\ref{eqn:characteristic_eqn}$)의 판별식 $a^2 - 4b$의 부호에 따라 경우를 세 가지로 나눌 수 있다.</p><ul><li>$a^2 - 4b &gt; 0$: 서로 다른 두 실근<li>$a^2 - 4b = 0$: 실이중근<li>$a^2 - 4b &lt; 0$: 켤레복소근</ul><h2 id="특성방정식의-판별식의-부호에-따른-일반해의-형태">특성방정식의 판별식의 부호에 따른 일반해의 형태</h2><h3 id="i-서로-다른-두-실근-lambda_1과-lambda_2">I. 서로 다른 두 실근 $\lambda_1$과 $\lambda_2$</h3><p>이 경우 임의의 구간에서 방정식 ($\ref{eqn:ode_with_constant_coefficients}$)의 해의 기저는</p>\[y_1 = e^{\lambda_1 x}, \quad y_2 = e^{\lambda_2 x}\]<p>이며, 이에 따른 일반해는</p>\[y = c_1 e^{\lambda_1 x} + c_2 e^{\lambda_2 x} \label{eqn:general_sol_1}\tag{6}\]<p>이다.</p><h3 id="ii-실이중근-lambda---cfraca2">II. 실이중근 $\lambda = -\cfrac{a}{2}$</h3><p>$a^2 - 4b = 0$일 경우 이차방정식 ($\ref{eqn:characteristic_eqn}$)은 한 개의 해 $\lambda = \lambda_1 = \lambda_2 = -\cfrac{a}{2}$만을 얻게 되며, 따라서 이로부터 얻을 수 있는 $y = e^{\lambda x}$ 형태의 해는</p>\[y_1 = e^{-(a/2)x}\]<p>의 한 개뿐이다. 기저를 얻기 위해서는 $y_1$과 독립적인 다른 형태의 두 번째 해 $y_2$를 알아내야 한다.</p><p>이러한 상황에서 활용할 수 있는 것이 앞서 알아보았던 <a href="/ko/posts/homogeneous-linear-odes-of-second-order/#계수내림-reduction-of-order">계수내림</a>이다. 찾고자 하는 두 번째 해를 $y_2=uy_1$으로 놓고,</p>\[\begin{align*} y_2 &amp;= uy_1, \\ y_2^{\prime} &amp;= u^{\prime}y_1 + uy_1^{\prime}, \\ y_2^{\prime\prime} &amp;= u^{\prime\prime}y_1 + 2u^{\prime}y_1^{\prime} + uy_1^{\prime\prime} \end{align*}\]<p>을 방정식 ($\ref{eqn:ode_with_constant_coefficients}$)에 대입하면</p>\[(u^{\prime\prime}y_1 + 2u^\prime y_1^\prime + uy_1^{\prime\prime}) + a(u^\prime y_1 + uy_1^\prime) + buy_1 = 0\]<p>을 얻는다. $u^{\prime\prime}$, $u^\prime$, $u$ 각 항끼리 모아서 정리하면</p>\[y_1u^{\prime\prime} + (2y_1^\prime + ay_1)u^\prime + (y_1^{\prime\prime} + ay_1^\prime + by_1)u = 0\]<p>이다. 여기서 $y_1$이 방정식 ($\ref{eqn:ode_with_constant_coefficients}$)의 해이기 때문에 마지막 괄호 안의 식은 $0$이며,</p>\[2y_1^\prime = -ae^{-ax/2} = -ay_1\]<p>이므로 첫 번째 괄호 안의 식 역시 $0$이다. 따라서 $u^{\prime\prime}y_1 = 0$만 남게 되며, 이로부터 $u^{\prime\prime}=0$이다. 두 번 적분하면 $u = c_1x + c_2$가 되며, 적분상수 $c_1$과 $c_2$는 어떤 값이든 될 수 있으므로 단순히 $c_1=1$, $c_2=0$을 선택하여 $u=x$로 놓을 수 있다. 그러면 $y_2 = uy_1 = xy_1$이 되며, $y_1$과 $y_2$는 선형 독립이므로 이 둘은 기저를 형성한다. 따라서 특성방정식 ($\ref{eqn:characteristic_eqn}$)이 중근을 갖는 경우에 임의의 구간에서의 방정식 ($\ref{eqn:ode_with_constant_coefficients}$)의 해의 기저는</p>\[e^{-ax/2}, \quad xe^{-ax/2}\]<p>이고, 이에 대응하는 일반해는</p>\[y = (c_1 + c_2x)e^{-ax/2} \label{eqn:general_sol_2}\tag{7}\]<p>이다.</p><h3 id="iii-켤레복소근--cfrac12a--iomega와--cfrac12a---iomega">III. 켤레복소근 $-\cfrac{1}{2}a + i\omega$와 $-\cfrac{1}{2}a - i\omega$</h3><p>이 경우 $a^2 - 4b &lt; 0$이고 $\sqrt{-1} = i$이므로 식 ($\ref{eqn:lambdas}$)에서</p>\[\cfrac{1}{2}\sqrt{a^2 - 4b} = \cfrac{1}{2}\sqrt{-(4b - a^2)} = \sqrt{-(b-\frac{1}{4}a^2)} = i\sqrt{b - \frac{1}{4}a^2}\]<p>이며, 여기서 실수 $\sqrt{b-\cfrac{1}{4}a^2} = \omega$로 정의하자.</p><p>$\omega$를 위와 같이 정의하면 특성방정식 ($\ref{eqn:characteristic_eqn}$)의 해는 켤레복소근 $\lambda = -\cfrac{1}{2}a \pm i\omega$가 되며, 이에 대응하는 방정식 ($\ref{eqn:ode_with_constant_coefficients}$)의 두 복소해</p>\[\begin{align*} e^{\lambda_1 x} &amp;= e^{-(a/2)x + i\omega x}, \\ e^{\lambda_2 x} &amp;= e^{-(a/2)x - i\omega x} \end{align*}\]<p>를 얻는다. 다만 이 경우에도 허수가 아닌 실수해의 기저를 다음과 같이 얻을 수 있다.</p><p>오일러 공식(Euler formula)</p>\[e^{it} = \cos t + i\sin t \label{eqn:euler_formula}\tag{8}\]<p>와, 위 식에서 $t$ 자리에 $-t$를 대입하여 얻는</p>\[e^{-it} = \cos t - i\sin t\]<p>의 두 식을 변끼리 더하고 빼면 다음을 얻는다.</p>\[\begin{align*} \cos t &amp;= \frac{1}{2}(e^{it} + e^{-it}), \\ \sin t &amp;= \frac{1}{2i}(e^{it} - e^{-it}). \end{align*} \label{eqn:cos_and_sin}\tag{9}\]<p>실수부 $r$과 허수부 $it$를 갖는 복소변수 $z = r + it$의 복소지수함수 $e^z$는 실함수 $e^r$, $\cos t$와 $\sin t$를 사용하여 다음과 같이 정의할 수 있다.</p>\[e^z = e^{r + it} = e^r e^{it} = e^r(\cos t + i\sin t) \label{eqn:complex_exp}\tag{10}\]<p>여기서 $r=-\cfrac{1}{2}ax$, $t=\omega x$로 놓으면 다음과 같이 쓸 수 있다.</p>\[\begin{align*} e^{\lambda_1 x} &amp;= e^{-(a/2)x + i\omega x} = e^{-(a/2)x}(\cos{\omega x} + i\sin{\omega x}) \\ e^{\lambda_2 x} &amp;= e^{-(a/2)x - i\omega x} = e^{-(a/2)x}(\cos{\omega x} - i\sin{\omega x}) \end{align*}\]<p><a href="/ko/posts/homogeneous-linear-odes-of-second-order/#중첩의-원리">중첩의 원리</a>에 의해 위의 복소해들의 합과 상수곱 또한 해가 된다. 따라서 두 등식을 변끼리 더하고 양변에 $\cfrac{1}{2}$을 곱하면 첫 번째 실수해 $y_1$을 다음과 같이 얻을 수 있다.</p>\[y_1 = e^{-(a/2)x} \cos{\omega x}. \label{eqn:basis_1}\tag{11}\]<p>같은 방법으로, 첫 번째 등식에서 두 번째 등식을 변끼리 빼고 양변에 $\cfrac{1}{2i}$를 곱하여 두 번째 실수해 $y_2$를 얻을 수 있다.</p>\[y_2 = e^{-(a/2)x} \sin{\omega x}. \label{eqn:basis_2}\tag{12}\]<p>$\cfrac{y_1}{y_2} = \cot{\omega x}$이고 이는 상수가 아니므로, $y_1$과 $y_2$는 모든 구간에서 선형 독립이며 따라서 방정식 ($\ref{eqn:ode_with_constant_coefficients}$)의 실수해의 기저를 이룬다. 이로부터 일반해</p>\[y = e^{-ax/2}(A\cos{\omega x} + B\sin{\omega x}) \quad \text{(}A,\, B\text{는 임의의 상수)} \label{eqn:general_sol_3}\tag{13}\]<p>를 얻는다.</p>]]> </content> </entry> <entry><title xml:lang="ko">Polyglot으로 Jekyll 블로그에서 다국어 지원하는 방법 (3) - Chirpy 테마 빌드 실패 및 검색 기능 오류 트러블슈팅</title><link href="https://www.yunseo.kim/ko/posts/how-to-support-multi-language-on-jekyll-blog-with-polyglot-3/" rel="alternate" type="text/html" hreflang="en" /><link href="https://www.yunseo.kim/ko/posts/how-to-support-multi-language-on-jekyll-blog-with-polyglot-3/" rel="alternate" type="text/html" hreflang="ko" /><link href="https://www.yunseo.kim/ja/posts/how-to-support-multi-language-on-jekyll-blog-with-polyglot-3/" rel="alternate" type="text/html" hreflang="ja" /><link href="https://www.yunseo.kim/zh-TW/posts/how-to-support-multi-language-on-jekyll-blog-with-polyglot-3/" rel="alternate" type="text/html" hreflang="zh-TW" /><link href="https://www.yunseo.kim/es/posts/how-to-support-multi-language-on-jekyll-blog-with-polyglot-3/" rel="alternate" type="text/html" hreflang="es" /><link href="https://www.yunseo.kim/pt-BR/posts/how-to-support-multi-language-on-jekyll-blog-with-polyglot-3/" rel="alternate" type="text/html" hreflang="pt-BR" /><link href="https://www.yunseo.kim/fr/posts/how-to-support-multi-language-on-jekyll-blog-with-polyglot-3/" rel="alternate" type="text/html" hreflang="fr" /><link href="https://www.yunseo.kim/de/posts/how-to-support-multi-language-on-jekyll-blog-with-polyglot-3/" rel="alternate" type="text/html" hreflang="de" /><link href="https://www.yunseo.kim/pl/posts/how-to-support-multi-language-on-jekyll-blog-with-polyglot-3/" rel="alternate" type="text/html" hreflang="pl" /><link href="https://www.yunseo.kim/cs/posts/how-to-support-multi-language-on-jekyll-blog-with-polyglot-3/" rel="alternate" type="text/html" hreflang="cs" /><link href="https://www.yunseo.kim/sw/posts/how-to-support-multi-language-on-jekyll-blog-with-polyglot-3/" rel="alternate" type="text/html" hreflang="sw" /><link href="https://www.yunseo.kim/am/posts/how-to-support-multi-language-on-jekyll-blog-with-polyglot-3/" rel="alternate" type="text/html" hreflang="am" /><published>2025-02-05T00:00:00+09:00</published> <updated>2025-10-08T00:53:56+09:00</updated> <id>https://www.yunseo.kim/ko/posts/how-to-support-multi-language-on-jekyll-blog-with-polyglot-3/</id> <author> <name>Yunseo Kim</name> </author> <category term="Dev" /> <category term="Web Dev" /> <summary xml:lang="ko">&apos;jekyll-theme-chirpy&apos; 기반의 Jekyll 블로그에 Polyglot 플러그인을 적용하여 다국어 지원을 구현한 과정을 소개한다. 이 포스트는 해당 시리즈의 세 번째 글로, Chirpy 테마에 Polyglot 적용 시 발생한 오류 원인을 식별하고 해결하는 부분을 다룬다.</summary> <content type="html" xml:lang="ko"> <![CDATA[<p>'jekyll-theme-chirpy' 기반의 Jekyll 블로그에 Polyglot 플러그인을 적용하여 다국어 지원을 구현한 과정을 소개한다. 이 포스트는 해당 시리즈의 세 번째 글로, Chirpy 테마에 Polyglot 적용 시 발생한 오류 원인을 식별하고 해결하는 부분을 다룬다.</p><em><p>* Mathematical equations and diagrams included in posts may not display properly when viewed with a feed reader.</p></em><h2 id="개요">개요</h2><p>12024년 7월 초, Jekyll 기반으로 Github Pages를 통해 호스팅 중인 본 블로그에 <a href="https://github.com/untra/polyglot">Polyglot</a> 플러그인을 적용하여 다국어 지원 구현을 추가하였다. 이 시리즈는 Chirpy 테마에 Polyglot 플러그인을 적용하는 과정에서 발생한 버그와 그 해결 과정, 그리고 SEO를 고려한 html 헤더와 sitemap.xml 작성법을 공유한다. 시리즈는 3개의 글로 이루어져 있으며, 읽고 있는 이 글은 해당 시리즈의 세 번째 글이다.</p><ul><li>1편: <a href="/ko/posts/how-to-support-multi-language-on-jekyll-blog-with-polyglot-1">Polyglot 플러그인 적용 &amp; html 헤더 및 sitemap 수정</a><li>2편: <a href="/ko/posts/how-to-support-multi-language-on-jekyll-blog-with-polyglot-2">언어 선택 버튼 구현 &amp; 레이아웃 언어 현지화</a><li>3편: Chirpy 테마 빌드 실패 및 검색 기능 오류 트러블슈팅 (본문)</ul><blockquote class="prompt-info"><p>원래는 총 2편으로 구성하였으나, 이후 몇 차례에 걸쳐 내용을 보강함에 따라 분량이 크게 늘어나 3편으로 개편하였다.</p></blockquote><h2 id="요구조건">요구조건</h2><ul class="task-list"><li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />빌드한 결과물(웹페이지)을 언어별 경로(ex. <code class="language-plaintext filepath highlighter-rouge">/posts/ko/</code>, <code class="language-plaintext filepath highlighter-rouge">/posts/ja/</code>)로 구분하여 제공할 수 있어야 한다.<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />다국어 지원에 추가적으로 소요되는 시간과 노력을 가능한 최소화하기 위해, 작성한 원본 마크다운 파일의 YAML front matter에 ‘lang’ 및 ‘permalink’ 태그를 일일이 지정해 주지 않아도 빌드 시 해당 파일이 위치한 로컬 경로(ex. <code class="language-plaintext filepath highlighter-rouge">/_posts/ko/</code>, <code class="language-plaintext filepath highlighter-rouge">/_posts/ja/</code>)에 따라 자동으로 언어를 인식할 수 있어야 한다.<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />사이트 내 각 페이지의 헤더 부분은 적절한 Content-Language 메타 태그와 hreflang 대체 태그, canonical 링크를 포함하여 다국어 검색을 위한 Google SEO 가이드라인을 충족해야 한다.<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />사이트 내에서 각 언어 버전별 페이지 링크를 누락 없이 <code class="language-plaintext filepath highlighter-rouge">sitemap.xml</code>로 제공할 수 있어야 하며, <code class="language-plaintext filepath highlighter-rouge">sitemap.xml</code> 자체는 중복 없이 루트 경로에 하나만 존재하여야 한다.<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" /><a href="https://github.com/cotes2020/jekyll-theme-chirpy">Chirpy 테마</a>에서 제공하는 모든 기능은 각 언어 페이지에서 정상 작동해야 하며, 그렇지 않다면 정상 작동하게끔 수정해야 한다.<ul class="task-list"><li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />‘Recently Updated’, ‘Trending Tags’ 기능 정상 작동<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />GitHub Actions를 이용한 빌드 과정에서 에러가 발생하지 않을 것<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />블로그 우상단 포스트 검색 기능 정상 작동</ul></ul><h2 id="시작하기-전에">시작하기 전에</h2><p>이 글은 <a href="/ko/posts/how-to-support-multi-language-on-jekyll-blog-with-polyglot-1">1편</a>과 <a href="/ko/posts/how-to-support-multi-language-on-jekyll-blog-with-polyglot-2">2편</a>에서 이어지는 글이므로, 만약 아직 읽지 않았다면 우선 이전 글부터 읽고 오는 것을 권장한다.</p><h2 id="트러블슈팅-relative_url_regex-target-of-repeat-operator-is-not-specified">트러블슈팅 (‘relative_url_regex’: target of repeat operator is not specified)</h2><p>(+ 12025.10.08. 업데이트) <a href="https://polyglot.untra.io/2025/09/20/polyglot.1.11.0/">본 버그는 Polyglot 1.11 버전에서 해결되었다</a>.</p><p>앞선 단계까지 진행한 후에 <code class="language-plaintext highlighter-rouge">bundle exec jekyll serve</code> 명령을 실행하여 빌드 테스트를 하였더니, <code class="language-plaintext highlighter-rouge">'relative_url_regex': target of repeat operator is not specified</code>라는 에러가 발생하며 빌드에 실패하였다.</p><div class="language-shell highlighter-rouge"><div class="highlight">class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
</pre><td class="rouge-code"><pre>...<span class="o">(</span>전략<span class="o">)</span>
                    <span class="nt">------------------------------------------------</span>
      Jekyll 4.3.4   Please append <span class="sb">`</span><span class="nt">--trace</span><span class="sb">`</span> to the <span class="sb">`</span>serve<span class="sb">`</span> <span class="nb">command 
                     </span><span class="k">for </span>any additional information or backtrace. 
                    <span class="nt">------------------------------------------------</span>
/Users/yunseo/.gem/ruby/3.2.2/gems/jekyll-polyglot-1.8.1/lib/jekyll/polyglot/
patches/jekyll/site.rb:234:in <span class="sb">`</span>relative_url_regex<span class="s1">': target of repeat operator 
is not specified: /href="?\/((?:(?!*.gem)(?!*.gemspec)(?!tools)(?!README.md)(
?!LICENSE)(?!*.config.js)(?!rollup.config.js)(?!package*.json)(?!.sass-cache)
(?!.jekyll-cache)(?!gemfiles)(?!Gemfile)(?!Gemfile.lock)(?!node_modules)(?!ve
ndor\/bundle\/)(?!vendor\/cache\/)(?!vendor\/gems\/)(?!vendor\/ruby\/)(?!en\/
)(?!ko\/)(?!es\/)(?!pt-BR\/)(?!ja\/)(?!fr\/)(?!de\/)[^,'</span><span class="s2">"</span><span class="se">\s\/</span><span class="s2">?.]+</span><span class="se">\.</span><span class="s2">?)*(?:</span><span class="se">\/</span><span class="s2">[^
</span><span class="se">\]\[</span><span class="s2">)("</span><span class="s1">'\s]*)?)"/ (RegexpError)

...(후략)
</span></pre></div></div><p>비슷한 이슈가 보고된 적 있는지 검색해본 결과, Polyglot 리포지터리에 <a href="https://github.com/untra/polyglot/issues/204">정확히 동일한 이슈</a>가 이미 등록되어 있었으며 해결책 또한 존재했다.</p><p>본 블로그에 적용 중인 <a href="https://github.com/cotes2020/jekyll-theme-chirpy/blob/master/_config.yml">Chirpy 테마의 <code class="language-plaintext filepath highlighter-rouge">_config.yml</code></a> 파일 중에는 다음과 같은 구문이 존재한다.</p><div file="\_config.yml" class="language-yml highlighter-rouge"><div class="highlight">class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
</pre><td class="rouge-code"><pre><span class="na">exclude</span><span class="pi">:</span>
  <span class="pi">-</span> <span class="s2">"</span><span class="s">*.gem"</span>
  <span class="pi">-</span> <span class="s2">"</span><span class="s">*.gemspec"</span>
  <span class="pi">-</span> <span class="s">docs</span>
  <span class="pi">-</span> <span class="s">tools</span>
  <span class="pi">-</span> <span class="s">README.md</span>
  <span class="pi">-</span> <span class="s">LICENSE</span>
  <span class="pi">-</span> <span class="s2">"</span><span class="s">*.config.js"</span>
  <span class="pi">-</span> <span class="s">package*.json</span>
</pre></div></div><p>문제의 원인은 <a href="https://github.com/untra/polyglot/blob/master/lib/jekyll/polyglot/patches/jekyll/site.rb">Polyglot의 <code class="language-plaintext filepath highlighter-rouge">site.rb</code></a> 파일에 포함된 다음 두 함수의 정규식 구문이 위의 <code class="language-plaintext highlighter-rouge">"*.gem"</code>, <code class="language-plaintext highlighter-rouge">"*.gemspec"</code>, <code class="language-plaintext highlighter-rouge">"*.config.js"</code>과 같이 와일드카드를 포함하는 글로빙(globbing) 패턴을 정상적으로 처리하지 못하는 데 있다.</p><div file="(polyglot root path)/lib/jekyll/polyglot/patches/jekyll/site.rb" class="language-ruby highlighter-rouge"><div class="highlight">class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">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
31
32
33
34
35
</pre><td class="rouge-code"><pre>    <span class="c1"># a regex that matches relative urls in a html document</span>
    <span class="c1"># matches href="baseurl/foo/bar-baz" href="/ko/foo/bar-baz" and others like it</span>
    <span class="c1"># avoids matching excluded files.  prepare makes sure</span>
    <span class="c1"># that all @exclude dirs have a trailing slash.</span>
    <span class="k">def</span> <span class="nf">relative_url_regex</span><span class="p">(</span><span class="n">disabled</span> <span class="o">=</span> <span class="kp">false</span><span class="p">)</span>
      <span class="n">regex</span> <span class="o">=</span> <span class="s1">''</span>
      <span class="k">unless</span> <span class="n">disabled</span>
        <span class="vi">@exclude</span><span class="p">.</span><span class="nf">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">x</span><span class="o">|</span>
          <span class="n">regex</span> <span class="o">+=</span> <span class="s2">"(?!</span><span class="si">#{</span><span class="n">x</span><span class="si">}</span><span class="s2">)"</span>
        <span class="k">end</span>
        <span class="vi">@languages</span><span class="p">.</span><span class="nf">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">x</span><span class="o">|</span>
          <span class="n">regex</span> <span class="o">+=</span> <span class="s2">"(?!</span><span class="si">#{</span><span class="n">x</span><span class="si">}</span><span class="se">\/</span><span class="s2">)"</span>
        <span class="k">end</span>
      <span class="k">end</span>
      <span class="n">start</span> <span class="o">=</span> <span class="n">disabled</span> <span class="p">?</span> <span class="s1">'ferh'</span> <span class="p">:</span> <span class="s1">'href'</span>
      <span class="sr">%r{</span><span class="si">#{</span><span class="n">start</span><span class="si">}</span><span class="sr">="?</span><span class="si">#{</span><span class="vi">@baseurl</span><span class="si">}</span><span class="sr">/((?:</span><span class="si">#{</span><span class="n">regex</span><span class="si">}</span><span class="sr">[^,'"</span><span class="se">\s</span><span class="sr">/?.]+</span><span class="se">\.</span><span class="sr">?)*(?:/[^</span><span class="se">\]\[</span><span class="sr">)("'</span><span class="se">\s</span><span class="sr">]*)?)"}</span>
    <span class="k">end</span>

    <span class="c1"># a regex that matches absolute urls in a html document</span>
    <span class="c1"># matches href="http://baseurl/foo/bar-baz" and others like it</span>
    <span class="c1"># avoids matching excluded files.  prepare makes sure</span>
    <span class="c1"># that all @exclude dirs have a trailing slash.</span>
    <span class="k">def</span> <span class="nf">absolute_url_regex</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">disabled</span> <span class="o">=</span> <span class="kp">false</span><span class="p">)</span>
      <span class="n">regex</span> <span class="o">=</span> <span class="s1">''</span>
      <span class="k">unless</span> <span class="n">disabled</span>
        <span class="vi">@exclude</span><span class="p">.</span><span class="nf">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">x</span><span class="o">|</span>
          <span class="n">regex</span> <span class="o">+=</span> <span class="s2">"(?!</span><span class="si">#{</span><span class="n">x</span><span class="si">}</span><span class="s2">)"</span>
        <span class="k">end</span>
        <span class="vi">@languages</span><span class="p">.</span><span class="nf">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">x</span><span class="o">|</span>
          <span class="n">regex</span> <span class="o">+=</span> <span class="s2">"(?!</span><span class="si">#{</span><span class="n">x</span><span class="si">}</span><span class="se">\/</span><span class="s2">)"</span>
        <span class="k">end</span>
      <span class="k">end</span>
      <span class="n">start</span> <span class="o">=</span> <span class="n">disabled</span> <span class="p">?</span> <span class="s1">'ferh'</span> <span class="p">:</span> <span class="s1">'href'</span>
      <span class="sr">%r{(?&lt;!hreflang="</span><span class="si">#{</span><span class="vi">@default_lang</span><span class="si">}</span><span class="sr">" )</span><span class="si">#{</span><span class="n">start</span><span class="si">}</span><span class="sr">="?</span><span class="si">#{</span><span class="n">url</span><span class="si">}#{</span><span class="vi">@baseurl</span><span class="si">}</span><span class="sr">/((?:</span><span class="si">#{</span><span class="n">regex</span><span class="si">}</span><span class="sr">[^,'"</span><span class="se">\s</span><span class="sr">/?.]+</span><span class="se">\.</span><span class="sr">?)*(?:/[^</span><span class="se">\]\[</span><span class="sr">)("'</span><span class="se">\s</span><span class="sr">]*)?)"}</span>
    <span class="k">end</span>
</pre></div></div><p>이 문제를 해결하는 방법은 두 가지이다.</p><h3 id="1-polyglot을-포크fork한-뒤-문제가-되는-부분을-수정하여-사용">1. Polyglot을 포크(fork)한 뒤 문제가 되는 부분을 수정하여 사용</h3><p>이 글을 작성하는 시점(12024.11.) 기준으로 <a href="https://jekyllrb.com/docs/configuration/options/#global-configuration">Jekyll 공식 문서</a>에서는 <code class="language-plaintext highlighter-rouge">exclude</code> 설정이 글로빙(globbing) 패턴 활용을 지원한다고 명시하고 있다.</p><blockquote><p>“This configuration option supports Ruby’s File.fnmatch filename globbing patterns to match multiple entries to exclude.”</p></blockquote><p>즉, 문제의 원인은 Chirpy 테마가 아니라 Polyglot의 <code class="language-plaintext highlighter-rouge">relative_url_regex()</code>, <code class="language-plaintext highlighter-rouge">absolute_url_regex()</code> 두 함수에 있으므로 이를 문제가 발생하지 않게끔 수정해 주는 것이 근본적인 해결책이다.</p><p><del>Polyglot에서 해당 버그는 아직 해결되지 않은 상태이므로,</del> 상술하였듯, <a href="https://polyglot.untra.io/2025/09/20/polyglot.1.11.0/">Polyglot 1.11 버전부터 이 문제는 해결되었다</a>. 문제가 발생하던 당시에는 <del><a href="https://hionpu.com/posts/github_blog_4#4-polyglot-%EC%9D%98%EC%A1%B4%EC%84%B1-%EB%AC%B8%EC%A0%9C">이 블로그 포스트</a>(사이트 없어짐)와</del> <a href="https://github.com/untra/polyglot/issues/204#issuecomment-2143270322">앞선 GitHub 이슈에 달린 답변</a>을 참고하여 Polyglot 리포지터리를 포크(fork)한 뒤에 문제가 되는 부분을 다음과 같이 수정하여 원본 Polyglot 대신 사용함으로써 해결 가능했다.</p><div file="(polyglot root path)/lib/jekyll/polyglot/patches/jekyll/site.rb" class="language-ruby highlighter-rouge"><div class="highlight">class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">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
31
</pre><td class="rouge-code"><pre>    <span class="k">def</span> <span class="nf">relative_url_regex</span><span class="p">(</span><span class="n">disabled</span> <span class="o">=</span> <span class="kp">false</span><span class="p">)</span>
      <span class="n">regex</span> <span class="o">=</span> <span class="s1">''</span>
      <span class="k">unless</span> <span class="n">disabled</span>
        <span class="vi">@exclude</span><span class="p">.</span><span class="nf">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">x</span><span class="o">|</span>
          <span class="n">escaped_x</span> <span class="o">=</span> <span class="no">Regexp</span><span class="p">.</span><span class="nf">escape</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
          <span class="n">regex</span> <span class="o">+=</span> <span class="s2">"(?!</span><span class="si">#{</span><span class="n">escaped_x</span><span class="si">}</span><span class="s2">)"</span>
        <span class="k">end</span>
        <span class="vi">@languages</span><span class="p">.</span><span class="nf">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">x</span><span class="o">|</span>
          <span class="n">escaped_x</span> <span class="o">=</span> <span class="no">Regexp</span><span class="p">.</span><span class="nf">escape</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
          <span class="n">regex</span> <span class="o">+=</span> <span class="s2">"(?!</span><span class="si">#{</span><span class="n">escaped_x</span><span class="si">}</span><span class="se">\/</span><span class="s2">)"</span>
        <span class="k">end</span>
      <span class="k">end</span>
      <span class="n">start</span> <span class="o">=</span> <span class="n">disabled</span> <span class="p">?</span> <span class="s1">'ferh'</span> <span class="p">:</span> <span class="s1">'href'</span>
      <span class="sr">%r{</span><span class="si">#{</span><span class="n">start</span><span class="si">}</span><span class="sr">="?</span><span class="si">#{</span><span class="vi">@baseurl</span><span class="si">}</span><span class="sr">/((?:</span><span class="si">#{</span><span class="n">regex</span><span class="si">}</span><span class="sr">[^,'"</span><span class="se">\s</span><span class="sr">/?.]+</span><span class="se">\.</span><span class="sr">?)*(?:/[^</span><span class="se">\]\[</span><span class="sr">)("'</span><span class="se">\s</span><span class="sr">]*)?)"}</span>
    <span class="k">end</span>

    <span class="k">def</span> <span class="nf">absolute_url_regex</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">disabled</span> <span class="o">=</span> <span class="kp">false</span><span class="p">)</span>
      <span class="n">regex</span> <span class="o">=</span> <span class="s1">''</span>
      <span class="k">unless</span> <span class="n">disabled</span>
        <span class="vi">@exclude</span><span class="p">.</span><span class="nf">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">x</span><span class="o">|</span>
          <span class="n">escaped_x</span> <span class="o">=</span> <span class="no">Regexp</span><span class="p">.</span><span class="nf">escape</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
          <span class="n">regex</span> <span class="o">+=</span> <span class="s2">"(?!</span><span class="si">#{</span><span class="n">escaped_x</span><span class="si">}</span><span class="s2">)"</span>
        <span class="k">end</span>
        <span class="vi">@languages</span><span class="p">.</span><span class="nf">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">x</span><span class="o">|</span>
          <span class="n">escaped_x</span> <span class="o">=</span> <span class="no">Regexp</span><span class="p">.</span><span class="nf">escape</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
          <span class="n">regex</span> <span class="o">+=</span> <span class="s2">"(?!</span><span class="si">#{</span><span class="n">escaped_x</span><span class="si">}</span><span class="se">\/</span><span class="s2">)"</span>
        <span class="k">end</span>
      <span class="k">end</span>
      <span class="n">start</span> <span class="o">=</span> <span class="n">disabled</span> <span class="p">?</span> <span class="s1">'ferh'</span> <span class="p">:</span> <span class="s1">'href'</span>
      <span class="sr">%r{(?&lt;!hreflang="</span><span class="si">#{</span><span class="vi">@default_lang</span><span class="si">}</span><span class="sr">" )</span><span class="si">#{</span><span class="n">start</span><span class="si">}</span><span class="sr">="?</span><span class="si">#{</span><span class="n">url</span><span class="si">}#{</span><span class="vi">@baseurl</span><span class="si">}</span><span class="sr">/((?:</span><span class="si">#{</span><span class="n">regex</span><span class="si">}</span><span class="sr">[^,'"</span><span class="se">\s</span><span class="sr">/?.]+</span><span class="se">\.</span><span class="sr">?)*(?:/[^</span><span class="se">\]\[</span><span class="sr">)("'</span><span class="se">\s</span><span class="sr">]*)?)"}</span>
    <span class="k">end</span>
</pre></div></div><h3 id="2-chirpy-테마의-_configyml-설정-파일에서-글로빙globbing-패턴을-정확한-파일명으로-대체">2. Chirpy 테마의 ‘_config.yml’ 설정 파일에서 글로빙(globbing) 패턴을 정확한 파일명으로 대체</h3><p>사실 정석적이고 이상적인 방법은 위의 패치가 Polyglot 메인스트림에 반영되는 것이다. 그러나 그 전까지는 포크한 버전을 대신 사용하여야 하는데, 이 경우 Polyglot 업스트림이 버전업될 때마다 해당 업데이트를 놓치지 않고 반영하며 따라가기가 번거롭기 때문에 나는 다른 방법을 사용하였다.</p><p><a href="https://github.com/cotes2020/jekyll-theme-chirpy">Chirpy 테마 리포지터리</a>에서 프로젝트 루트 경로에 위치하는 파일 중 <code class="language-plaintext highlighter-rouge">"*.gem"</code>, <code class="language-plaintext highlighter-rouge">"*.gemspec"</code>, <code class="language-plaintext highlighter-rouge">"*.config.js"</code> 패턴에 대응하는 파일을 확인해 보면 어차피 아래의 3개밖에 없다.</p><ul><li><code class="language-plaintext filepath highlighter-rouge">jekyll-theme-chirpy.gemspec</code><li><code class="language-plaintext filepath highlighter-rouge">purgecss.config.js</code><li><code class="language-plaintext filepath highlighter-rouge">rollup.config.js</code></ul><p>따라서 <code class="language-plaintext filepath highlighter-rouge">_config.yml</code> 파일의 <code class="language-plaintext highlighter-rouge">exclude</code> 구문에서 글로빙(globbing) 패턴을 삭제하고 아래와 같이 바꿔 적어 주면 Polyglot이 문제 없이 처리할 수 있게 된다.</p><div file="\_config.yml" class="language-yml highlighter-rouge"><div class="highlight">class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
</pre><td class="rouge-code"><pre><span class="na">exclude</span><span class="pi">:</span> <span class="c1"># https://github.com/untra/polyglot/issues/204 이슈 참고하여 수정.</span>
  <span class="c1"># - "*.gem"</span>
  <span class="pi">-</span> <span class="s">jekyll-theme-chirpy.gemspec</span> <span class="c1"># - "*.gemspec"</span>
  <span class="pi">-</span> <span class="s">tools</span>
  <span class="pi">-</span> <span class="s">README.md</span>
  <span class="pi">-</span> <span class="s">LICENSE</span>
  <span class="pi">-</span> <span class="s">purgecss.config.js</span> <span class="c1"># - "*.config.js"</span>
  <span class="pi">-</span> <span class="s">rollup.config.js</span>
  <span class="pi">-</span> <span class="s">package*.json</span>
</pre></div></div><h2 id="검색-기능-수정">검색 기능 수정</h2><p>앞선 단계까지 진행하였을 때 거의 대부분의 사이트 기능이 의도한 대로 만족스럽게 작동하였다. 그러나, Chirpy 테마를 적용한 페이지 우상단에 위치한 검색 바가 <code class="language-plaintext highlighter-rouge">site.default_lang</code>(본 블로그의 경우 영어) 이외의 언어로 된 페이지는 색인하지 못하며, 영문 이외의 다른 언어 페이지에서 검색했을 때에도 검색 결과로 영문 페이지 링크를 출력한다는 문제가 있음을 뒤늦게 발견하였다.</p><p>원인을 파악하기 위해, 검색 기능에 관여하는 파일들이 무엇이고 그 중 어디에서 문제가 발생하는지 살펴보자.</p><h3 id="_layoutsdefaulthtml">‘_layouts/default.html’</h3><p>블로그 내 모든 페이지의 틀을 구성하는 <a href="https://github.com/cotes2020/jekyll-theme-chirpy/blob/master/_layouts/default.html"><code class="language-plaintext filepath highlighter-rouge">_layouts/default.html</code></a> 파일을 확인해 보면, <code class="language-plaintext highlighter-rouge">&lt;body&gt;</code> 일레먼트 안에 <code class="language-plaintext filepath highlighter-rouge">search-results.html</code>과 <code class="language-plaintext filepath highlighter-rouge">search-loader.html</code>의 내용을 불러오고 있음을 확인할 수 있다.</p><div file="\_layouts/default.html" class="language-liquid highlighter-rouge"><div class="highlight">class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
</pre><td class="rouge-code"><pre>  &lt;body&gt;
    <span class="cp">{%</span><span class="w"> </span><span class="nt">include</span><span class="w"> </span>sidebar.html<span class="w"> </span><span class="na">lang</span><span class="o">=</span><span class="nv">lang</span><span class="w"> </span><span class="cp">%}</span>

    &lt;div id="main-wrapper" class="d-flex justify-content-center"&gt;
      &lt;div class="container d-flex flex-column px-xxl-5"&gt;
        
        (...중략...)

        <span class="cp">{%</span><span class="w"> </span><span class="nt">include_cached</span><span class="w"> </span><span class="nv">search-results</span><span class="p">.</span><span class="nv">html</span><span class="w"> </span><span class="na">lang</span><span class="o">=</span><span class="nv">lang</span><span class="w"> </span><span class="cp">%}</span>
      &lt;/div&gt;

      &lt;aside aria-label="Scroll to Top"&gt;
        &lt;button id="back-to-top" type="button" class="btn btn-lg btn-box-shadow"&gt;
          &lt;i class="fas fa-angle-up"&gt;&lt;/i&gt;
        &lt;/button&gt;
      &lt;/aside&gt;
    &lt;/div&gt;

    (...중략...)

    <span class="cp">{%</span><span class="w"> </span><span class="nt">include_cached</span><span class="w"> </span><span class="nv">search-loader</span><span class="p">.</span><span class="nv">html</span><span class="w"> </span><span class="na">lang</span><span class="o">=</span><span class="nv">lang</span><span class="w"> </span><span class="cp">%}</span>
  &lt;/body&gt;
</pre></div></div><h3 id="_includessearch-resulthtml">‘_includes/search-result.html’</h3><p><a href="https://github.com/cotes2020/jekyll-theme-chirpy/blob/master/_includes/search-results.html"><code class="language-plaintext filepath highlighter-rouge">_includes/search-result.html</code></a>은 검색창에 검색어 입력 시 해당 키워드에 대한 검색 결과를 저장하기 위한 <code class="language-plaintext highlighter-rouge">search-results</code> 컨테이너를 구성한다.</p><div file="\_includes/search-result.html" class="language-html highlighter-rouge"><div class="highlight">class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
</pre><td class="rouge-code"><pre><span class="c">&lt;!-- The Search results --&gt;</span>

<span class="nt">&lt;div</span> <span class="na">id=</span><span class="s">"search-result-wrapper"</span> <span class="na">class=</span><span class="s">"d-flex justify-content-center d-none"</span><span class="nt">&gt;</span>
  <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"col-11 content"</span><span class="nt">&gt;</span>
    <span class="nt">&lt;div</span> <span class="na">id=</span><span class="s">"search-hints"</span><span class="nt">&gt;</span>
      {% include_cached trending-tags.html %}
    <span class="nt">&lt;/div&gt;</span>
    <span class="nt">&lt;div</span> <span class="na">id=</span><span class="s">"search-results"</span> <span class="na">class=</span><span class="s">"d-flex flex-wrap justify-content-center text-muted mt-3"</span><span class="nt">&gt;&lt;/div&gt;</span>
  <span class="nt">&lt;/div&gt;</span>
<span class="nt">&lt;/div&gt;</span>
</pre></div></div><h3 id="_includessearch-loaderhtml">‘_includes/search-loader.html’</h3><p><a href="https://github.com/cotes2020/jekyll-theme-chirpy/blob/master/_includes/search-loader.html"><code class="language-plaintext filepath highlighter-rouge">_includes/search-loader.html</code></a>이 바로 <a href="https://github.com/christian-fei/Simple-Jekyll-Search">Simple-Jekyll-Search</a> 라이브러리 기반의 검색을 구현해 둔 핵심적인 부분으로, 이는 <a href="#assetsjsdatasearchjson"><code class="language-plaintext filepath highlighter-rouge">search.json</code></a> 색인 파일의 내용 중 입력 키워드와 일치하는 부분을 찾아 해당 포스트 링크를 <code class="language-plaintext highlighter-rouge">&lt;article&gt;</code> 일레먼트로 반환하는 JavaScript를 방문자의 브라우저 상에서 실행함으로써 Client-Side로 동작함을 알 수 있다.</p><div file="\_includes/search-loader.html" class="language-js highlighter-rouge"><div class="highlight">class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
</pre><td class="rouge-code"><pre><span class="p">{</span><span class="o">%</span> <span class="nx">capture</span> <span class="nx">result_elem</span> <span class="o">%</span><span class="p">}</span>
  <span class="o">&lt;</span><span class="nx">article</span> <span class="kd">class</span><span class="o">=</span><span class="dl">"</span><span class="s2">px-1 px-sm-2 px-lg-4 px-xl-0</span><span class="dl">"</span><span class="o">&gt;</span>
    <span class="o">&lt;</span><span class="nx">header</span><span class="o">&gt;</span>
      <span class="o">&lt;</span><span class="nx">h2</span><span class="o">&gt;&lt;</span><span class="nx">a</span> <span class="nx">href</span><span class="o">=</span><span class="dl">"</span><span class="s2">{url}</span><span class="dl">"</span><span class="o">&gt;</span><span class="p">{</span><span class="nx">title</span><span class="p">}</span><span class="o">&lt;</span><span class="sr">/a&gt;&lt;/</span><span class="nx">h2</span><span class="o">&gt;</span>
      <span class="o">&lt;</span><span class="nx">div</span> <span class="kd">class</span><span class="o">=</span><span class="dl">"</span><span class="s2">post-meta d-flex flex-column flex-sm-row text-muted mt-1 mb-1</span><span class="dl">"</span><span class="o">&gt;</span>
        <span class="p">{</span><span class="nx">categories</span><span class="p">}</span>
        <span class="p">{</span><span class="nx">tags</span><span class="p">}</span>
      <span class="o">&lt;</span><span class="sr">/div</span><span class="err">&gt;
</span>    <span class="o">&lt;</span><span class="sr">/header</span><span class="err">&gt;
</span>    <span class="o">&lt;</span><span class="nx">p</span><span class="o">&gt;</span><span class="p">{</span><span class="nx">snippet</span><span class="p">}</span><span class="o">&lt;</span><span class="sr">/p</span><span class="err">&gt;
</span>  <span class="o">&lt;</span><span class="sr">/article</span><span class="err">&gt;
</span><span class="p">{</span><span class="o">%</span> <span class="nx">endcapture</span> <span class="o">%</span><span class="p">}</span>

<span class="p">{</span><span class="o">%</span> <span class="nx">capture</span> <span class="nx">not_found</span> <span class="o">%</span><span class="p">}</span><span class="o">&lt;</span><span class="nx">p</span> <span class="kd">class</span><span class="o">=</span><span class="dl">"</span><span class="s2">mt-5</span><span class="dl">"</span><span class="o">&gt;</span><span class="p">{{</span> <span class="nx">site</span><span class="p">.</span><span class="nx">data</span><span class="p">.</span><span class="nx">locales</span><span class="p">[</span><span class="nx">include</span><span class="p">.</span><span class="nx">lang</span><span class="p">].</span><span class="nx">search</span><span class="p">.</span><span class="nx">no_results</span> <span class="p">}}</span><span class="o">&lt;</span><span class="sr">/p&gt;{% endcapture %</span><span class="err">}
</span>
<span class="o">&lt;</span><span class="nx">script</span><span class="o">&gt;</span>
  <span class="p">{</span><span class="o">%</span> <span class="nx">comment</span> <span class="o">%</span><span class="p">}</span> <span class="nl">Note</span><span class="p">:</span> <span class="nx">dependent</span> <span class="nx">library</span> <span class="nx">will</span> <span class="nx">be</span> <span class="nx">loaded</span> <span class="k">in</span> <span class="s2">`js-selector.html`</span> <span class="p">{</span><span class="o">%</span> <span class="nx">endcomment</span> <span class="o">%</span><span class="p">}</span>
  <span class="nb">document</span><span class="p">.</span><span class="nf">addEventListener</span><span class="p">(</span><span class="dl">'</span><span class="s1">DOMContentLoaded</span><span class="dl">'</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
    <span class="nc">SimpleJekyllSearch</span><span class="p">({</span>
      <span class="na">searchInput</span><span class="p">:</span> <span class="nb">document</span><span class="p">.</span><span class="nf">getElementById</span><span class="p">(</span><span class="dl">'</span><span class="s1">search-input</span><span class="dl">'</span><span class="p">),</span>
      <span class="na">resultsContainer</span><span class="p">:</span> <span class="nb">document</span><span class="p">.</span><span class="nf">getElementById</span><span class="p">(</span><span class="dl">'</span><span class="s1">search-results</span><span class="dl">'</span><span class="p">),</span>
      <span class="na">json</span><span class="p">:</span> <span class="dl">'</span><span class="s1">{{ </span><span class="dl">'</span><span class="o">/</span><span class="nx">assets</span><span class="o">/</span><span class="nx">js</span><span class="o">/</span><span class="nx">data</span><span class="o">/</span><span class="nx">search</span><span class="p">.</span><span class="nx">json</span><span class="dl">'</span><span class="s1"> | relative_url }}</span><span class="dl">'</span><span class="p">,</span>
      <span class="na">searchResultTemplate</span><span class="p">:</span> <span class="dl">'</span><span class="s1">{{ result_elem | strip_newlines }}</span><span class="dl">'</span><span class="p">,</span>
      <span class="na">noResultsText</span><span class="p">:</span> <span class="dl">'</span><span class="s1">{{ not_found }}</span><span class="dl">'</span><span class="p">,</span>
      <span class="na">templateMiddleware</span><span class="p">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">prop</span><span class="p">,</span> <span class="nx">value</span><span class="p">,</span> <span class="nx">template</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">if </span><span class="p">(</span><span class="nx">prop</span> <span class="o">===</span> <span class="dl">'</span><span class="s1">categories</span><span class="dl">'</span><span class="p">)</span> <span class="p">{</span>
          <span class="k">if </span><span class="p">(</span><span class="nx">value</span> <span class="o">===</span> <span class="dl">''</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">return</span> <span class="s2">`</span><span class="p">${</span><span class="nx">value</span><span class="p">}</span><span class="s2">`</span><span class="p">;</span>
          <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
            <span class="k">return</span> <span class="s2">`&lt;div class="me-sm-4"&gt;&lt;i class="far fa-folder fa-fw"&gt;&lt;/i&gt;</span><span class="p">${</span><span class="nx">value</span><span class="p">}</span><span class="s2">&lt;/div&gt;`</span><span class="p">;</span>
          <span class="p">}</span>
        <span class="p">}</span>

        <span class="k">if </span><span class="p">(</span><span class="nx">prop</span> <span class="o">===</span> <span class="dl">'</span><span class="s1">tags</span><span class="dl">'</span><span class="p">)</span> <span class="p">{</span>
          <span class="k">if </span><span class="p">(</span><span class="nx">value</span> <span class="o">===</span> <span class="dl">''</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">return</span> <span class="s2">`</span><span class="p">${</span><span class="nx">value</span><span class="p">}</span><span class="s2">`</span><span class="p">;</span>
          <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
            <span class="k">return</span> <span class="s2">`&lt;div&gt;&lt;i class="fa fa-tag fa-fw"&gt;&lt;/i&gt;</span><span class="p">${</span><span class="nx">value</span><span class="p">}</span><span class="s2">&lt;/div&gt;`</span><span class="p">;</span>
          <span class="p">}</span>
        <span class="p">}</span>
      <span class="p">}</span>
    <span class="p">});</span>
  <span class="p">});</span>
<span class="o">&lt;</span><span class="sr">/script</span><span class="err">&gt;
</span></pre></div></div><h3 id="assetsjsdatasearchjson">‘/assets/js/data/search.json’</h3><div file="/assets/js/data/search.json" class="language-liquid highlighter-rouge"><div class="highlight">class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
</pre><td class="rouge-code"><pre>---
layout: compress
swcache: true
---

[
  <span class="cp">{%</span><span class="w"> </span><span class="nt">for</span><span class="w"> </span><span class="nv">post</span><span class="w"> </span><span class="nt">in</span><span class="w"> </span><span class="nv">site</span><span class="p">.</span><span class="nv">posts</span><span class="w"> </span><span class="cp">%}</span>
  {
    "title": <span class="cp">{{</span><span class="w"> </span><span class="nv">post</span><span class="p">.</span><span class="nv">title</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="nf">jsonify</span><span class="w"> </span><span class="cp">}}</span>,
    "url": <span class="cp">{{</span><span class="w"> </span><span class="nv">post</span><span class="p">.</span><span class="nv">url</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="nf">relative_url</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="nf">jsonify</span><span class="w"> </span><span class="cp">}}</span>,
    "categories": <span class="cp">{{</span><span class="w"> </span><span class="nv">post</span><span class="p">.</span><span class="nv">categories</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="nf">join</span><span class="p">:</span><span class="w"> </span><span class="s1">', '</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="nf">jsonify</span><span class="w"> </span><span class="cp">}}</span>,
    "tags": <span class="cp">{{</span><span class="w"> </span><span class="nv">post</span><span class="p">.</span><span class="nv">tags</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="nf">join</span><span class="p">:</span><span class="w"> </span><span class="s1">', '</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="nf">jsonify</span><span class="w"> </span><span class="cp">}}</span>,
    "date": "<span class="cp">{{</span><span class="w"> </span><span class="nv">post</span><span class="p">.</span><span class="nv">date</span><span class="w"> </span><span class="cp">}}</span>",
    <span class="cp">{%</span><span class="w"> </span><span class="nt">include</span><span class="w"> </span>no-linenos.html<span class="w"> </span><span class="na">content</span><span class="o">=</span><span class="nv">post</span><span class="p">.</span><span class="nv">content</span><span class="w"> </span><span class="cp">%}</span>
    <span class="cp">{%</span><span class="w"> </span><span class="nt">assign</span><span class="w"> </span><span class="nv">_content</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nv">content</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="nf">strip_html</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="nf">strip_newlines</span><span class="w"> </span><span class="cp">%}</span>
    "snippet": <span class="cp">{{</span><span class="w"> </span><span class="nv">_content</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="nf">truncate</span><span class="p">:</span><span class="w"> </span><span class="mi">200</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="nf">jsonify</span><span class="w"> </span><span class="cp">}}</span>,
    "content": <span class="cp">{{</span><span class="w"> </span><span class="nv">_content</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="nf">jsonify</span><span class="w"> </span><span class="cp">}}</span>
  }<span class="cp">{%</span><span class="w"> </span><span class="nt">unless</span><span class="w"> </span><span class="nb">forloop.last</span><span class="w"> </span><span class="cp">%}</span>,<span class="cp">{%</span><span class="w"> </span><span class="nt">endunless</span><span class="w"> </span><span class="cp">%}</span>
  <span class="cp">{%</span><span class="w"> </span><span class="nt">endfor</span><span class="w"> </span><span class="cp">%}</span>
]
</pre></div></div><p>Jekyll의 Liquid 문법을 이용하여 사이트 내 모든 포스트의 제목, URL, 카테고리 및 태그 정보, 작성일자, 본문 중 첫 200자 스니펫, 그리고 전체 본문 내용을 담는 JSON 파일을 정의하고 있다.</p><h3 id="검색-기능-동작-구조-및-문제-발생-부분-파악">검색 기능 동작 구조 및 문제 발생 부분 파악</h3><p>즉 정리하자면, GitHub Pages상에서 Chirpy 테마를 호스팅하는 경우 검색 기능은 다음과 같은 프로세스로 동작한다.</p><pre><code class="language-mermaid">stateDiagram
  state "Changes" as CH
  state "Build start" as BLD
  state "Create search.json" as IDX
  state "Static Website" as DEP
  state "In Test" as TST
  state "Search Loader" as SCH
  state "Results" as R
    
  [*] --&gt; CH: Make Changes
  CH --&gt; BLD: Commit &amp; Push origin
  BLD --&gt; IDX: jekyll build
  IDX --&gt; TST: Build Complete
  TST --&gt; CH: Error Detected
  TST --&gt; DEP: Deploy
  DEP --&gt; SCH: Search Input
  SCH --&gt; R: Return Results
  R --&gt; [*]
</code></pre><p>여기서 <code class="language-plaintext filepath highlighter-rouge">search.json</code>은 Polyglot에 의해 다음과 같이 각 언어별로 생성됨을 확인하였다.</p><ul><li><code class="language-plaintext filepath highlighter-rouge">/assets/js/data/search.json</code><li><code class="language-plaintext filepath highlighter-rouge">/ko/assets/js/data/search.json</code><li><code class="language-plaintext filepath highlighter-rouge">/ja/assets/js/data/search.json</code><li><code class="language-plaintext filepath highlighter-rouge">/zh-TW/assets/js/data/search.json</code><li><code class="language-plaintext filepath highlighter-rouge">/es/assets/js/data/search.json</code><li><code class="language-plaintext filepath highlighter-rouge">/pt-BR/assets/js/data/search.json</code><li><code class="language-plaintext filepath highlighter-rouge">/fr/assets/js/data/search.json</code><li><code class="language-plaintext filepath highlighter-rouge">/de/assets/js/data/search.json</code></ul><p>따라서 문제의 원인이 되는 부분은 “Search Loader”이다. 영문 이외에 다른 언어 버전의 페이지가 검색되지 않는 문제는 <code class="language-plaintext filepath highlighter-rouge">_includes/search-loader.html</code>에서 현재 방문 중인 페이지의 언어와 무관하게 영문 색인 파일(<code class="language-plaintext filepath highlighter-rouge">/assets/js/data/search.json</code>)만을 정적으로 불러오기 때문에 발생한다.</p><blockquote class="prompt-warning"><ul><li>다만, 마크다운이나 html 형식 파일과는 달리 JSON 파일에 대해서는 <code class="language-plaintext highlighter-rouge">post.title</code>, <code class="language-plaintext highlighter-rouge">post.content</code> 등 Jekyll 제공 변수들에 대한 Polyglot wrapper는 동작하나 <a href="https://github.com/untra/polyglot?tab=readme-ov-file#relativized-local-urls">Relativized Local Urls</a> 기능은 작동하지 않는 것으로 보인다.<li>마찬가지로, JSON 파일 템플릿 내에서는 Jekyll 기본 제공 변수 이외에 <a href="https://github.com/untra/polyglot?tab=readme-ov-file#features">Polyglot에서 추가로 제공하는 <code class="language-plaintext highlighter-rouge">{{ site.default_lang }}</code>, <code class="language-plaintext highlighter-rouge">{{ site.active_lang }}</code> liquid 태그</a>에는 접근 불가능함을 테스트 과정에서 확인하였다.</ul><p>따라서 색인 파일 내 <code class="language-plaintext highlighter-rouge">title</code>, <code class="language-plaintext highlighter-rouge">snippet</code>, <code class="language-plaintext highlighter-rouge">content</code> 등의 값은 언어별로 다르게 생성되나, <code class="language-plaintext highlighter-rouge">url</code> 값은 언어를 고려하지 않은 기본 경로를 반환하며 이에 대한 적절한 처리를 “Search Loader” 부분에 추가해 주어야 한다.</p></blockquote><h3 id="문제-해결">문제 해결</h3><p>이를 해결하려면 <code class="language-plaintext filepath highlighter-rouge">_includes/search-loader.html</code>의 내용을 다음과 같이 수정하면 된다.</p><div file="\_includes/search-loader.html" class="language-plaintext highlighter-rouge"><div class="highlight">class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">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
</pre><td class="rouge-code"><pre>{% capture result_elem %}
  &lt;article class="px-1 px-sm-2 px-lg-4 px-xl-0"&gt;
    &lt;header&gt;
      {% if site.active_lang != site.default_lang %}
      &lt;h2&gt;&lt;a {% static_href %}href="/{{ site.active_lang }}{url}"{% endstatic_href %}&gt;{title}&lt;/a&gt;&lt;/h2&gt;
      {% else %}
      &lt;h2&gt;&lt;a href="{url}"&gt;{title}&lt;/a&gt;&lt;/h2&gt;
      {% endif %}

(...중략...)

&lt;script&gt;
  {% comment %} Note: dependent library will be loaded in `js-selector.html` {% endcomment %}
  document.addEventListener('DOMContentLoaded', () =&gt; {
    {% assign search_path = '/assets/js/data/search.json' %}
    {% if site.active_lang != site.default_lang %}
      {% assign search_path = '/' | append: site.active_lang | append: search_path %}
    {% endif %}
    
    SimpleJekyllSearch({
      searchInput: document.getElementById('search-input'),
      resultsContainer: document.getElementById('search-results'),
      json: '{{ search_path | relative_url }}',
      searchResultTemplate: '{{ result_elem | strip_newlines }}',

(...후략)
</pre></div></div><ul><li><code class="language-plaintext highlighter-rouge">site.active_lang</code>(현재 페이지 언어)와 <code class="language-plaintext highlighter-rouge">site.default_lang</code>(사이트 기본 언어)가 같지 않을 경우 JSON 파일로부터 불러온 포스트 URL 앞에 <code class="language-plaintext highlighter-rouge">"/{{ site.active_lang }}"</code> prefix를 덧붙이도록 <code class="language-plaintext highlighter-rouge">{% capture result_elem %}</code> 부분의 liquid 구문을 수정하였다.<li>같은 방법으로, 빌드 과정에서 현재 페이지의 언어와 사이트 기본 언어를 비교하여 같다면 기본 경로(<code class="language-plaintext filepath highlighter-rouge">/assets/js/data/search.json</code>)를, 다르다면 해당 언어에 맞는 경로(e.g. <code class="language-plaintext filepath highlighter-rouge">/ko/assets/js/data/search.json</code>)를 <code class="language-plaintext highlighter-rouge">search_path</code>로 지정하도록 <code class="language-plaintext highlighter-rouge">&lt;script&gt;</code> 부분을 수정하였다.</ul><p>위와 같이 수정한 후 웹사이트를 다시 빌드하면 각 언어에 맞게 검색 결과가 정상적으로 표시됨을 확인하였다.</p><blockquote class="prompt-tip"><p><code class="language-plaintext highlighter-rouge">{url}</code>은 추후 검색 실행 시 JS에 의해 JSON 파일에서 읽어들인 URL 값이 들어가는 자리이지 빌드 시점에서는 유효한 URL이 아니기 때문에, Polyglot에서 localization 대상으로 인식하지 않으므로 직접 언어에 따라 처리해야 한다. 문제는 정작 그렇게 처리한 <code class="language-plaintext highlighter-rouge">"/{{ site.active_lang }}{url}"</code> 템플릿은 빌드 시 상대 URL로 인식되며, 이미 localization이 완료되었지만 Polyglot이 그것까진 알지 못하므로 중복으로 localization을 수행하려 한다는 것이다(e.g. <code class="language-plaintext filepath highlighter-rouge">"/ko/ko/posts/example-post"</code>). 이를 막기 위해 <a href="https://github.com/untra/polyglot?tab=readme-ov-file#disabling-url-relativizing"><code class="language-plaintext highlighter-rouge">{% static_href %}</code> 태그</a>를 명시하였다.</p></blockquote>]]> </content> </entry> </feed>
