I am trying to alter some voxel values in Matlab.
I am using the following code:
for p=1:100
Vol(Vol(:,:,p) > 0) = 65535; %altering voxel values in the volume to 65535 if value > 0.
end
Unfortunately, I find all the values being altered, as if the condition is not working, although if i write Vol(Vol(:,:,1)>0)= 65535 immediately in the command line it works perfectly.
Any clue where the error is?
The reason why is because you are not indexing each slice properly in your volume. When you are doing this for loop, what will happen is that the Boolean condition that is provided in Vol is modifying only the first channel.
Consider this small example. Let's create a 3 x 3 x 3 matrix of all 1s.
A = ones(3,3,3)
A(:,:,1) =
1 1 1
1 1 1
1 1 1
A(:,:,2) =
1 1 1
1 1 1
1 1 1
A(:,:,3) =
1 1 1
1 1 1
1 1 1
Let's set the first slice all to 65535 according to your condition:
A(A(:,:,1) > 0) = 65535
A(:,:,1) =
65535 65535 65535
65535 65535 65535
65535 65535 65535
A(:,:,2) =
1 1 1
1 1 1
1 1 1
A(:,:,3) =
1 1 1
1 1 1
1 1 1
This certainly works as we expect. Now let's try going to the second channel:
A(A(:,:,2) > 0) = 65535
A(:,:,1) =
65535 65535 65535
65535 65535 65535
65535 65535 65535
A(:,:,2) =
1 1 1
1 1 1
1 1 1
A(:,:,3) =
1 1 1
1 1 1
1 1 1
Oh no! It didn't work! It only worked for the first channel.... why? The reason why is because A(:,:,1) or any other channel provides a 2D matrix. If you provide a single 2D matrix, it only modifies the first slice of the volume. As such, as your loop keeps progressing, only the first channel gets modified (if at all). If you wanted to modify the second channel, you would have to create a 3D matrix, where the first slice would have all logical false, while the second slice contains the Boolean mask from Vol(:,:,2) > 0.
The 3D slicing stuff is probably complicated, especially for someone new to MATLAB. As such, I would recommend you do this to make things simpler. If you want to modify each slice, consider placing each binary mask as a temporary variable, modifying that temporary variable, then manually assigning this back to each slice. In other words:
for p=1:100
temp = Vol(:,:,p); %//Extract p'th channel
temp(temp > 0) = 65535; %// Find non-zero pixels and set to 65535
Vol(:,:,p) = temp; %// Set back to p'th channel.
end
Another recommended suggestion
Instead of using for loops, I would like to recommend this simple one-liner:
Vol(Vol > 0) = 65535;
This will automatically create a 3D Boolean matrix that will index Vol, and it will find those locations that are greater than 0, and set all of those locations to 65535. This avoids the need of any unnecessary for loops. This one-line essentially performs what the above for loop is doing, but is much more quicker... and I daresay much easier to read.
For your problem, I would just do :
Vol(Vol(:,:,1:100) > 0) = 65535;
No need for loop.
Related
i seen a post on the site about it and i didn't understand the answer, can i get explanation please:
question:
Write code to determine if a number is divisible by 3. The input to the function is a single bit, 0 or 1, and the output should be 1 if the number received so far is the binary representation of a number divisible by 3, otherwise zero.
Examples:
input "0": (0) output 1
inputs "1,0,0": (4) output 0
inputs "1,1,0,0": (6) output 1
This is based on an interview question. I ask for a drawing of logic gates but since this is stackoverflow I'll accept any coding language. Bonus points for a hardware implementation (verilog etc).
Part a (easy): First input is the MSB.
Part b (a little harder): First input is the LSB.
Part c (difficult): Which one is faster and smaller, (a) or (b)? (Not theoretically in the Big-O sense, but practically faster/smaller.) Now take the slower/bigger one and make it as fast/small as the faster/smaller one.
answer:
State table for LSB:
S I S' O
0 0 0 1
0 1 1 0
1 0 2 0
1 1 0 1
2 0 1 0
2 1 2 0
Explanation: 0 is divisible by three. 0 << 1 + 0 = 0. Repeat using S = (S << 1 + I) % 3 and O = 1 if S == 0.
State table for MSB:
S I S' O
0 0 0 1
0 1 2 0
1 0 1 0
1 1 0 1
2 0 2 0
2 1 1 0
Explanation: 0 is divisible by three. 0 >> 1 + 0 = 0. Repeat using S = (S >> 1 + I) % 3 and O = 1 if S == 0.
S' is different from above, but O works the same, since S' is 0 for the same cases (00 and 11). Since O is the same in both cases, O_LSB = O_MSB, so to make MSB as short as LSB, or vice-versa, just use the shortest of both.
thanks for the answers in advanced.
Well, I suppose the question isn't entirely off-topic, since you asked about logic design, but you'll have to do the coding yourself.
You have 3 states in the S column. These track the value of the current full input mod 3. So, S0 means the current input mod 3 is 0, and so is divisible by 0 (remember also that 0 is divisible by 3). S1 means the remainder is 1, S2 means that the remainder is 2.
The I column gives the current input (0 or 1), and S' gives the next state (in other words, the new number mod 3).
For 'LSB', the new number is the old number << 1, plus either 0 or 1. Write out the table. For starters, if the old modulo was 0, then the new modulo will be 0 if the input bit was 0, and will be 1 if the new input was 1. This gives you the first 2 rows in the first table. Filling in the rest is left as an exercise for you.
Note that the O column is just 1 if the next state is 0, as expected.
I wrote a program to calculate a square finite difference matrix, where you can enter the number of rows (equals the number of columns) -> this is stored in the variable matrix. The program works fine:
program fin_diff_matrix
implicit none
integer, dimension(:,:), allocatable :: A
integer :: matrix,i,j
print *,'Enter elements:'
read *, matrix
allocate(A(matrix,matrix))
A = 0
A(1,1) = 2
A(1,2) = -1
A(matrix,matrix) = 2
A(matrix,matrix-1) = -1
do j=2,matrix-1
A(j,j-1) = -1
A(j,j) = 2
A(j,j+1) = -1
end do
print *, 'Matrix A: '
write(*,1) A
1 format(6i10)
end program fin_diff_matrix
For the output I want that matrix is formatted for the output, e.g. if the user enters 6 rows the output should also look like:
2 -1 0 0 0 0
-1 2 -1 0 0 0
0 -1 2 -1 0 0
0 0 -1 2 -1 0
0 0 0 -1 2 -1
0 0 0 0 -1 2
The output of the format should also be variable, e.g. if the user enters 10, the output should also be formatted in 10 columns. Research on the Internet gave the following solution for the format statement with angle brackets:
1 format(<matrix>i<10)
If I compile with gfortran in Linux I always get the following error in the terminal:
fin_diff_matrix.f95:37.12:
1 format(<matrix>i10)
1
Error: Unexpected element '<' in format string at (1)
fin_diff_matrix.f95:35.11:
write(*,1) A
1
Error: FORMAT label 1 at (1) not defined
What doesn't that work and what is my mistake?
The syntax you are trying to use is non-standard, it works only in some compilers and I discourage using it.
Also, forget the FORMAT() statements for good, they are obsolete.
You can get your own number inside the format string when you construct it yourself from several parts
character(80) :: form
form = '( (i10,1x))'
write(form(2:11),'(i10)') matrix
write(*,form) A
You can also write your matrix in a loop per row and then you can use an arbitrarily large count number or a * in Fortran 2008.
do i = 1, matrix
write(*,'(999(i10,1x))') A(:,i)
end do
do i = 1, matrix
write(*,'(*(i10,1x))') A
end do
Just check if I did not transpose the matrix inadvertently.
I was looking at a challenge online (at King's website) and although I understand the general idea behind it I'm slightly lost - maybe the wording is a little off? Here is the problem and I'll state what I don't understand below:
Error correcting codes are used in a wide variety of applications
ranging from satellite communication to music CDs. The idea is to
encode a binary string of length k as a binary string of length n>k,
called a codeword such that even if some bit(s) of the encoding are
corrupted (if you scratch on your CD for instance), the original k-bit
string can still be recovered. There are three important parameters
associated with an error correcting code: the length of codewords (n),
the dimension (k) which is the length of the unencoded strings, and
finally the minimum distance (d) of the code. Distance between two
codewords is measured as hamming distance, i.e., the number of
positions in which the codewords differ: 0010 and 0100 are at distance
2. The minimum distance of the code is the distance between the two different codewords that are closest to each other. Linear codes are a
simple type of error correcting codes with several nice properties.
One of them being that the minmum distance is the smallest distance
any non-zero codeword has to the zero codeword (the codeword
consisting of n zeros always belongs to a linear code of length n).
Another nice property of linear codes of length n and dimension k is
that they can be described by an n×k generator matrix of zeros and
ones. Encoding a k-bit string is done by viewing it as a column vector
and multiplying it by the generator matrix. The example below shows a
generator matrix and how the string 1001 is encoded. graph.png Matrix
multiplication is done as usual except that additon is done modulo 2
(i.e., 0+1=1+0=1 and 0+0=1+1=0). The set of codewords of this code is
then simply all vectors that can be obtained by encoding all k-bit
strings in this way. Write a program to calculate the minimum distance
for several linear error correcting codes of length at most 30 and
dimension at most 15. Each code will be given as a generator matrix.
Input You will be given several generator matrices as input. The first
line contains an integer T indicating the number of test cases. The
first line of each test case gives the parameters n and k where
1≤n≤30, 1≤k≤15 and n > k, as two integers separated by a single space.
The following n lines describe a generator matrix. Each line is a row
of the matrix and has k space separated entries that are 0 or 1.
Output For each generator matrix output a single line with the minimum
distance of the corresponding linear code.
Sample Input 1
2
7 4
1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1
0 1 1 1
1 0 1 1
1 1 0 1
3 2
1 1
0 0
1 1
Sample Output 1
3
0
Now my assumption is that the question is asking "Write a program that can take in the linear code in matrix form and say what the minimum distance is from an all zero codeword" I just don't understand why there is a 3 output for the first input and a 0 for the second input?
Very confused.
Any ideas?
For first example:
Input binary string: 1000
Resulting code: 1100001
Hamming distance to zero codeword 0000000: 3
For second example:
Input binary string: 11
Resulting code: 000
Hamming distance to zero codeword 000: 0
Your goal is to find valid non-zero codeword (which can be produced from some non-zero k-bit input string) with minimal Hamming distance to zero codeword (in different words - with minimal amount of ones in binary representation) and return that distance.
Hope that helps, the problem description is indeed a little bit hard to understand.
EDIT. I've made typo in first example. Actual input should be 1000 not 0001. Also it's may be not clear what exactly is input string and how the codeword is calculated. Let's look at first sample.
Input binary string: 1000
This binary string in general is not part of generator matrix. It is just one of all possible non-zero 4-bit strings. Let's multiply it by generator matrix:
(1 0 0 0) * (1 0 0 0) = 1
(0 1 0 0) * (1 0 0 0) = 0
(0 0 1 0) * (1 0 0 0) = 0
(0 0 0 1) * (1 0 0 0) = 0
(0 1 1 1) * (1 0 0 0) = 0
(1 0 1 1) * (1 0 0 0) = 1
(1 1 0 1) * (1 0 0 0) = 1
One way to find input that produces "minimal" codeword is to iterate all 2^k-1 non-zero k-bit strings and calculate codeword for each of them. This is feasible solution for k <= 15.
Another example for first test case 0011 (it's possible to have multiple inputs that produce "minimal" output):
(1 0 0 0) * (0 0 1 1) = 0
(0 1 0 0) * (0 0 1 1) = 0
(0 0 1 0) * (0 0 1 1) = 1
(0 0 0 1) * (0 0 1 1) = 1
(0 1 1 1) * (0 0 1 1) = 2 = 0 (mod 2)
(1 0 1 1) * (0 0 1 1) = 2 = 0 (mod 2)
(1 1 0 1) * (0 0 1 1) = 1
Resulting code 0011001 also has Hamming distance 3 to the zero codeword. There is no 4-bit string with code that has less that 3 ones in binary representation. That's why the answer for first test case is 3.
I have the following array:
AA = zeros(5,3);
AA(1,3)=1;
AA(3,3)=1;
AA(4,2)=1;
and I want to place the value one in the collumns defined by the following
vector a = [0; 2; 0; 0; 1]. Each value of this vector refers to the collumn
index that we want to change in each row. When zero apears no changes should be made.
Desired output:
0 0 1
0 1 0
0 0 1
0 1 0
1 0 0
Could you please suggest a way to do this without for loop? The goal is
a faster execution.
Thanks!!!
Approach 1
nrows = size(AA,1) %// Get the no. of rows, as we would use this parameter later on
%// Calculate the linear indices with `a` as the column indices and
%// [1:nrows] as the row indices
idx = (a-1)*nrows+[1:nrows]' %//'
%// Select the valid linear indices (ones that have the corresponding a as non-zeros
%// and use them to index into AA and set those as 1's
AA(idx(a~=0))=1
Code output with given AA -
>> AA
AA =
0 0 1
0 1 0
0 0 1
0 1 0
1 0 0
Approach 2
AA(sub2ind(size(AA),find(a~=0),a(a~=0)))=1
Breaking it down to few steps for explanation:
find(a~=0) and a(a~=0) gets us the VALID row and columns indices respectively as needed for sub2ind(size(),row,column) format.
sub2ind gets us the linear indices, which we can use to index into input matrix AA and set those in AA as 1's.
Hi I am struggling with reading data from a file quickly enough. ( Currently left for 4hrs, then crashed) must be a simpler way.
The text file looks similar like this:
From To
1 5
3 2
2 1
4 3
From this I want to form a matrix so that there is a 1 in the according [m,n]
The current code is:
function [z] = reed (A)
[m,n]=size(A);
i=1;
while (i <= n)
z(A(1,i),A(2,i))=1;
i=i+1;
end
Which output the following matrix, z:
z =
0 0 0 0 1
1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
My actual file has 280,000,000 links to and from, this code is too slow for this size file. Does anybody know a much faster was to do this in matlab?
thanks
You can do something along the lines of the following:
>> A = zeros(4,5);
>> B = importdata('testcase.txt');
>> A(sub2ind(size(A),B.data(:,1),B.data(:,2))) = 1;
My test case, 'testcase.txt' contains your sample data:
From To
1 5
3 2
2 1
4 3
The result would be:
>> A
A =
0 0 0 0 1
1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
EDIT - 1
After taking a look at your data, it seems that even if you modify this code appropriately, you may not have enough memory to execute it as the matrix A would become too large.
As such, you can use sparse matrices to achieve the same as given below:
>> B = importdata('web-Stanford.txt');
>> A = sparse(B.data(:,1),B.data(:,2),1,max(max(B.data)),max(max(B.data)));
This would be the approach I'd recommend as your A matrix will have a size of [281903,281903] which would usually be too large to handle due to memory constraints. A sparse matrix on the other hand, maintains only those matrix entries which are non-zero, thus saving on a lot of space. In most cases, you can use sparse matrices more-or-less as you use normal matrices.
More information about the sparse command is given here.
EDIT - 2
I'm not sure why it isn't working for you. Here's a screenshot of how I did it in case that helps:
EDIT - 3
It seems that you're getting a double matrix in B while I'm getting a struct. I'm not sure why this is happening; I can only speculate that you deleted the header lines from the input file before you used importdata.
Basically it's just that my B.data is the same as your B. As such, you should be able to use the following instead:
>> A = sparse(B(:,1),B(:,2),1,max(max(B)),max(max(B)));