Berlekamp-Massey minimal LFSR issues - lfsr

I am having some issues getting the correct LFSR for my sequence(pattern), when I implement it as LFSR and the corresponding taps, it doesn't generate the sequence, any suggestions? The goal patt is {1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1};
My code following wikipedia's version for binary field (https://en.wikipedia.org/wiki/Berlekamp%E2%80%93Massey_algorithm):
#include <stdio.h>
int main()
{
int patt[]={1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1};
int n=sizeof(patt)/sizeof(int);
int N=0, L=0, m=-1, b[n], c[n], d=0, t[n], j;
b[0]=1;
c[0]=1;
float val;
for(int i=1; i<n; i++){
b[i]=0;
c[i]=0;
//printf("b[%d]=%d, c[%d]=%d; ",i,b[i],i,c[i]);
}
while (N < n){
printf("N=%d, ",N);
d=c[0]*patt[N];//initializing the value of d
for(int i=1; i<=L; i++){
//printf("d = %d + %d*%d, ",d,c[i],patt[N-L]);
d=d ^ c[i]*patt[N-L];
//printf("d=%d \n",d);
}
printf("d=%d\n", d);
if (d==0){
printf("c=c\n\n");
}
else{
for(int i=0; i<n; i++){
t[i]=c[i];
}
j=0;
while(N-m+j<=n-1){
printf("c[%d-%d+%d]=c[%d-%d+%d]^b[%d]; c[%d]=c[%d]^b[%d], %d=%d^%d; ", N, m, j, N, m, j, j, N-m+j, N-m+j, j, c[N-m+j], c[N-m+j], b[j]);
c[N-m+j]=c[N-m+j]^b[j];//XOR operator: ^
printf("c=%d\n",c[N-m+j]);
j++;
}
printf("\n");
val=N;
val=val/2;
printf("L=%d, N=%d, N/2=%f \n",L, N, val);
if(L<= val){
printf("updating L, m & b\n\n");
L=N+1-L;
m=N;
for(int i=0; i<n; i++){
b[i]=t[i];
}
}
}
N++;
}
int CiSi=c[L]*patt[0];;
for(int i=1; i<L; i++){
CiSi=CiSi ^ c[L-i]*patt[i];//XORing
}
printf("CiSi = %d;", CiSi);
printf("c=");
for(int i=0; i<n; i++){
printf("%d ",c[i]);
}
return 0;
}
The answers per cycle:
N=0, d=1
c[0--1+0]=c[0--1+0]^b[0]; c[1]=c[1]^b[0], 0=0^1; c=1
c[0--1+1]=c[0--1+1]^b[1]; c[2]=c[2]^b[1], 0=0^0; c=0
c[0--1+2]=c[0--1+2]^b[2]; c[3]=c[3]^b[2], 0=0^0; c=0
c[0--1+3]=c[0--1+3]^b[3]; c[4]=c[4]^b[3], 0=0^0; c=0
c[0--1+4]=c[0--1+4]^b[4]; c[5]=c[5]^b[4], 0=0^0; c=0
c[0--1+5]=c[0--1+5]^b[5]; c[6]=c[6]^b[5], 0=0^0; c=0
c[0--1+6]=c[0--1+6]^b[6]; c[7]=c[7]^b[6], 0=0^0; c=0
c[0--1+7]=c[0--1+7]^b[7]; c[8]=c[8]^b[7], 0=0^0; c=0
c[0--1+8]=c[0--1+8]^b[8]; c[9]=c[9]^b[8], 0=0^0; c=0
c[0--1+9]=c[0--1+9]^b[9]; c[10]=c[10]^b[9], 0=0^0; c=0
c[0--1+10]=c[0--1+10]^b[10]; c[11]=c[11]^b[10], 0=0^0; c=0
c[0--1+11]=c[0--1+11]^b[11]; c[12]=c[12]^b[11], 0=0^0; c=0
L=0, N=0, N/2=0.000000
updating L, m & b
N=1, d=0
c=c
N=2, d=1
c[2-0+0]=c[2-0+0]^b[0]; c[2]=c[2]^b[0], 0=0^1; c=1
c[2-0+1]=c[2-0+1]^b[1]; c[3]=c[3]^b[1], 0=0^0; c=0
c[2-0+2]=c[2-0+2]^b[2]; c[4]=c[4]^b[2], 0=0^0; c=0
c[2-0+3]=c[2-0+3]^b[3]; c[5]=c[5]^b[3], 0=0^0; c=0
c[2-0+4]=c[2-0+4]^b[4]; c[6]=c[6]^b[4], 0=0^0; c=0
c[2-0+5]=c[2-0+5]^b[5]; c[7]=c[7]^b[5], 0=0^0; c=0
c[2-0+6]=c[2-0+6]^b[6]; c[8]=c[8]^b[6], 0=0^0; c=0
c[2-0+7]=c[2-0+7]^b[7]; c[9]=c[9]^b[7], 0=0^0; c=0
c[2-0+8]=c[2-0+8]^b[8]; c[10]=c[10]^b[8], 0=0^0; c=0
c[2-0+9]=c[2-0+9]^b[9]; c[11]=c[11]^b[9], 0=0^0; c=0
c[2-0+10]=c[2-0+10]^b[10]; c[12]=c[12]^b[10], 0=0^0; c=0
L=1, N=2, N/2=1.000000
updating L, m & b
N=3, d=0
c=c
N=4, d=0
c=c
N=5, d=0
c=c
N=6, d=1
c[6-2+0]=c[6-2+0]^b[0]; c[4]=c[4]^b[0], 0=0^1; c=1
c[6-2+1]=c[6-2+1]^b[1]; c[5]=c[5]^b[1], 0=0^1; c=1
c[6-2+2]=c[6-2+2]^b[2]; c[6]=c[6]^b[2], 0=0^0; c=0
c[6-2+3]=c[6-2+3]^b[3]; c[7]=c[7]^b[3], 0=0^0; c=0
c[6-2+4]=c[6-2+4]^b[4]; c[8]=c[8]^b[4], 0=0^0; c=0
c[6-2+5]=c[6-2+5]^b[5]; c[9]=c[9]^b[5], 0=0^0; c=0
c[6-2+6]=c[6-2+6]^b[6]; c[10]=c[10]^b[6], 0=0^0; c=0
c[6-2+7]=c[6-2+7]^b[7]; c[11]=c[11]^b[7], 0=0^0; c=0
c[6-2+8]=c[6-2+8]^b[8]; c[12]=c[12]^b[8], 0=0^0; c=0
L=2, N=6, N/2=3.000000
updating L, m & b
N=7, d=0
c=c
N=8, d=1
c[8-6+0]=c[8-6+0]^b[0]; c[2]=c[2]^b[0], 1=1^1; c=0
c[8-6+1]=c[8-6+1]^b[1]; c[3]=c[3]^b[1], 0=0^1; c=1
c[8-6+2]=c[8-6+2]^b[2]; c[4]=c[4]^b[2], 1=1^1; c=0
c[8-6+3]=c[8-6+3]^b[3]; c[5]=c[5]^b[3], 1=1^0; c=1
c[8-6+4]=c[8-6+4]^b[4]; c[6]=c[6]^b[4], 0=0^0; c=0
c[8-6+5]=c[8-6+5]^b[5]; c[7]=c[7]^b[5], 0=0^0; c=0
c[8-6+6]=c[8-6+6]^b[6]; c[8]=c[8]^b[6], 0=0^0; c=0
c[8-6+7]=c[8-6+7]^b[7]; c[9]=c[9]^b[7], 0=0^0; c=0
c[8-6+8]=c[8-6+8]^b[8]; c[10]=c[10]^b[8], 0=0^0; c=0
c[8-6+9]=c[8-6+9]^b[9]; c[11]=c[11]^b[9], 0=0^0; c=0
c[8-6+10]=c[8-6+10]^b[10]; c[12]=c[12]^b[10], 0=0^0; c=0
L=5, N=8, N/2=4.000000
N=9, d=0
c=c
N=10, d=0
c=c
N=11, d=0
c=c
N=12, d=1
c[12-6+0]=c[12-6+0]^b[0]; c[6]=c[6]^b[0], 0=0^1; c=1
c[12-6+1]=c[12-6+1]^b[1]; c[7]=c[7]^b[1], 0=0^1; c=1
c[12-6+2]=c[12-6+2]^b[2]; c[8]=c[8]^b[2], 0=0^1; c=1
c[12-6+3]=c[12-6+3]^b[3]; c[9]=c[9]^b[3], 0=0^0; c=0
c[12-6+4]=c[12-6+4]^b[4]; c[10]=c[10]^b[4], 0=0^0; c=0
c[12-6+5]=c[12-6+5]^b[5]; c[11]=c[11]^b[5], 0=0^0; c=0
c[12-6+6]=c[12-6+6]^b[6]; c[12]=c[12]^b[6], 0=0^0; c=0
L=5, N=12, N/2=6.000000
updating L, m & b
CiSi = 0;
CiSi = 0; Testing the values mentioned as a result of the algorithm looks correct because is equal to zero, but
c=1 1 0 1 0 1 1 1 1; excluding the last 4 zeros due to their values as zeros
c=1 1 0 1 0 1 1 1 1, this are the coefficients of the polynomial starting from left to right: C0,..., Ck: 1 + x^2 + x^4 + x^5 + x^6 + x^7
When I implement this values the results are NOT RIGHT
Implementation of the LFSR with the taps in the corresponding positions, x0 is excluded according to https://en.wikipedia.org/wiki/Linear-feedback_shift_register and also Wang Laung-Terng, Wu Cheng-Wen and W. Xiaoqing, "VLSI Test Principles and Architectures - Design for Testability", 2006:
%Matlab source code
clear all;
seed=[1 1 0 0 0 0 1 0];
seed_sz=size(seed);
%Loop to initialize a array
for i=1:50
A{i}=1:seed_sz(1,2);
A{i}(1,1:end)=0;
end
filename='LFSR rightshift no x0 c program.xlsx';
for i=1:50
A{i}=seed;
xlswrite(filename,A{i},'1',['A',int2str(i)]);
XOR_output=xor(seed(1,8),seed(1,7));
XOR_output=xor(XOR_output,seed(1,6));
XOR_output=xor(XOR_output,seed(1,5));
XOR_output=xor(XOR_output,seed(1,3));
XOR_output=xor(XOR_output,seed(1,1));
%Right shift the seed
seed=circshift(seed,1);
seed(1,1)=XOR_output;
end
Flow chart of the algorithm adapted from wikipedia

Compared to the Wikipedia pseudocode that it aims at implementing, the question's code has two clear discrepancies (at least the second is a fatal bug):
d=c[0]*patt[N] should be d=patt[N] to match d ← sN…
d=d ^ c[i]*patt[N-L] should be d=d ^ c[i]*patt[N-i] to match the other terms of d ← sN ⊕ c1sN−1 ⊕ c2sN−2 ⊕ … ⊕ cLsN−L
As an aside the code does not show the final L, that is the length of the minimal LFSR for the stream. But that L is also the index of the last 1 in the output, so we can get away with that omission.
With these changes the code outputs c=1 0 1 0 1 1 0 0 0 0 0 0 0, that is an LFSR with L=5 bits and the recurrence si ← si-2 ⊕ si-4 ⊕ si-5, or equivalently si+5 ← si+3 ⊕ si+1 ⊕ si. That indeed matches the sequence! Applied to the 5 first given terms it computes the next 8 ones:
s[ 0] := 1
s[ 1] := 1
s[ 2] := 0
s[ 3] := 0
s[ 4] := 0
s[ 5] := s[ 3] ^ s[ 1] ^ s[ 0] = 0 ^ 1 ^ 1 = 0
s[ 6] := s[ 4] ^ s[ 2] ^ s[ 1] = 0 ^ 0 ^ 1 = 1
s[ 7] := s[ 5] ^ s[ 3] ^ s[ 2] = 0 ^ 0 ^ 0 = 0
s[ 8] := s[ 6] ^ s[ 4] ^ s[ 3] = 1 ^ 0 ^ 0 = 1
s[ 9] := s[ 7] ^ s[ 5] ^ s[ 4] = 0 ^ 0 ^ 0 = 0
s[10] := s[ 8] ^ s[ 6] ^ s[ 5] = 1 ^ 1 ^ 0 = 0
s[11] := s[ 9] ^ s[ 7] ^ s[ 6] = 0 ^ 0 ^ 1 = 1
s[12] := s[10] ^ s[ 8] ^ s[ 7] = 0 ^ 1 ^ 0 = 1
Interpretation of the program's output:
the rightmost 1 in the output tells the width of the LFSR, and the rest should be ignored;
the 1 digits in the output, except the leftmost, correspond to the terms to XOR in a Fibonnaci LFSR, from most recent to oldest;
the leftmost output is 1 and corresponds to the next term computed;
the 1 digits in reading order correspond to the terms of the Fibonacci polynomial from 1 to xL (here, 1+x2+x4+x5), or equivalently to the terms of the Galois polynomial from xL to 1 (here, x5+x3+x1+1)
The initial state in Fibonacci convention is simply the first L terms of the given si, that is patt[i] in the question's code.
Here is a streamlined version of the code with less and clearer output, perusing for to clarify the intent, sticking to variable names in the original pseudocode, compatible with more C compilers, using Boolean operators when possible, staying away from floating point, and making loops with minimalist end conditions. It seems to work just fine in the few tests I made.
// Berlekamp-Massey algorithm per https://en.wikipedia.org/w/index.php?title=Berlekamp%E2%80%93Massey_algorithm&oldid=808089047#The_algorithm_for_the_binary_field
#include <stdio.h>
int main(void) {
int s[]={1,1,0,0,0,0,1,0,1,0,0,1,1}; // bits of the stream to analyse
#define n (sizeof(s)/sizeof(*s)) // how many bits there are
int b[n], c[n], t[n], d, j, N, L=0, m=-1;
for(j=n; --j>0;)
b[j]=c[j]=0;
b[0]=c[0]=1;
for(N=0; N<n; ++N) { // For N=0 step 1 while N<n
d=s[N]; // first term of discrepancy
for(j=L; j>0; --j) // other terms of discrepancy
d ^= c[j]&s[N-j];
if (d!=0) { // non-zero discrepancy
for(j=n; --j>=0;) // copy c to t
t[j]=c[j];
for(j=n-N+m; --j>=0;) // XOR b (reversed) into c
c[N-m+j] ^= b[j];
if(L+L<=N) { // if L<=N/2
L=N+1-L;
m=N;
for(j=n; --j>=0;) // copy t to b
b[j]=t[j];
}
}
}
printf("s ="); // show input
for(j=0; j<n; j++)
printf(" %d",s[j]);
printf("\nc =");
for(j=0; j<=L; j++) // show result
printf(" %d",c[j]);
printf("\nL = %d\n",L); // show degree of polynomial
return 0;
}
// The above code outputs the following:
// s = 1 1 0 0 0 0 1 0 1 0 0 1 1
// c = 1 0 1 0 1 1
// L = 5
I have a critic on the Wikipedia pseudocode and its transcription to code: indexes are going in reverse directions in the sequence under analysis si and the polynomial being constructed ci; that seems to only create complications.

Supplement to fgrieu's answer. Code for Fibonacci and Galois LFSR, showing both left and right shift algorithms. These will produce the original string plus 2 more bits (0 1), which is a 15 bit repeating pattern. The starting LFSR values are different in order for the output pattern to match the original string pattern.
// Fibonacci LFSR right shift
printf("fr=");
d = 0x03;
do {
printf(" %1x", d & 1);
m = ((d>>3)^(d>>1)^(d>>0))&1;
d = (d >> 1)|(m << 4);
} while (d != 0x3);
printf("\n");
// Fibonacci LFSR left shift
printf("fl=");
d = 0x18;
do {
printf(" %1x", d >> 4);
m = ((d>>4)^(d>>3)^(d>>1)) & 1;
d = ((d << 1)&0x1e) | m;
} while (d != 0x18);
printf("\n");
// Galios LFSR right shift
printf("gr=");
d = 0x1f;
do {
printf(" %1x", d & 1);
m = d & 1;
d >>= 1;
if (m)
d ^= 0x1a;
} while (d != 0x1f);
printf("\n");
// Galios LFSR left shift
printf("gl=");
d = 0x1f;
do {
printf(" %1x", d >> 4);
d <<= 1;
if (d & 0x20)
d ^= 0x2b;
} while (d != 0x1f);
printf("\n");
output:
fr= 1 1 0 0 0 0 1 0 1 0 0 1 1 0 1
fl= 1 1 0 0 0 0 1 0 1 0 0 1 1 0 1
gr= 1 1 0 0 0 0 1 0 1 0 0 1 1 0 1
gl= 1 1 0 0 0 0 1 0 1 0 0 1 1 0 1

Related

Split vector to multiple vectors

I'm looking for a simple method to transforming a vector of the following type
[1 1 0 1 1]
To this group of vectors:
[0 0 0 0 1]
[0 0 0 1 0]
[0 1 0 0 0]
[1 0 0 0 0]
The vector itself represents polynomial coefficients (x^4 + x^3 + x + 1)
Thanks
Here are some approaches. Input is a vector v, output is a matrix M:
[~, rr, vv] = find(v);
M = full(sparse(1:nnz(v), flip(rr), 1));
M = flip(eye(numel(v)));
M = M(logical(v),:)
M = zeros(nnz(v), numel(v));
M(sub2ind(size(M), 1:size(M,1), flip(find(v)))) = 1;
M = double(bsxfun(#eq, flip(find(v(:))), 1:numel(v)));

Filling up gaps in matrix's rows

Let g be a matrix containing ones\zeroes. I want to fill up gaps of zeros (complete ones sequences) in the rows of g which are smaller then a given k.
For example fill up with ones all gaps smaller then three zeros. This code will work:
[m,n]=size(g);
k=3
for i=1:m
j=1
while (j<n)
if(g(i,j)==0)
flag=0;
for w=1:k
if(g(i,j+w-1)==1)
flag=1;
end
end
if(flag)
for w=1:k
g(i,j+w-1)=1;
end
else
while(~flag&j<n)
j=j+1;
if(g(i,j)==1)
flag=1;
end
end
end
end
j=j+1;
end
end
Is there a way to do so without all the for loops?
A short version using some built-in function:
M = [1 1 1 1 1
1 1 1 0 0
1 1 1 0 1
1 1 0 0 0
0 1 1 1 1]
Mopen = ~imopen(~padarray(M,[0,1],1),strel('line',3,0));
Mfill = Mopen(:,2:end-1);
A vectorized version:
k = 3;
d = diff( g,1,2);
L = d ~= 0;
c = cumsum([zeros(size(g,1),1) L],2)+1;
b = bsxfun(#plus, c, cumsum([0; c(1:end-1,end)]));
a =accumarray(reshape(b.',[],1),1);
f= find(a<k);
g(ismember(b,f) & g==0) = 1;
Example :
g =
1 1 1 1 1
1 1 1 0 0
1 1 1 0 1
1 1 0 0 0
0 1 1 1 1
result =
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 0 0 0
1 1 1 1 1
Another potential solution is to cast each row to a char array and then perform substitutions based on a regular expressions
g = round(rand(30,70));
figure();
subplot(121);
imagesc(g)
[m,n]=size(g);
k=3;
pattern = ['(?<!',char(0),')(',char(0),'{1,',num2str(k-1),'})(?!',char(0),')'];
for i=1:m
[matchstart,matchend] = regexp(char(g(i,:)),pattern);
for j = 1:length(matchstart)
g(i,matchstart(j):matchend(j)) = 1;
end
end
subplot(122);
imagesc(g)

create vectors using exponent/power for numbers using prime powers

I am trying to create vectors for every number up to n by just using the exponents of the prime numbers, using prime vector PV=[2 3 5 7 11 13 17 19 23 29] to recognize each number and store these vectors for later calculations. My PVE=[k k k k k k k k k k x], with k being the exponents corrisponding to PV, and x is the exponent of any prime that PV does not divide, so x will always be 0 or 1 because my n is 960=(31^2)-1. So if any number in this set divides some number 9, for instance the vector exponent of 9 would be [0 2 0 0 0 0 0 0 0 0 0] as 3^2 is 9. and the vector for 22 would be [1 0 0 0 1 0 0 0 0 0 0] and this is 2*11=22. so every "numba" as in my program from 2 to n would have a prime vector exponent (PVE). This comes from the fundamental theorem of arithmetic that every number can be expressed as the product of primes, and it is unique.
Could you please look at my program to see what I am doing wrong to get the exponents.
Program:
n=960
for numba=2:n
for c=2:numba-1
if numba==2
c=2
if mod(numba,c)~=0
numba=p
end
end
end
end
for k=1:9
PVEC=[2^k 3^k 5^k 7^k 11^k 13^k 17^k 19^k 23^k 29^k]
if p>29
if mod(numba,PVEC)==0
max(PVEC,k) & PVE==[k k k k k k k k k k 0]
if mod(numba,PVE)~=0
PVE=[0 0 0 0 0 0 0 0 0 0 1]
end
end
end
end
You can compute PVE for each numba in one line, using factors and histc:
PVE = histc(factor(numba),[PV inf])
Example:
>> PV = [2 3 5 7 11 13 17 19 23 29];
>> numba = 22;
>> PVE = histc(factor(numba),[PV inf])
PVE =
1 0 0 0 1 0 0 0 0 0 0
>> numba = 9;
>> PVE = histc(factor(numba),[PV inf])
PVE =
0 2 0 0 0 0 0 0 0 0 0
I don't quite understand what you are trying to do in your first loop, but if I were you, I would use recursion to get an exponent. Something like this...
function [ expo ] = get_exponent( p, num, depth )
% return the exponent
% p: prime number
% num: number to be analyzed
% depth: depth of the recursion
if p==1,
error ('Do not use 1 for p!!')
end
if mod(num,p) == 0,
depth = depth+1;
expo = get_exponent(p, num/p, depth);
else
expo = depth;
end
end
This get_exponent function returns the exponent for some number num of some prime p. For example,
>> get_exponent(5,325,0)
ans =
2
>> get_exponent(13,325,0)
ans =
1
Use this function in your second loop to get exponent of each prime.

Find solution of homegenous system in MATLAB

General solution of A*x=b in MATLAB is given by
x=A\b
for example
A = [2 -1 1; 1 2 3; 3 0 -1]
A =
2 -1 1
1 2 3
3 0 -1
b = [8; 9; 3]
b =
8
9
3
x = A\b
x =
2.0000
-1.0000
3.0000
what about solution of system A*x=0?please help me
Testing on singular matrix
A=[1 2 3;2 1 4;3 3 7]
A =
1 2 3
2 1 4
3 3 7
>> det(A)
ans =
0
b=[0;0;0];
>> linsolve(A,b)
Warning: Matrix is close to singular or badly scaled.
Results may be inaccurate. RCOND = 1.903239e-017.
ans =
0
0
0
#Robert P.
is this correct?
A=[2 3 1;-1 3 1;1 6 2]
A =
2 3 1
-1 3 1
1 6 2
>> det(A);
>> det(A)
ans =
0
>> [U S V]=svd(A);
>> x=V(:,end);
>> A*x
ans =
1.0e-015 *
0.2220
0.2220
0.4441
You can use Singular value decomposition, svd to get an x that satisfies Ax=0 if there are non-trivial solutions:
A = [2 -1 1; 2 -1 1; 3 2 1];
[U S V] = svd(A);
x = V(:,end)
x =
-0.39057
0.13019
0.91132
A*x =
0
0
0
A = [2 -1 1; 1 2 3; 3 0 -1]
b = [0; 0; 0]
x = A\b
Assuming that "0" stands for a zero vector and not the scalar.
Ok in your case:
>> A = [2 -1 1; 1 2 3; 3 0 -1]
A =
2 -1 1
1 2 3
3 0 -1
>> b = [0; 0; 0]
b =
0
0
0
>> x = A\b
x =
0
0
0
Or you can use linsolve:
>> linsolve(A,b)
ans =
0
0
0
But if det(A==0) you should use the eigenvector corresponds the zero eigenvalue, something like that:
>> A = [2 -1 1; 1 2 3; 3 0 -1]
A =
2 -1 1
1 2 3
3 0 -1
>> b = [0; 0; 0]
b =
0
0
0
>> [v m] = eig(A)
v =
1.0000 0.4472 0
0 0.8944 0
0 0 1.0000
m =
0 0 0
0 2 0
0 0 3
You will have infinite number of solutions, every vector parallel to [1 0 0] will be a solution.

Convert an array of bounded integers to matrix of bit arrays

Suppose I have an array a of bounded integers (in this case bounded by 5):
a = [3 4 4 2 1 5 5];
I want to convert this array of integers to a length(a) x 5 matrix A where each row is a bit array with a 1 in the column indexed by the integer from a:
A = [0 0 1 0 0;
0 0 0 1 0;
0 0 0 1 0;
0 1 0 0 0;
1 0 0 0 0;
0 0 0 0 1;
0 0 0 0 1];
This is easily accomplished with a for loop:
n = length(a)
A = zeros(n, max(a(:)));
for k = 1 : n
A(k, a(k)) = 1;
end
I am looking for a vectorized implementation that does not use a for loop.
Two possible methods:
use sparse:
A = sparse( 1:n, a, 1, n, max(a(:)) );
if you want a non-sparse result
full(A);
Using sun2ind:
A = zeros( n, max(a(:)) );
A( sub2ind(size(A), 1:n, a ) ) = 1;