Mean of one variable when another variable equals 1 in matlab - subset

I would like to get the mean of my reaction time column when my stimnum column is equal to 1
I am not sure if i can do this with one simple line of code or if i need to do a for loop.
stimnum = randi([1 3], [1 100]);
y = 1 + 1.*randn(1, 100);
rt = (y.^2) +.01;
A = rand(1,100);
correct = A>=0.2;
Data= [stimnum; rt; correct ]';
Data = dataset({ Data, 'Stimnum', 'RT', 'Correct'});
rtmean = mean (Data.RT{Data.Stimnum == 1});

Related

Matlab AppDesigner: Listbox from Excel

I'm creating an app in App Designer. What I would like to do is when selecting one or multiple options, these get assigned a value of 1.
The list(i.e. "Column") is read in the following way and list options are assigned to a struct variable with a default value of 0.
table1 = readtable("file.xls");
for i = 1:length(rmmissing(table1{:,"Column"}))
s.(char(rmmissing(table1{i,"Column"}))) = 0;
end
This outputs the following table.
s.Anna = 0
s.Bett = 0
s.Cyrielle = 0
s.Dylan = 0
My problem is that I can't figure out a way of updating the value from 0 to 1, whenever I highlight one of the options. I don't know how to essentially pick up a selected value and updating it.
So as an example, If I highlight "Anna" and "Cyrielle", these should update to 1, as shown below.
s.Anna = 1
s.Bett = 0
s.Cyrielle = 1
s.Dylan = 0
I tried an if statement like. Whilst this works, it means I have to hard-code the names, which I don't want. So it needs to dynamically pick out the name that is selected.
if app.ColumnListBox.Value == "Anna"
s.Anna = 1;
else
s.Anna = 0;
end
The listbox would look like this:
Listbox
The output I get when selecting one name is:
s =
struct with fields:
Anna: 1
Bett: 0
Cyrielle: 0
Dylan: 0
However if I select multiple options, everything goes to 0:
Multiple names
s =
struct with fields:
Anna: 0
Bett: 0
Cyrielle: 0
Dylan: 0
The code now is as follows:
names = fieldnames(s);
for j = 1:numel(names)
name = names{j};
if app.ListBox.Value == string(name)
s.(name) = 1;
else
s.(name) = 0;
end
end
assignin("base","s",s)
Any help would be much appreciated!
You should be able to make your if condition less hard coded with something like
names = fieldnames(s);
for iField = 1:numel(names)
% Assign current name to variable, e.g. "Anna"
name = names{iField};
% loop over the fields and check if selected
if app.ColumnListBox.Value == string(name)
s.(name) = 1;
else
s.(name) = 0;
end

RCPP and the %*% operator, revisited

I'm trying to decide if it makes sense to implement R's %*% operator in RCpp
if my dataset is huge. BUT, I am really having trouble getting a RCpp implementation.
Here is my example R code
# remove everything in the global environment
rm(list = ls())
n_states = 4 # number of states
v_n <- c("H", "S1", "S2", "D") # the 4 states of the model:
n_t = 100 # number of transitions
# create transition matrix with random numbers. This transition matrix is constant.
m_P = matrix(runif(n_states*n_t), # insert n_states * n_t random numbers (can change this later)
nrow = n_states,
ncol = n_states,
dimnames = list(v_n, v_n))
# create markov trace, what proportion of population in each state at each period (won't make sense due to random numbers but that is fine)
m_TR <- matrix(NA,
nrow = n_t + 1 ,
ncol = n_states,
dimnames = list(0:n_t, v_n)) # create Markov trace (n_t + 1 because R doesn't understand Cycle 0)
# initialize Markov trace
m_TR[1, ] <- c(1, 0, 0, 0)
# run the loop
microbenchmark::microbenchmark( # function from microbenchmark library used to calculate how long this takes to run
for (t in 1:n_t){ # throughout the number of cycles
m_TR[t + 1, ] <- m_TR[t, ] %*% m_P # estimate the Markov trace for cycle the next cycle (t + 1)
}
) # end of micro-benchmark function
print(m_TR) # print the result.
And, here is the replacement for the %*% operator: (WHich doesn't seem to work correctly at all, although I can't fgure out why.
library(Rcpp)
cppFunction(
'void estimate_markov(int n_t, NumericMatrix m_P, NumericMatrix m_TR )
{
// We want to reproduce this
// matrix_A[X+1,] <- matrix_A[X,] %*% matrix_B
// The %*% operation behaves as follows for a vector_V %*% matrix_M
// Here the Matrix M is populated with letters so that you can
// more easily see how the operation is performed
// So, a multiplication like this:
//
// V M
// {1} %*% {A D}
// {2} {B E}
// {3} {C F}
//
// Results in a vector:
// V_result
// {1*A + 1*D}
// {2*B + 2*E}
// {3*C + 3*F}
//
// Now use values instead of letters for M (ex: A=1, B=2, .., F=6)
// V_result
// {1*1 + 1*4} {1 + 4} {5}
// {2*2 + 2*5} => {4 + 10} => {14}
// {3*3 + 3*6} {9 + 18} {27}
//
// Note that the RHS matrix may contain any number of columns,
// but *MUST* must contain the same number of rows as LHS vector
// Get dimensions of matricies , and sanity check
// number of elements in a vector from the LHS matrix must equal == number of row on the RHS
if( m_TR.cols() != m_P.rows())
throw std::range_error("Matrix mismatch, m_P.rows != m_TR.rows");
// we want to know these dimensions, and there is no reason to call these functons in a loop
// store the values once
int cnt_P_cols = m_P.cols();
int cnt_TR_cols = m_TR.cols();
//
for(int Index = 1; Index <= n_t; ++Index)
{
// iterate over the columns in m_TR
for(int col_iter = 0; col_iter < cnt_TR_cols; ++col_iter)
{
// an accumulator for the vector multiplication
double sum = 0;
// The new value comes from the previous row (Index-1)
double orig_TR = m_TR(col_iter, Index-1);
// iterate over the columns in m_P corresponding to this Index
for(int p_iter = 0; p_iter < cnt_P_cols; ++p_iter)
{
// accumulate the value of this TR scalar * the m_P vector
sum += orig_TR * m_P(p_iter, Index);
}
m_TR(col_iter, Index) = sum;
}
}
}'
)
Can someone point me to where my logic is going wrong.

How to find the lexicographically smallest string by reversing a substring?

I have a string S which consists of a's and b's. Perform the below operation once. Objective is to obtain the lexicographically smallest string.
Operation: Reverse exactly one substring of S
e.g.
if S = abab then Output = aabb (reverse ba of string S)
if S = abba then Output = aabb (reverse bba of string S)
My approach
Case 1: If all characters of the input string are same then output will be the string itself.
Case 2: if S is of the form aaaaaaa....bbbbbb.... then answer will be S itself.
otherwise: Find the first occurence of b in S say the position is i. String S will look like
aa...bbb...aaaa...bbbb....aaaa....bbbb....aaaaa...
|
i
In order to obtain the lexicographically smallest string the substring that will be reversed starts from index i. See below for possible ending j.
aa...bbb...aaaa...bbbb....aaaa....bbbb....aaaaa...
| | | |
i j j j
Reverse substring S[i:j] for every j and find the smallest string.
The complexity of the algorithm will be O(|S|*|S|) where |S| is the length of the string.
Is there a better way to solve this problem? Probably O(|S|) solution.
What I am thinking if we can pick the correct j in linear time then we are done. We will pick that j where number of a's is maximum. If there is one maximum then we solved the problem but what if it's not the case? I have tried a lot. Please help.
So, I came up with an algorithm, that seems to be more efficient that O(|S|^2), but I'm not quite sure of it's complexity. Here's a rough outline:
Strip of the leading a's, storing in variable start.
Group the rest of the string into letter chunks.
Find the indices of the groups with the longest sequences of a's.
If only one index remains, proceed to 10.
Filter these indices so that the length of the [first] group of b's after reversal is at a minimum.
If only one index remains, proceed to 10.
Filter these indices so that the length of the [first] group of a's (not including the leading a's) after reversal is at a minimum.
If only one index remains, proceed to 10.
Go back to 5, except inspect the [second/third/...] groups of a's and b's this time.
Return start, plus the reversed groups up to index, plus the remaining groups.
Since any substring that is being reversed begins with a b and ends in an a, no two hypothesized reversals are palindromes and thus two reversals will not result in the same output, guaranteeing that there is a unique optimal solution and that the algorithm will terminate.
My intuition says this approach of probably O(log(|S|)*|S|), but I'm not too sure. An example implementation (not a very good one albeit) in Python is provided below.
from itertools import groupby
def get_next_bs(i, groups, off):
d = 1 + 2*off
before_bs = len(groups[i-d]) if i >= d else 0
after_bs = len(groups[i+d]) if i <= d and len(groups) > i + d else 0
return before_bs + after_bs
def get_next_as(i, groups, off):
d = 2*(off + 1)
return len(groups[d+1]) if i < d else len(groups[i-d])
def maximal_reversal(s):
# example input: 'aabaababbaababbaabbbaa'
first_b = s.find('b')
start, rest = s[:first_b], s[first_b:]
# 'aa', 'baababbaababbaabbbaa'
groups = [''.join(g) for _, g in groupby(rest)]
# ['b', 'aa', 'b', 'a', 'bb', 'aa', 'b', 'a', 'bb', 'aa', 'bbb', 'aa']
try:
max_length = max(len(g) for g in groups if g[0] == 'a')
except ValueError:
return s # no a's after the start, no reversal needed
indices = [i for i, g in enumerate(groups) if g[0] == 'a' and len(g) == max_length]
# [1, 5, 9, 11]
off = 0
while len(indices) > 1:
min_bs = min(get_next_bs(i, groups, off) for i in indices)
indices = [i for i in indices if get_next_bs(i, groups, off) == min_bs]
# off 0: [1, 5, 9], off 1: [5, 9], off 2: [9]
if len(indices) == 1:
break
max_as = max(get_next_as(i, groups, off) for i in indices)
indices = [i for i in indices if get_next_as(i, groups, off) == max_as]
# off 0: [1, 5, 9], off 1: [5, 9]
off += 1
i = indices[0]
groups[:i+1] = groups[:i+1][::-1]
return start + ''.join(groups)
# 'aaaabbabaabbabaabbbbaa'
TL;DR: Here's an algorithm that only iterates over the string once (with O(|S|)-ish complexity for limited string lengths). The example with which I explain it below is a bit long-winded, but the algorithm is really quite simple:
Iterate over the string, and update its value interpreted as a reverse (lsb-to-msb) binary number.
If you find the last zero of a sequence of zeros that is longer than the current maximum, store the current position, and the current reverse value. From then on, also update this value, interpreting the rest of the string as a forward (msb-to-lsb) binary number.
If you find the last zero of a sequence of zeros that is as long as the current maximum, compare the current reverse value with the current value of the stored end-point; if it is smaller, replace the end-point with the current position.
So you're basically comparing the value of the string if it were reversed up to the current point, with the value of the string if it were only reversed up to a (so-far) optimal point, and updating this optimal point on-the-fly.
Here's a quick code example; it could undoubtedly be coded more elegantly:
function reverseSubsequence(str) {
var reverse = 0, max = 0, first, last, value, len = 0, unit = 1;
for (var pos = 0; pos < str.length; pos++) {
var digit = str.charCodeAt(pos) - 97; // read next digit
if (digit == 0) {
if (first == undefined) continue; // skip leading zeros
if (++len > max || len == max && reverse < value) { // better endpoint found
max = len;
last = pos;
value = reverse;
}
} else {
if (first == undefined) first = pos; // end of leading zeros
len = 0;
}
reverse += unit * digit; // update reverse value
unit <<= 1;
value = value * 2 + digit; // update endpoint value
}
return {from: first || 0, to: last || 0};
}
var result = reverseSubsequence("aaabbaabaaabbabaaabaaab");
document.write(result.from + "→" + result.to);
(The code could be simplified by comparing reverse and value whenever a zero is found, and not just when the end of a maximally long sequence of zeros is encountered.)
You can create an algorithm that only iterates over the input once, and can process an incoming stream of unknown length, by keeping track of two values: the value of the whole string interpreted as a reverse (lsb-to-msb) binary number, and the value of the string with one part reversed. Whenever the reverse value goes below the value of the stored best end-point, a better end-point has been found.
Consider this string as an example:
aaabbaabaaabbabaaabaaab
or, written with zeros and ones for simplicity:
00011001000110100010001
We iterate over the leading zeros until we find the first one:
0001
^
This is the start of the sequence we'll want to reverse. We will start interpreting the stream of zeros and ones as a reversed (lsb-to-msb) binary number and update this number after every step:
reverse = 1, unit = 1
Then at every step, we double the unit and update the reverse number:
0001 reverse = 1
00011 unit = 2; reverse = 1 + 1 * 2 = 3
000110 unit = 4; reverse = 3 + 0 * 4 = 3
0001100 unit = 8; reverse = 3 + 0 * 8 = 3
At this point we find a one, and the sequence of zeros comes to an end. It contains 2 zeros, which is currently the maximum, so we store the current position as a possible end-point, and also store the current reverse value:
endpoint = {position = 6, value = 3}
Then we go on iterating over the string, but at every step, we update the value of the possible endpoint, but now as a normal (msb-to-lsb) binary number:
00011001 unit = 16; reverse = 3 + 1 * 16 = 19
endpoint.value *= 2 + 1 = 7
000110010 unit = 32; reverse = 19 + 0 * 32 = 19
endpoint.value *= 2 + 0 = 14
0001100100 unit = 64; reverse = 19 + 0 * 64 = 19
endpoint.value *= 2 + 0 = 28
00011001000 unit = 128; reverse = 19 + 0 * 128 = 19
endpoint.value *= 2 + 0 = 56
At this point we find that we have a sequence of 3 zeros, which is longer that the current maximum of 2, so we throw away the end-point we had so far and replace it with the current position and reverse value:
endpoint = {position = 10, value = 19}
And then we go on iterating over the string:
000110010001 unit = 256; reverse = 19 + 1 * 256 = 275
endpoint.value *= 2 + 1 = 39
0001100100011 unit = 512; reverse = 275 + 1 * 512 = 778
endpoint.value *= 2 + 1 = 79
00011001000110 unit = 1024; reverse = 778 + 0 * 1024 = 778
endpoint.value *= 2 + 0 = 158
000110010001101 unit = 2048; reverse = 778 + 1 * 2048 = 2826
endpoint.value *= 2 + 1 = 317
0001100100011010 unit = 4096; reverse = 2826 + 0 * 4096 = 2826
endpoint.value *= 2 + 0 = 634
00011001000110100 unit = 8192; reverse = 2826 + 0 * 8192 = 2826
endpoint.value *= 2 + 0 = 1268
000110010001101000 unit = 16384; reverse = 2826 + 0 * 16384 = 2826
endpoint.value *= 2 + 0 = 2536
Here we find that we have another sequence with 3 zeros, so we compare the current reverse value with the end-point's value, and find that the stored endpoint has a lower value:
endpoint.value = 2536 < reverse = 2826
so we keep the end-point set to position 10 and we go on iterating over the string:
0001100100011010001 unit = 32768; reverse = 2826 + 1 * 32768 = 35594
endpoint.value *= 2 + 1 = 5073
00011001000110100010 unit = 65536; reverse = 35594 + 0 * 65536 = 35594
endpoint.value *= 2 + 0 = 10146
000110010001101000100 unit = 131072; reverse = 35594 + 0 * 131072 = 35594
endpoint.value *= 2 + 0 = 20292
0001100100011010001000 unit = 262144; reverse = 35594 + 0 * 262144 = 35594
endpoint.value *= 2 + 0 = 40584
And we find another sequence of 3 zeros, so we compare this position to the stored end-point:
endpoint.value = 40584 > reverse = 35594
and we find it has a smaller value, so we replace the possible end-point with the current position:
endpoint = {position = 21, value = 35594}
And then we iterate over the final digit:
00011001000110100010001 unit = 524288; reverse = 35594 + 1 * 524288 = 559882
endpoint.value *= 2 + 1 = 71189
So at the end we find that position 21 gives us the lowest value, so it is the optimal solution:
00011001000110100010001 -> 00000010001011000100111
^ ^
start = 3 end = 21
Here's a C++ version that uses a vector of bool instead of integers. It can parse strings longer than 64 characters, but the complexity is probably quadratic.
#include <vector>
struct range {unsigned int first; unsigned int last;};
range lexiLeastRev(std::string const &str) {
unsigned int len = str.length(), first = 0, last = 0, run = 0, max_run = 0;
std::vector<bool> forward(0), reverse(0);
bool leading_zeros = true;
for (unsigned int pos = 0; pos < len; pos++) {
bool digit = str[pos] - 'a';
if (!digit) {
if (leading_zeros) continue;
if (++run > max_run || run == max_run && reverse < forward) {
max_run = run;
last = pos;
forward = reverse;
}
}
else {
if (leading_zeros) {
leading_zeros = false;
first = pos;
}
run = 0;
}
forward.push_back(digit);
reverse.insert(reverse.begin(), digit);
}
return range {first, last};
}

Why am I not getting an expected output using logical operators and indexing?

I am having trouble achieving an expected output. I am trying to create a byte adder using logical operators such as AND, XOR and OR. I have taken the minimal code required to reproduce the problem out of code, so assume that finalfirstvalue = "1010" and finalsecondvalue = "0101".
secondvalueindex = (len(finalsecondvalue) - 1)
carry, finalans = False, []
for i in range(-1, -len(finalfirstvalue) - 1, -1):
andone = (bool(finalfirstvalue[i])) & (bool(finalsecondvalue[secondvalueindex]))
xorone = (bool(finalfirstvalue[i])) ^ (bool(finalsecondvalue[secondvalueindex]))
andtwo = (bool(carry)) & (bool(xorone))
xortwo = (bool(carry)) ^ (bool(xorone))
orone = (bool(andone)) | (bool(andtwo))
carry = (bool(orone))
finalans.append(xortwo)
secondvalueindex -= 1
answer = ''.join(str(e) for e in finalans)
print (answer)
Actual Output: FalseTrueTrueTrue
Expected Output: TrueTrueTrueTrue
The code then follows to change back into zeroes and ones.
Because its missing a single boolean I feel like the issue is with my indexing. Although I've played around with it a bit and not had any luck.
I need to carry out these operations on the two variables mentioned at the start, but for the right most elements, and then move to the left by one for the next loop and so on.
First mistake is You are representing your binary numbers as string values.
finalfirstvalue = "1010"
finalsecondvalue = "0101"
secondvalueindex = (len(finalsecondvalue) - 1) == 3
So in second for loop you will get the result as
(finalsecondvalue[secondvalueindex]) == '0'
If you check in your Idle
>>> bool('0')
True
>>>
Because '0' is not actual 0 it is an non-empty string so it return True.
You need to cast your result to int before checking them with bool
Like this
(bool(int(finalsecondvalue[secondvalueindex])))
EDIT 2 Adding with variable lenghts
Full adder with verification using bin() function
a="011101"
b="011110"
if a>b:
b=b.zfill(len(a))
if a<b:
a=a.zfill(len(b))
finalfirstvalue = a
finalsecondvalue = b
carry, finalans = 0, []
secondvalueindex = (len(finalsecondvalue))
for i in reversed(range(0, len(finalfirstvalue))):
xorone = (bool(int(finalfirstvalue[i]))) ^ (bool(int(finalsecondvalue[i])))
andone = (bool(int(finalfirstvalue[i]))) & (bool(int(finalsecondvalue[i])))
xortwo = (carry) ^ (xorone)
andtwo = (carry) & (xorone)
orone = (andone) | (andtwo)
carry = (orone)
finalans.append(xortwo)
finalans.reverse()
answer=(''.join(str(e) for e in finalans))
print(str(carry)+answer)
print(bin(int(a,2) + int(b,2))) #verification
So I found the issue was to do with carry. I changed my code to look like the following. Prior to this code below, is code to convert binary values to boolean. For instance, all ones will equal True and all zeroes will equal False.
carry, finalans = False, []
indexvalue = (len(finalfirstvalue)-1)
while indexvalue >= 0:
andone = (firstvaluelist[indexvalue]) & (secondvaluelist[indexvalue])
xorone = (firstvaluelist[indexvalue]) ^ (secondvaluelist[indexvalue])
andtwo = (carry) & (xorone)
xortwo = (carry) ^ (xorone)
orone = (andone) | (andtwo)
carry = (orone)
if (carry == True) & (indexvalue == 0):
finalans.append(xortwo)
finalans.append(True)
else:
finalans.append(xortwo)
indexvalue -= 1
for n, i in enumerate(finalans):
if i == False:
finalans[n] = "0"
if i == True:
finalans[n] = "1"
finalans.reverse()
answer = ''.join(str(e) for e in finalans)
print (answer)
So if there was a single value missing, it was still stored in carry from the final loop but did not get the opportunity to be appended to the final result. To fix this, I added in an if statement to check if carry is containing anything (True) and if the loop is on its final loop by checking if indexvalue is at 0. This way, if the inputs are 32 and 32, rather than getting [False, False, False, False, False, False] as the output, the newly entered if statement will add the missing value in.

match check in matlab

i have strings like these:
s{1,2} = 'string';
s{2,2} = 'string2';
and in workspace structure like this
U.W.string = [2 2.5 3]
I want to check (in loop) s{1,2} or s{2,2} or s{i,2} matches any structure with the same name. If so, assign values from this structure to some variable var(i). How can it be done?
Use isfields to check, if a string is the name of a field in a struct. Then use the syntax struct.(name), where name is a string to access the field. Your code might look something like:
test = struct('hello', 'world', 'count', 42, 'mean', 10);
fields = {'test', 'count';
'hello', 'text';
'more', 'less'};
values = {pi, 'dummy', -1};
for row = 1 : size(fields, 1)
for column = 1 : size(fields, 2)
if isfield(test, fields{row, column})
test.(fields{row, column}) = values{row};
end
end
end
This converts the initial struct
test =
hello: 'world'
count: 42
mean: 10
to this one
test =
hello: 'dummy'
count: 3.1416
mean: 10
A shorter implementation is achieved by removing the inner loop and giving a cell-array to isfields:
for row = 1 : size(fields, 1)
%# Note the parenthesis instead of curly braces in the next statement.
match = isfield(test, fields(row, :));
if any(match)
test.(fields{row, match}) = values{row};
end
end
Use isfield(structName,fieldName). This should do the trick:
strings{1,1} = 'foo';
strings{1,2} = 'bar';
strings{1, 3} = 'foobar';
U.W.foo = 1;
U.W.foobar = 5;
for idx = 1:length(strings)
if(isfield(U.W,strings{1,idx}))
expression = sprintf('outvar(idx) = U.W.%s',strings{1,idx});
eval(expression);
end
end

Resources