How to set Nodata value into zero - function

I have a question. How can I set null value into 0 on an image. Is there any way to do this in matlab. The image type is float-point, 32 bit, tif format. Null value (Nodata) of this image is -3.4028234663e+038. So the number is out of range of float-point. So I wanna replace those values with 0.

Generally speaking, you can find all the elements to replace by:
idx = (I == x); % # x is the "null" value
where I is your image and x is the desired value to replace (in your case, that is the "null" value). However, a more practical syntax would be using a certain threshold value instead of the exact value:
idx = (I > y); % # y is a value much lower than x
Now idx holds the logical indices of the elements you want to zero out. After you obtain idx, just do:
I(idx) = 0;
P.S
In practice, you can do achieve the same result without creating a temporary variable idx, like so:
I(I > y) = 0;

Related

Out of range value for column in MySQL float column

I have a MySQL database with a table containing many columns declared as float type, e.g.TgPhi_L1_Min FLOAT DEFAULT NULL,. The table is filled by a program written in C++Builder 10.3 using FireDAC (TFDQuery) that collects data from a measuring device. The code responsible for that looks like this:
FDQuery_InsertData->Open("SELECT * FROM {id measurements_general} WHERE 1=2");
FDQuery_InsertData->Insert();
FDQuery_InsertData->FieldByName("meter_id")->AsInteger = MeterId;
FDQuery_InsertData->FieldByName("cfg_id")->AsInteger = ConfigId;
FDQuery_InsertData->FieldByName("date_time")->AsDateTime = DateTime;
FDQuery_InsertData->FieldByName("insert_date_time")->AsDateTime = Now();
for (auto i = 0; i < DescriptorsGeneral.List->Count; i++)
{
if (IsNan(Data[DescriptorsGeneral.Indexes[i]]) || IsInfinite(Data[DescriptorsGeneral.Indexes[i]]))
continue;
FDQuery_InsertData->FieldByName(DescriptorsGeneral.List->Strings[i])->AsSingle = Data[DescriptorsGeneral.Indexes[i]]; //Data is passed as a parameter to this function, float *Data;
}
FDQuery_InsertData->Post();
Everything goes fine, until someday a measuring device sent a value which is the maximum float value of 0x7F7FFFFF. It shouldn't be a problem, but I got an exception
First chance exception at $772A3642. Exception class EMySQLNativeException with message '[FireDAC][Phys][MySQL] Out of range value for column 'TgPhi_L1_Min' at row 1'. Process Meter_Server.exe (12796).
Trying to understand what happened, I turned on FireDAC's monitor, and it turns out that the value inserted into the INSERT statement indeed exceeds the float range i.e. 3.4028235E38. What I find more surprising is that numbers passed to the INSERT statement differ in precision, although all are declared the same way (MySQL float, FireDAC single), eg 0.98364758, 0, 3.4028235E38, -3.4028235E38, 0, 3.4028235E38, -3.4028235E38, 29.885546.
The parameters of fetching columns by TFDQuery are: Col add [Index=86, SrcName="TgPhi_L1", SrcType=Single, SrcSize=0, SrcPrec=12, SrcScale=31, Type=Single, Size=0, Prec=12, Scale=31].
I tried with FormatOptions: CheckPrecision and Round2Scale, I added my own mapping rules setting ScaleMin and PrecMin, but none of it affected values in the INSERT statement sent to the database by FireDAC.
Can anyone help me solve this problem? what I am doing wrong?
EDITED:
I'm confused, of course when I prepare a proper string manually, as #GarrGodfrey suggested, it works, but it doesn't work with TFDQuery in the way I did it. TFDQuery knows that the field is the single type, and finally always converts and rounds the values to single precision. The problem is, the single type fields have a Precision property set to 7, which complies with the float standard. But in MySQL I'm not sure, this is where I'm lost.
In C++, the following two numbers are treated as equal:
float x = 3.4028235E38;
float y = 3.402823466385288E38;
I think, this is because y has much more precision and is rounded. In MySQL, these are two different numbers: x is out of range and y is not, why?
CREATE PROCEDURE `test_float`()
begin
declare x float;
declare y float;
set x = 3.4028235E38;
set y = 3.402823466385288E38;
select x, y;
end

Prepping the number of inputs for a function in MATLAB

For example, ndgrid has inputs as n vectors where n is decided by the user.
For my use case, n can change. I would like to prepare the input list before hand, based on n, then feed the inputs to ndgrid. How do I do that please?
For example, say I have 3 row vectors x1, x2, and x3. Then, if n=3 and I put inputs = [x1,x2,x3], and I use ndgrid(inputs) then MATLAB treats this as ndgrid([x1,x2,x3]) instead of ndgrid(x1,x2,x3). I want the latter, not the former. How do I solve this please?
When we use a cell array, for example x = {some,stuff,inside} you can unpack the cell with x{:}, in a function call, each elements of the cell will be passed as an argument: myfunction(x{:}) is equivalent to myfunction(some, stuff, inside).
In your case:
% Number of inputs
k = 3;
% Put your k input in a cell array
x = {1:3,1:3,1:3};
% If needed you can also have a dynamic output variable
X = cell(k,1);
% Get the result
[X{:}] = ndgrid(x{:})

MATLAB return of vector function with IF statement

I am calling a self written function 'func' of a vector like this:
x_values=[0 1 2];
result=func(x_values);
The problem is that in this function i have an if statement to determine the ouput. If I apply this function to a scalar, I have no problem, but if I apply it to a vector of numbers, the if statement doesn't do his job. why? And how can i repair it?
function [y]=func(x)
if(x==0)
y=0
else
y=1./sin(x);
end
end
You need to treat the zero and non-zero entries separately. This is easily achieved via indexing:
function [y]=func(x)
xIsZero = x==0;
%# preassign y
y = x;
%# fill in values for y
y(xIsZero) = 0
y(~xIsZero) = 1./sin(x(~xIsZero))
The answer is explained in the help document of IF:
An evaluated expression is true when the result is nonempty and
contains all nonzero elements (logical or real numeric). Otherwise,
the expression is false.
Conclusion: either add a for loop, or find a better way to vectorize your expression
You want to assign only a subset of the vector. For example:
function [y]=func(x)
y=zeros(size(x));
mask = x ~= 0;
y(mask) = 1 ./ sin(x(mask));
end

How to write arbitrary datatypes into Matlab cell array

This is a general question, not related to a particular operation. I would like to be able to write the results of an arbitrary function into elements of a cell array without regard for the data type the function returns. Consider this pseudocode:
zout = cell(n,m);
myfunc = str2func('inputname'); %assume myfunc puts out m values to match zout dimensions
zout(1,:) = myfunc(x,y);
That will work for "inputname" == "strcat" , for example, given that x and y are strings or cells of strings with appropriate dimension. But if "inputname" == "strcmp" then the output is a logical array, and Matlab throws an error. I'd need to do
zout(1,:) = num2cell(strcmp(x,y));
So my question is: is there a way to fill the cell array zout without having to test for the type of variable generated by myfunc(x,y ? Should I be using a struct in the first place (and if so, what's the best way to populate it)?
(I'm usually an R user, where I could just use a list variable without any pain)
Edit: To simplify the overall scope, add the following "requirement" :
Let's assume for now that, for a function which returns multiple outputs, only the first one need be captured in zout . But when this output is a vector of N values or a vector of cells (i.e. Nx1 cell array), these N values get mapped to zout(1,1:N) .
So my question is: is there a way to fill the cell array zout without having to test for the type of variable generated by myfunc(x,y) ? Should I be using a struct in the first place (and if so, what's the best way to populate it)?
The answer provided by #NotBoStyf is almost there, but not quite. Cell arrays are the right way to go. However, the answer very much depends on the number of outputs from the function.
Functions with only one output
The function strcmp has only one output, which is an array. The reason that
zout{1,:} = strcmp(x,y)
gives you an error message, when zout is dimensioned N x 2, is that the left-hand side (zout{1,:}) expects two outputs from the right-hand side. You can fix this with:
[zout{1,:}] = num2cell(strcmp(x,y)); % notice the square brackets on the LHS
However, there's really no reason to do this. You can simply define zout as an N x 1 cell array and capture the results:
zout = cell(1,1);
x = 'a';
y = { 'a', 'b' };
zout{1} = strcmp(x,y);
% Referring to the results:
x_is_y_1 = zout{1}(1);
x_is_y_2 = zout{1}(2);
There's one more case to consider...
Functions with multiple outputs
If your function produces multiple outputs (as opposed to a single output that is an array), then this will only capture the first output. Functions that produce multiple outputs are defined like this:
function [outA,outB] = do_something( a, b )
outA = a + 1;
outB = b + 2;
end
Here, you need to explicitly capture both output arguments. Otherwise, you just get a. For example:
outA = do_something( [1,2,3], [4,5,6] ); % outA is [2,3,4]
[outA,outB] = do_something( [1,2,3], [4,5,6] ); % outA is [2,3,4], outB is [6,7,8]
Z1 = cell(1,1);
Z1{1,1} = do_something( [1,2,3], [4,5,6] ); % Z1{1,1} is [2,3,4]
Z2 = cell(1,2);
Z2{1,1:2} = do_something( [1,2,3], [4,5,6] ); % Same error as above.
% NB: You really never want to have a cell expansion that is not surrounded
% by square brackets.
% Do this instead:
[Z2{1,1:2}] = do_something( [1,2,3], [4,5,6] ); % Z2{1,1} is [2,3,4], Z2{1,2} is [6,7,8]
This can also be done programmatically, with some limits. Let's say we're given function
func that takes one input and returns a constant (but unknown) number of outputs. We
have cell array inp that contains the inputs we want to process, and we want to collect the results in cell around outp:
N = numel(inp);
M = nargout(#func); % number of outputs produced by func
outp = cell(N,M);
for i=1:N
[ outp{i,:} ] = func( inp{i} );
end
This approach has a few caveats:
It captures all of the outputs. This is not always what you want.
Capturing all of the outputs can often change the behavior of the function. For example, the find function returns linear indices if only one output is used, row/column indices if two outputs are used, and row/column/value if three outputs are used.
It won't work for functions that have a variable number of outputs. These functions are defined as function [a,b,...,varargout] = func( ... ). nargout will return a negative number if the function has varargout declared in its output list, because there's no way for Matlab to know how many outputs will be produced.
Unpacking array and cell outputs into a cell
All true so far, but: what I am hoping for is a generic solution. I can't use num2cell if the function produces cell outputs. So what worked for strcmp will fail for strcat and vice versa. Let's assume for now that, for a function which returns multiple outputs, only the first one need be captured in zout – Carl Witthoft
To provide a uniform output syntax for all functions that return either a cell or an array, use an adapter function. Here is an example that handles numeric arrays and cells:
function [cellOut] = cellify(input)
if iscell(input)
cellOut = input;
elseif isnumeric(input)
cellOut = num2cell(input);
else
error('cellify currently does not support structs or objects');
end
end
To unpack the output into a 2-D cell array, the size of each output must be constant. Assuming M outputs:
N = numel(inp);
% M is known and constant
outp = cell(N,M);
for i=1:N
outp(i,:) = cellify( func( inp{i} ) ); % NB: parentheses instead of curlies on LHS
end
The output can then be addressed as outp{i,j}. An alternate approach allows the size of the output to vary:
N = numel(inp);
% M is not necessary here
outp = cell(N,1);
for i=1:N
outp{i} = cellify( func( inp{i} ) ); % NB: back to curlies on LHS
end
The output can then be addressed as outp{i}{j}, and the size of the output can vary.
A few things to keep in mind:
Matlab cells are basically inefficient pointers. The JIT compiler does not always optimize them as well as numeric arrays.
Splitting numeric arrays into cells can cost quite a bit of memory. Each split value is actually a numeric array, which has size and type information associated with it. In numeric array form, this occurs once for each array. When the array is split, this incurs once for each element.
Use curly braces instead when asigning a value.
Using
zout{1,:} = strcmp(x,y);
instead should work.

Most efficient way to search a sorted matrix?

I have an assignment to write an algorithm (not in any particular language, just pseudo-code) that receives a matrix [size: M x N] that is sorted in a way that all of it's rows are sorted and all of it's columns are sorted individually, and finds a certain value within this matrix. I need to write the most time-efficient algorithm I can think of.
The matrix looks something like:
1 3 5
4 6 8
7 9 10
My idea is to start at the first row and last column and simply check the value, if it's bigger go down and if it's smaller than go left and keep doing so until the value is found or until the indexes are out of bounds (in case the value does not exist). This algorithm works at linear complexity O(m+n). I've been told that it's possible to do so with a logarithmic complexity. Is it possible? and if so, how?
Your matrix looks like this:
a ..... b ..... c
. . . . .
. 1 . 2 .
. . . . .
d ..... e ..... f
. . . . .
. 3 . 4 .
. . . . .
g ..... h ..... i
and has following properties:
a,c,g < i
a,b,d < e
b,c,e < f
d,e,g < h
e,f,h < i
So value in lowest-rigth most corner (eg. i) is always the biggest in whole matrix
and this property is recursive if you divide matrix into 4 equal pieces.
So we could try to use binary search:
probe for value,
divide into pieces,
choose correct piece (somehow),
goto 1 with new piece.
Hence algorithm could look like this:
input: X - value to be searched
until found
divide matrix into 4 equal pieces
get e,f,h,i as shown on picture
if (e or f or h or i) equals X then
return found
if X < e then quarter := 1
if X < f then quarter := 2
if X < h then quarter := 3
if X < i then quarter := 4
if no quarter assigned then
return not_found
make smaller matrix from chosen quarter
This looks for me like a O(log n) where n is number of elements in matrix. It is kind of binary search but in two dimensions. I cannot prove it formally but resembles typical binary search.
and that's how the sample input looks? Sorted by diagonals? That's an interesting sort, to be sure.
Since the following row may have a value that's lower than any value on this row, you can't assume anything in particular about a given row of data.
I would (if asked to do this over a large input) read the matrix into a list-struct that took the data as one pair of a tuple, and the mxn coord as the part of the tuple, and then quicksort the matrix once, then find it by value.
Alternately, if the value of each individual location is unique, toss the MxN data into a dictionary keyed on the value, then jump to the dictionary entry of the MxN based on the key of the input (or the hash of the key of the input).
EDIT:
Notice that the answer I give above is valid if you're going to look through the matrix more than once. If you only need to parse it once, then this is as fast as you can do it:
for (int i = 0; i<M; i++)
for (int j=0; j<N; j++)
if (mat[i][j] == value) return tuple(i,j);
Apparently my comment on the question should go down here too :|
#sagar but that's not the example given by the professor. otherwise he had the fastest method above (check the end of the row first, then proceed) additionally, checking the end of the middlest row first would be faster, a bit of a binary search.
Checking the end of each row (and starting on the end of the middle row) to find a number higher than the checked for number on an in memory array would be fastest, then doing a binary search on each matching row till you find it.
in log M you can get a range of rows able to contain the target (binary search on the first value of rows, binary search on last value of rows, keep only those rows whose first <= target and last >= target) two binary searches is still O(log M)
then in O(log N) you can explore each of these rows, with again, a binary search!
that makes it O(logM x logN)
tadaaaa
public static boolean find(int a[][],int rows,int cols,int x){
int m=0;
int n=cols-1;
while(m<rows&&n>=0){
if(a[m][n]==x)
return1;
else if(a[m][n]>x)
n--;
else m++;
}
}
what about getting the diagonal out, then binary search over the diagonal, start bottom right check if it is above, if yes take the diagonal array position as the column it is in, if not then check if it is below. each time running a binary search on the column once you have a hit on the diagonal (using the array position of the diagonal as the column index). I think this is what was stated by #user942640
you could get the running time of the above and when required (at some point) swap the algo to do a binary search on the initial diagonal array (this is taking into consideration its n * n elements and getting x or y length is O(1) as x.length = y.length. even on a million * million binary search the diagonal if it is less then half step back up the diagonal, if it is not less then binary search back towards where you where (this is a slight change to the algo when doing a binary search along the diagonal). I think the diagonal is better than the binary search down the rows, Im just to tired at the moment to look at the maths :)
by the way I believe running time is slightly different to analysis which you would describe in terms of best/worst/avg case, and time against memory size etc. so the question would be better stated as in 'what is the best running time in worst case analysis', because in best case you could do a brute linear scan and the item could be in the first position and this would be a better 'running time' than binary search...
Here is a lower bound of n. Start with an unsorted array A of length n. Construct a new matrix M according to the following rule: the secondary diagonal contains the array A, everything above it is minus infinity, everything below it is plus infinity. The rows and columns are sorted, and looking for an entry in M is the same as looking for an entry in A.
This is in the vein of Michal's answer (from which I will steal the nice graphic).
Matrix:
min ..... b ..... c
. . .
. II . I .
. . .
d .... mid .... f
. . .
. III . IV .
. . .
g ..... h ..... max
Min and max are the smallest and largest values, respectively. "mid" is not necessarily the average/median/whatever value.
We know that the value at mid is >= all values in quadrant II, and <= all values in quadrant IV. We cannot make such claims for quadrants I and III. If we recurse, we can eliminate one quadrant at each level.
Thus, if the target value is less than mid, we must search quadrants I, II, and III. If the target value is greater than mid, we must search quadrants I, III, and IV.
The space reduces to 3/4 its previous at each step:
n * (3/4)x = 1
n = (4/3)x
x = log4/3(n)
Logarithms differ by a constant factor, so this is O(log(n)).
find(min, max, target)
if min is max
if target == min
return min
else
return not found
else if target < min or target > max
return not found
else
set mid to average of min and max
if target == mid
return mid
else
find(b, f, target), return if found
find(d, h, target), return if found
if target < mid
return find(min, mid, target)
else
return find(mid, max, target)
JavaScript solution:
//start from the top right corner
//if value = el, element is found
//if value < el, move to the next row, element can't be in that row since row is sorted
//if value > el, move to the previous column, element can't be in that column since column is sorted
function find(matrix, el) {
//some error checking
if (!matrix[0] || !matrix[0].length){
return false;
}
if (!el || isNaN(el)){
return false;
}
var row = 0; //first row
var col = matrix[0].length - 1; //last column
while (row < matrix.length && col >= 0) {
if (matrix[row][col] === el) { //element is found
return true;
} else if (matrix[row][col] < el) {
row++; //move to the next row
} else {
col--; //move to the previous column
}
}
return false;
}
this is wrong answer
I am really not sure if any of the answers are the optimal answers. I am going at it.
binary search first row, and first column and find out the row and column where "x" could be. you will get 0,j and i,0. x will be on i row or j column if x is not found in this step.
binary search on the row i and the column j you found in step 1.
I think the time complexity is 2* (log m + log n).
You can reduce the constant, if the input array is a square (n * n), by binary searching along the diagonal.