I am stuck on this chunk of code
hdiag = zeros(Float64,2)
hdiag = [0,0]
println(hdiag)
hdiag[1] = randn()
In the last line I obtain an InexactError.
It is strange because randn() it's a Float64, but for some reason I have to do hdiag=randn(2) and then there should not be a problem.
The line:
hdiag = [0,0]
changes hdiag to refer to a completely new and different array than what it was before. In this case, that new array is an integer array, and so any subsequent assignments into it need to be convertible to integers.
Indexed assignment is different; it changes the contents of the existing array. So you can use hdiag[:] = [0,0] and it will change the contents, converting the integers to floats as it does so. This gets even easier in version 0.5, where you can use the new .= dot assignment syntax to assign into an existing array:
hdiag .= [0,0]
will do what you want. For more details on arrays, bindings, and assignment, I recommend reading this blog post: Values vs. Bindings: The Map is Not the Territory.
Related
I have a directory on my computer with several .fits files that I am trying to work with in IDL. For some reason I am unable to add all of the arrays together correctly, as I'm getting negative numbers in the totaled array when all of the individual elements in all files are positive.
In IDL, I tried the following code:
flatsfiles = file_search(Vflats, filter)
addedflats = make_array(1530,1020,value=0)
FOREACH element, flatsfiles DO BEGIN
flatsarray = readfits(element)
addedflats = [addedflats + flatsarray]
ENDFOREACH
Pretty simple code, yet the values in addedflats are negative, while all the arrays have ONLY positive elements on the order of 10^4. Can anyone see where I'm going wrong, or have a different way of doing this?
I've also tried adding the arrays one by one to see where it goes wrong:
array = readfits(flatsfiles[0])
addedflats = [addedflats + array]
array2 = readfits(flatsfiles[1])
addedflats = [addedflats + array2]
Here, the first addedflats array shows the same thing as array, which is expected since it's just being added to an array of 0's. The second addedflats, however, gives negative numbers again. For reference, the first element of array is 25189, the first element of array2 is 24030, but the first element of addedflats is -16317 rather than the expected 49219. TIA!!
Be careful of integer types that might not be able to hold the sum. Your example is probably 16-bit signed integers (the default integers in IDL):
IDL> print, 25189 + 24030
-16317
To fix, declare at least one of the arrays that you are adding to be an integer type that is big enough to hold there result. Here, 32-bit longs are sufficient (just doing scalars for simplicity, but the same works for arrays):
IDL> print, 25189L + 24030L
49219
I am a beginner at Octave, that is why I will share something too obvious for the most.
cell_arr = cell(2,2,2);
cell_arr(2,2,2) = cell(2,2,2);
error: =: nonconformant arguments (op1 is 2x2x2, op2 is 2x2x2)
I am assigning an array of the same dimensionality as the cell_array, and it is not accepted. What should I change?
This is a spin-off from Please Explain Octave-Error : operator /: nonconformant arguments (op1 is 1x1, op2 is 1x10) and Error: nonconformant arguments (op1 is 1x3, op2 is 1x2) which both do not deal with cell arrays.
It's not clear what you're trying to do, but your understanding of cells seems to be a bit confused.
To make matters worse, I think you are coming across a bug: https://savannah.gnu.org/bugs/?func=detailitem&item_id=59637
I don't want to get too technical and confuse you even more, but what is happening here is this. We usually introduce cell arrays by saying this little story:
"There are two kinds of arrays: normal arrays, and cell arrays. Normal arrays always need to be 'rectangular', and contain elements of the same type. Cell arrays on the other hand, can contain elements of different types."
However, this isn't exactly true. It's a simplification. In reality, a 'cell' is simply a special kind of object; a container if you like. And a cell array then, is simply a normal array, whose elements are all 'cell objects'. In fact, the cell command is simply a shortcut way for creating an array of empty cells, nothing more.
More generally, cell arrays are indexed using {}, which opens up the cell object, and gives you its contents.
However, since they can also be thought of as normal arrays of 'cell objects', you can also index it with () like a normal array, and return the 'cell object' itself (as opposed to its contents).
E.g.
a = cell(1,2) # this is equivalent to a = { [], [] }
a{1} # returns an empty numerical array, which is what the first cell contains.
a(1) # returns a cell object, which happens to contain an empty numerical array.
Regarding the bug you're coming across, octave seems to report the wrong size for the elements you're trying to access when it comes to multidimensional cell arrays. This has been reported. What you should have been getting was something like
Error: op1 is 1x1, op2 is 2x2x2
In other words: "you are trying to cram a 2x2x2 array (whose elements happen to be cell objects) into a space that only fits a single element (i.e. at position 2,2,2)."
The reason for the error is that a new cell array can only be assigned to an existing cell array if the dimensions are exactly the same.
cell_arr = cell(2,2,2);
x = cell(2,2,2);
cell_arr(2,2,2) = x;
The last line causes an error, since cell_arr(2,2,2) chooses just the second item of each dimension, and not the 2 items of each dimension. Instead, only the initialisation of cell(2,2,2) builds a cell array of 2 items for each dimension.
It is thus important on which side you are, and whether you initiate or re-use a cell array.
The following works:
cell_arr(:,:,:) = x;
cell_arr(1:2,1:2,1:2) = x;
cell_arr(1:end,1:end,1:end) = x;
cell_arr(:,:,:) = x(1:2,1:2,1:2);
cell_arr(:,:,:) = x(:,:,:);
cell_arr(:,:,:) = x(1:end,1:end,1:end);
Of course, a directly initiated cell array can also be assigned:
cell_arr(:,:,:) = cell(1:2,1:2,1:2);
and this does not work with "end", since it does not exist till then:
cell_arr(1:end,1:end,1:end) = cell(1:end,1:end,1:end);
error: invalid use of 'end': may only be used to index existing value
Thus the solution is as follows, if you want to assign something to cell_arr(2,2,2):
Right: Two cell arrays of 2x2x2 are created.
cell_arr = cell(2,2,2);
x = cell(2,2,2);
And then:
Left: Only the 2nd item of each dim is chosen = 1x1. Right: Thus, only one item can be chosen per dim, for example the first item as follows:
cell_arr(2,2,2) = x(1,1,1);
I have an array representing image metadata that I want to clear out. Currently, I use the empty!() function but it is throwing an error because I think it needs to be a dictionary and I have an array so I am looking for an alternate way to clear the Array.
For reference, here is the type I am working with:
Array{ImageMetadata.ImageMeta{ColorTypes.Gray{FixedPointNumbers.Normed{UInt8,8}},2,Array{ColorTypes.Gray{FixedPointNumbers.Normed{UInt8,8}},2},P} where P<:AbstractDict{Symbol,Any},1}
empty! shouldn't be throwing an error:
julia> x = rand(10);
julia> empty!(x)
0-element Array{Float64,1}
Would be useful to know what error you're actually seeing.
I am not sure what you mean by "clear", but in general you can use fill! to fill the array with a value of your choice.
However, if your question is to make an array filled with some values to be set to have #undef in its entries (if its eltype allows for it), then I do not know of a method to make this. You can use similar to create a new array that will have the same shape and be uninitialized.
I am trying to read a .tif-file in julia as a Floating Point Array. With the FileIO & ImageMagick-Package I am able to do this, but the Array that I get is of the Type Array{ColorTypes.Gray{FixedPointNumbers.Normed{UInt8,8}},2}.
I can convert this FixedPoint-Array to Float32-Array by multiplying it with 255 (because UInt8), but I am looking for a function to do this for any type of FixedPointNumber (i.e. reinterpret() or convert()).
using FileIO
# Load the tif
obj = load("test.tif");
typeof(obj)
# Convert to Float32-Array
objNew = real.(obj) .* 255
typeof(objNew)
The output is
julia> using FileIO
julia> obj = load("test.tif");
julia> typeof(obj)
Array{ColorTypes.Gray{FixedPointNumbers.Normed{UInt8,8}},2}
julia> objNew = real.(obj) .* 255;
julia> typeof(objNew)
Array{Float32,2}
I have been looking in the docs quite a while and have not found the function with which to convert a given FixedPoint-Array to a FloatingPont-Array without multiplying it with the maximum value of the Integer type.
Thanks for any help.
edit:
I made a small gist to see if the solution by Michael works, and it does. Thanks!
Note:I don't know why, but the real.(obj) .* 255-code does not work (see the gist).
Why not just Float32.()?
using ColorTypes
a = Gray.(convert.(Normed{UInt8,8}, rand(5,6)));
typeof(a)
#Array{ColorTypes.Gray{FixedPointNumbers.Normed{UInt8,8}},2}
Float32.(a)
The short answer is indeed the one given by Michael, just use Float32.(a) (for grayscale). Another alternative is channelview(a), which generally performs channel separation thus also stripping the color information from the array. In the latter case you won't get a Float32 array, because your image is stored with 8 bits per pixel, instead you'll get an N0f8 (= FixedPointNumbers.Normed{UInt8,8}). You can read about those numbers here.
Your instinct to multiply by 255 is natural, given how other image-processing frameworks work, but Julia has made some effort to be consistent about "meaning" in ways that are worth taking a moment to think about. For example, in another programming language just changing the numerical precision of an array:
img = uint8(255*rand(10, 10, 3)); % an 8-bit per color channel image
figure; image(img)
imgd = double(img); % convert to double-precision, but don't change the values
figure; image(imgd)
produces the following surprising result:
That second "all white" image represents saturation. In this other language, "5" means two completely different things depending on whether it's stored in memory as a UInt8 vs a Float64. I think it's fair to say that under any normal circumstances, a user of a numerical library would call this a bug, and a very serious one at that, yet somehow many of us have grown to accept this in the context of image processing.
These new types arise because in Julia we've gone to the effort to implement new numerical types (FixedPointNumbers) that act like fractional values (e.g., between 0 and 1) but are stored internally with the same bit pattern as the "corresponding" UInt8 (the one you get by multiplying by 255). This allows us to work with 8-bit data and yet allow values to always be interpreted on a consistent scale (0.0=black, 1.0=white).
I am using this piece of code and a stackoverflow will be triggered, if I use Extlib's Hashtbl the error does not occur. Any hints to use specialized Hashtbl without stackoverflow?
module ColorIdxHash = Hashtbl.Make(
struct
type t = Img_types.rgb_t
let equal = (==)
let hash = Hashtbl.hash
end
)
(* .. *)
let (ctable: int ColorIdxHash.t) = ColorIdxHash.create 256 in
for x = 0 to width -1 do
for y = 0 to height -1 do
let c = Img.get img x y in
let rgb = Color.rgb_of_color c in
if not (ColorIdxHash.mem ctable rgb) then ColorIdxHash.add ctable rgb (ColorIdxHash.length ctable)
done
done;
(* .. *)
The backtrace points to hashtbl.ml:
Fatal error: exception Stack_overflow Raised at file "hashtbl.ml",
line 54, characters 16-40 Called from file "img/write_bmp.ml", line
150, characters 52-108 ...
Any hints?
Well, you're using physical equality (==) to compare the colors in your hash table. If the colors are structured values (I can't tell from this code), none of them will be physically equal to each other. If all the colors are distinct objects, they will all go into the table, which could really be quite a large number of objects. On the other hand, the hash function is going to be based on the actual color R,G,B values, so there may well be a large number of duplicates. This will mean that your hash buckets will have very long chains. Perhaps some internal function isn't tail recursive, and so is overflowing the stack.
Normally the length of the longest chain will be 2 or 3, so it wouldn't be surprising that this error doesn't come up often.
Looking at my copy of hashtbl.ml (OCaml 3.12.1), I don't see anything non-tail-recursive on line 54. So my guess might be wrong. On line 54 a new internal array is allocated for the hash table. So another idea is just that your hashtable is just getting too big (perhaps due to the unwanted duplicates).
One thing to try is to use structural equality (=) and see if the problem goes away.
One reason you may have non-termination or stack overflows is if your type contains cyclic values. (==) will terminates on cyclic values (while (=) may not), but Hash.hash is probably not cycle-safe. So if you manipulate cyclic values of type Img_types.rgb_t, you have to devise your one cycle-safe hash function -- typically, calling Hash.hash on only one of the non-cyclic subfields/subcomponents of your values.
I've already been bitten by precisely this issue in the past. Not a fun bug to track down.