I am trying to perform a modulo operation in MATLAB, and I'm not sure how to convert the input variable to the correct data type for the modulo operation to complete.
Here is what I have:
sequence = 0;
....
sequence = sequence + 1;
if (modp(sequence, 3) == 0)
....
In C-ish, I'm looking to perform if (sequence % 3 == 0).
MATLAB complains that there is no modp operation for a double, and that I must use an int. However, the documentation doesn't say which integer format I need to use (i.e., int8, int64, et cetera) and none of those integer formats work.
What am I doing wrong?
Did you realize you are using a function of the "symbolic toolbox"? I don't see any advantage in this case thus simply use mod(a,b) from Matlab (there is also a fixed point mod(a,b) and symbolic mod(a,b), don't confuse them)
http://www.mathworks.de/de/help/matlab/ref/mod.html
Related
I am well aware that one is able to assign a value to an array or constant in Swift and have those value represented in different formats.
For Integer: One can declare in the formats of decimal, binary, octal or hexadecimal.
For Float or Double: One can declare in the formats of either decimal or hexadecimal and able to make use of the exponent too.
For instance:
var decInt = 17
var binInt = 0b10001
var octInt = 0o21
var hexInt = 0x11
All of the above variables gives the same result which is 17.
But what's the catch? Why bother using those other than decimal?
There are some notations that can be way easier to understand for people even if the result in the end is the same. You can for example think in cases like colour notation (hexadecimal) or file permission notation (octal).
Code is best written in the most meaningful way.
Using the number format that best matches the domain of your program, is just one example. You don't want to obscure domain specific details and want to minimize the mental effort for the reader of your code.
Two other examples:
Do not simplify calculations. For example: To convert a scaled integer value in 1/10000 arc minutes to a floating point in degrees, do not write the conversion factor as 600000.0, but instead write 10000.0 * 60.0.
Chose a code structure that matches the nature of your data. For example: If you have a function with two return values, determine if it's a symmetrical or asymmetrical situation. For a symmetrical situation always write a full if (condition) { return A; } else { return B; }. It's a common mistake to write if (condition) { return A; } return B; (simply because 'it works').
Meaning matters!
I'm trying to print scalar as it would look like if it was int32. That is, if I have 2532063508, if I write it in 4 bytes and read as int32, I would read -1762903788.
using int32 function in Matlab didn't work, because the way it works is, values outside the range [-2^31,2^31-1] map to the nearest endpoint.
So I tried to use typecast:
typecast(uint32(2532063508), 'int32')
works perfectly, but if I write e.g. -1 there, uint32() returns 0 so it fails.
P.S. I want it to work for signed integers as input as well, that is, for -1 it should return -1
any suggestions?
You can do calculations in int64 then convert to uint32:
f = #(x)typecast(uint32(mod(int64(x),int64(2)^32)),'int32');
Or
function y = f(x)
y = typecast(uint32(mod(int64(x),int64(2)^32)),'int32');
end
So f([-1, 2532063508]) returns [-1, -1762903788].
I'm creating a program to simulate a random walk and it requires the user to input an integer number of steps to take for the walk.
The prompt for this uses code very similar to this:
**% Ask user for a number.
defaultValue = 45;
titleBar = 'Enter a value';
userPrompt = 'Enter the integer';
caUserInput = inputdlg(userPrompt, titleBar, 1,{num2str(defaultValue)});
if isempty(caUserInput),return,end; % Bail out if they clicked Cancel.
% Round to nearest integer in case they entered a floating point number.
integerValue = round(str2double(cell2mat(caUserInput)));
% Check for a valid integer.
if isnan(integerValue)
% They didn't enter a number.
% They clicked Cancel, or entered a character, symbols, or something else not allowed.
integerValue = defaultValue;
message = sprintf('I said it had to be an integer.\nI will use %d and continue.', integerValue);
uiwait(warndlg(message));
end**
However, I want it to simply display the "Enter a value" prompt again if the user does not enter an integer the first time i.e. 4.4.
Any ideas?
Thanks!
if (mod(integerValue,1) == 0)
will evaluate to true if integerValue is an integer. Simply augment your if statement w/ this logic. You might want to consider changing to using a while loop so the user can enter bad input more than once.
The first answer is totally correct for checking for an integer value, but to address the "show prompt again" issue you can just use a loop conditioning it to get the exact kind of data you want:
caUserInput = nan; %or anything worng for that matter
while isempty(caUserInput) || isnan(caUserInput)
caUserInput = inputdlg(userPrompt, titleBar, 1,{num2str(defaultValue)});
end
if you want you can start it again with different argument lines in a more fancy style:
inputiswrong = 1; %or anything worng for that matter
while inputiswrong
inputiswrong = 0;
caUserInput = inputdlg(userPrompt, titleBar, 1,{num2str(defaultValue)});
if isempty(caUserInput )
userPrompt = 'Try again with an input';
inputiswrong = 1;
end
if isnan(caUserInput )
userPrompt = 'not really a number';
inputiswrong = 1;
end
%and so on
end
In both scenarios you should consider transforming the caUserInput to something you could use, i think inputdlg returns a cell so maybe a cell2mat() around the inputdlg().
Remember that unspecified inputs in MATLAB are double-precision by default. For instance a=3 is not an integer. So you should consider two cases:
Integer type
If you are talking about integer type in MATLAB the easiest way is to use isinteger function by MATLAB:
tf = isinteger(A)
for instance:
isinteger(4.4)
=
0
as I mentioned before, 3 is not an integer:
isinteger(3)
=
0
but this one is integer actually:
isinteger(uint8(3))
=
1
To repeat the input query also easily use the same function in a while loop
while ~isinteger(a)
disp('enter an integer');
....
end
Constant double-precision with no decimal
But if you are considering normal constant inputs to be integers you could convert them to integer and compare the result with the original value:
while a ~= double(int64(a))
disp('enter an integer');
....
end
int64 converts the double type to integer, and double converts it back to double. If in this process the number remains unchanged, then you could consider that it was intended to be an integer.
Recommendation for you specific program
I would use a fix function to get rid of the decimal parts. Usually when you receive a double-precision number including decimal values, the main intention is the the number before the floating point. So in many algorithms it is common practice to use fix to round each element of the given number to the nearest integer toward zero.
I am intentionally casting an array of boolean values to integers but I get this warning:
Warning: Extension: Conversion from LOGICAL(4) to INTEGER(4) at (1)
which I don't want. Can I either
(1) Turn off that warning in the Makefile?
or (more favorably)
(2) Explicitly make this cast in the code so that the compiler doesn't need to worry?
The code will looking something like this:
A = (B.eq.0)
where A and B are both size (n,1) integer arrays. B will be filled with integers ranging from 0 to 3. I need to use this type of command again later with something like A = (B.eq.1) and I need A to be an integer array where it is 1 if and only if B is the requested integer, otherwise it should be 0. These should act as boolean values (1 for .true., 0 for .false.), but I am going to be using them in matrix operations and summations where they will be converted to floating point values (when necessary) for division, so logical values are not optimal in this circumstance.
Specifically, I am looking for the fastest, most vectorized version of this command. It is easy to write a wrapper for testing elements, but I want this to be a vectorized operation for efficiency.
I am currently compiling with gfortran, but would like whatever methods are used to also work in ifort as I will be compiling with intel compilers down the road.
update:
Both merge and where work perfectly for the example in question. I will look into performance metrics on these and select the best for vectorization. I am also interested in how this will work with matrices, not just arrays, but that was not my original question so I will post a new one unless someone wants to expand their answer to how this might be adapted for matrices.
I have not found a compiler option to solve (1).
However, the type conversion is pretty simple. The documentation for gfortran specifies that .true. is mapped to 1, and false to 0.
Note that the conversion is not specified by the standard, and different values could be used by other compilers. Specifically, you should not depend on the exact values.
A simple merge will do the trick for scalars and arrays:
program test
integer :: int_sca, int_vec(3)
logical :: log_sca, log_vec(3)
log_sca = .true.
log_vec = [ .true., .false., .true. ]
int_sca = merge( 1, 0, log_sca )
int_vec = merge( 1, 0, log_vec )
print *, int_sca
print *, int_vec
end program
To address your updated question, this is trivial to do with merge:
A = merge(1, 0, B == 0)
This can be performed on scalars and arrays of arbitrary dimensions. For the latter, this can easily be vectorized be the compiler. You should consult the manual of your compiler for that, though.
The where statement in Casey's answer can be extended in the same way.
Since you convert them to floats later on, why not assign them as floats right away? Assuming that A is real, this could look like:
A = merge(1., 0., B == 0)
Another method to compliment #AlexanderVogt is to use the where construct.
program test
implicit none
integer :: int_vec(5)
logical :: log_vec(5)
log_vec = [ .true., .true., .false., .true., .false. ]
where (log_vec)
int_vec = 1
elsewhere
int_vec = 0
end where
print *, log_vec
print *, int_vec
end program test
This will assign 1 to the elements of int_vec that correspond to true elements of log_vec and 0 to the others.
The where construct will work for any rank array.
For this particular example you could avoid the logical all together:
A=1-(3-B)/3
Of course not so good for readability, but it might be ok performance-wise.
Edit, running performance tests this is 2-3 x faster than the where construct, and of course absolutely standards conforming. In fact you can throw in an absolute value and generalize as:
integer,parameter :: h=huge(1)
A=1-(h-abs(B))/h
and still beat the where loop.
I have the number: a = 3.860575156847749e+003; and I would show it in a normal manner. So I write b = sprintf('%0.1f' a);. If I print b I will get: 3860.6. This is perfect. Matter of fact, while a is a double type, b has been converted in char.
What can I do to proper format that number and still have a number as final result?
Best regards
Well, you have to distinguish between both the numerical value (the number stored in your computer's memory) and its decimal representation (the string/char array you see on your screen). You can't really impose a format on a number: a number has a value which can be represented as a string in different ways (e.g. 1234 = 1.234e3 = 12.34e2 = 0.1234e4 = ...).
If you want to store a number with less precision, you can use round, floor, ceil to calculate a number which has less precision than the original number.
E.g. if you have a = 3.860575156847749e+003 and you want a number that only has 5 significant digits, you can do so by using round:
a = 3.860575156847749e+003;
p = 0.1; % absolute precision you want
b = p .* round(a./p)
This will yield a variable b = 3.8606e3 which can be represented in different ways, but should contain zeros (in practice: very small values are sometimes unavoidable) after the fifth digit. I think that is what you actually want, but remember that for a computer this number is equal to 3.86060000 as well (it is just another string representation of the same value), so I want to stress again that the decimal representation is not set by rounding the number but by (implicitly) calling a function that converts the double to a string, which happens either by sprintf, disp or possibly some other functions.
Result of sprintf y a text variable. have you tried to declare a variable as integer (for example) and use this as return value for sprintf instruction?
This can be useful to you: http://blogs.mathworks.com/loren/2006/12/27/displaying-numbers-in-matlab/