I have 2 vectors like this:
rawRT (nx1 double)
354
521
0
428
568
0
289
...
552
prob (nx1 double)
.82
.75
.59
.27
.67
.36
...
.12
Each value in rawRT corresponds to the value of the same order/location in prob. First, I want to apply some sort of transform to the values in prob if their corresponding values in rawRT is greater than zero.
I could do this: index = rawRT>0. Next, I find the values in prob that correspond to the ones in rawRT that are greater than 0: prob_temp = prob(index). Next, I apply the transform: prob_transform = [some function](prob_temp).
Now, what I am not sure how to do is to replace the values in prob with values from prob_transform in a way that the values that were NOT transformed in prob will remain intact. So in this example, prob(1,1), prob(2,1) will be replaced by values from prob_transform while prob(3,1) will remain the same as original.
Could anyone help?
You just use the same index again for assignment
prob(index) = prob_transform;
You could do this all in one hit
index = rawRT>0;
prob(index) = someFunction( prob(index) );
Related
rand(3,4)
generates the following 3x4 matrix for me:
0.4229 0.4709 0.6385 0.3196
0.0942 0.6959 0.0336 0.5309
0.5985 0.6999 0.0688 0.6544
How can I limit the values generated to a specific range? Like restricting them to values between 1 and 100. And how can I specify whether I want the random numbers to be float or int?
You can multiply by the range you want, and add the minimum value. So, to get a matrix with values in the range [1, 100], do:
1 + 99*rand(3,4)
If you want single or something else, use the typename argument to specify this.
If you want integers, use randi:
1 + randi(99,3,4)
i want to know the coding to find the maximum value, over a certain range.
i already coded like below.
f=f'
ac_yyyy_f=ac_yyyy_f'
[row,col] = ind2sub(size(ac_yyyy_f),find(ac_yyyy_f==max(ac_yyyy_f)))
but the problem is, sometimes the maximum value of Y axis choosen by my code is not what i want.
the X axis has the range of 0 to 100000 and i want the maximum between 20000 to 100000. the problem is sometimes the max value show up at the range of 0 to 20000.
How can i figure this out?
Use the max() function:
%let R be your range of values
R = [2 1 7 4];
[value, index] = max(R);
In the above example, value will be 7 and index will be 3
For more info: http://fr.mathworks.com/help/matlab/ref/max.html
I'm using a vector of random integers to stand in for your function output.
a = floor(rand(1,100000)*100);
[val, idx] = max(a(20000:100000));
You want to use the max function here to find the maximum value rather than find.
Now, the other part of the task is getting the max value from a certain part of your matrix. You can pass just a subset of a vector or matrix to a function by indexing it with a range of values. Note that idx gives you the position of val within a(20000:100000). If you need the position within a, you need to use idx+19999.
Also, you should take a look at the matrix indexing reference—there are many different and fun ways to index a matrix—because indexing is one of the most important features of matlab.
Here's the reference for the max function:
http://www.mathworks.com/help/matlab/ref/max.html
And the reference for indexing:
http://www.mathworks.com/help/matlab/math/matrix-indexing.html
You can use the max function with a subset of your array. It will return the maximum value, as well as the index where it is located. Be sure to correct the index it returns you based on your desired range. Like this:
%//create an array of 100,000 values to play with.
f=floor(rand(100000,1).*100);
%//find the max between f(20000) and f(100000)
[myMax, I] = max( f(20000:100000) );
%//correct the index based on where we started looking
%//for the max. Subtract 1 because it's MATLAB!
myIndex = I+20000-1;
This results in:
>> myMax
myMax =
99
>> myIndex
myIndex =
20045
>> f(myIndex)
ans =
99
I want to generate sequence of toss outcomes of n trials using the help of rand() function. I read about rand() from MATLAB reference code that rand() generates 0 and 1 or random numbers within specified range, how I can make the outcome of rand() to be variable H and T - that represent head and tail- ?
Sample Code, let 1 be H and 0 is T:
n = 10;
x = rand(1,n)<0.5;
t = 1:10;
plot(t,x);
title('outcomes of tossing a coin 10 times');
xlabel('trials');
ylabel('outcome');
axis([1 10 0 1.2]);
display(x);
Command Window
x =
1 0 1 0 0 0 1 1 1 0
That's pretty easy. Create a cell array of strings that contains two strings: Heads and Tails:
outcome = {'Heads', 'Tails'};
Next, you can use rand like you did before, but then cast this to double and add 1 so that you get values that are 1 and 2. The reason why you need this is because you can use this output to index into outcome, as MATLAB begins accessing values at index 1. However, if you create your logical vector of rand(1,n) < 0.5 then add 1 to this result, the output will be coalesced into a double anyway so you would implicitly be casting the result.
You can then use this to index into outcome to get your desired results. To reproduce this on my end:
%// Set seed for reproducibility
rng(123123);
x = rand(10,1) < 0.5; %// Generate random vector of logical 0s and 1s
%// Cast to double then add with 1 so we can generate a vector of 1s and 2s
x = x + 1;
%// Declare that cell array of strings
outcome = {'Heads', 'Tails'};
%// Use the vector of 1s and 2s to get our desired strings
y = outcome(x)
... and we get:
y =
Columns 1 through 7
'Tails' 'Heads' 'Tails' 'Heads' 'Heads' 'Tails' 'Tails'
Columns 8 through 10
'Tails' 'Heads' 'Tails'
Note that y will be a cell array of strings, and so if you want to access a particular string, do:
str = y{idx};
idx is the position of where you want to access.
However, if I can suggest something else, you can try using randi and specify the maximum value of what you want to generate to be 2. This way, you are guaranteed to produce values between 1 and 2 like so:
x = randi(2, 10, 1);
This would generate a 10 x 1 array of values that are either 1 or 2. To me this looks more readable, but whatever you're comfortable with. You can then use this result and directly access outcome to get what you want.
Can any one tell me how to return a matched value to a comparison between a value and a column vector in MATLAB. So lets say the value to be compared is 200 and I got a column vector:
a = [21; 32; 433; 54; 42;]
I want to find which element in the vector a returns the match for the comparison 200 <= a
If I do: x = any(200 <= a) the value of x will be 0 or 1 based on if the condition satisfy. But if I want to know which value in vector 'a' satisfied the condition how can I find that out? In this case element 3 and value is 433
The other answers are good, but find is unnecessary. Whenever possible, use logical indexing instead. Seeing 200 <= a is a bit strange for me. I like seeing the variable on the left side, so this is the same as saying a >= 200. In any case, you can do this:
vals = a(200 <= a);
200 <= a would return a logical vector where 1 denotes that the element satisfies the condition you're looking for and 0 would mean that the condition isn't satisfied. If we displayed 200 <= a, this is what we get:
>> 200 <= a
ans =
0
0
1
0
0
This means that only the third element satisfies your criteria. If we used this logical vector and indexed into a, we would return only those elements that satisfied your condition from a. As such, we would get:
vals =
433
Use find as follows:
positions = find(200<=a); %// all positions satisfying condition
values = a(positions); %// values at those positions
You can use find to get a vector of indices that satisfy the condition.
The following command returns the value at the index found to meet the criteria.
a(find(a >= 200))
ans =
433
Likewise, a <= 200:
a(find(a <= 200))
ans =
21
32
54
42
As #David points out in the comments, you don't need to use the find command, but it works just the same.
I have the following matrix which keeps track of the starting and ending points of data ranges (the first column represents "starts" and the second column represents the "ends"):
myMatrix = [
162 199; %// this represents the range 162:199
166 199; %// this represents the range 166:199
180 187; %// and so on...
314 326;
323 326;
397 399;
419 420;
433 436;
576 757;
579 630;
634 757;
663 757;
668 757;
676 714;
722 757;
746 757;
799 806;
951 953;
1271 1272
];
I need to eliminate all the ranges (ie. rows) which are contained within a larger range present in the matrix. For example the ranges [166:199] and [180:187] are contained within the range [162:199] and thus, rows 2 and 3 would need to be removed.
The solution I thought of was to calculate a sort of "running" max on the second column to which subsequent values of the column are compared to determine whether or not they need to be removed. I implemented this with the use of a for loop as follows:
currentMax = myMatrix(1,2); %//set first value as the maximum
[sizeOfMatrix,~] = size(myMatrix); %//determine the number of rows
rowsToRemove = false(sizeOfMatrix,1); %//pre-allocate final vector of logicals
for m=2:sizeOfMatrix
if myMatrix(m,2) > currentMax %//if new max is reached, update currentMax...
currentMax = myMatrix(m,2);
else
rowsToRemove(m) = true; %//... else mark that row for removal
end
end
myMatrix(rowsToRemove,:) = [];
This correctly removes the "redundant" ranges in myMatrix and produces the following matrix:
myMatrix =
162 199
314 326
397 399
419 420
433 436
576 757
799 806
951 953
1271 1272
Onto the questions:
1) It would seem that there has to be a better way of calculating a "running" max than a for loop. I looked into accumarray and filter, but could not figure out a way to do it with those functions. Is there a potential alternative that skips the for loop (some kind of vectorized code that is more efficient)?
2) Is there a completely different (that is, more efficient) way to accomplish the final goal of removing all the ranges that are contained within larger ranges in myMatrix? I don't know if I'm over-thinking this whole thing...
Approach #1
bsxfun based brute-force approach -
myMatrix(sum(bsxfun(#ge,myMatrix(:,1),myMatrix(:,1)') & ...
bsxfun(#le,myMatrix(:,2),myMatrix(:,2)'),2)<=1,:)
Few explanations on the proposed solution:
Compare all starts indices against each other for "contained-ness" and similarly for ends indices. Note that the "contained-ness" criteria has to be for either of these two :
Greater than or equal to for starts and lesser than or equal to for ends
Lesser than or equal to for starts and greater than or equal to for ends.
I just so happen to go with the first option.
See which rows satisfy at least one "contained-ness" and remove those to have the desired result.
Approach #2
If you are okay with an output that has sorted rows according to the first column and if there are lesser number of local max's, you can try this alternative approach -
myMatrix_sorted = sortrows(myMatrix,1);
col2 = myMatrix_sorted(:,2);
max_idx = 1:numel(col2);
while 1
col2_selected = col2(max_idx);
N = numel(col2_selected);
labels = cumsum([true ; diff(col2_selected)>0]);
idx1 = accumarray(labels, 1:N ,[], #(x) findmax(x,col2_selected));
if numel(idx1)==N
break;
end
max_idx = max_idx(idx1);
end
out = myMatrix_sorted(max_idx,:); %// desired output
Associated function code -
function ix = findmax(indx, s)
[~,ix] = max(s(indx));
ix = indx(ix);
return;
I ended up using the following for the "running maximum" problem (but have no comment on its efficiency relative to other solutions):
function x = cummax(x)
% Cumulative maximum along dimension 1
% Adapted from http://www.mathworks.com/matlabcentral/newsreader/view_thread/126657
% Is recursive, but magically so, such that the number of recursions is proportional to log(n).
n = size(x, 1);
%fprintf('%d\n', n)
if n == 2
x(2, :) = max(x);
elseif n % had to add this condition relative to the web version, otherwise it would recurse infinitely with n=0
x(2:2:n, :) = cummax(max(x(1:2:n-1, :), x(2:2:n, :)));
x(3:2:n, :) = max(x(3:2:n, :), x(2:2:n-1, :));
end