Subfunctions in matlab - string

I have function called Assignment in Matlab with PsychToolBox. This function shows a random color to the paritcipant and require participant to name the color and record this data.
function should return me 2 output as a string
rgb code of the random color like: trial(1).color = [5 5 5]
a matrix which correspond to the sound record.
I write the main functions and color part is okay, but I cannot integrate the recording function into the main function.
in main function I use this string trial.data = recording(1,0,5)
and then I wrote a subfunction named "recording"
function recording (wavfilename, voicetrigger, maxsecs)
bla, bla
end
However, the main function does not recognize the subfunction. Am I doing an logical error? the error message is below
Error: File: assignment.m Line: 40 Column: 27
Unexpected MATLAB expression.
line 40 = trial.data = recording(1,0,5)
function ass8(trial)
Screen('Preference', 'SkipSyncTests', 1)
ListenChar(2);
Screen('HideCursorHelper', 0, 0)
[myWin, rect]=Screen('OpenWindow',0,[128,128,128]);
centerX=rect(3)/2;
centerY=rect(4)/2;
for trial = 1:100
Screen('TextSize', myWin, 30);
Screen('TextFont', myWin, 'Times');
[normBoundsRect, offsetBoundsRect] = Screen('TextBounds',myWin, 'What is the color of the rectangle?');
Screen('DrawText', myWin, 'What is the color of the rectangle?', (centerX-(normBoundsRect(3)/2)),(centerY-(normBoundsRect(4)/2+150)), [0,0,0]);
Screen('Flip', myWin)
WaitSecs(1)% inter stimulus interval
color = randi(255,1,3)
while 1
Screen('FillRect', myWin, color ,[583, 284, 783, 484])
% [ (centerX-100), (centerY-100), (centerX+100),(centerY+100)]);
Screen('Flip', myWin)
WaitSecs(3)
trial.color = color % trial 'ın rengini belirtmesini söyledim
trial.data = reco(1,0 5)% trial'ın ismi 1, kayıt yapacağı süre ise 3 sn
if Waitsecs(3)==1
break; % Terminates the loop if the condition is % satisfied
end
end
pause(.05);
% [clicks, x, y, buttons] = GetClicks(myWin);
%
% buttons=0;
% while ~buttons
% [x, y, buttons] = GetMouse(myWin);
% end
% while 1
% [x,y,buttons] = GetMouse(myWin);
% if ~buttons(1)
% break;
% end
% end
Screen('CloseAll')
end
end
function reco(wavfilename, voicetrigger, maxsecs)
%
% AssertOpenGL;
if nargin < 1
wavfilename = [];
end
if nargin < 2
voicetrigger = [];
end
if isempty(voicetrigger)
voicetrigger = 0;
end
if nargin < 3
maxsecs = [];
end
if isempty(maxsecs)
maxsecs = inf;
end
InitializePsychSound;
freq = 44100;
pahandle = PsychPortAudio('Open', [], 2, 0, freq, 2);
PsychPortAudio('GetAudioData', pahandle, 10);
PsychPortAudio('Start', pahandle, 0, 0, 1);
if voicetrigger > 0
% Yes. Fetch audio data and check against threshold:
level = 0;
% Repeat as long as below trigger-threshold:
while level < voicetrigger
% Fetch current audiodata:
[audiodata offset overflow tCaptureStart] = PsychPortAudio('GetAudioData', pahandle);
% Compute maximum signal amplitude in this chunk of data:
if ~isempty(audiodata)
level = max(abs(audiodata(1,:)));
else
level = 0;
end
% Below trigger-threshold?
if level < voicetrigger
% Wait for a millisecond before next scan:
WaitSecs(0.0001);
end
end
else
% Start with empty sound vector:
recordedaudio = [];
end
s = PsychPortAudio('GetStatus', pahandle)
while ~KbCheck && ((length(recordedaudio) / s.SampleRate) < maxsecs)
% Wait a second...
WaitSecs(1);
% Query current capture status and print it to the Matlab window:
s = PsychPortAudio('GetStatus', pahandle);
% Print it:
fprintf('\n\nAudio capture started, press any key for about 1 second to quit.\n');
fprintf('This is some status output of PsychPortAudio:\n');
disp(s);
% Retrieve pending audio data from the drivers internal ringbuffer:
audiodata = PsychPortAudio('GetAudioData', pahandle);
nrsamples = size(audiodata, 2);
% Plot it, just for the fun of it:
plot(1:nrsamples, audiodata(1,:), 'r', 1:nrsamples, audiodata(2,:), 'b');
drawnow;
% And attach it to our full sound vector:
recordedaudio = [recordedaudio audiodata]; %#ok<AGROW>
end
PsychPortAudio('Stop', pahandle);
audiodata = PsychPortAudio('GetAudioData', pahandle);
recordedaudio = [recordedaudio audiodata];
PsychPortAudio('Close', pahandle);
if ~isempty(wavfilename)
psychwavwrite(transpose(recordedaudio), 44100, 16, wavfilename)
end
fprintf('helal lan!\n');
ListenChar(2);
end

Related

How to extract substrings with different lengths?

I have an n by 2 matrix that contains start and end indices of substrings of a specified string. How can I extract the n by 1 cell array of substrings without a for-loop?
string = 'Hello World!';
ranges = [1 1;
2 3;
4 5;
3 7];
substrings = cell(size(ranges, 1), 1);
for i=1:size(ranges, 1)
substrings{i} = string(ranges(i, 1):ranges(i, 2));
end
The expected result:
substrings =
'H'
'el'
'lo'
'llo W'
You can use cellfun to make it a single-line operation:
str = 'Hello World!';
ranges = [ 1 1;
2 3;
4 5;
3 7];
% first convert "ranges" to a cell object
Cranges = mat2cell(ranges,ones(size(ranges,1),1),2);
% call "cellfun" on every row/entry of "Cranges"
cellfun(#(x)str(x(1):x(2)),Cranges, 'UniformOutput',false)
ans =
4×1 cell array
{'H' }
{'el' }
{'lo' }
{'llo W'}
I have changed the variable string to str because string is a native function in MATLAB (converting the input to the type string).
Although this is single-line operation, it doesn't mean that it is more efficient:
Num = 1000000;
substrings = cell(size(ranges, 1), 1);
% time for-loop
tic
for j = 1:Num
for i = 1:size(ranges, 1)
substrings{i} = str(ranges(i, 1):ranges(i, 2));
end
end
toc;
Cranges = mat2cell(ranges,ones(size(ranges,1),1),2);
% time function-call
tic
for j = 1:Num
substrings = cellfun(#(x)str(x(1):x(2)),Cranges, 'UniformOutput',false);
end
toc;
Elapsed time is 3.929622 seconds.
Elapsed time is 50.319609 seconds.

Does xlswrite have limitations?

I'm running MATLAB R2017a. I am trying to execute a simple program that writes 3 characters to an Excel file. When I run the program with a small number of values it is fine but when I increase it to the millions, the program pauses.
Does anyone know why the programming is pausing like this?
X = []
filename = 'PopltnFL.xlsx';
NumTrump = 4617886;
NumClinton = 4504975;
NumOther = 297025;
*% Values for which program runs without puasing*
% NumTrump = 4;
% NumClinton = 4;
% NumOther = 2;
%
for ii = 1:NumTrump
X = [X,'T'];
end
for jj = 1:NumClinton
X = [X,'C'];
end
for kk = 1:NumOther
X = [X,'O'];
end
X = X';
xlswrite(filename,X)

Dynamic Programming, choosing the highest total value

The Data:
A list of integers increasing in order (0,1,2,3,4,5.......)
A list of values that belong to those integers. As an example, 0 = 33, 1 = 45, 2 = 21, ....etc.
And an incrementing variable x which represent a minimum jump value.
x is the value of each jump. For example if x = 2, if 1 is chosen you cannot choose 2.
I need to determine the best way to choose integers, given some (x), that produce the highest total value from the value list.
EXAMPLE:
A = a set of 1 foot intervals (0,1,2,3,4,5,6,7,8,9)
B = the amount of money at each interval (9,5,7,3,2,7,8,10,21,12)
Distance = the minimum distance you can cover
- i.e. if the minimum distance is 3, you must skip 2 feet and leave the money, then you can
pick up the amount at the 3rd interval.
if you pick up at 0, the next one you can pick up is 3, if you choose 3 you can
next pick up 6 (after skipping 4 and 5). BUT, you dont have to pick up 6, you
could pick up 7 if it is worth more. You just can't pick up early.
So, how can I programmatically make the best jumps and end with the most money at the end?
So I am using the below equation for computing the opt value in the dynamic programming:
Here d is distance.
if (i -d) >= 0
opt(i) = max (opt(i-1), B[i] + OPT(i-d));
else
opt(i) = max (opt(i-1), B[i]);
Psuedo-code for computing the OPT value:
int A[] = {integers list}; // This is redundant if the integers are consecutive and are always from 0..n.
int B[] = {values list};
int i = 0;
int d = distance; // minimum distance between two picks.
int numIntegers = sizeof(A)/sizeof(int);
int opt[numIntegers];
opt[0] = B[0]; // For the first one Optimal value is picking itself.
for (i=1; i < numIntegers; i++) {
if ((i-d) < 0) {
opt[i] = max (opt[i-1], B[i]);
} else {
opt[i] = max (opt[i-1], B[i] + opt[i-d]);
}
}
EDIT based on OP's requirement about getting the selected integers from B:
for (i=numIntegres - 1; i >= 0;) {
if ((i == 0) && (opt[i] > 0)) {
printf ("%d ", i);
break;
}
if (opt[i] > opt[i-1]) {
printf ("%d ", i);
i = i -d;
} else {
i = i - 1;
}
}
If A[] does not have consecutive integers from 0 to n.
int A[] = {integers list}; // Here the integers may not be consecutive
int B[] = {values list};
int i = 0, j = 0;
int d = distance; // minimum distance between two picks.
int numAs = sizeof(A)/sizeof(int);
int numIntegers = A[numAs-1]
int opt[numIntegers];
opt[0] = 0;
if (A[0] == 0) {
opt[0] = B[0]; // For the first one Optimal value is picking itself.
j = 1;
}
for (i=1; i < numIntegers && j < numAs; i++, j++) {
if (i < A[j]) {
while (i < A[j]) {
opt[i] = opt[i -1];
i = i + 1:
}
}
if ((i-d) < 0) {
opt[i] = max (opt[i-1], B[j]);
} else {
opt[i] = max (opt[i-1], B[j] + opt[i-d]);
}
}

Compare to string of names

I am trying to compare the names of two strings, and trying to pick out the name that are not included in the other string.
h = 1;
for i = 1:name_size_main
checker = 0;
main_name = main(i);
for j = 1:name_size_image
image_name = image(j);
temp = strcmpi(image_name, main_name);
if temp == 1;
checker = temp;
end
end
if checker == 0
result(h) = main_name;
h = h+1;
end
end
but it keeps returning the entire string as result, the main string contain roughly 1000 names, the images name contain about 300 names, so it should return about 700 names in result but it keep returning all 1000 names.
I tried your code with small vectors:
main = ['aaa' 'bbb' 'ccc' 'ddd'];
image = ['bbb' 'ddd'];
name_size_main = size(main,2);
name_size_image = size(image,2);
h = 1;
for i = 1:name_size_main
checker = 0;
main_name = main(i);
for j = 1:name_size_image
image_name = image(j);
temp = strcmpi(image_name, main_name);
if temp == 1;
checker = temp;
end
end
if checker == 0
result(h) = main_name;
h = h+1;
end
end
I get result = 'aaaccc', is it not what you want to get?
EDIT:
If you are using cell arrays, you should change the line result(h) = main_name; to result{h} = main_name; like that:
main = {'aaa' 'bbb' 'ccc' 'ddd'};
image = {'bbb' 'ddd'};
name_size_main = size(main,2);
name_size_image = size(image,2);
result = cell(0);
h = 1;
for i = 1:name_size_main
checker = 0;
main_name = main(i);
for j = 1:name_size_image
image_name = image(j);
temp = strcmpi(image_name, main_name);
if temp == 1;
checker = temp;
end
end
if checker == 0
result{h} = main_name;
h = h+1;
end
end
You can use cells of string along with setdiff or setxor.
A = cellstr(('a':'t')') % a cell of string, 'a' to 't'
B = cellstr(('f':'z')') % 'f' to 'z'
C1 = setdiff(A,B,'rows') % gives 'a' to 'e'
C2 = setdiff(B,A,'rows') % gives 'u' to 'z'
C3 = setxor(A,B,'rows') % gives 'a' to 'e' and 'u' to 'z'

Calculate min, max, count in linux file [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I have a file on linux server that has data like :
a 22
a 10
a 17
a 51
a 33
b 51
b 47
c 33
I want a shell script or linux commands to find min, avg, 90%, max and count for each value in column 1.
Example:
for a min = 10, avg = 26, 90% = 33, max = 51, and count = 5.
Here a version with even the 90% percentile using gawk.
The definition of percentile is that one given by
Wikipedia and called Nearest rank.
The function round can be found here.
#!/bin/bash
gawk '
function round(x, ival, aval, fraction)
{
ival = int(x) # integer part, int() truncates
# see if fractional part
if (ival == x) # no fraction
return ival # ensure no decimals
if (x < 0) {
aval = -x # absolute value
ival = int(aval)
fraction = aval - ival
if (fraction >= .5)
return int(x) - 1 # -2.5 --> -3
else
return int(x) # -2.3 --> -2
} else {
fraction = x - ival
if (fraction >= .5)
return ival + 1
else
return ival
}
}
# the following block processes all the lines
# and populates counters and values
{
if($1 in counters) {
counters[$1]++;
} else {
counters[$1] = 1;
}
i = counters[$1];
values[$1, i] = $2;
} END {
for (c in counters) {
delete tmp;
min = values[c, 1];
max = values[c, 1];
sum = values[c, 1];
tmp[1] = values[c, 1];
for (i = 2; i <= counters[c]; i++) {
if (values[c, i] < min) min = values[c, i];
if (values[c, i] > max) max = values[c, i];
sum += values[c, i];
tmp[i] = values[c, i];
}
# The following 3 lines compute the percentile.
n = asort(tmp, tmp_sorted);
idx = round(0.9 * n + 0.5); # Nearest rank definition
percentile = tmp_sorted[idx];
# Output of the statistics for this group.
printf "for %s min = %d, avg = %f, 90 = %d,max = %d, count = %d\n", c, min, (sum / counters[c]), percentile, max, counters[c];
}
}'
To run execute:
./stats.sh < input.txt
I am assuming that the above script is named stats.sh and your input is saved in input.txt.
The output is:
for a min = 10, avg = 26.600000, 90 = 51,max = 51, count = 5
for b min = 47, avg = 49.000000, 90 = 51,max = 51, count = 2
for c min = 33, avg = 33.000000, 90 = 33,max = 33, count = 1
Here the explanation:
counters is an associative array, the key is the value in column 1
and the value is the number of values found in the input for each
value in column 1.
values is a two dimensional (value_in_column_one, counter_per_value)
array that keeps all the values grouped by value in column one.
At the end of the script the outermost loop goes trough all the values
found in column 1. The innermost for loop analyses all the values belonging
to a particular value in column 1 and it computes all the statics.
For lines starting with a, here's an awk script.
$ echo 'a 22
a 10
a 17
a 51
a 33
b 51
b 47
c 33' | awk 'BEGIN{n=0;s=0;};/^a/{n=n+1;s=s+$2;};END{print n;print s;print s/n;}'
5
133
26.6
Using awk:
awk 'NR==1{min=$1} {sum+=$2; if(min>=$2) min=$2; if(max<$2) max=$2}
END{printf("max=%d,min=%d,count=%d,avg=%.2f\n", max, min, NR, (sum/NR))}' file
max=51,min=10,count=8,avg=33.00
EDIT:
awk '$1 != v {
if (NR>1)
printf("For %s max=%d,min=%d,count=%d,avg=%.2f\n", v, max, min, k, (sum/k));
v=$1;
min=$2;
k=sum=max=0
}
{
k++;
sum+=$2;
if (min > $2)
min=$2;
if (max < $2)
max=$2
}
END {
printf("For %s max=%d,min=%d,count=%d,avg=%.2f\n", v, max, min, k, (sum/k))
}' < <(sort -n -k1,2 f)
OUTPUT:
For a max=51,min=10,count=5,avg=26.60
For b max=51,min=47,count=2,avg=49.00
For c max=33,min=33,count=1,avg=33.00

Resources