Strided copy between HOST and DEVICE clEnqueueWriteBufferRect - copy

I search for a means to transfer data from two HOST buffers into a single DEVICE buffer in the following strided way:
Below are the two host buffers
Host_buffer_1 = [0 5] // copy to device with a stride equals to 5
Host_buffer_2 = [1 2 3 4 6 7 8 9] // each region of 4 numbers copy with a stride
I need the resulting Device buffer to be
device buffer [0 1 2 3 4 5 6 7 8 9]
Do I have to realize it on the HOST first and then a normal transfer to the device, or do you know a means to achieve this using clEnqueueWriteBufferRect function for instance, but this function does not have any stride parameter, right?
Thanks

You can use cl calls to do the rectangular patch copy on the fly. However, performance wise, I am not sure if this is the right approach.
If you shape your data as a 2D:
0 1 2 3 4
5 6 7 8 9
Then the buffers map like:
Device Host1 Host2
1 2 2 2 2 1 2 2 2 2
1 2 2 2 2 1 2 2 2 2
Therefore the copy rect commands should be:
clEnqueueWriteBufferRect(queue, buffer, CL_FALSE,
{0,0,0}, //buffer_origin
{0,0,0}, //host_origin
{1,2,1}, //region
5*sizeof(type), //buffer_row_pitch
0, //buffer_slice_pitch
1*sizeof(type), //host_row_pitch
0, //host_slice_pitch
host1, 0, NULL, NULL);
clEnqueueWriteBufferRect(queue, buffer, CL_FALSE,
{1,0,0}, //buffer_origin
{0,0,0}, //host_origin
{4,2,1}, //region
5*sizeof(type), //buffer_row_pitch
0, //buffer_slice_pitch
4*sizeof(type), //host_row_pitch
0, //host_slice_pitch
host2, 0, NULL, NULL);
But be VERY careful with the row_pitch and slice_pitch, as well as the offsets and regions. Since it is quite easy to get messed up. (And please check my code if you use it)
clEnqueueWriteBufferRect

Related

Reshape a matrix by splitting it after k columns in MATLAB

Suppose that I have a matrix , let's call it A, as follows:
1 2 3 4 5 1 2 3 4 5
0 2 4 6 8 1 3 5 7 9
And I want to reshape it into a matrix like this:
1 2 3 4 5
0 2 4 6 8
1 2 3 4 5
1 3 5 7 9
So, basically, what I want to be done is that MATLAB first reads a block of size (2,5) and then splits the remaining matrix to the next row and then repeats this so on so forth until we get something like in my example.
I tried to do this using MATLAB's reshape command in several ways but I failed. Any help is appreciated. In case that it matters, my original data is larger. It's (2,1080). Thanks.
I don't believe you can do this in a single command, but perhaps someone will correct me. If speed isn't a huge concern a for loop should work fine.
Alternatively you can get your results by reshaping each row of A and then placing the results into every other row of a new matrix. This will also work with your larger data.
A = [1 2 3 4 5 1 2 3 4 5
0 2 4 6 8 1 3 5 7 9];
An = zeros(numel(A)/5, 5); % Set up new, empty matrix
An(1:2:end,:) = reshape(A(1,:), 5, [])'; % Write the first row of A to every other row of An
An(2:2:end,:) = reshape(A(2,:), 5, [])' % Write second row of A to remaining rows
An =
1 2 3 4 5
0 2 4 6 8
1 2 3 4 5
1 3 5 7 9
You may need to read more about indexing in the Matlab's documentation.
For your example, it is easy to do the following
A=[1 2 3 4 5 1 2 3 4 5; 0 2 4 6 8 1 3 5 7 9]
a1=A(:,1:5); % extract all rows, and columns from 1 to 5
a2=A(:,6:end); % extract all rows, and columns from 6 to end
B=[a1;a2] % construct a new matrix.
It is not difficult to build some sort of loops to extract the rest.
Here's a way you can do it in one line using the reshape and permute commands:
B = reshape(permute(reshape(A,2,5,[]), [1,3,2]), [], 5);
The reshape(A,2,5,[]) command reshapes your A matrix into a three-dimensional tensor of dimension 2 x 5 x nblocks, where nblocks is the number of blocks in A in the horizontal direction. The permute command then swaps the 2nd and 3rd dimensions of this 3D tensor, so that it becomes a 2 x nblocks x 5 tensor. The final reshape command then transforms the 3D tensor into a matrix of dimension (2*nblocks) x 5.
Looking at the results at each stage may give you a better idea of what's happening.

RaspberryPi - check state of disconnected pins

I want write script for detecting which pin is connected with which one.
For example (BCM mode) I connect GPIO2 with GPIO3 and GPIO4 with GPIO5. My idea was to check each with each if there are connected.
for i in range(2,6):
for j in range(2,6):
check(i,j)
If all pins are connected it works, but if same of them are disconnected code print same crazy for me output. I think all input should return 0, but as you see same of them are in HIGHT state.
output:
1 2 3
0 2 4
0 2 5
1 3 2
0 3 4
0 3 5
1 4 2
1 4 3
0 4 5
1 5 2
1 5 3
0 5 4
code:
import RPi.GPIO as GPIO
from time import sleep
GPIO.setmode(GPIO.BCM)
for i in range(2, 6):
for j in range(2, 6):
if i == j:
continue
GPIO.setup([2, 3, 4, 5], GPIO.OUT, initial=GPIO.LOW)
GPIO.setup(i, GPIO.OUT, initial=GPIO.HIGH)
GPIO.setup(j, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
sleep(0.1)
if GPIO.input(j):
l.add(tuple(sorted((i, j))))
print(l)
I think the problem You have is related to pull-up and pull-down resistors. They are used to ensure the "known" level of digital value (1 or 0).
http://www.resistorguide.com/pull-up-resistor_pull-down-resistor/
There are many solutions to this "problem" -here is one for Arduino but actually every digital IC has these "problem" and datasheet should say how to deal with unconnected pins and what to expect in case of leaving them dangling.
https://electronics.stackexchange.com/questions/35704/arduino-has-an-input-value-in-disconnected-pin

Assigning values in neighborhood of local maxima’s to the value of local maxima based on varying window width (non symmetric window width)

This question is an extension of my previous question with some new issues so I thought to make a new query. I hope it is ok.
https://stackoverflow.com/questions/46054811/changing-the-values-in-the-neighbourhood-of-local-maxima-to-the-local-maxima/46055833#46055833
Query:
Where I find local maxima. I want to make a window and assign the values depending upon window size to the neighbors the value of local maxima.
Problem: (I want my window size to change as in my original signal I have different behavior around local maxima’s.) For example in 8th window local maxima is at 34th location but I have assigned the values on the left of 34th location the value of local maxima.
In short I want to have varying and controllable window width.
Please have a look at the attached picture to get an idea of output what I want.
I hope it will give some good idea.
I want to have varying and non symmetric means not same at every local maxima window width .
I have also attached a code for nlfilter which is doing exactly what I want to do means it makes window and assign values to local maximas within that window width but I need to have flexible and changeable window width.
Is it possible to have varying window width or is there some other way possible to do that.
enter image description here
Code:
t = 1:35 ;
Y = [1 3 13 6 2 7 5 4 2 4 1 0 1 2 3 5 0 0 1 0 0 2 3 6 7 0 0 8 0 1 1 2 3 4 2];
n = 2;
[p l] = findpeaks(Y);
locations = zeros(size(Y));
locations(l) = true;
locations = conv(locations, ones(1, 2*n+1), 'same') > 0;
X = -inf(size(Y)); % create temporary
X(l) = Y(l); % copy the local maxima
X = nlfilter(X, [1 2*n+1 ], #(x) max(x)); %replace all values with it local maxima
X(l) = Y(l); % ensure local maxima are not changed
Y(locations) = X(locations); % copy filtered temporary to output
figure(1)
hold on
plot(t,Y,'r')
t = 1:35 ;
Y = [1 3 13 6 2 7 5 4 2 4 1 0 1 2 3 5 0 0 1 0 0 2 3 6 7 0 0 8 0 1 1 2 3 4 2];
plot(t,Y,'b')
hold off
I shall be grateful to you for your valuable replies.
Further Explanation:
Please have a look at the pictures attached.
2nd picture is a part of original signal with local maximas mentioned as green dots.
In 1st pictures the red lines shows the region which I want to assign the value of local maxima. Green Dot is local maxima . So you will see that if I apply window with fixed width it will not work because the points before local maxima are less than after local maxima.
The reason for placing 1 outside in example is same that there are few points before local maxima which I want to flat as compared to after local maxima.
The same is the case with other windows like last window 8 I have local maxima on 34th location but why I have chosen large values before it is only due to the values I want to assign the values of local maxima .
You can define a criterion that starting form a peak and going to the both sides we compute variance of neighbors of the peak and we increase the radius of the neighborhood until variance of neighboring elements becomes greater than a predefined threshold.
Here idx_peaks is position of peaks and peaks is value of peaks. After applying the threshold you can get number of elements before and after position of each peak n_before and n_after. Then you can find indices of neighborhood and assign values to them.
Y = [1 3 13 6 2 7 5 4 2 4 1 0 1 2 3 5 0 0 1 0 0 2 3 6 7 0 0 8 0 1 1 2 3 4 2];
idx_peaks = [3 6 10 16 19 25 28 34];
peaks = [13 7 4 5 1 7 8 4];
threshold = 2;
cumvar = #(a)cumsum(a(:).^2)./(1:numel(a)).'-(cumsum(a(:))./(1:numel(a)).').^2;
categ = zeros(numel(Y),1);
categ(idx_peaks)=1;
forward_categ = cumsum(categ(idx_peaks(1):end));
n_after = accumarray(forward_categ,Y(idx_peaks(1):end),[],#(x)sum(cumvar(x)<threshold)-1).';
backward_categ = cumsum(flipud(categ(1:idx_peaks(end))));
n_before = flipud(accumarray(backward_categ,fliplr(Y(1:idx_peaks(end))),[],#(x)sum(cumvar(x)<threshold)-1)).';
lo = idx_peaks-n_before;
up = idx_peaks+n_after;
val = repelem(peaks,up-lo+1);
index=cumsum(accumarray(cumsum([1;up(:)-lo(:)+1]),[lo(:);0]-[0;up(:)]-1)+1);
index= index(1:end-1);
Y(index) = val
Here is the result when setting the threshold to 2 :
Y=
[1 3 13 6 2 7 4 4 4 4 4 4 1 5 5 5 1 1 1 1 1 1 1 7 7 0 0 8 4 4 4 4 4 4 4]

How to change the value of the diagonal column of the matrix?

How do I change the list of value to all 1? I need the top right to bottom left also end up with 1.
rc = input('Please enter a value for rc: ');
mat = ones(rc,rc);
for i = 1:rc
for j = 1:rc
mat(i,j) = (i-1)+(j-1);
end
end
final = mat
final(diag(final)) = 1 % this won't work?
Code for the original problem -
final(1:size(final,1)+1:end)=1
Explanation: As an example consider a 5x5 final matrix, the diagonal elements would have indices as (1,1), (2,2) .. (5,5). Convert these to linear indices - 1, 7 and so on till the very last element, which is exactly what 1:size(final,1)+1:end gets us.
Edit : If you would like to set the diagonal(from top right to bottom left elements) as 1, one approach would be -
final(fliplr(eye(size(final)))==1)=1
Explanation: In this case as well we can use linear indexing, but just for more readability and maybe a little fun, we can use logical indexing with a proper mask, which is being created with fliplr(eye(size(final)))==1.
But, if you care about performance, you can use linear indexing here as well, like this -
final(sub2ind(size(final),1:size(final,1),size(final,2):-1:1))=1
Explanation: Here we are creating the linear indices with the rows and columns indices of the elements to be set. The rows here would be - 1:size(final,1) and columns are size(final,2):-1:1. We feed these two to sub2ind to get us the linear indices that we can use to index into final and set them to 1.
If you would to squeeze out the max performance here, go with this raw version of sub2ind -
final([size(final,2)-1:-1:0]*size(final,1) + [1:size(final,1)])=1
All of the approaches specified so far are great methods for doing what you're asking.
However, I'd like to provide another viewpoint and something that I've noticed in your code, as well as an interesting property of this matrix that may or may not have been noticed. All of the anti-diagonal values in your matrix have values equal to rc - 1.
As such, if you want to set all of the anti-diagonal values to 1, you can cheat and simply find those values equal to rc-1 and set these to 1. In other words:
final(final == rc-1) = 1;
Minor note on efficiency
As a means of efficiency, you can do the same thing your two for loops are doing when constructing mat by using the hankel command:
mat = hankel(0:rc-1,rc-1:2*(rc-1))
How hankel works in this case is that the first row of the matrix is specified by the vector of 0:rc-1. After, each row that follows incrementally shifts values to the left and adds an increasing value of 1 to the right. This keeps going until you encounter the vector seen in the second argument, and at this point we stop. In other words, if we did:
mat = hankel(0:3,3:6)
This is what we get:
mat =
0 1 2 3
1 2 3 4
2 3 4 5
3 4 5 6
Therefore, by specifying rc = 5, this is the matrix I get with hankel, which is identical to what your code produces (before setting the anti-diagonal to 1):
mat =
0 1 2 3 4
1 2 3 4 5
2 3 4 5 6
3 4 5 6 7
4 5 6 7 8
Tying it all together
With hankel and the cheat that I mentioned, we can compute what you are asking in three lines of code - with the first line of code asking for the dimensions of the matrix:
rc = input('Please enter a value for rc: ');
mat = hankel(0:rc-1, rc-1:2*(rc-1));
mat(mat == rc-1) = 1;
mat contains your final matrix. Therefore, with rc = 5, this is the matrix I get:
mat =
0 1 2 3 1
1 2 3 1 5
2 3 1 5 6
3 1 5 6 7
1 5 6 7 8
Here's a simple method where I just add/subtract the appropriate matrices to end up with the right thing:
final=mat-diag(diag(mat-1))+fliplr(diag([2-rc zeros(1,rc-2) 2-rc]))
Here is one way to do it:
Say we have a the square matrix:
a = ones(5, 5)*5
a =
5 5 5 5 5
5 5 5 5 5
5 5 5 5 5
5 5 5 5 5
5 5 5 5 5
You can remove the diagonal, then create a diagonal list of ones to replace it:
a = a - fliplr(diag(diag(fliplr(a)))) + fliplr(diag(ones(length(a), 1)))
a =
5 5 5 5 1
5 5 5 1 5
5 5 1 5 5
5 1 5 5 5
1 5 5 5 5
The diag(ones(length(a), 1)) can be any vector, ie. 1->5:
a = a - fliplr(diag(diag(fliplr(a)))) + fliplr(diag(1:length(a)))
a =
5 5 5 5 1
5 5 5 2 5
5 5 3 5 5
5 4 5 5 5
5 5 5 5 5

2 groups, 1 way, repeated measure anova in MaLlab

I have 2 groups of persons with repeated measures (the order of the measures does not matter [1,2] is the same as [2,1]). The data could look like that (3 persons per group, 6 measures each):
groupA = [1 3 6 5 2 9; 2 5 3 4 5 8; 8 7 3 6 2 4];
groupB = [3 4 5 4 4 1; 2 8 4 2 1 2; 3 2 5 5 1 2];
A straightforward way would be to compare the 2 groups via a ranksum test of the mean values of each person:
meansA = mean(groupA, 2); % => [4.3 4.5 5.0]
meansB = mean(groupB, 2); % => [3.5 3.2 3.0]
[p, h] = ranksum(meansA, meansB)
However, this type of analysis neglects that each of the mean values consists of several measures (and therefore underestimates the significance).
A statistician told me to use a "repeated measure ANOVA" instead but none of the ANOVA functions of MatLab seems to do exactly what I want. The closest thing that I could find was:
>> [p, atab] = anovan([1 3 6 5 2 9 2 5 3 4 5 8 8 7 3 6 2 4 3 4 5 4 4 1 2 8 4 2 1 2 3 2 5 5 1 2], {[zeros(1,18) ones(1,18)],[1 1 1 1 1 1 2 2 2 2 2 2 3 3 3 3 3 3 4 4 4 4 4 4 5 5 5 5 5 5 6 6 6 6 6 6]}, 'varnames', {'individual', 'groupAorB'}, 'display', 'off')
p =
NaN
0.9774
But this seems not to work in the way I want it (NaN value and unrealistic p-value). I would be happy for any suggestions on how to perform an appropriate statistical test on these data in MatLab.
You should have a look at this FileExchange entry that deals with the one-way repeated measure ANOVA:
http://www.mathworks.com/matlabcentral/fileexchange/5576-rmaov1
The author (Antonio Trujillo-Ortiz) made some other nice entries for different designs (2 and 3 way anovas with repeated measures).
Unfortunately, the regular statistical functions in Matlab do not allow for repeated measure designs.
The nan signifies that a model which accounts for INDIVIDUAL, accounts for all of the variance of GROUP. In otherwords, if you fit an intercept for each INDIVIDUAL, then try to find the variability due to GROUP, you have no variance left. The model is "overspecified".
This is because you actually need a mixed effects model - you are looking for a between-subjects effect. In order to achieve this, you need to tell MATLAB that INDIVIDUAL is nested inside GROUP. So you use the following parameters for anovan:
'random', INDIVIDUAL
'nested', INDIVIDUAL_within_GROUP
Having said that, I don't know what error covariance assumptions this makes - i.e. does it assume a diagonal covariance matrix?
If you want more control over the assumptions being made, I suggest you investigate NLMEFIT from the statistics toolbox. This allows mixed effects models specifying the covariance.