并行计算
展开阅读
展开阅读
共享内存模型
锁,信号量(semaphore)
线程模型
分布式内存的信息传输模型
数据并行模型
分区全局地址空间(PGAS)
并行文件系统
存储协议
展开阅读
定理:主问题(P)
$$ \begin{align*} &\max && c^\top x \\ &s.t. && Ax=b \\ & && x\geq0 \end{align*} $$
的对偶问题(D)为
$$ \begin{align*} &\min && b^\top y \\ &s.t. && A^\top y\geq c \end{align*} $$
任何线性规划问题都可以写成标准形式,如下例:
非标准形式(P1)
$$ \begin{align*} &\max && d^\top x \\ &s.t. && Fx=0 \\ & && Ix\leq c \\ & && x\geq0 \end{align*} $$
引入松弛变量$x^\prime$,则有标准形式(P)
$$ \begin{align*} &\max && \begin{bmatrix}d\\0\end{bmatrix} ^\top \begin{bmatrix}x\\x^\prime\end{bmatrix} \\ &s.t. && \begin{bmatrix}I & 1\\F & 0\end{bmatrix}\begin{bmatrix}x\\x^\prime\end{bmatrix}= \begin{bmatrix}c\\0\end{bmatrix} \\ & && \begin{bmatrix}x\\x^\prime\end{bmatrix}\geq0 \end{align*} $$
使用以上定理可以很容易得到对偶问题
对于最小化问题,可以先转为最大化问题再使用以上定理,也可以直接使用以下定理
定理:主问题(P)
$$ \begin{align*} &\min && c^\top x \\ &s.t. && Ax=b \\ & && x\geq0 \end{align*} $$
则有对偶问题(D)
$$ \begin{align*} &\max && b^\top y \\ &s.t. && A^\top y\leq c \end{align*} $$
展开阅读
python中的
p=re.compile(r"")
p.match("...")
只会从头匹配到尾,一般用于split之后的token的匹配,因此一般使用re.findall("...")
,或直接替换用re.sub()
给定类似[!abc](sfsdfsdf)abc
类型的字符串,如何把它替换成$abc
?
s=re.sub(r"\!\[(.*)\]\(.*?\)\1",r"$\1$",s)
其中要对!
,[]
,()
进行转义,使用?
取消greedy模式,并可以在用来替换的raw字符串中使用capture到的group
展开阅读
?
表示单个字符;*
(star)表示任意数量的字符;**
(global star)表示递归地匹配任意数量的字符,包括/
;[aeiou]
和正则表达式意义相同,但是匹配失败时会escape变回原意;[!aeiou]
表示除了aeiou;{aeiou}
匹配失败时不会变回原意,并且可以嵌套其他通配符,{a..z}
匹配a到z
通配符是先解释,再执行。不匹配时,会原样输出。只适用于单层路径(除了global star)。文件名中可能出现通配符。
展开阅读
初始化动态二维矩阵
#include<stdio.h>
#include<stdlib.h>
int** matrix(int height,int width,int initial)
{
int **a=malloc(sizeof *a * height);
printf("Initializing matrix of size %d X %d with initial value %d\n", height,width,initial);
for(int i=0;i<height;i++)
{
a[i]=malloc(sizeof *(a[i]) * width);
for(int j=0;j<width;j++)
{
a[i][j]=initial;
}
}
printf("Printing the matrix...\n");
for(int i=0;i<height;i++)
{
for(int j=0;j<width;j++)
{
printf("%d ",a[i][j]);
}
printf("\n");
}
}
int main(void)
{
int** m=matrix(4,5,0);
return 0;
}
分析复杂变量声明
#include<stdio.h>
#include<string.h>
#include<ctype.h>
#define MAXTOKEN 100
enum { NAME, PARENS, BRACKETS};
void dcl(void);
void dirdcl(void);
int gettoken(void);
int tokentype;
char token[MAXTOKEN];
char name[MAXTOKEN];
char datatype[MAXTOKEN];
char out[1000];
main()
{
while (gettoken() != EOF) {
strcpy(datatype, token);
out[0] = '\0';
dcl();
if (tokentype != '\n')
printf("syntax error\n");
printf("%s: %s %s\n", name, out, datatype);
}
return 0;
}
/* dcl: parse a declarator */
void dcl(void)
{
int ns;
for (ns = 0; gettoken() == '*'; ) /* count *'s */
ns++;
dirdcl();
while (ns-- > 0)
strcat(out, " pointer to");
}
/* dirdcl: parse a direct declarator */
void dirdcl(void)
{
int type;
if (tokentype == '(') { /* ( dcl ) */
dcl();
if (tokentype != ')')
printf("error: missing )\n");
} else if (tokentype == NAME) /* variable name */
strcpy(name, token);
else
printf("error: expected name or (dcl)\n");
while ((type=gettoken()) == PARENS || type == BRACKETS)
if (type == PARENS)
strcat(out, " function returning");
else {
strcat(out, " array");
strcat(out, token);
strcat(out, " of");
}
}
int gettoken(void)
{
int c, getch(void);
void ungetch(int);
char *p = token;
while ((c = getch()) == ' ' || c == '\t')
;
if (c == '(') {
if ((c = getch()) == ')') {
strcpy(token, "()");
return tokentype = PARENS;
} else {
ungetch(c);
return tokentype = '(';
}
} else if (c == '[') {
for (*p++ = c; (*p++ = getch()) != ']'; )
;
*p = '\0';
return tokentype = BRACKETS;
} else if (isalpha(c)) {
for (*p++ = c; isalnum(c = getch()); )
*p++ = c;
*p = '\0';
ungetch(c);
return tokentype = NAME;
} else
return tokentype = c;
}
#define BUFSIZE 100
char buf[BUFSIZE];
int bufp = 0;
int getch(void)
{
return (bufp >0) ? buf[--bufp] : getchar();
}
void ungetch(int c)
{
if (bufp >= BUFSIZE)
printf("üngetch: too many characters\n");
else
buf[bufp++] = c;
}
打印进度条
void progress_bar(const int n, const int tot)
{
int i, pgr = n*50/tot, rem = (tot-n)*50/tot;
printf("\r[");
for (i=0; i<pgr; i++)
printf("#");
for (i=0; i<rem; i++)
printf("-");
printf("]");
}
lambda表达式
#define lambda(lambda$_ret, lambda$_args, lambda$_body)\
// 语句表达式
({\
lambda$_ret lambda$__anon$ lambda$_args\
lambda$_body\
lambda$__anon$;\ // 返回值
})
注释切换代码
#include<stdio.h>
int main(){
/**
printf("1\n");
/*/
printf("2\n");
//*/
/**/
printf("3\n");
/*/
printf("4\n");
//*/
return 0;
}
展开阅读
录制宏
qq
x
x
<Esc>
q
执行宏
@q
分屏
:sp filename
:vsp filename
<Ctrl + w>
v
<Ctrl + w>
s
<Ctrl + w>
h
<Ctrl + w>
l
<Ctrl + w>
j
<Ctrl + w>
k
跳转到历史编辑位置
<Ctrl + o>
<Ctrl + i>
在当前目录下的文件的内容中递归地搜索abc,跳转到下一个搜索到的内容
:vimgrep abc **/*.*
:cnext
删除到第20行
d20G
跳转到上一段,下一段
{
}
防止粘贴引起缩进混乱
:set paste
不退出vim编译运行代码
:!gcc test.c
:! a
编辑多行
<Ctrl-v>
"move to the last line
<Shift-I>
"edit
<Esc>
加密文件
:X
"输入密码
自动补全<Ctrl-n>
合并多个行
按V并移动,选中要合并的行
:j
合并两行:<Shift-j>
在新tab中打开文件
:tabnew filename
跳转tab
gt
gT
把制表符换成空格
:retab
比较文件
vimdiff file1 file2
:vert diffsplit file2
<Ctrl-u> 向上跳转
<Ctrl-d> 向下跳转
<Ctrl-f> 向前跳转
<Ctrl-b> 向后跳转
手动安装插件
:set runtimepath? "如果怕麻烦直接粘贴到这里的任一路径中
"set runtimepath^=~/.vim/bundle/ctrlp.vim "或添加到.vimrc里
查找替换
:{作用范围}s/{目标}/{替换}/{替换标志}
:%s/foo/bar/g
"替换当前行及之后共3行中的内容
:.,.+3s/foo/bar/g
重构代码
"跳转到变量定义处
gd
"跳转到上一个大括号
[{
"跳转到互补的括号
%
"生成当前搜索正在使用的正则表达式
<Ctrl-r>/
"使用ctags生成代码索引
!ctags -R
"跨文件查找定义位置
<Ctrl-]>
"返回旧的文件
<Ctrl-t>
"sudo apt install global #使用gtags生成索引
"gtags -v
:set csprg=gtags-cscope
:cs add GTAGS
在用Ctrl-V选中的Visual Block中查找替换
"替换掉Visual Block中所有空格
"在选中后按:
:'<,'>s/\%V\s\%V//g
查看二进制文件
:set binary
:%!xxd -p
:%!xxd -p -r
:w
切换编码格式
:set enc " 查看当前编码格式
:e ++enc=cp1252 " 重载为masm32 editor默认编码
:e ++enc=gb2312 " 重载为windows汉字编码
:w ++enc=utf-8 " 保存为utf-8格式
自动补全与拼写检查
:set spell spelllang=en " 打开拼写检查
:set nospell " 关闭拼写检查
]s " 找到下一个错误拼写单词
z= " 拼写建议
zg " 把未识别单词加入字典
<Ctrl-n> "<Ctrl-p> 自动补全
undo tree
:earlier 10 " 恢复到10分钟之前的状态
:later 10 " 恢复到10分钟之后的状态
g- " 按时间向前恢复
g+ " 按时间向后恢复
输入希腊字母
<Ctrl-k>
t*
配置文件
syntax enable
set expandtab
set smarttab
set shiftwidth=4
set tabstop=4
set ai
set si
set wrap
set fileencodings=ucs-bom,utf-8,utf-16,gb2312,gbk,big5,gb18030,latin1
set encoding=utf8
filetype plugin on
filetype indent on
set history=5000
set autoread
set so=7
let $LANG='en'
set langmenu=en
set ruler
set nu
set hid
set ignorecase
set smartcase
set hlsearch
set incsearch
set lazyredraw
set magic
set showmatch
set mouse=a
set undofile
set undodir=~/.vim/undodir
set backupdir=~/.vim/backupdir
set directory=~/.vim/swapdir
set noerrorbells
set novisualbell
"set spell spelllang=en
set autochdir
colorscheme industry
"以下为rust-analyzer和ALE插件
filetype plugin indent on
let g:ale_linters = {'rust': ['analyzer']}
set completeopt=menu,menuone,preview,noselect,noinsert
let g:ale_completion_enabled = 1
"以下为cscope需要的设置
set csprg=gtags-cscope
set cscopequickfix=s-,c-,d-,i-,t-,e-
set csto=0
set cscopetag
set cst
if filereadable("GTAGS")
cs add GTAGS
elseif $CSCOPE_DB != ""
cs add $CSCOPE_DB
endif
set tags=./tags,tags;
" 记住上次打开的位置
if has("autocmd")
au BufReadPost * if line("'\"") > 1 && line("'\"") <= line("$") | exe "normal! g'\"" | endif
endif
展开阅读
交错级数:
展开阅读
格式说明:1234567表示和弦级数,“,”分隔不同小节,“ ”分隔同一小节和弦,M表示大和弦,m表示小和弦,其余符号标记在括号内,如IVm7-5表示为4m(7-5),但顺阶和弦的大小不会标出。歌曲名字下标记出调式(不严格按照原歌曲调式)
誰かが傷ついても
bB大调(其实是g小调,懒得改了)
6,4,2 5,1
4,2,7,3
4,5,6 5,4
2,6,2,3M
6,3,4 5,1
4,3,2,3M
6,3,4 5,1
4,3,2 5,6,2 5,4,6
綺麗で儚いもの
#F大调
1 3,6,5 4,1 5
1 3,6,1 2,4 5
6 5,4,6 5,4
2 5,3 6,4
1(add9),5
4,1,2 b6,6,4,1,2,5
4,1,2 b6,6,4 5,3 6,2 5,1
展开阅读
import numpy as np
import cv2
def zmMinFilterGray(src, r=7):
'''最小值滤波,r是滤波器半径'''
return cv2.erode(src, np.ones((2*r+1, 2*r+1)))
def guidedfilter(I, p, r, eps):
'''引导滤波,直接参考网上的matlab代码'''
height, width = I.shape
m_I = cv2.boxFilter(I, -1, (r,r))
m_p = cv2.boxFilter(p, -1, (r,r))
m_Ip = cv2.boxFilter(I*p, -1, (r,r))
cov_Ip = m_Ip-m_I*m_p
m_II = cv2.boxFilter(I*I, -1, (r,r))
var_I = m_II-m_I*m_I
a = cov_Ip/(var_I+eps)
b = m_p-a*m_I
m_a = cv2.boxFilter(a, -1, (r,r))
m_b = cv2.boxFilter(b, -1, (r,r))
return m_a*I+m_b
def getV1(m, r, eps, w, maxV1): #输入rgb图像,值范围[0,1]
'''计算大气遮罩(暗通道)图像V1和光照值A, V1 = 1-t/A'''
V1 = np.min(m,2) #得到暗通道图像
#V1 = inverse_color_01(V1)
# cv2.imshow("dark channel", V1)
# cv2.waitKey(0)
V1 =guidedfilter(V1, zmMinFilterGray(V1,7), r, eps) #使用引导滤波优化
bins = 2000
ht = np.histogram(V1, bins) #计算大气光照A
d = np.cumsum(ht[0])/float(V1.size)
for lmax in range(bins-1, 0, -1):
if d[lmax]<=0.999:
break
A = np.mean(m,2)[V1>=ht[1][lmax]].max()
V1 = np.minimum(V1*w, maxV1) #对值范围进行限制
return V1,A
def deHaze(m, r=81, eps=0.001, w=0.95, maxV1=0.80):
Y = np.zeros(m.shape)
V1,A = getV1(m, r, eps, w, maxV1) #得到遮罩图像和大气光照
for k in range(3):
Y[:,:,k] = (m[:,:,k]-V1)/(1-V1/A) #颜色校正
Y = np.clip(Y, 0, 1)
return Y
def interpo(x, middle_ratio, max_x, max_num):
# 自定义的直方图
#| /\
#| / \
#| / \
#|/____ratio___\___
#
if not 0<=x<=max_x:
return 0
elif x<middle_ratio*max_x:
return int(max_num/(middle_ratio*max_x)*x)+1
else:
return int(max_num - max_num/(255-middle_ratio*max_x)*(x-middle_ratio*max_x))+1
def func(ratio):
# 使用自定义的直方图曲线func()生成直方图实例化图像
ret = []
for i in range(256):
ret = ret + [i]*interpo(i, ratio, 255, 1000)
return np.array(ret)
def find_nearest_above(my_array, target):
diff = my_array - target
mask = np.ma.less_equal(diff, -1)
# We need to mask the negative differences
# since we are looking for values above
if np.all(mask):
c = np.abs(diff).argmin()
return c # returns min index of the nearest if target is greater than any value
masked_diff = np.ma.masked_array(diff, mask)
return masked_diff.argmin()
def hist_match(original, specified):
oldshape = original.shape
original = original.ravel()
specified = specified.ravel()
# get the set of unique pixel values and their corresponding indices and counts
s_values, bin_idx, s_counts = np.unique(original, return_inverse=True,return_counts=True)
t_values, t_counts = np.unique(specified, return_counts=True)
# Calculate s_k for original image
s_quantiles = np.cumsum(s_counts).astype(np.float64)
s_quantiles /= s_quantiles[-1]
# Calculate s_k for specified image
t_quantiles = np.cumsum(t_counts).astype(np.float64)
t_quantiles /= t_quantiles[-1]
# Round the values
sour = np.around(s_quantiles*255)
temp = np.around(t_quantiles*255)
# Map the rounded values
b=[]
for data in sour[:]:
b.append(find_nearest_above(temp,data))
b= np.array(b,dtype='uint8')
return b[bin_idx].reshape(oldshape)
def hist_match_all(img):
# 对图像的每个通道都进行直方图规定化,使用func()中定义的直方图进行规定
result = np.zeros_like(img)
for i in range(3):
specified = func(0.2)
result[:,:,i] = hist_match(img[:,:,i], specified)
return result
def image_hist(image): #画三通道图像的直方图
color = ("blue", "green", "red")#画笔颜色的值可以为大写或小写或只写首字母或大小写混合
for i, color in enumerate(color):
hist = cv2.calcHist([image], [i], None, [256], [0, 256])
plt.plot(hist, color=color)
plt.xlim([0, 256])
plt.show()
def normalize(img):
# 将像素最大值小于255的图像归一化到255
return (img/np.max(img)*255).astype(np.uint8)
def hist_match_dark_prior(img, dark=False):
# 基于暗/亮通道的直方图规定化
result = img.copy()
for i in range(3):
result[:,:,i] = cv2.equalizeHist(result[:,:,i])
if dark==False:
dark_prior = np.min(result, axis=2)
else:
dark_prior = np.max(result, axis=2)
#image_hist(np.stack([dark_prior]*3, axis=2))
for j in range(3):
for i in range(3):
result[:,:,i] = hist_match(result[:,:,i], dark_prior)
result = normalize(result)
#image_hist(result)
return result
if __name__=="__main__":
img = cv2.imread("filename")
img = hist_match_all(img)
img = dehaze255(img)
cv2.imwrite("filename_write", img)
再放一个pytorch版的:
import torch
def torch_equalize(image):
"""Implements Equalize function from PIL using PyTorch ops based on:
https://github.com/tensorflow/tpu/blob/master/models/official/efficientnet/autoaugment.py#L352"""
def scale_channel(im, c):
"""Scale the data in the channel to implement equalize."""
im = im[:, :, c]
# Compute the histogram of the image channel.
histo = torch.histc(im, bins=256, min=0, max=255)#.type(torch.int32)
# For the purposes of computing the step, filter out the nonzeros.
nonzero_histo = torch.reshape(histo[histo != 0], [-1])
step = (torch.sum(nonzero_histo) - nonzero_histo[-1]) // 255
def build_lut(histo, step):
# Compute the cumulative sum, shifting by step // 2
# and then normalization by step.
lut = (torch.cumsum(histo, 0) + (step // 2)) // step
# Shift lut, prepending with 0.
lut = torch.cat([torch.zeros(1), lut[:-1]])
# Clip the counts to be in range. This is done
# in the C code for image.point.
return torch.clamp(lut, 0, 255)
# If step is zero, return the original image. Otherwise, build
# lut from the full histogram and step and then index from it.
if step == 0:
result = im
else:
# can't index using 2d index. Have to flatten and then reshape
result = torch.gather(build_lut(histo, step), 0, im.flatten().long())
result = result.reshape_as(im)
return result.type(torch.uint8)
# Assumes RGB for now. Scales each channel independently
# and then stacks the result.
image = image.type(torch.float)
s1 = scale_channel(image, 0)
s2 = scale_channel(image, 1)
s3 = scale_channel(image, 2)
image = torch.stack([s1, s2, s3], 2)
return image
def find_nearest_above(my_array, target):
diff = my_array - target
mask = diff <= -1
# We need to mask the negative differences
# since we are looking for values above
if torch.all(mask):
c = torch.abs(diff).argmin()
return c # returns min index of the nearest if target is greater than any value
masked_diff = diff.clone()
masked_diff[mask] = 9999
return masked_diff.argmin()
def hist_match(source, template):
s = source.view(-1)
t = template.view(-1)
s_values, bin_idx, s_counts = torch.unique(s, return_inverse=True, return_counts=True)
t_values, t_counts = torch.unique(t, return_counts=True)
s_quantities = torch.cumsum(s_counts,0).type(torch.float)
t_quantities = torch.cumsum(t_counts,0).type(torch.float)
s_quantities = s_quantities/s_quantities[s_quantities.shape[0]-1]
t_quantities = t_quantities/t_quantities[t_quantities.shape[0]-1]
sour = (s_quantities * 255).type(torch.long)
temp = (t_quantities * 255).type(torch.long)
b = torch.zeros(sour.shape)
for i in range(sour.shape[0]):
b[i] = find_nearest_above(temp, sour[i])
s=b[bin_idx]
return s.view(source.shape)
def hist_match_dark_prior(img):
# input: img[h, w, c]
# output:res[h, w, c]
result = img.clone()
result = torch_equalize(result)
dark_prior,_ = torch.min(result, axis=2)
for i in range(3):
result[:,:,i] = hist_match(result[:,:,i], dark_prior)
return result
if __name__=='__main__':
from PIL import Image
import numpy as np
im=Image.open("Night-schene-03.jpg")
img=torch.from_numpy(np.array(im))
img1=hist_match_dark_prior(img).numpy()
im1=Image.fromarray(img1)
im1.save('out.png')
展开阅读
G是群, $a\in G$ 则 $|a|$ 表示a的阶
$a|b$ 表示a整除b,如2|6
$a\perp b$ 表示a和b互素,如 $3\perp 5$
d是r和s的最小公倍数记作 $d=[r,s]$
群G有子群H,群G的阶是可以被子群H的阶整除的,此时我们称[G:H]为H在G下的指数,指数的多少与陪集个数是相同的
对于环)(R,+,·),已知(R, +)是阿贝尔群。R的子集I称为R的一个右理想,若I满足:
如果I既是R的右理想又是R的左理想,那么I是R的理想。
设G是群,H是G的子群,称子群H在群G中的左陪集或右陪集的个数为H在G中的指数,记作 $\left[ {G:H} \right]$ 。拉格朗日定理: $|G| = |H|\left[ {G:H} \right]$
设H是群G的子群,如果对每个 $a\in G$ 都有 $aH=Ha$ 则称H是群G的正规子群,记作 $H \triangleleft G$ ,如果G只有平凡的正规子群,且 $G\neq \{e\}$ 则称G为单群
设G为群,H是G的正规子群,H的所有陪集 $G/H = \{ aH|a \in G\} $ 关于G的子集上的乘法运算构成的群称为G关于H的的商群
环R的理想 P是素理想,当且仅当它是一个真理想(也就是说,P ≠ R),且对于R的任何两个理想A和B,若有AB ⊆ P,则A ⊆ P或B ⊆ P。
任意有单位元的环一定有极大理想,a是R的极大理想当且仅当R/a是单纯环
除环 非零环 整环