This question already has answers here:
matlab double comparison
(3 answers)
Closed 9 years ago.
I'm trying to compare three numbers in a if statement but they don't match even if they are the same.
here are the numbers from the command window,
>> a = (round2(final_aucscore(10, 1),1e-4))
a =
0.9369
>> b = (round2(final_aucscore(10, 2),1e-4))
b =
0.9598
>> c = (round2(final_aucscore(10, 3),1e-4))
c =
0.9509
the function round2 can be found in the file echange here.
here's my code:
for mmm = 1:265
a = (round2(final_aucscore(mmm, 1),1e-4));
b = (round2(final_aucscore(mmm, 2),1e-4));
c = (round2(final_aucscore(mmm, 3),1e-4));
if a == 0.9369 && b == 0.9598 && c == 0.9509
auc_idx = idx(1:kk);
save('auc_idx', 'auc_idx', 'mmm');
break;
end
end
shouldn't it stop and save when mmm = 10?
The problem you're facing here comes from rounding error.
Try this
foo = 0.9369;
bar = (round2(foo,1e-4));
disp(bar == foo)
disp(foo-bar)
You could instead make a function to compare only within a certain precision.
What every computer scientist should know about floating-point arithmetic. Read it and weep.
Related
This question already has answers here:
Create variables with names from strings
(6 answers)
Closed 3 years ago.
I've been getting this Subscripted assignment dimension mismatch error in matlab when trying to transpose a vector inside a for loop. I've checked other questions and solutions to no avail and any input would be greatly appreciated.
id = spikes.labels(:,1);
cl = id(spikes.labels(:,2) == 2);
for i = 1:length(cl);
ii = cl(i);
indexSpike = find(spikes.assigns == ii);
Unit = spikes.unwrapped_times(indexSpike);
strcat('Unit', num2str(ii)) = Unit';
save (strcat('Unit', num2str(ii), '.mat'), strcat('Unit', num2str(ii)));
end
In the second to last line inside the loop I need to transpose the vector called Unit and name it according to ii.
This is where I get the error.
You can make a structure array for this problem. Structure will have two properties name and value. Assign strcat('Unit', num2str(ii)) to name and Unit' to value
units(ii).name = strcat('Unit', num2str(ii));
units(ii).value = Unit';
save (strcat('Unit', num2str(ii), '.mat'), Unit');
This question already has answers here:
How to declare variables immune to clear all?
(3 answers)
Closed 7 years ago.
Often when running long memory expensive programs I want to clear everything but some specific variables. If one wants to delete just some variables clear varA varB can be used, but what about deleting all but this specific variables?
As mentioned above, clearvars includes a syntax for keeping variables in the workspace while clearing the remainder:
a = 1; b = 1; c = 1; d = 1;
keepvars = {'c', 'd'};
clearvars('-except', keepvars{:});
Which functions as expected.
Like clear, it can also accommodate regexp matching:
a1 = 1; a2 = 1; b = 1; c = 1;
keepvars = 'a\d'; % regex pattern
clearvars('-except', '-regexp', keepvars);
Which retains a1 and a2, as expected.
Make use of the fact that both who and whos have return values that can be stored in variables. The former returns a cell array of strings, the latter a struct array. For what you need, the former will suffice:
%// don't delete these '
keepvars = {'varA','varB'};
%// delete these
delvars = setdiff(who,keepvars);
clear(delvars{:},'delvars');
I am currently in the debugging process, and I found that this is happening, ruining everything. For reference, f = #(x)ax^3+bx^2+c*x+d (where in this specific case, a = 2, b = -7, c = -8, d = 16).
Also, I notice that temp == -1.6861 returns false..
This is a typical floating-point problem. Your number is NOT -1.6861, but something close to it. Try format long and then looking at temp. Or even better, try sprintf('%25.20f',temp). temp is the root of your function f as it should be, just not exactly -1.6861.
You actually have to be really careful with this:
(1/3-7/3/7)==0
is false, since
>> (1/3-7/3/7)
ans =
-5.5511e-17
This question already has answers here:
ternary operator in matlab
(12 answers)
Closed 8 years ago.
Is there a one-liner in MATLAB for this?
if a > b
foo = 'r';
else
foo = 'g';
end
There is no syntactic sugar for one-line if-statements in MatLab, but if your statement is really simple you could write it in one line.
I used to have one-line if-statements like that in my old project:
if (k < 1); k = 1; end;
In your case it'll look something like:
if a > b; foo = 'r'; else; foo = 'g'; end;
or, if you don't like semicolons
if a > b, foo = 'r'; else, foo = 'g'; end
Not as pretty as you may have expected, though.
Not as elegant as a C style ternary operator but you can take advantage of the fact that matlab will automatically cast logicals into doubles in this situation. So you can just multiply your desired result for true (r in this case) by your condition (a > b), and add that to the product of your desired result for false (i.e. g) with the not of your condition:
foo = (a > b)*c + (~(a > b))*d
so if we let c = 'r' and d = 'g' then all we need to do is cast foo back to a char at the end:
char(foo)
or
char((a > b)*'r' + ~(a > b)*'g')
Note that this will only work if c and d have the same dimensions (because of the +)...
Try to avoid using if statements in matlab, and just convert your logic to (vector) math:
foo = 1 + (a <= b)
Edit:
For the more general case, of assigning 'r' or 'g', you can use:
col = {'r', 'g'};
foo = col(1 + (a > b));
So for example with an isGreen boolean you could do:
foo = col(1 + isGreen);
This could also be a boolean returning function
foo = col(1 + isGreen(a))
I have a legacy code doing math calculations. It is reportedly written in QBasic, and runs under VB6 successfully. I plan to write the code into a newer language/platform. For which I must first work backwards and come up with a detailed algorithm from existing code.
The problem is I can't understand syntax of few lines:
Dim a(1 to 200) as Double
Dim b as Double
Dim f(1 to 200) as Double
Dim g(1 to 200) as Double
For i = 1 to N
a(i) = b: a(i+N) = c
f(i) = 1#: g(i) = 0#
f(i+N) = 0#: g(i+N) = 1#
Next i
Based on my work with VB5 like 9 years ago, I am guessing that a, f and g are Double arrays indexed from 1 to 200. However, I am completely lost about this use of # and : together inside the body of the for-loop.
: is the line continuation character, it allows you to chain multiple statements on the same line. a(i) = b: a(i+N) = c is equivalent to:
a(i)=b
a(i+N)=c
# is a type specifier. It specifies that the number it follows should be treated as a double.
I haven't programmed in QBasic for a while but I did extensively in highschool. The # symbol indicates a particular data type. It is to designate the RHS value as a floating point number with double precision (similar to saying 1.0f in C to make 1.0 a single-precision float). The colon symbol is similar to the semicolon in C, as well, where it delimits different commands. For instance:
a(i) = b: a(i+N) = c
is, in C:
a[i] = b; a[i+N] = c;