Calculation data from one array to another - arrays

I have two array, the first one is data_array(50,210), the second one is dest_array(210,210). The goal, using data from data_array to calculate the values of dest_array at specific indicies, without using for-loop.
I do it in such way:
function [ out ] = grid_point( row,col,cg_row,cg_col,data,kernel )
ker_len2 = floor(length(kernel)/2);
op1_vals = data((row - ker_len2:row + ker_len2),(col - ker_len2:col + ker_len2));
out(cg_row,cg_col) = sum(sum(op1_vals.*kernel)); %incorre
end
function [ out ] = sm(dg_X, dg_Y)
%dg_X, dg_Y - arrays of size 210x210, the values - coordinates of data in data_array,
%index of each element - position this data at 210x210 grid
data_array = randi(100,50,210); %data array
kernel = kernel_sinc2d(17,'hamming'); %sinc kernel for calculations
ker_len2 = floor(length(kernel)/2);
%adding the padding for array, to avoid
%the errors related to boundaries of data_array
data_array = vertcat(data_array(linspace(ker_len2+1,2,ker_len2),:),...
data_array,...
data_array(linspace(size(data_array,1)-1,size(data_array,1) - ker_len2,ker_len2),:));
data_array = horzcat(data_array(:,linspace(ker_len2+1,2,ker_len2)),...
data_array,...
data_array(:,linspace(size(data_array,2)-1,(size(data_array,2) - ker_len2,ker_len2)));
%cg_X, cg_Y - arrays of indicies for X and Y directions
[cg_X,cg_Y] = meshgrid(linspace(1,210,210),linspace(1,210,210));
%for each point at grid(210x210) formed by cg_X and cg_Y,
%we should calculate the value, using the data from data_array(210,210).
%after padding, data_array will have size (50 + ker_len2*2, 210 + ker_len2*2)
dest_array = arrayfun(#(y,x,cy,cx) grid_point(y, x, cy, cx, data_array, kernel),...
dg_Y, dg_X, cg_Y, cg_X);
end
But, it seems that arrayfun cannot resolve my problem, because I use arrays with different sizes. Have somebody the ideas of this?

I am not completely sure, but judging from the title, this may be what you want:
%Your data
data_array_small = rand(50,210)
data_array_large = zeros(210,210)
%Indicating the points of interest
idx = randperm(size(data_array_large,1));
idx = idx(1:size(data_array_small,1))
%Now actually use the information:
data_array_large(idx,:) = data_array_small

Related

MATLAB : how to solve coupled differential equations dependend on data stored in arrays

I want to solve a system of two ordinary differential equations in MATLAB.
The parameters of the ODEs depend on measured data stored in two arrays, F and T.
When I run the program, I always get the error shown below. I am sure it has something to do with the arrays, because when I use single numbers for F and T (e.g. F = 60; T = 30;) the program works fine.
Subscript indices must either be real positive integers or logicals.
Error in dynamics (line 46)
ddyn(1) = k1*F(t) + v_b(t) - k_1*dyn(1) - v_a(t);
Error in ode23 (line 256)
f(:,2) = feval(odeFcn,t+h*A(1),y+f*hB(:,1),odeArgs{:});
Error in main (line 33)
[t,sol] = ode23(#dynamics , (1:1:3000),[0 0]);
Here is the code I use for the main function and the ODE system:
Main function:
[t,sol] = ode45(#dynamics , (1:1:3000),[0 0]);
ODE system:
function [ddyn] = dynamics(t,dyn)
% constant numbers
k1 = 10^-2; k_1 = 8* 10^-3; k2 = 10^-2; k_2 = 4*10^-3;
V_max_a = 1.6; V_max_b = 3.5;
K_M_a = 1.5*10^-3; K_M_b = 2*10^-3;
K_a_F = 9.4*10^5; K_a_T = 3.9*10; K_b_F = 1.3*10^4; K_b_T = 1.2*10^-10;
r_a_F = 4.3*10^7; r_a_T = 4.2*10^9; r_b_F = 6.9*10^-7; r_b_T = 6.2*10^-9;
%arrays with data e.g.
F = 1:3000;
T = 1:3000;
% program works if I use numbers, e.g.:
%F = 60; T = 30;
ddyn = zeros(2,1);
R_a_F = (K_a_F + r_a_F* F)/(K_a_F + r_a_F);
R_a_T = (K_a_T + r_a_T* T)/(K_a_T + r_a_T);
R_b_F = (K_b_F + r_b_F* F)/(K_b_F + r_b_F);
R_b_T = (K_b_T + r_b_T* T)/(K_b_T + r_b_T);
v_a = (V_max_a*dyn(1))/(K_M_a + dyn(1))*R_a_F .*R_a_T;
v_b = (V_max_b*dyn(2))/(K_M_b + dyn(2))*R_b_F .*R_b_T;
ddyn(1) = k1*F(t) + v_b(t) - k_1*dyn(1) - v_a(t);
ddyn(2) = k2*T(t) + v_a(t) - k_2*dyn(2) - v_b(t);
All of the functions in the Matlab ODE suite, including ode45, assume t to be continuous and use a dynamic time-step to achieve a certain level of accuracy.1 As such, you cannot assume t to be an integer and should never be used as an index as you are doing with F(t). To quote from the documentation:
If tspan contains more than two elements [t0,t1,t2,...,tf], then the solver returns the solution evaluated at the given points. This does not affect the internal steps that the solver uses to traverse from tspan(1) to tspan(end). Thus, the solver does not necessarily step precisely to each point specified in tspan.
Therefore, assuming F and T are continuous functions in time, I'd recommend making a function that performs interpolation in time, more than likely via interp1, and pass that function to your ODE function through parametrization. For example:
tspan = 1:3000;
Ffun = #(t) interp1(tspan,F,t); % Default is linear
[t,sol] = ode45(#(t,dyn) dynamics(t,dyn,Ffun) , tspan , [0 0]);
That's just an example but should, hopefully, be serviceable.
1 In particular, ode45 uses the Dormand-Prince (4,5) Runkge-Kutta pair for its time integration; in short, the function compares a fourth order and fifth order solution to decide if the result from the current time-step is good enough or if it should be reduced.

Sort array elements by the frequency of its elements

Is it possible in matlab/octave to use the sort function to sort an array based on the relative frequency of their elements?
For example the array
m= [4,4,4,10,10,10,4,4,5]
should result in this array:
[5,10,10,10,4,4,4,4,4]
5 is the less frequent element and is on the top while 4 is the most frequent and it's on bottom.
Should one use the indices provided by histcount?
The following code first calculates how often each element occurs and then uses runLengthDecode to expand the unique elements.
m = [4,4,4,10,10,10,4,4,5];
u_m = unique(m);
elem_count = histc(m,u_m);
[elem_count, idx] = sort(elem_count);
m_sorted = runLengthDecode(elem_count, u_m(idx));
The definition of runLengthDecode is copied from this answer:
For MATLAB R2015a+:
function V = runLengthDecode(runLengths, values)
if nargin<2
values = 1:numel(runLengths);
end
V = repelem(values, runLengths);
end
For versions before R2015a:
function V = runLengthDecode(runLengths, values)
%// Actual computation using column vectors
V = cumsum(accumarray(cumsum([1; runLengths(:)]), 1));
V = V(1:end-1);
%// In case of second argument
if nargin>1
V = reshape(values(V),[],1);
end
%// If original was a row vector, transpose
if size(runLengths,2)>1
V = V.'; %'
end
end
One way would be to use accumarray to find the count of each number (I suspect you can use histcounts(m,max(m))) but then you have to clear all the 0s).
m = [4,4,4,10,10,10,4,4,5];
[~,~,subs]=unique(m);
freq = accumarray(subs,subs,[],#numel);
[~,i2] = sort(freq(subs),'descend');
m(i2)
By combinging my approach with that of m.s. you can get a simpler solution:
m = [4,4,4,10,10,10,4,4,5];
[U,~,i1]=unique(m);
freq= histc(m,U);
[~,i2] = sort(freq(i1),'descend');
m(i2)
You could count the number of repetitions with bsxfun, sort that, and apply that sorting to m:
[~, ind] = sort(sum(bsxfun(#eq,m,m.')));
result = m(ind);

Error adding to a array

I have used this method to add to arrays in other programs but this it doesn't seem to work. I am confused and can't find a answer to the problem.
Error:
The sample size is: Error using horzcat
CAT arguments dimensions are not consistent.
Error in CalculateElo (line 14)
playerGroup = [playerGroup r];
Code:
function [accuracy] = CalculateElo (referenceElo , sampleSize, lower, upper)
fprintf('The sample size is: %d', sampleSize);
% Popoulate an new array
playerGroup = [];
playerGroup = [playerGroup referenceElo];
for i=1:(sampleSize - 1)
%Create group size
a = 0;
b = 2000;
r = (b-a).*rand(1000,1) + a;
playerGroup = [playerGroup r];
end
An expression like [x y] tries to concatenate the arrays x and y along dimension 2. Each row of an array in Matlab must have the same length (similarly, each column must have the same length). Hence, if size(x,1) = size(y,1), [x y] will return an array with size equal to size(x,1) along the first dimension and size(x,2)+size(y,2) along the second dimension. Otherwise you will get a cat error like the one you show.
r has size (1000,1), so unless the first dimension of referenceElo has size 1000, you will get a cat error.
You didn't mention the size of referenceElo, but I'm guessing it's a single number. You could use the ' (transpose) operator to write
playerGroup = [playerGroup r'];
returning an array of size (1,1001). Or you could use an expression of form [x;y], which concatenates along dimension 1:
playerGroup = [playerGroup;r];
returning an array of size (1001,1).

How to create a grid from 1D array using R?

I have a file which contains a 209091 element 1D binary array representing the global land area
which can be downloaded from here:
ftp://sidads.colorado.edu/DATASETS/nsidc0451_AMSRE_Land_Parms_v01/AMSRE_flags_2002/
I want to create a full from the 1D data arrays using provided ancillary row and column files .globland_r and globland_c which can be downloaded from here:
ftp://sidads.colorado.edu/DATASETS/nsidc0451_AMSRE_Land_Parms_v01/AMSRE_ancil/
There is a code written in Matlab for this purpose and I want to translate this Matlab code to R but I do not know Matlab
function [gridout, EASE_r, EASE_s] = mkgrid_global(x)
%MKGRID_GLOBAL(x) Creates a matrix for mapping
% gridout = mkgrid_global(x) uses the 2090887 element array (x) and returns
%Load ancillary EASE grid row and column data, where <MyDir> is the path to
%wherever the globland_r and globland_c files are located on your machine.
fid = fopen('C:\MyDir\globland_r','r');
EASE_r = fread(fid, 209091, 'int16');
fclose(fid);
fid = fopen('C:\MyDir\globland_c','r');
EASE_s = fread(fid, 209091, 'int16');
fclose(fid);
gridout = NaN.*zeros(586,1383);
%Loop through the elment array
for i=1:1:209091
%Distribute each element to the appropriate location in the output
%matrix (but MATLAB is
%(1,1)
end
EDit following the solution of #mdsumner:
The files MLLATLSB and MLLONLSB (4-byte integers) contain latitude and longitude (multiply by 1e-5) for geo-locating the full global EASE grid matrix (586×1383)
MLLATLSB and MLLONLSB can be downloaded from here:
ftp://sidads.colorado.edu/DATASETS/nsidc0451_AMSRE_Land_Parms_v01/AMSRE_ancil/
## the sparse dims, literally the xcol * yrow indexes
dims <- c(1383, 586)
cfile <- "ftp://sidads.colorado.edu/DATASETS/nsidc0451_AMSRE_Land_Parms_v01/AMSRE_ancil/globland_c"
rfile <- "ftp://sidads.colorado.edu/DATASETS/nsidc0451_AMSRE_Land_Parms_v01/AMSRE_ancil/globland_r"
## be nice, don't abuse this
col <- readBin(cfile, "integer", n = prod(dims), size = 2, signed = FALSE)
row <- readBin(rfile, "integer", n = prod(dims), size = 2, signed = FALSE)
## example data file
fdat <- "ftp://sidads.colorado.edu/DATASETS/nsidc0451_AMSRE_Land_Parms_v01/AMSRE_flags_2002/flags_2002170A.bin"
dat <- readBin(fdat, "integer", n = prod(dims), size = 1, signed = FALSE)
## now get serious
m <- matrix(as.integer(NA), dims[2L], dims[1L])
m[cbind(row + 1L, col + 1L)] <- dat
image(t(m)[,dims[2]:1], col = rainbow(length(unique(m)), alpha = 0.5))
Maybe we can reconstruct this map projection too.
flon <- "MLLONLSB"
flat <- "MLLATLSB"
## the key is that these are integers, floats scaled by 1e5
lon <- readBin(flon, "integer", n = prod(dims), size = 4) * 1e-5
lat <- readBin(flat, "integer", n = prod(dims), size = 4) * 1e-5
## this is all we really need from now on
range(lon)
range(lat)
library(raster)
library(rgdal) ## need for coordinate transformation
ex <- extent(projectExtent(raster(extent(range(lon), range(lat)), crs = "+proj=longlat"), "+proj=cea"))
grd <- raster(ncols = dims[1L], nrows = dims[2L], xmn = xmin(ex), xmx = xmax(ex), ymn = ymin(ex), ymx = ymax(ex), crs = "+proj=cea")
There is probably an "out by half pixel" error in there, left as an exercise.
Test
plot(setValues(grd, m), col = rainbow(max(m, na.rm = TRUE), alpha = 0.5))
Hohum
library(maptools)
data(wrld_simpl)
plot(spTransform(wrld_simpl, CRS(projection(grd))), add = TRUE)
We can now save the valid cellnumbers to match our "grd" template, then read any particular dat-file and just populate the template with those values based on cellnumbers. Also, it seems someone trod nearly this path earlier but not much was gained:
How to identify lat and long for a global matrix?

Three dimensional table in Lua

I need the best way to store a three dimensional table for pixels. What I need to do is have multiple x,y tables (basically three dimensional) it is to raster multiple two dimensional pixel maps with transparency. You see I can create two dimensions easily like so:
pixels = {{},{}}
pixels[1][5] = "green" --just an example
print(pixels[1][5])
However, I cannot do this like I can in Java...
pixels = {{}, {}, {}}
pixels[1][4][3] = "red" -- [x][y][z]
print(pixels[1][4][3])
This is the functionality I want, but I have disgustingly got around this by doing this...
pixels = {}
pixels["x23,y02,z05"] = "green"
print(pixels["x23,y02,z05"]")
I just use string.sub, and string.concat to read and set the tables... I really would like the functionality of example 2 to work, however I know it might need to be implemented differently.
There are basically two ways to go about this
Auto-tables
Auto-tables generate sub-tables transparently using metatables and essentially after creating it you should be able to forget about them.
function newAutotable(dim)
local MT = {};
for i=1, dim do
MT[i] = {__index = function(t, k)
if i < dim then
t[k] = setmetatable({}, MT[i+1])
return t[k];
end
end}
end
return setmetatable({}, MT[1]);
end
-- Usage
local at = newAutotable(3);
print(at[0]) -- returns table
print(at[0][1]) -- returns table
print(at[0][1][2]) -- returns nil
at[0][1][2] = 2;
print(at[0][1][2]) -- returns value
print(at[0][1][3][3]) -- error, because only 3 dimensions set
What is not so nice about them is that they generate lots of tables -- obviously. That's some memory overhead and each level of depth increases the execution time.
What's nice about them is that they can be completely dynamic in size. You could even make them infinitely deep. Though in your use-case this is very likely not necessary and probably even a bad idea.
This structure is very suitable for non-integer indexes though, you could for example make the depth even depend on a "template structure" and so implement a transparent dynamic configuration table, but I'm getting side-tracked...
Flattened arrays
The other variant are flattened arrays. user3125367 already wrote about them, but I want to expand on this as this can be done a lot more convenient and explain a few things.
Often flattening your multi-dimensional arrays is a good idea in CG anyway, since then you can do many matrix operations very easily. Calculating a modified index is also relatively cheap in terms of processing time required. But it should be noted, although kind of obvious, that this approach only works with numeric keys and a predefined size of your matrix.
function newMdArray(X, Y, Z)
local MT = { __call = function(t, x, y, z, v)
if x>X or y>Y or z>Z or x<1 or y<1 or z<1 then return; end
local k = x + X*(y-1) + X*Y*(z-1);
if v ~= nil then t[k] = v; end
return t[k];
end };
return setmetatable({}, MT);
end
-- Usage
local mdt = newMdArray(100, 100, 100);
local v = mdt(1, 2, 3);
mdt(1, 2, 3, v*.1);
This code is taken from another answer from me: dynamic tables or arrays
It can probably be optimised a little (for example calculate X*Y in the closure) but I wanted to paste the original code here. Anyway, with this you can both easily work on the flattened structure by just using normal array indexing:
for i=1, #mdt
mdt[i] = (mdt[i] or 0)*.5
end
As well as access 3d indexes directly:
mdt(12, 13, 14, 0)
You can also easily modify the function to return a default value for missing keys by adding an __index field to the metatable or so that the table saves the matrix dimensions etc.
In addition to classic 'array in array in array' scheme, you can use benefits of Lua table internals. How? Lua table is just a mapping from key to value, and when you use it as an array, you may skip some keys and this will cost virtually nothing.
t = { }
t[1] = "Hello"
t[500000] = "World" -- does NOT allocate additional 499999 elements
So, if your data is sparse (over 50% of your 3d-points having no value), you may benefit from this:
local n_x, n_y, n_z = 1920, 1080, 1000
local n_xy = n_x * n_y
function setValue(t, x, y, z, value)
assert(x > 0 and x < n_x)
assert(y > 0 and y < n_y)
assert(z > 0 and z < n_z)
t[((z-1) * n_xy) + ((y-1) * n_z) + x] = value
end
function getValue(t, x, y, z)
assert(x > 0 and x < n_x)
assert(y > 0 and y < n_y)
assert(z > 0 and z < n_z)
return t[((z-1) * n_xy) + ((y-1) * n_z) + x]
end
t = { }
setValue(t, 1, 1, 1, "red")
setValue(t, 1, 1, 2, "green")
In your first code:
pixels = {{},{}}
is equivalent to:
pixels = {}
pixels[1] = {}
pixels[2] = {}
Here, pixels[1] is already a table, that's why you can assign a value to pixels[1][5].
But in you second code:
pixels = {{}, {}, {}}
Here, pixels is still a two-dimensional array (with 3 elements). It's equivalent to :
pixels = {}
pixels[1] = {}
pixels[2] = {}
pixels[3] = {}
pixels[1] is a table, but pixels[1][4] is not. What you need to do is to give pixels[1][4] a table constructor like this:
pixels = {{}, {}, {}}
pixels[1][4] = {} --initialize it to an empty table
pixels[1][4][3] = "red"
print(pixels[1][4][3])

Resources