|
| 1 | +//Based on following MATLAB code |
| 2 | + /* |
| 3 | + Original Matlab Code |
| 4 | + r = y; |
| 5 | + s = zeros(n, 1); |
| 6 | + for iter = 1:iters |
| 7 | + pseudo_data = At*(r)+s; |
| 8 | + sigma_hat = sqrt(1 / m*sum(fabs(r). ^ 2)); |
| 9 | + s = (fabs(pseudo_data)> lambda*sigma_hat).*(fabs(pseudo_data) - lambda*sigma_hat).*sign(pseudo_data); |
| 10 | + r = y - A*(s)+1 / m.*r.*length(find(fabs(s)>0)); |
| 11 | + end |
| 12 | + x_hat = s; |
| 13 | + end*/ |
| 14 | + |
| 15 | +#include "math.h" |
| 16 | +#include <stdio.h> |
| 17 | +#include <stdlib.h> |
| 18 | + |
| 19 | +#define M 64 // Number of measurement |
| 20 | +#define N 224 // Number of samples |
| 21 | +#define lambda 1.35 // lambda is determinded from exprimental data from RICE DSP github |
| 22 | +#define number_of_iterations 120 //self defined! |
| 23 | + |
| 24 | +int matMul(float *mat1, float *mat2, float *result, int m, int n, int q); |
| 25 | +int matMul_M(float *mat1, float *mat2, float *result, int m, int n, int q); //Matrix multipication with M being fixed (for loop unrolling) |
| 26 | +int matMul_N(float *mat1, float *mat2, float *result, int m, int n, int q); |
| 27 | +int transpose(float *mat1, float *mat2, int m, int n); |
| 28 | +int matSUB(float *mat1, float *mat2, float *result, int m, int n); //Matrix subtraction |
| 29 | +int matADD(float *mat1, float *mat2, float *result, int m, int n); //Matrix addition |
| 30 | +float norm2(float *vec); |
| 31 | +int print(float *mat, int m, int n); |
| 32 | +float sum_array(float *arr, int m); //Sum of elements of a vector |
| 33 | +float SNR(float *a, float *b, int Length); //Signal to Noise ratio |
| 34 | +float MSE(float *a, float *b, int Length); //Mean square error |
| 35 | + |
| 36 | + |
| 37 | +float sign(float input) |
| 38 | +{ |
| 39 | + return (float)((0 < input) - (input < 0)); |
| 40 | +} |
| 41 | + |
| 42 | +int main() |
| 43 | +{ |
| 44 | + |
| 45 | +//First we generate some test data for reconstruction part |
| 46 | + float A[M][N]; |
| 47 | + int i,j,k,K; |
| 48 | + int d; |
| 49 | + for (i = 0; i < M; i++) |
| 50 | + for (j = 0; j < N; j++){ |
| 51 | + int temp=0; |
| 52 | + //_TCE_RAND(1,temp); |
| 53 | + A[i][j] = (float)(rand()%3)-1; |
| 54 | + } |
| 55 | + |
| 56 | + float x[N], Y[M], At[N][M]; |
| 57 | + float middle_data[N], s[N], r[M], temp[M]; |
| 58 | + transpose((float *)A, (float *)At, M, N); |
| 59 | + float sigma; |
| 60 | + float Minve = 1 / (float)(M); |
| 61 | + float inv_sqrt_M = 1 / sqrtf(M); |
| 62 | + float inv_sqrt_N = 1 / sqrtf(N); |
| 63 | + float factor=lambda / sqrtf(M); |
| 64 | + |
| 65 | + //for (i = 1; i < M; i++) |
| 66 | + // for (j = 1; j < N; j++) |
| 67 | + // A[i][j] = (rand() % 2); // DO NOT USE THIS FUNCTION |
| 68 | + |
| 69 | + for (i = 0; i < M; i++) |
| 70 | + for (j = 0; j<N; j++) |
| 71 | + A[i][j] = A[i][j] * inv_sqrt_N; |
| 72 | + |
| 73 | + |
| 74 | + for (i = 0; i < N; i++) // only 6 out of N coeff of x are nonzero |
| 75 | + x[i] = 0; |
| 76 | + |
| 77 | + |
| 78 | + x[6] = (float)(102); |
| 79 | + x[2] = (float)(12); |
| 80 | + x[3] = (float)(32); |
| 81 | + |
| 82 | + |
| 83 | + |
| 84 | + matMul_N((float *)A,(float *) x,(float *) Y, M, N, 1); |
| 85 | + |
| 86 | + for (i = 0; i < N; i++) |
| 87 | + s[i] = 0; |
| 88 | + |
| 89 | + transpose((float *)A, (float *)At, M, N); |
| 90 | + for (i = 0; i < M; i++) |
| 91 | + r[i] = Y[i]; |
| 92 | + |
| 93 | + //Reconstruction begins here |
| 94 | +int ii,iii; |
| 95 | +printf("Algorithm Starts here:\n"); |
| 96 | +for (iii=0;iii<10;iii++) |
| 97 | + for (ii = 0; ii < number_of_iterations; ii++){ //AMP |
| 98 | + { |
| 99 | + matMul_M((float *)At, (float *)r, (float *)middle_data, N, M, 1); |
| 100 | + matADD(s, middle_data, s, N, 1); |
| 101 | + sigma = norm2(r) ; |
| 102 | + float astane= sigma* factor; |
| 103 | + int b = 0; //b = sum(fabs(s)>0) / m; |
| 104 | + for (i = 0; i < N; i+=8) |
| 105 | + { |
| 106 | + float mediatevalue1=fabs(s[i]) - astane; |
| 107 | + float mediatevalue2=fabs(s[i+1]) - astane; |
| 108 | + float mediatevalue3=fabs(s[i+2]) - astane; |
| 109 | + float mediatevalue4=fabs(s[i+3]) - astane; |
| 110 | + float mediatevalue5=fabs(s[i+4]) - astane; |
| 111 | + float mediatevalue6=fabs(s[i+5]) - astane; |
| 112 | + float mediatevalue7=fabs(s[i+6]) - astane; |
| 113 | + float mediatevalue8=fabs(s[i+7]) - astane; |
| 114 | + |
| 115 | + if (mediatevalue1>0) { s[i] = (mediatevalue1)*sign(s[i]);//s = (abs(pseudo_data)> lambda*sigma_hat).*(abs(pseudo_data) - lambda*sigma_hat).*sign(pseudo_data); |
| 116 | + b = b +1; }else s[i] = 0; |
| 117 | + |
| 118 | + if (mediatevalue2>0) { s[i+1] = (mediatevalue2)*sign(s[i+1]);//s = (abs(pseudo_data)> lambda*sigma_hat).*(abs(pseudo_data) - lambda*sigma_hat).*sign(pseudo_data); |
| 119 | + b = b +1;}else s[i+1] = 0; |
| 120 | + |
| 121 | + if (mediatevalue3>0){ s[i+2] = (mediatevalue3)*sign(s[i+2]);//s = (abs(pseudo_data)> lambda*sigma_hat).*(abs(pseudo_data) - lambda*sigma_hat).*sign(pseudo_data); |
| 122 | + b = b +1;}else s[i+2] = 0; |
| 123 | + |
| 124 | + if (mediatevalue4>0) { s[i+3] = (mediatevalue4)*sign(s[i+3]);//s = (abs(pseudo_data)> lambda*sigma_hat).*(abs(pseudo_data) - lambda*sigma_hat).*sign(pseudo_data); |
| 125 | + b = b +1;}else s[i+3] = 0; |
| 126 | + |
| 127 | + if (mediatevalue5>0) { s[i+4] = (fabs(s[i+4]) - astane)*sign(s[i+4]);//s = (abs(pseudo_data)> lambda*sigma_hat).*(abs(pseudo_data) - lambda*sigma_hat).*sign(pseudo_data); |
| 128 | + b = b +1;}else s[i+4] = 0; |
| 129 | + |
| 130 | + if (mediatevalue6>0) { s[i+5] = (fabs(s[i+5]) - astane)*sign(s[i+5]);//s = (abs(pseudo_data)> lambda*sigma_hat).*(abs(pseudo_data) - lambda*sigma_hat).*sign(pseudo_data); |
| 131 | + b = b +1;}else s[i+5] = 0; |
| 132 | + |
| 133 | + if (mediatevalue7>0) { s[i+6] = (fabs(s[i+6]) - astane)*sign(s[i+6]);//s = (abs(pseudo_data)> lambda*sigma_hat).*(abs(pseudo_data) - lambda*sigma_hat).*sign(pseudo_data); |
| 134 | + b = b +1;}else s[i+6] = 0; |
| 135 | + |
| 136 | + if (mediatevalue8>0) { s[i+7] = (fabs(s[i+7]) - astane)*sign(s[i+7]);//s = (abs(pseudo_data)> lambda*sigma_hat).*(abs(pseudo_data) - lambda*sigma_hat).*sign(pseudo_data); |
| 137 | + b = b +1;}else s[i+7] = 0; |
| 138 | + |
| 139 | + } |
| 140 | + // r = y - H*s + b.*r; |
| 141 | + b = b * Minve; ; |
| 142 | + matMul_N((float *)A, s, temp, M, N, 1); |
| 143 | + for (i = 0; i < M; i+=4){ |
| 144 | + r[i] = Y[i] - temp[i] + b*r[i]; |
| 145 | + r[i+1] = Y[i+1] - temp[i+1] + b*r[i+1]; |
| 146 | + r[i+2] = Y[i+2] - temp[i+2] + b*r[i+2]; |
| 147 | + r[i+3] = Y[i+3] - temp[i+3] + b*r[i+3]; |
| 148 | + } |
| 149 | + |
| 150 | + //if (MSE(s,x,N)<0.1) /////// BREAKING CONDITION |
| 151 | + // break; |
| 152 | + |
| 153 | + } |
| 154 | +} |
| 155 | + printf("Iteration Number: %d",ii); |
| 156 | + SNR(x,s,N); |
| 157 | + // print(s,1,N); |
| 158 | + // SNR(x,s,N); |
| 159 | + return(-1- 0); |
| 160 | +} |
| 161 | + |
| 162 | + |
| 163 | + |
| 164 | + |
| 165 | + |
| 166 | +int matSUB(float *mat1, float *mat2, float *result, int m, int n) { |
| 167 | + //Calculates mat1_m*n - mat2_m*n and reutrns the resultant matrix to result |
| 168 | + //Matrices should be the same size |
| 169 | + int i,j,k,K; |
| 170 | + for (i = 0; i < m; i++) { |
| 171 | + for (j = 0; j < n; j++) |
| 172 | + *(result + i*n + j) = *(mat1 + i*n + j) - *(mat2 + i*n + j); |
| 173 | + } |
| 174 | + return(0); |
| 175 | +} |
| 176 | + |
| 177 | + |
| 178 | +int matADD(float *mat1, float *mat2, float *result, int m, int n) { |
| 179 | + //Calculates mat1_m*n + mat2_m*n and reutrns the resultant matrix to result |
| 180 | + //Matrices should be the same size |
| 181 | + int i,j,k,K; |
| 182 | + for (i = 0; i < m; i++) { |
| 183 | + for (j = 0; j < n; j++) |
| 184 | + *(result + i*n + j) = *(mat1 + i*n + j) + *(mat2 + i*n + j); |
| 185 | + } |
| 186 | + return(0); |
| 187 | +} |
| 188 | + |
| 189 | + |
| 190 | + |
| 191 | + |
| 192 | + |
| 193 | + |
| 194 | + |
| 195 | +int matMul(float *mat1, float *mat2, float *result, int m, int n, int q) { |
| 196 | + //Multiplication for Mat1_(m*n) * Mat2_(n*k) |
| 197 | + // M,N and K are dimentions of matrices |
| 198 | + // Output is going to sit in the matrix that result represents here |
| 199 | + float sum; |
| 200 | + int i,j,k,K; |
| 201 | + for (i = 0; i < m; i++) { |
| 202 | + for (j = 0; j < q; j++) { |
| 203 | + sum = 0; |
| 204 | + for (k = 0; k < n; k++) { |
| 205 | + sum = sum + *(mat1 + i*n + k) * *(mat2 + k*q + j); |
| 206 | + } |
| 207 | + *(result + i*q + j) = sum; |
| 208 | + } |
| 209 | + } |
| 210 | + return(0); |
| 211 | +} |
| 212 | + |
| 213 | +int matMul_M( float *mat1, float *mat2, float *result, int m, int n, int q) { |
| 214 | + float sum1,sum2,sum3,sum4; |
| 215 | + int i,j,k,K; |
| 216 | + for (i = 0; i < m; i++) { |
| 217 | + for (j = 0; j < q; j++) { |
| 218 | + sum1 = 0;sum2 = 0;sum3 = 0;sum4 = 0; |
| 219 | + float* index_t1=mat1 + i*n; |
| 220 | + float* index_t2=mat2 + j; |
| 221 | + for (k = 0; k < M; k+=4) { |
| 222 | + sum1 = sum1 + *(index_t1 + k) * *(index_t2 + k*q); //sum = sum + *(mat1 + i*n + k) * *(mat2 + k*q + j); |
| 223 | + sum2 = sum2 + *(index_t1 + k+1) * *(index_t2 + (k+1)*q); |
| 224 | + sum3 = sum3 + *(index_t1 + k+2) * *(index_t2 + (k+2)*q); |
| 225 | + sum4 = sum4 + *(index_t1 + k+3) * *(index_t2 + (k+3)*q); |
| 226 | + } |
| 227 | + *(result + i*q + j) = sum1 + sum2+sum3+sum4; |
| 228 | + } |
| 229 | + } |
| 230 | + return(0); |
| 231 | +} |
| 232 | + |
| 233 | +int matMul_N( float *mat1, float *mat2, float *result, int m, int n, int q) { |
| 234 | + float sum1,sum2,sum3,sum4; |
| 235 | + int i,j,k,K; |
| 236 | + for (i = 0; i < m; i++) { |
| 237 | + for (j = 0; j < q; j++) { |
| 238 | + sum1 = 0;sum2 = 0;sum3 = 0;sum4 = 0; |
| 239 | + float* index_t1=mat1 + i*n; |
| 240 | + float* index_t2=mat2 + j; |
| 241 | + for (k = 0; k < N; k+=4) { |
| 242 | + sum1 = sum1 + *(index_t1 + k) * *(index_t2 + k*q); //sum = sum + *(mat1 + i*n + k) * *(mat2 + k*q + j); |
| 243 | + sum2 = sum2 + *(index_t1 + k+1) * *(index_t2 + (k+1)*q); |
| 244 | + sum3 = sum3 + *(index_t1 + k+2) * *(index_t2 + (k+2)*q); |
| 245 | + sum4 = sum4 + *(index_t1 + k+3) * *(index_t2 + (k+3)*q); |
| 246 | + } |
| 247 | + *(result + i*q + j) = sum1+sum2+sum3+sum4; |
| 248 | + } |
| 249 | + } |
| 250 | + return(0); |
| 251 | +} |
| 252 | + |
| 253 | +int transpose(float *mat1, float *mat2, int m, int n) |
| 254 | +{ |
| 255 | + //transposes mat1_m*n which is input to mat2_n*m which is out |
| 256 | + // M,N dimentions of matrices |
| 257 | + int i,j,k,K; |
| 258 | + for (i = 0; i<m; i++) |
| 259 | + for (j = 0; j < n; j++) |
| 260 | + { |
| 261 | + *(mat2 + j*m + i) = *(mat1 + i*n + j); |
| 262 | + } |
| 263 | + return(0); |
| 264 | +} |
| 265 | + |
| 266 | + |
| 267 | + |
| 268 | +float norm2(float *vec) { //Calculate norm 2 of input vector, since all vectors are M length here, for loop unrolling loops are defined over constant M |
| 269 | + float sum=0; |
| 270 | + int i,j,k,K; |
| 271 | + for (i = 0; i < M; i++) |
| 272 | + { |
| 273 | + sum += *(vec + i) * *(vec + i); |
| 274 | + } |
| 275 | + return sqrtf(sum); |
| 276 | +} |
| 277 | + |
| 278 | + |
| 279 | +int print(float *mat, int m, int n) { |
| 280 | + // Prints mat with dimentions of m and n |
| 281 | + int i,j,k,K; |
| 282 | + for (i = 0;i < m;i++) { |
| 283 | + for (j = 0;j < n;j++){ |
| 284 | + //_TCE_STREAM_OUT((char) *(mat+i*n+j)); |
| 285 | + printf("%f ",*(mat+i*n+j)); |
| 286 | + } |
| 287 | + printf("\n"); |
| 288 | + } |
| 289 | + return(1); |
| 290 | +} |
| 291 | + |
| 292 | + |
| 293 | + |
| 294 | +float sum_array(float *arr, int m) { |
| 295 | + float sum = 0; |
| 296 | + int i,j,k,K; |
| 297 | + for (i = 0; i < m; i++) |
| 298 | + sum += *(arr + i); |
| 299 | + return(sum); |
| 300 | +} |
| 301 | + |
| 302 | +float MSE(float *a, float *b, int Length) |
| 303 | +{ |
| 304 | + int l; |
| 305 | + float temp; |
| 306 | + float mse = 0; |
| 307 | + for (l = 0; l<Length; l++) |
| 308 | + { |
| 309 | + temp = a[l] - b[l]; |
| 310 | + mse += temp*temp; |
| 311 | + } |
| 312 | + return mse; |
| 313 | +} |
| 314 | + |
| 315 | +float SNR(float *a, float *b, int Length) |
| 316 | +{ |
| 317 | + int l,i; |
| 318 | + int temp; |
| 319 | + float mse = MSE(a, b, Length); |
| 320 | + float signal_power = 0; |
| 321 | + for (i = 0; i<Length; i++) |
| 322 | + signal_power += a[i] * a[i]; |
| 323 | + |
| 324 | + printf("mse : %d \n", (int)mse); |
| 325 | + printf("signal_power : %d \n",(int) signal_power); |
| 326 | + float snr = 10 * log10(signal_power / mse); |
| 327 | + printf("SNR : %d \n", (int)snr); |
| 328 | + return snr; |
| 329 | +} |
0 commit comments