├── Circle_Packing ├── CP.m ├── F_box.m ├── F_coll.m ├── P_box.m ├── P_coll.m └── draw_circle.m ├── README.md ├── SVM ├── F_data.m ├── F_pos.m ├── F_separation.m ├── F_sum.m ├── P_data.m ├── P_pos.m ├── P_separation.m ├── P_sum.m └── SVM.m ├── Sudoku ├── F_knowThat.m ├── F_onlyOne.m ├── P_knowThat.m ├── P_onlyOne.m └── Sudoku.m ├── TV_Denoising ├── FL.m ├── F_diff.m ├── F_quad.m ├── P_diff.m └── P_quad.m └── index.html /Circle_Packing/CP.m: -------------------------------------------------------------------------------- 1 | % ADMM Parameters 2 | 3 | % 4 | alpha = 0.001; 5 | 6 | % check out reasonable r vs num_balls relations here [http://www.packomania.com] 7 | %r = 0.149; % r = 0.149; won't work 8 | %num_balls = 10; 9 | 10 | r = 0.071; % r = 0.072; won't work 11 | num_balls = 50; 12 | 13 | % Initialization 14 | u_box = rand(num_balls,2); 15 | u_coll = rand(num_balls, num_balls,4); 16 | 17 | m_box = rand(num_balls,2); 18 | m_coll = rand(num_balls, num_balls,4); 19 | 20 | z = rand(num_balls,2); 21 | 22 | % bookeeping convergence 23 | evol_z = []; 24 | evol_u = []; 25 | evol_m = []; 26 | t = 0; 27 | %% 28 | while(1) 29 | t = t+1; 30 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 31 | % 32 | %process left nodes 33 | % 34 | %%%%%%%%%%%%%%%%%%%% 35 | % first process box nodes 36 | m_box_old = m_box; % bookeeping convergence 37 | u_box_old = u_box; % bookeeping convergence 38 | for j = 1:num_balls 39 | [m_box(j,1) , m_box(j,2) , u_box(j,1) , u_box(j,2)] = F_box( z(j,1), z(j,2), u_box(j,1) , u_box(j,2) ,alpha ,r); 40 | end 41 | 42 | % second process coll nodes 43 | m_coll_old = m_coll; % bookeeping convergence 44 | u_coll_old = u_coll; % bookeeping convergence 45 | for j = 1:num_balls-1 46 | for k = j+1:num_balls 47 | [ m_coll(j,k,1) , m_coll(j,k,2) , m_coll(j,k,3) , m_coll(j,k,4) , u_coll(j,k,1), u_coll(j,k,2), u_coll(j,k,3), u_coll(j,k,4)] = F_coll( z(j,1) , z(j,2) , z(k,1), z(k,2), u_coll(j,k,1), u_coll(j,k,2), u_coll(j,k,3), u_coll(j,k,4) , alpha , r); 48 | end 49 | end 50 | 51 | 52 | 53 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 54 | 55 | 56 | 57 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 58 | % 59 | %process right nodes 60 | % 61 | %%%%%%%%%%%%%%%%%%%% 62 | 63 | z_old = z; % bookeeping convergence 64 | z = 0*z; 65 | 66 | for j = 1:num_balls 67 | z(j,1) = z(j,1) + m_box(j,1); 68 | z(j,2) = z(j,2) + m_box(j,2); 69 | end 70 | for j = 1:num_balls-1 71 | for k = j+1:num_balls 72 | z(j,1) = z(j,1) + m_coll(j,k,1); 73 | z(j,2) = z(j,2) + m_coll(j,k,2); 74 | z(k,1) = z(k,1) + m_coll(j,k,3); 75 | z(k,2) = z(k,2) + m_coll(j,k,4); 76 | end 77 | end 78 | z = z / num_balls; 79 | 80 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 81 | 82 | if (mod(t,1000) == 0) 83 | evol_u = [evol_u , log(norm(u_box(:) - u_box_old(:)) + norm(u_coll(:) - u_coll_old(:)))]; 84 | evol_m = [evol_m , log(norm(m_box(:) - m_box_old(:)) + norm(m_coll(:) - m_coll_old(:)))]; 85 | evol_z = [evol_z , log(norm(z-z_old)) ]; 86 | subplot(2,1,1); 87 | axis([0 1 0 1]); 88 | cla; 89 | hold on; 90 | draw_circle(z,r); 91 | plot([0,0,1,1,0],[0,1,1,0,0],'-'); 92 | hold off; 93 | 94 | subplot(2,1,2); 95 | cla; 96 | hold on; 97 | plot(evol_z); 98 | plot(evol_m); 99 | plot(evol_u); 100 | hold off; 101 | drawnow; 102 | end 103 | 104 | end 105 | -------------------------------------------------------------------------------- /Circle_Packing/F_box.m: -------------------------------------------------------------------------------- 1 | function [m_1, m_2, new_u_1, new_u_2] = F_box(z_1, z_2, u_1, u_2,alpha , r) 2 | 3 | % compute internal updates 4 | [x_1 , x_2] = P_box(z_1 - u_1 , z_2 - u_2 ,r); 5 | 6 | new_u_1 = u_1 - alpha*(z_1 - x_1); 7 | new_u_2 = u_2 - alpha*(z_2 - x_2); 8 | 9 | % compute outgoing messages 10 | m_1 = new_u_1 + x_1; 11 | m_2 = new_u_2 + x_2; 12 | end 13 | -------------------------------------------------------------------------------- /Circle_Packing/F_coll.m: -------------------------------------------------------------------------------- 1 | function [m_1,m_2,m_3,m_4,new_u_1,new_u_2,new_u_3,new_u_4] = F_coll(z_1,z_2,z_3,z_4,u_1,u_2,u_3,u_4, alpha , r) 2 | 3 | % Compute internal updates 4 | [x_1,x_2,x_3,x_4] = P_coll(z_1-u_1,z_2-u_2,z_3-u_3,z_4-u_4 , r); 5 | 6 | new_u_1 = u_1-(z_1-x_1); new_u_2 = u_2-alpha*(z_2-x_2); 7 | new_u_3 = u_3-(z_3-x_3); new_u_4 = u_4-alpha*(z_4-x_4); 8 | 9 | % Compute outgoing messages 10 | m_1 = new_u_1 + x_1; m_2 = new_u_2 + x_2; 11 | m_3 = new_u_3 + x_3; m_4 = new_u_4 + x_4; 12 | end 13 | -------------------------------------------------------------------------------- /Circle_Packing/P_box.m: -------------------------------------------------------------------------------- 1 | function [x_1 , x_2 ] = P_box(z_minus_u_1, z_minus_u_2,r) 2 | 3 | x_1 = min([1-r, max([r, z_minus_u_1])]); 4 | x_2 = min([1-r, max([r, z_minus_u_2])]); 5 | 6 | end 7 | 8 | -------------------------------------------------------------------------------- /Circle_Packing/P_coll.m: -------------------------------------------------------------------------------- 1 | function [x_1, x_2, x_3, x_4] = P_coll(z_minus_u_1, z_minus_u_2, z_minus_u_3, z_minus_u_4 , r) 2 | 3 | d = sqrt((z_minus_u_1 - z_minus_u_3)^2 + (z_minus_u_2 - z_minus_u_4)^2); 4 | if (d > 2*r) 5 | x_1 = z_minus_u_1; x_2 = z_minus_u_2; 6 | x_3 = z_minus_u_3; x_4 = z_minus_u_4; 7 | return; 8 | end 9 | x_1 = 0.5*(z_minus_u_1 + z_minus_u_3) + r*(z_minus_u_1 - z_minus_u_3)/d; 10 | x_2 = 0.5*(z_minus_u_2 + z_minus_u_4) + r*(z_minus_u_2 - z_minus_u_4)/d; 11 | x_3 = 0.5*(z_minus_u_1 + z_minus_u_3) - r*(z_minus_u_1 - z_minus_u_3)/d; 12 | x_4 = 0.5*(z_minus_u_2 + z_minus_u_4) - r*(z_minus_u_2 - z_minus_u_4)/d; 13 | end 14 | 15 | -------------------------------------------------------------------------------- /Circle_Packing/draw_circle.m: -------------------------------------------------------------------------------- 1 | function [] = draw_circle(centers,r) 2 | 3 | 4 | theta = 0:0.01:2*pi; 5 | 6 | for i = 1:size(centers,1) 7 | 8 | x_l = centers(i,1) + r.*cos(theta); 9 | y_l = centers(i,2) +r.*sin(theta); 10 | 11 | scatter(x_l,y_l,1); 12 | end 13 | 14 | 15 | end -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ADMM-tutorial 2 | 3 | This repository contains the code for the tutorial presented at the 2018, Open Data Science Conference (ODSC) in Boston. 4 | 5 | The slides can be found at http://www.jbento.info/slides/ADMM_Tutorial_ODSC_2018.pdf 6 | 7 | The tutorial covers four different problems. All of them are solved using the Alternating Direction Method of Multipliers (ADMM). 8 | 9 | Two of the examples concern convex optimization problems: SVM and Total Variation Denoising. 10 | Two of the examples concern non-convex optimization problems: Circle packing and solving Sudoku puzzles. 11 | 12 | The tutorial, and the code, approach the problems from an angle that leads to the math and code being as simple as possible. 13 | The code is not meant for speed, and the variant of the ADMM that we cover is not the fastest possible one. 14 | 15 | Please cite this tutorial using the following references. 16 | 17 | @article{safavi2018admmtutorial, 18 | title={Networks and large scale optimization}, note={Open Data Science Conference}, 19 | author={Safavi, Sam and Bento, Jos{\’e}}, 20 | year={2018} 21 | } 22 | 23 | @inproceedings{hao2016testing, 24 | title={Testing fine-grained parallelism for the ADMM on a factor-graph}, 25 | author={Hao, Ning and Oghbaee, AmirReza and Rostami, Mohammad and Derbinsky, Nate and Bento, Jos{\'e}}, booktitle={Parallel and Distributed Processing Symposium Workshops, 2016 IEEE International}, pages={835--844}, 26 | year={2016}, 27 | organization={IEEE} 28 | } 29 | 30 | @inproceedings{francca2016explicit, 31 | title={An explicit rate bound for over-relaxed ADMM}, 32 | author={Fran{\c{c}}a, Guilherme and Bento, Jos{\'e}}, booktitle={Information Theory (ISIT), 2016 IEEE International Symposium on}, pages={2104--2108}, 33 | year={2016}, 34 | organization={IEEE} 35 | } 36 | 37 | @article{derbinsky2013improved, 38 | title={An improved three-weight message-passing algorithm}, 39 | author={Derbinsky, Nate and Bento, Jos{\'e} and Elser, Veit and Yedidia, Jonathan S}, journal={arXiv preprint arXiv:1305.1961}, 40 | year={2013} 41 | } 42 | 43 | @article{bento2018complexity, 44 | title={On the Complexity of the Weighted Fussed Lasso}, author={Bento, Jos{\’e} and Furmaniak, Ralph and Ray, Surjyendu}, journal={arXiv preprint arXiv:1801.04987}, 45 | year={2018} 46 | } 47 | -------------------------------------------------------------------------------- /SVM/F_data.m: -------------------------------------------------------------------------------- 1 | function [M_data,M_plane, new_U_data,new_U_plane] = F_data(Z_slack, Z_plane,U_data_slack,U_data_plane, x_i, y_i) 2 | 3 | [X_data, X_plane] = P_data( Z_slack - U_data_slack , Z_plane - U_data_plane , x_i, y_i); 4 | 5 | new_U_data = U_data_slack + (X_data - Z_slack); 6 | new_U_plane = U_data_plane + (X_plane - Z_plane); 7 | 8 | M_plane = new_U_plane + X_plane; 9 | M_data = new_U_data + X_data; 10 | 11 | end -------------------------------------------------------------------------------- /SVM/F_pos.m: -------------------------------------------------------------------------------- 1 | function [M, new_U] = F_pos(Z , U) 2 | 3 | X = P_pos( Z - U ); 4 | 5 | new_U = U + (X - Z); 6 | 7 | M = new_U + X; 8 | 9 | end -------------------------------------------------------------------------------- /SVM/F_separation.m: -------------------------------------------------------------------------------- 1 | function [M, new_U] = F_separation(Z, U) 2 | 3 | X = P_separation( Z - U ); 4 | 5 | new_U = U + (X - Z); 6 | 7 | M = new_U + X; 8 | 9 | end 10 | 11 | -------------------------------------------------------------------------------- /SVM/F_sum.m: -------------------------------------------------------------------------------- 1 | function [M, new_U] = F_sum(Z, U) 2 | 3 | X = P_sum( Z - U ); 4 | 5 | new_U = U + (X - Z); 6 | 7 | M = new_U + X; 8 | 9 | end 10 | 11 | 12 | -------------------------------------------------------------------------------- /SVM/P_data.m: -------------------------------------------------------------------------------- 1 | function [X_data, X_plane] = P_data(Z_slack_minus_U_data_slack, Z_plane_minus_U_data_plane, x_i, y_i) 2 | 3 | if (y_i*Z_plane_minus_U_data_plane'*x_i >= 1 - Z_slack_minus_U_data_slack) 4 | 5 | X_data = Z_slack_minus_U_data_slack; 6 | X_plane = Z_plane_minus_U_data_plane; 7 | 8 | else 9 | beta = ((1-[1;y_i*x_i]'*[Z_slack_minus_U_data_slack;Z_plane_minus_U_data_plane])/([1;y_i.*x_i]'*[1;y_i*x_i])); 10 | X_data = Z_slack_minus_U_data_slack + beta; 11 | X_plane = Z_plane_minus_U_data_plane + beta*y_i*x_i; 12 | 13 | end 14 | 15 | -------------------------------------------------------------------------------- /SVM/P_pos.m: -------------------------------------------------------------------------------- 1 | function [X] = P_pos(Z_minus_U) 2 | 3 | X = max(Z_minus_U,0); 4 | 5 | end 6 | -------------------------------------------------------------------------------- /SVM/P_separation.m: -------------------------------------------------------------------------------- 1 | function [X] = P_separation(Z_minus_U) 2 | 3 | global rho 4 | global lambda 5 | 6 | X = (rho/(lambda + rho)) * Z_minus_U ; 7 | 8 | end 9 | -------------------------------------------------------------------------------- /SVM/P_sum.m: -------------------------------------------------------------------------------- 1 | function [X] = P_sum(Z_minus_U) 2 | 3 | global rho 4 | 5 | X = Z_minus_U - (1 / rho) ; 6 | 7 | end 8 | 9 | -------------------------------------------------------------------------------- /SVM/SVM.m: -------------------------------------------------------------------------------- 1 | %Create random data 2 | clc 3 | close all 4 | clear 5 | a=0:0.1:1; 6 | n = 100; 7 | p = 2; 8 | x(1,1:n/2) = (abs(0.1+0.9*rand(1,n/2))); 9 | x(1,n/2+1:n) = (abs(0.1+0.9*rand(1,n/2))); 10 | x(2,1:n/2) = x(1,1:n/2)+0.1*rand(1,n/2); 11 | x(2,n/2+1:n) = x(1,n/2+1:n)-0.1*rand(1,n/2); 12 | x = [x;ones(1,n)]; 13 | y=zeros(n,1); 14 | for i=1:n/2 15 | y(i) = 1; 16 | plot(x(1,i),x(2,i),'xb','MarkerSize',8); 17 | hold on 18 | end 19 | for i=n/2+1:n 20 | y(i)=-1; 21 | plot(x(1,i),x(2,i),'or','MarkerSize',8); 22 | hold on 23 | end 24 | ss= abs(rand(1,n)); 25 | % y = sign(randn(n,1)); 26 | % x = randn(p,n); 27 | % x = [x;ones(1,n)]; 28 | 29 | 30 | cvx_begin 31 | 32 | variable gap(n,1); 33 | variable hyperplane(p+1); 34 | 35 | minimize ( sum( gap) + (0.5/10)* (pow_pos(norm(hyperplane(1:p)),2)) ) 36 | 37 | subject to 38 | 39 | for i =1:n 40 | y(i)*hyperplane'*x(:,i) >= 1 - gap(i); 41 | end 42 | gap >= 0; 43 | 44 | cvx_end 45 | 46 | 47 | global rho;rho = 1;global lambda;lambda = 0.1; 48 | 49 | %Initialization 50 | U_pos = randn(n,1); 51 | U_sum = randn(n,1); 52 | U_norm = randn(p,1); 53 | U_data = randn(p+2,n); 54 | 55 | M_pos = randn(n,1); 56 | M_sum = randn(n,1); 57 | M_norm = randn(p,1); 58 | M_data = randn(p+2,n); 59 | 60 | Z_slack = randn(n,1); 61 | Z_plane = randn(p+1,1); 62 | Z_plane(p+1)=randn(1); 63 | 64 | %ADMM iterations 65 | for t = 1:2000 66 | % POSITIVE SLACK 67 | [M_pos, U_pos] = F_pos(Z_slack , U_pos); 68 | % SLACK SUM COST 69 | [M_sum, U_sum] = F_sum(Z_slack , U_sum); 70 | % SEPARATION COST 71 | [M_norm, U_norm] = F_separation(Z_plane(1:p) , U_norm); 72 | % DATA CONSTRAINT 73 | for i = 1:n 74 | [M_data(1,i), M_data(2:end,i), U_data(1,i) , U_data(2:end,i) ] = F_data( Z_slack(i), Z_plane, U_data(1,i),U_data(2:end,i),x(:,i),y(i)); 75 | end 76 | 77 | 78 | % Z updates 79 | Z_slack = M_pos + M_sum; 80 | for i = 1:n 81 | Z_slack(i) = Z_slack(i) + M_data(1,i); 82 | end 83 | Z_slack = Z_slack / 3; 84 | 85 | 86 | 87 | Z_plane(1:p) = M_norm; 88 | for i = 1:p 89 | for j = 1:n 90 | Z_plane(i) = Z_plane(i) + M_data(i+1,j); 91 | end 92 | end 93 | Z_plane(1:p) = Z_plane(1:p) / (n+1); 94 | 95 | for i = 1:n 96 | Z_plane(p+1) = Z_plane(p+1)+ M_data(p+2,i); 97 | end 98 | Z_plane(p+1) = Z_plane(p+1)/n; 99 | 100 | 101 | % hold on 102 | for i=1:n/2 103 | y(i) = 1; 104 | plot(x(1,i),x(2,i),'xb','MarkerSize',8); 105 | hold on 106 | end 107 | for i=n/2+1:n 108 | y(i)=-1; 109 | plot(x(1,i),x(2,i),'or','MarkerSize',8); 110 | hold on 111 | end 112 | 113 | h1=plot(a, (-hyperplane(1)*a - hyperplane(3)) / (hyperplane(2)),'g','LineWidth',1); 114 | hold on 115 | h2=plot(a, (-Z_plane(1)*a - Z_plane(3)) / (Z_plane(2)),'m','LineWidth',1); 116 | legend([h1 h2],{'Exact solution' 'ADMM'},'Location','northwest') 117 | 118 | set(gca,'fontsize',12) 119 | set(gcf,'color','w') 120 | set(gca,'TickLabelInterpreter','latex') 121 | set(gca, 'FontName', 'Times New Roman') 122 | str = sprintf('Iteration: %d', t); 123 | title(str,'fontweight','normal') 124 | xlim([0 1]) 125 | ylim([0 1]) 126 | drawnow; 127 | F(t) = getframe(gcf); 128 | if t<2000 129 | clf 130 | end 131 | end 132 | 133 | max(abs([Z_slack;Z_plane] - [gap;hyperplane])) 134 | 135 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 136 | % plot(y,'b','LineWidth',1) 137 | 138 | 139 | 140 | % hold on 141 | % plot(w,'g','LineWidth',1) 142 | % % hold on 143 | % plot(z,'r','LineWidth',1) 144 | 145 | %legend('Noisy data','Filtered (CVX)','Filtered (ADMM)','fontsize','12','Interpreter','latex') 146 | % legend('Noisy data','Filtered (CVX)','Filtered (ADMM)') 147 | 148 | % h1 = plot(z,'r'); 149 | % set(h1,'Visible','off') 150 | % hold on 151 | 152 | % drawnow; 153 | %pause(1) 154 | % F(t) = getframe(gcf); 155 | % if t<25 156 | % clf 157 | % end 158 | %movie(F) 159 | 160 | v = VideoWriter('SVM2', 'Motion JPEG AVI'); 161 | v.FrameRate = 20; 162 | v.Quality = 100; 163 | open(v) 164 | writeVideo(v,F) 165 | close(v) 166 | 167 | 168 | 169 | -------------------------------------------------------------------------------- /Sudoku/F_knowThat.m: -------------------------------------------------------------------------------- 1 | function [ M, new_U ] = F_knowThat(k, Z, U ) 2 | % Detailed explanation goes here 3 | 4 | X = P_knowThat(k, Z - U ); 5 | 6 | new_U = U + (X - Z); 7 | 8 | M = new_U + X; 9 | 10 | 11 | end 12 | 13 | -------------------------------------------------------------------------------- /Sudoku/F_onlyOne.m: -------------------------------------------------------------------------------- 1 | function [ M, new_U ] = F_onlyOne( Z, U ) 2 | %M, Z and U are n by one vectors 3 | 4 | X = P_onlyOne( Z - U ); 5 | 6 | new_U = U + (X - Z); 7 | 8 | M = new_U + X; 9 | 10 | end -------------------------------------------------------------------------------- /Sudoku/P_knowThat.m: -------------------------------------------------------------------------------- 1 | function [ X ] = P_knowThat( k, Z_minus_U ) 2 | %Z_minus_U is an n by 1 vector 3 | 4 | X = 0*Z_minus_U; 5 | X(k) = 1; 6 | 7 | 8 | end 9 | 10 | -------------------------------------------------------------------------------- /Sudoku/P_onlyOne.m: -------------------------------------------------------------------------------- 1 | function [ X ] = P_onlyOne( Z_minus_U ) 2 | %X and Z_minus U are n by one vectors 3 | 4 | X =0*Z_minus_U; 5 | [~,b] = max(Z_minus_U); 6 | X(b) = 1; 7 | 8 | end -------------------------------------------------------------------------------- /Sudoku/Sudoku.m: -------------------------------------------------------------------------------- 1 | n = 9; known_data = [1,4,6;1,7,4;2,1,7;2,6,3;2,7,6;3,5,9;3,6,1;3,8,8;5,2,5;5,4,1;5,5,8;5,9,3;6,4,3;6,6,6;6,8,4;6,9,5;7,2,4;7,4,2;7,8,6;8,1,9;8,3,3;9,2,2;9,7,1;]; 2 | box_indices = 1:n;box_indices = reshape(box_indices,sqrt(n),sqrt(n));box_indices = kron(box_indices,ones(sqrt(n)));% box indexing 3 | u_onlyOne_rows = randn(n,n,n);u_onlyOne_cols = randn(n,n,n);u_onlyOne_boxes = randn(n,n,n);u_onlyOne_cells = randn(n,n,n); % Initialization (number , row, col) 4 | m_onlyOne_rows = randn(n,n,n);m_onlyOne_cols = randn(n,n,n);m_onlyOne_boxes = randn(n,n,n);m_onlyOne_cells = randn(n,n,n); 5 | u_knowThat = randn(n,n,n);m_knowThat = randn(n,n,n);z = randn(n,n,n); 6 | for t = 1:15000 7 | % Process left nodes 8 | % First process knowThat nodes 9 | for i = 1:size(known_data,1) 10 | number = known_data(i,3);pos_row = known_data(i,1);pos_col = known_data(i,2); 11 | [m_knowThat(:,pos_row,pos_col),u_knowThat(:,pos_row,pos_col)] = F_knowThat(number,z(:,pos_row,pos_col),u_knowThat(:,pos_row,pos_col)); 12 | end 13 | % Second process onlyOne nodes 14 | for number = 1:n % rows 15 | for pos_row = 1:n 16 | [m_onlyOne_rows(number,pos_row,:), u_onlyOne_rows(number,pos_row,:)] = F_onlyOne(z(number,pos_row,:),u_onlyOne_rows(number,pos_row,:)); 17 | end 18 | end 19 | for number = 1:n %columns 20 | for pos_col = 1:n 21 | [m_onlyOne_cols(number,:,pos_col),u_onlyOne_cols(number,:,pos_col)] = F_onlyOne(z(number,:,pos_col),u_onlyOne_cols(number,:,pos_col)); 22 | end 23 | end 24 | for number = 1:n %boxes 25 | for pos_box = 1:n 26 | [pos_row,pos_col] = find(box_indices==pos_box); linear_indices_for_box_ele = sub2ind([n,n,n],number*ones(n,1),pos_row,pos_col); 27 | [m_onlyOne_boxes(linear_indices_for_box_ele),u_onlyOne_boxes(linear_indices_for_box_ele)] = F_onlyOne(z(linear_indices_for_box_ele),u_onlyOne_boxes(linear_indices_for_box_ele) ); 28 | end 29 | end 30 | for pos_col = 1:n %cells 31 | for pos_row = 1:n 32 | [m_onlyOne_cells(:,pos_col,pos_row),u_onlyOne_cells(:,pos_col,pos_row) ] = F_onlyOne(z(:,pos_col,pos_row),u_onlyOne_cells(:,pos_col,pos_row)); 33 | end 34 | end 35 | % Process right nodes 36 | z = 0*z;z = (m_onlyOne_rows + m_onlyOne_cols + m_onlyOne_boxes + m_onlyOne_cells)/4; 37 | for i = 1:size(known_data,1) 38 | number = known_data(i,3);pos_row = known_data(i,1);pos_col = known_data(i,2); 39 | z(number,pos_row,pos_col) = (4*z(number,pos_row,pos_col) + m_knowThat(number,pos_row,pos_col))/5; 40 | end 41 | final = zeros(n); 42 | for i = 1:n 43 | final = final + i*reshape(z(i,:,:),n,n); 44 | end 45 | disp(final); 46 | end 47 | 48 | -------------------------------------------------------------------------------- /TV_Denoising/FL.m: -------------------------------------------------------------------------------- 1 | close all 2 | clc 3 | clear 4 | close all 5 | % ADMM Parameters 6 | n = 100; 7 | global y; 8 | global rho; 9 | global lambda; 10 | 11 | y = sign(sin(0:10*2*pi/(n-1):10*2*pi))' + 0.1*randn(n,1); 12 | 13 | 14 | cvx_begin 15 | variable w(n,1) 16 | 17 | minimize ( 0.5*(w-y)'*(w-y) + lambda*norm(w(2:end)-w(1:end-1),1) ) 18 | cvx_end 19 | 20 | plot(y,'b','LineWidth',1) 21 | xlim([0 100]) 22 | ylim([-1.5 2]) 23 | set(gca,'fontsize',12) 24 | set(gcf,'color','w') 25 | set(gca,'TickLabelInterpreter','latex') 26 | set(gca, 'FontName', 'Times New Roman') 27 | % title(['Iteration: ' t]) 28 | % str = sprintf('Iteration: %d', t); 29 | % title(str,'fontweight','normal') 30 | F(1) = getframe(gcf); 31 | F(2) = getframe(gcf); 32 | hold on 33 | plot(w,'g','LineWidth',1) 34 | set(gcf,'color','w') 35 | F(3) = getframe(gcf); 36 | lambda = 0.7; 37 | 38 | % ADMM parameter 39 | rho = 1; 40 | 41 | % Initialization 42 | u_quad = randn(n,1); 43 | u_diff = randn(n-1,2); 44 | 45 | m_quad = randn(n,1); 46 | m_diff = randn(n-1,2); 47 | 48 | z = randn(n,1); 49 | 50 | for t=1:25 51 | 52 | %%%%%%%%%%%%%%%%%%%% 53 | % 54 | %process left nodes 55 | % 56 | %%%%%%%%%%%%%%%%%%%%% 57 | % first process quad nodes 58 | for i = 1:n 59 | [m_quad(i) , u_quad(i)] = F_quad( z(i), u_quad(i),i ); 60 | end 61 | % second process diff nodes 62 | for j = 1:n-1 63 | [ m_diff(j,1), m_diff(j,2), u_diff(j,1), u_diff(j,2)] = F_diff( z(j), z(j+1) , u_diff(j,1), u_diff(j,2) ); 64 | end 65 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 66 | 67 | 68 | 69 | %%%%%%%%%%%%%%%%%%%%% 70 | % 71 | %process right nodes 72 | % 73 | %%%%%%%%%%%%%%%%%%%%% 74 | z = 0*z; 75 | for i = 2:n-1 76 | z(i)= (m_quad(i) + m_diff(i-1,2) + m_diff(i,1))/3; 77 | end 78 | z(1) = (m_quad(1) + m_diff(1,1))/2; 79 | z(n) = (m_quad(n) + m_diff(n-1,2))/2; 80 | 81 | plot(y,'b','LineWidth',1) 82 | xlim([0 100]) 83 | ylim([-1.5 2]) 84 | set(gca,'fontsize',12) 85 | set(gca,'TickLabelInterpreter','latex') 86 | set(gca, 'FontName', 'Times New Roman') 87 | set(gcf,'color','w') 88 | % title(['Iteration: ' t]) 89 | str = sprintf('Iteration: %d', t); 90 | title(str,'fontweight','normal') 91 | 92 | hold on 93 | plot(w,'g','LineWidth',1) 94 | set(gca,'color','w') 95 | 96 | % hold on 97 | plot(z,'r','LineWidth',1) 98 | set(gcf,'color','w') 99 | 100 | %legend('Noisy data','Filtered (CVX)','Filtered (ADMM)','fontsize','12','Interpreter','latex') 101 | legend('Noisy data','Filtered (Exact solution)','Filtered (ADMM)') 102 | 103 | % h1 = plot(z,'r'); 104 | % set(h1,'Visible','off') 105 | % hold on 106 | 107 | drawnow; 108 | %pause(1) 109 | F(t+3) = getframe(gcf); 110 | if t<25 111 | clf 112 | end 113 | end 114 | %movie(F) 115 | 116 | v = VideoWriter('Lasso', 'Motion JPEG AVI'); 117 | v.FrameRate = 3; 118 | v.Quality = 100; 119 | open(v) 120 | writeVideo(v,F) 121 | close(v) 122 | -------------------------------------------------------------------------------- /TV_Denoising/F_diff.m: -------------------------------------------------------------------------------- 1 | function [ m_1, m_2, new_u_1, new_u_2 ] = F_diff( z_1, z_2, u_1, u_2 ) 2 | 3 | 4 | [x_1, x_2] = P_diff(z_1 - u_1, z_2 - u_2); 5 | 6 | new_u_1 = u_1 + (x_1 - z_1); 7 | new_u_2 = u_2 + (x_2 - z_2); 8 | 9 | m_1 = new_u_1 + x_1; 10 | m_2 = new_u_2 + x_2; 11 | 12 | 13 | end 14 | 15 | -------------------------------------------------------------------------------- /TV_Denoising/F_quad.m: -------------------------------------------------------------------------------- 1 | function [ m, new_u] = F_quad(z, u,i) 2 | 3 | x = P_quad(z - u,i); 4 | 5 | new_u = u + (x - z); 6 | 7 | m = new_u + x; 8 | 9 | end -------------------------------------------------------------------------------- /TV_Denoising/P_diff.m: -------------------------------------------------------------------------------- 1 | function [ x_1, x_2 ] = P_diff( z_minus_u_1,z_minus_u_2) 2 | 3 | global rho; 4 | global lambda; 5 | 6 | beta = max(-lambda/rho, min(lambda/rho,(z_minus_u_2 - z_minus_u_1)/2)); 7 | x_1 = z_minus_u_1 + beta; 8 | x_2 = z_minus_u_2 - beta; 9 | 10 | end 11 | 12 | -------------------------------------------------------------------------------- /TV_Denoising/P_quad.m: -------------------------------------------------------------------------------- 1 | function [ x ] = P_quad( z_minus_u, i ) 2 | global y; 3 | global rho; 4 | x = (z_minus_u*rho + y(i))/(1+rho); 5 | end 6 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 |

Hello !

2 | --------------------------------------------------------------------------------