跳至主要內容

在 Python 偵測極值

摘要​

偵測訊號的極值。

訊號的產生​

舉例產生一個偽造的訊號。

  • 3 [Hz] 的訊號 + 0.01 [Hz] 的訊號 + 雜訊
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from scipy import signal

t = np.arange(30 * 100) / 100
x = np.sin(2 * np.pi * t / 3) + np.random.randn(len(t)) * 0.2 + np.sin(2 * np.pi * t / 100)
df = pd.DataFrame({'Data': x}, index=pd.to_datetime(t, unit='s').time)

fig, ax = plt.subplots()
df.plot(ax=ax, xlim=['00:00:00', '00:00:10'])
plt.show()

tmp

檢查訊號的特性​

def acorr(df: pd.DataFrame, ra: int = 3, fs=100):
x = np.correlate(df.Data.values, df.Data.values, mode='full')
t = (np.arange(len(x)) - len(x) / 2 + 0.5) / fs
x /= x.max()
fig, ax = plt.subplots()
ax.set_xlim(-ra, ra)
ax.set_ylim(0, 1)
ax.plot(t, x)
ax.set_title('Autocorrelation')
ax.grid(axis='x')
ax.set_xticks(np.linspace(-ra, ra, 2 * ra + 1))
plt.show()

acorr(df)

可以看出主要的訊號是 1/3 [Hz]。因此,對 1/3 [Hz] 施加低通濾波器。

tmp

套用低通濾波器並偵測極值​

套用低通濾波器以便偵測極值。

如果在 1/3 [Hz] 施加低通濾波器仍無法正確偵測,請逐步降低頻率。

tmp

fs = 10
lpf = 0.1
b, a = signal.butter(5, lpf / fs * 2, 'low')
df['Filter'] = signal.filtfilt(b, a, df.Data.values)
max_idx = signal.argrelmax(df['Filter'].values)
min_idx = signal.argrelmin(df['Filter'].values)

df['max_index'] = False
df.iloc[max_idx[0], 2] = True
df['min_index'] = False
df.iloc[min_idx[0], 3] = True

fig, ax = plt.subplots()
df.plot(ax=ax)
ax.set_xlim(['00:00:00', '00:00:30'])
ax.scatter(
df.loc[df['max_index'], ['Filter']].index,
df.loc[df['max_index'], ['Filter']],
color='tab:orange',
zorder=3)
ax.scatter(
df.loc[df['min_index'], ['Filter']].index,
df.loc[df['min_index'], ['Filter']],
color='tab:green',
zorder=3)
plt.show()

C 語言的二維陣列處理

用結構體將行數、列數與儲存數值的記憶體整合在一起,會更方便操作。

#include <stdio.h>
#include <stdlib.h>

typedef struct {
float *data;
int col_size;
int row_size;
} Mat;

void MatInit(Mat *mat, int row_size, int col_size) {
mat->row_size = row_size;
mat->col_size = col_size;
mat->data = (float *)calloc(row_size * col_size, sizeof(float));
}

float *MatAt(Mat *mat, int i, int j) {
return mat->data + i * mat->col_size + j;
}

void MatFree(Mat *mat) { free(mat->data); }

int main(void) {
Mat mat;
MatInit(&mat, 30, 5); // 初始化 30 行 5 列的矩陣
*MatAt(&mat, 0, 0) = 50; // 將第 0 行第 0 列設為 50
printf("%f\n", *MatAt(&mat, 0, 0)); // 顯示第 0 行第 0 列的數值

MatFree(&mat);

return 0;
}

從安裝腳本中得到錯誤的結果

這篇備忘錄記錄了當我從安裝腳本中得到錯誤結果時的解決方法。


問題描述​

有時,當我運行某些安裝腳本(例如來自 GitHub 的自動安裝腳本或官方提供的 install.sh)時,會遇到以下錯誤信息:

Got bad result from install script

這個錯誤通常表示腳本執行不成功,或者沒有返回預期的成功代碼。這可能是由於多種原因造成的,例如:

  • 網絡問題:下載資源失敗。
  • 權限問題:腳本沒有足夠的權限執行某些操作。
  • 依賴缺失:系統中缺少腳本所需的工具或庫。
  • 環境不兼容:腳本是為不同環境設計的,或者當前環境變量不正確。
  • 腳本本身的問題:腳本有 bug。

解決方案​

1. 檢查網絡連接​

確保你的設備連接到互聯網,並且沒有任何防火牆或代理設置阻止腳本訪問外部資源。

ping google.com

2. 檢查權限​

確保你以正確的權限運行腳本。對於需要系統級更改的腳本,通常需要使用 sudo。

sudo bash install.sh

3. 安裝缺失的依賴​

仔細閱讀腳本的輸出,查找是否有關於缺少命令或庫的錯誤信息。通常,腳本作者會在 README 中列出先決條件。

常見的依賴包管理器命令:

  • Ubuntu/Debian:sudo apt install <package_name>
  • CentOS/Fedora:sudo yum install <package_name> 或 sudo dnf install <package_name>
  • macOS (Homebrew):brew install <package_name>

4. 檢查環境變量​

某些腳本依賴特定的環境變量。確保你的 PATH 設置正確,並且所有必要的環境變量都已導出。

你可以使用 env 命令查看當前的環境變量。

5. 逐行執行腳本 (調試)​

如果上述方法都無效,你可以嘗試逐行執行腳本,以找出問題的確切位置。

  1. 打開腳本:
    vim install.sh
  2. 在腳本開頭添加 set -x: 這會讓 Shell 打印出每個執行的命令,幫助你追蹤問題。
    #!/bin/bash
    set -x
    # ... 腳本其餘內容
  3. 運行腳本:觀察輸出,當腳本失敗時,最後一個打印的命令通常是導致問題的原因。

6. 查閱腳本的 GitHub 頁面或文檔​

如果腳本來自開源項目,請訪問其 GitHub 儲存庫。查看 Issues 頁面,看看是否有其他人遇到過相同的問題,或者在 Wiki/文檔中查找是否有特定的故障排除指南。

7. 嘗試不同的安裝方式​

如果腳本提供的安裝方式失敗,看看項目是否提供了替代的安裝方式,例如:

  • 手動編譯
  • Docker 容器
  • 包管理器安裝(如 apt, yum, brew, npm, pip 等)

總結​

遇到 "Got bad result from install script" 錯誤時,不要慌張。系統地檢查網絡、權限、依賴和環境變量,並利用調試工具,通常可以找到問題的根源並解決它。

NMF (HALS) 的實作

import numpy as np

X = np.array([[1, 1], [2, 1], [3, 1.2], [4, 1], [5, 0.8], [6, 1]])

n_components, n_samples, n_features, = (2,) + X.shape
W = np.random.uniform(size = (n_samples, n_components))
H = np.random.uniform(size = (n_components, n_features))

eps = 1e-4

# NMF
for i in range(100):
# update B
A = X.T.dot(W)
B = W.T.dot(W)
for j in range(n_components):
tmp = H[j, :] + A[:, j] - H.T.dot(B[:, j])
H[j, :] = np.maximum(tmp, eps)

# update A
C = X.dot(H.T)
D = H.dot(H.T)
for j in range(n_components):
tmp = W[:, j] * D[j, j] + C[:, j] - W.dot(D[:, j])
W[:, j] = np.maximum(tmp, eps)
norm = np.linalg.norm(W[:, j])
if norm > 0:
W[:, j] /= norm

print(W)
print(H)
print(W.dot(H))

在 brew 環境下無法安裝 nokogiri 時的解決方法

發生了以下兩個錯誤:

zlib is missing; necessary for building libxml2
xslt is missing. Please locate mkmf.log to investigate how it is failing.

解決方法

  • 安裝 libxslt 與 libxml2
  • 指定 brew 安裝的 libxml2 路徑
brew install libxslt libxml2
bundle config build.nokogiri --use-system-libraries --with-xml2-include=$(brew --prefix libxml2)/include/libxml2

參考網站

WSL 上的 DNS 配置

這篇備忘錄記錄了在 WSL(Windows Subsystem for Linux)上配置 DNS 的方法。

資訊

WSL 允許你在 Windows 上運行 Linux 環境,但有時網絡配置(尤其是 DNS)可能會遇到問題。了解如何正確配置 DNS 可以確保你的 WSL 環境能夠正常解析域名。

WSL 中的 DNS 工作原理​

默認情況下,WSL 會嘗試從 Windows 主機獲取 DNS 配置。這通常是通過在 WSL 虛擬機中生成 /etc/resolv.conf 文件來實現的。這個文件通常包含一個指向 Windows DNS 服務的 IP 地址,例如 172.X.X.X。

常見問題​

  • 無法解析域名:這是最常見的問題,表現為無法訪問互聯網或特定服務。
  • DNS 解析速度慢:有時默認配置會導致 DNS 查詢變慢。

解決方法​

方法 1:禁用 /etc/resolv.conf 的自動生成 (推薦)​

WSL 每次啟動時都會自動重新生成 /etc/resolv.conf。禁用此功能可以讓你手動配置 DNS。

  1. 創建或編輯 wsl.conf 文件

    在 WSL 環境中,創建或編輯 /etc/wsl.conf 文件:

    sudo vim /etc/wsl.conf

    添加以下內容:

    [network]
    generateResolvConf = false

    保存並退出。

  2. 重啟 WSL

    在 PowerShell 或 CMD 中,終止 WSL 以使其應用更改:

    wsl --shutdown

    然後重新啟動你的 WSL 發行版。

  3. 手動編輯 /etc/resolv.conf

    現在,你可以手動編輯 /etc/resolv.conf 並添加你喜歡的 DNS 服務器。例如,使用 Google DNS:

    sudo vim /etc/resolv.conf

    添加以下內容:

    nameserver 8.8.8.8
    nameserver 8.8.4.4

    保存並退出。

    :::warning 注意 如果你在 wsl.conf 中設置了 generateResolvConf = false,/etc/resolv.conf 將不再被自動覆蓋。 :::

方法 2:在 Windows 中配置 DNS​

WSL 從 Windows 繼承 DNS 設置,因此你也可以直接在 Windows 的網絡適配器設置中更改 DNS 服務器。

  1. 打開 網絡和 Internet 設置 -> 更改適配器選項。
  2. 右鍵點擊你的網絡連接(例如 Wi-Fi 或乙太網),選擇 屬性。
  3. 選擇 Internet 協議版本 4 (TCP/IPv4),然後點擊 屬性。
  4. 選擇 使用下列 DNS 服務器地址,然後輸入你偏好的 DNS 服務器,例如 Google DNS (8.8.8.8 和 8.8.4.4)。
  5. 點擊 確定 保存更改。

重啟你的 WSL 發行版,它應該會自動獲取新的 DNS 設置。

方法 3:使用 netsh (Windows 命令)​

在某些情況下,你可以使用 netsh 命令來重置或配置 Windows 的 DNS 緩存。

ipconfig /flushdns
netsh interface ip delete dns "乙太網" all
netsh interface ip add dns "乙太網" 8.8.8.8 index=1

將 "乙太網" 替換為你的實際網絡適配器名稱。

測試 DNS 解析​

你可以使用 ping 或 dig 命令來測試 DNS 解析是否正常工作:

ping google.com

或

sudo apt install dnsutils # 如果沒有安裝 dig
dig google.com

總結​

通過禁用 /etc/resolv.conf 的自動生成並手動配置,或者直接在 Windows 中更改 DNS 設置,你可以有效地解決 WSL 中的 DNS 問題。選擇適合你的方法,以確保 WSL 環境的網絡連接穩定可靠。

Windows OpenSSH Permission denied 問題

  • 可以使用密碼登入(雖然設定中已停用)
  • 使用公鑰驗證時發生 Permission denied

連線至 localhost:22 時,出現以下錯誤:

hikari@localhost: Permission denied (publickey,keyboard-interactive).

image

原因

Administrators 群組(即「系統管理員使用者」)預設會從 C:\ProgramData\ssh\administrators_authorized_keys 讀取公鑰進行驗證。

需要將其改為 $env:userprofile\.ssh\authorized_keys。

解決方法

以系統管理員權限開啟 C:\ProgramData\ssh\sshd_config,將以下兩行註解掉:

image

- Match Group administrators
- AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys
+ #Match Group administrators
+ # AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys

儲存後,重新啟動服務。

Restart-Service sshd

Termux 上的 Powerline

這篇備忘錄記錄了在 Termux 上安裝和配置 Powerline 的方法。

資訊

Powerline 是一個為各種 Shell(如 Bash、Zsh)和編輯器(如 Vim)提供美觀且功能豐富的狀態欄插件。它顯示有用的信息,如當前 Git 分支、Vim 模式、Python 虛擬環境等。

安裝步驟​

1. 更新 Termux 套件​

在安裝任何新軟體之前,建議先更新 Termux 的套件列表:

pkg update && pkg upgrade

2. 安裝必要的套件​

Powerline 需要 Python 環境。此外,為了顯示特殊字元(如箭頭),你需要安裝一個支持 Powerline 字體。

pkg install python python-pip
pkg install git

3. 安裝 Powerline​

使用 pip 安裝 Powerline:

pip install --user powerline-status

安裝完成後,Powerline 的可執行文件會位於 ~/.local/bin/。

4. 配置 Shell​

你需要將 Powerline 添加到你的 Shell 配置中。這裡以 Bash 為例。

編輯 ~/.bashrc 文件:

vim ~/.bashrc

在文件末尾添加以下內容:

# Powerline
export PATH="$PATH:$HOME/.local/bin"
powerline-daemon -q
POWERLINE_BASH_CONTINUATION=1
POWERLINE_BASH_SELECT=1
. ~/.local/lib/python*/site-packages/powerline/bindings/bash/powerline.sh

保存並退出,然後重新載入 ~/.bashrc:

source ~/.bashrc

5. 安裝 Powerline 字體​

為了讓 Powerline 正確顯示特殊字元,你需要一個 Powerline 字體。在 Termux 中,你可以直接安裝。

pkg install termux-api
termux-setup-storage

然後,你可以下載並安裝一個 Powerline 字體。由於 Termux 的環境限制,直接修改系統字體可能比較麻煩。一種常見的做法是使用支持 Powerline 的終端模擬器(如 Termux 的默認字體通常已支持)。

如果你在其他 Linux 環境下,你可以安裝 fonts-powerline:

sudo apt install fonts-powerline

或者手動下載並安裝字體。

6. 配置 Powerline 主題 (可選)​

Powerline 允許你自定義狀態欄的外觀。你可以創建自己的配置或修改現有的配置。

通常,配置文件位於 ~/.config/powerline/。你可以複製預設配置進行修改:

mkdir -p ~/.config/powerline
cp -r ~/.local/lib/python*/site-packages/powerline/config_files ~/.config/powerline/

然後編輯 ~/.config/powerline/config.json 或 ~/.config/powerline/themes/shell/default.json。

總結​

通過上述步驟,你可以在 Termux 上成功安裝和配置 Powerline,為你的命令行界面帶來更美觀和信息豐富的狀態欄。這將極大地提升你的終端使用體驗。

Termux 上的 SSH

這篇備忘錄記錄了在 Termux 上使用 SSH 的方法。

資訊

Termux 是一個 Android 上的終端模擬器和 Linux 環境應用程式,它允許你運行許多 Linux 命令和工具。SSH 是一種安全的網絡協議,用於在不安全的網絡上安全地執行網絡服務。

在 Termux 中,你可以將其作為 SSH 客戶端連接到遠端服務器,也可以將其設置為 SSH 服務器,以便從其他設備連接到你的 Android 設備。

1. 作為 SSH 客戶端​

安裝 OpenSSH​

Termux 提供了一個 OpenSSH 套件,你可以通過 pkg 命令安裝:

pkg update && pkg upgrade
pkg install openssh

連接到遠端服務器​

安裝完成後,你可以使用 ssh 命令連接到遠端服務器:

ssh user@hostname_or_ip

例如:

你也可以使用 SSH 密鑰進行身份驗證,這比密碼更安全。

生成 SSH 密鑰​

如果尚未生成,你可以在 Termux 中生成 SSH 密鑰對:

ssh-keygen

按照提示操作,通常可以直接按 Enter 使用默認值。公鑰會保存在 ~/.ssh/id_rsa.pub,私鑰在 ~/.ssh/id_rsa。

上傳公鑰到遠端服務器​

將你的公鑰複製到遠端服務器的 ~/.ssh/authorized_keys 文件中:

ssh-copy-id user@hostname_or_ip

或者手動複製:

cat ~/.ssh/id_rsa.pub | ssh user@hostname_or_ip "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"

2. 作為 SSH 服務器​

啟動 SSH 服務器​

Termux 內置了一個 SSH 服務器。默認情況下,它在端口 8022 上運行。 要啟動 SSH 服務器,只需運行 sshd 命令:

sshd

:::warning 注意 每次 Termux 應用程式關閉或設備重啟後,你都需要重新運行 sshd 命令來啟動 SSH 服務器。 :::

設置 SSH 密碼​

如果你想使用密碼連接,你需要為你的 Termux 用戶設置一個密碼:

passwd

輸入並確認你的密碼。

從其他設備連接​

現在,你可以從你的電腦或其他設備連接到 Termux SSH 服務器。你需要知道你的 Android 設備在局域網中的 IP 地址。

在你的電腦上:

ssh -p 8022 user@android_device_ip

其中 user 是你的 Termux 用戶名(通常是 u0_aXXX 這樣的字串,但對於 Termux SSH 服務器,你可以直接使用 sshd 運行時的用戶名,通常是 root 或者你當前的 shell 用戶)。

查找 Termux 用戶名​

你可以在 Termux 中運行 whoami 命令來查看當前用戶名。 更可靠的方法是,當你啟動 sshd 後,它會使用當前的用戶身份。如果你沒有顯式設置用戶,它可以是 root (如果你以 root 權限運行) 或者默認的 Termux 用戶。

停止 SSH 服務器​

要停止 SSH 服務器,你可以找到 sshd 進程並終止它:

pkill sshd

總結​

Termux 提供了強大的 SSH 功能,無論是作為客戶端還是服務器,都能極大地增強你的 Android 設備的實用性。這使得在手機上進行開發、遠端管理或其他基於 SSH 的任務變得可能。

在 Windows 上停用 OpenSSH 的密碼驗證

開啟具有系統管理員權限的終端機​

編輯設定檔需要系統管理員權限,請以系統管理員身份開啟終端機。

在終端機圖示上按右鍵,選擇「以系統管理員身份執行」。

image

image

在終端機中開啟設定檔​

執行以下命令:

notepad C:\ProgramData\ssh\sshd_config

image

編輯設定檔​

- # PasswordAuthentication yes
+ PasswordAuthentication no

image

變更為

image

並儲存變更。

重新啟動 SSH 伺服器​

返回終端機,執行以下命令以重新啟動 SSH 伺服器:

Restart-Service sshd

連線測試​

測試設定是否已生效。

執行以下命令,若看到以下訊息:

ssh localhost
user@localhost: Permission denied (publickey,keyboaard-interactive).

即表示設定正確。