I have two variables, the first is 1D flow vector containing 230 data and the second is 2D temperature matrix (230*44219).
I am trying to find the correlation matrix between each flow value and corresponding 44219 temperature. This is my code below.
Houlgrave_flow_1981_2000 = window(Houlgrave_flow_average, start = as.Date("1981-11-15"),end = as.Date("2000-12-15"))
> str(Houlgrave_flow_1981_2000)
‘zoo’ series from 1981-11-15 to 2000-12-15
Data: num [1:230] 0.085689 0.021437 0.000705 0 0.006969 ...
Index: Date[1:230], format: "1981-11-15" "1981-12-15" "1982-01-15" "1982-02-15" ...
Hulgrave_SST_1981_2000=X_sst[1:230,]
> str(Hulgrave_SST_1981_2000)
num [1:230, 1:44219] -0.0733 0.432 0.2783 -0.1989 0.1028 ...
sf_Houlgrave_SF_SST = NULL
sst_Houlgrave_SF_SST = NULL
cor_Houlgrave_SF_SST = NULL
for (i in 1:230) {
for(j in 1:44219){
sf_Houlgrave_SF_SST[i] = Houlgrave_flow_1981_2000[i]
sst_Houlgrave_SF_SST[i,j] = Hulgrave_SST_1981_2000[i,j]
cor_Houlgrave_SF_SST[i,j] = cor(sf_Houlgrave_SF_SST[i],Hulgrave_SST_1981_2000[i,j])
}
}
The error message always says:
Error in sst_Houlgrave_SF_SST[i, j] = Hulgrave_SST_1981_2000[i, j] :
incorrect number of subscripts on matrix
Thank you for your help.
try this:
# prepare empty matrix of correct size
cor_Houlgrave_SF_SST <- matrix(nrow=dim(Hulgrave_SST_1981_2000)[1],
ncol=dim(Hulgrave_SST_1981_2000)[2])
# Good practice to not specify "230" or "44219" directly, instead
for (i in 1:dim(Hulgrave_SST_1981_2000)[1]) {
for(j in 1:dim(Hulgrave_SST_1981_2000)[2]){
cor_Houlgrave_SF_SST[i,j] <- cor(sf_Houlgrave_SF_SST[i],Hulgrave_SST_1981_2000[i,j])
}
}
The two redefinitions inside your loop were superfluous I believe. The main problem with your code was not defining the matrix - i.e. the cor variable did not have 2 dimensions, hence the error.
It is apparently also good practice to define empty matrices for results in for-loops by explicitly giving them correct dimensions in advance - is meant to make the code more efficient.
Related
I am trying to use compressed sensing for a 2D matrix. I am trying to run the following piece of code -
Nf=800;
N=401;
E=E(Nf,N); %matrix of signal(this only for sampling) real matrix E is 2D matrix with size of Nf and N
% compressive sensing
M=ceil(0.3*N);
psi=fft(eye(N));
phi=randi(M,N);
EE = permute(E,[2 1]);
theta=phi*psi;
for k=1:Nf
y(:,k)=phi*EE(:,k);
end
x0 = theta.'*y;
for p=1:Nf
X_hat(:,p) = l1eq_pd(x0(:,p), theta, [], y(:,p), 1e-5); %l1eq_pd=l1-magic
end
X1_hat=psi*X_hat;
XX_hat=permute(X1_hat,[2 1]);
but while running the code I get the following error.
Error using linsolve
Matrix must be positive definite.
Error in l1eq_pd (line 77)
[w, hcond] = linsolve(A*A', b, opts);
Error in simulation_mono_SAR (line 91)
X_hat(:,p) = l1eq_pd(x0(:,p), theta, [], y(:,p), 1e-5);
Could someone point me, what is the problem? Is it a problem inherent to l1-magic? shall I use another solver?
I have experience in python but am new to IDL. I am trying to write a function that will return two bins. I want to use the min function to get my bin edges. My issue is that I am trying to use the min_subscript argument to denote each bin edge, and I can't figure out how to do this in a for loop. I want to write my code so that each loop has 2 different min_subscript variables (the two edges of the bin), and these variables are written into their own arrays. Here is my code:
FUNCTION DBIN, radius, data, wbin, radbin, databin
FOR i = 0, N_ELEMENTS(radius)-1 DO BEGIN
l = lonarr(N_ELEMENTS(radius))
m = lonarr(N_ELEMENTS(radius))
junk1 = min(abs(radius - radius[i]), l[i])
junk2 = min(abs(radius - (radius[i] + wbin)), m[i])
radbin = lonarr(N_ELEMENTS(radius))
radbin[i] = radius[l[i]:m[i]]
databin = lonarr(N_ELEMENTS(data))
databin[i] = total(data[l[i]:m[i]])
ENDFOR
END
wbin is the desired bin width. The junk variables only exist for the purpose of getting the min_subscripts at those locations. The min_subscripts are the l[i]'s and the m[i]'s.
I appreciate any help!!
The min_subscript argument is trying to pass a value back to you, so you must pass a "named variable" to it. Named variables have pass by reference behavior. So you have to do it in two steps, something like:
junk1 = min(abs(radius - radius[i]), li)
l[i] = li
Above, li is a named variable, so it can receive and pass back the value. Then you can put it in your storage array.
I think I'm incorrectly accessing and assigning variables from a matrix. I understand that arrays, matrices, and tables are different in R. What I want to end up with is an array of values called "c" that has either a 1 or 2 assigning an element from input to either Mew(number 1) or Mewtwo(number 2. I also want the distance from Mew to all other points in an array called dMew as well as dMewtwo an array of the distance from Mewtwo to all other elements in input. What I end up with is NA_real_ for all variables except input. There is a lot of great information on accessing rows or columns of various data structures in R but I'm interested in accessing single elements. Any advice would be most helpful. I apologize if this has been answered before but I couldn't find it anywhere.
#Read input from a csv data file
input = read.csv("~/Desktop/Engineering/iris.csv",head=FALSE)
input = input[c(0:3)]
input = as.matrix(input)
#set random centroids
Mew = input[1,1]
Mewtwo = input[nrow(input),ncol(input)]
#Determine Distance
dist <- function(x, y) {
return(sqrt((x - y)^2))
}
#Determine the clusters
dMew = matrix(,nrow(input), ncol(input))
dMewtwo = matrix(,nrow(input), ncol(input))
c = matrix(,nrow(input), ncol(input))
for (i in 1:nrow(input)) {
for (j in 1:ncol(input)) {
dMew[i,j] = dist(Mew, input[i,j])
dMewtwo[i,j] = dist(Mewtwo, input[i,j])
if (dMew[i,j] > dMewtwo[i,j]) {
c[i,j] = 2
} else {
c[i,j] = 1
}
}
}
#Update the centroids
Mew = mean(dMew)
Mewtwo = mean(dMewtwo)
I have no problem running the code with the following input:
input = data.frame(V1=1:5,V2=1:5,V3=1:5)
so it seems to be a problem related to your data. Also you should avoid using "c" as a variable name and note that dist() is already a function in the stats package. Also, you can avoid the for-loops by using apply() and ifelse():
#Read input from a csv data file
input = data.frame(V1=1:5,V2=1:5,V3=1:5)
input = input[c(1:3)]
input = as.matrix(input)
#set random centroids
Mew = input[1,1]
Mewtwo = input[nrow(input),ncol(input)]
#Determine Distance
dist.eu <- function(x, y) {
return(sqrt((x - y)^2))
}
dMew<-apply(input,c(1,2),dist.eu,Mew)
dMewtwo<-apply(input,c(1,2),dist.eu,Mewtwo)
c.mat<-ifelse(dMew > dMewtwo,2,1)
c.mat
I have a problem with my code. I originally wrote it in Lazarus, but compiling it on fpc compiler on Windows and Linux still gives me problems. Linux gives "Segmentation fault" and windows external SIGSEV.
My goal is to generate permutations with this program.
It is just for curiosity and learning.
Program source:
program CombinationGeneration;
{$mode objfpc}{$H+}
const
K = 6; // Number of elements chosen
N = 26; // Number of elements to choose from
ALPHABET: Array[1..N] of Char = ('A','B','C','D','E','F','G','H','I','J','K','L','M', // Elements
'N','O','P','Q','R','S','T','U','V','W','X','Y','Z'); //
Type
TCombination = Array of Byte; // Combination elemnts array type
PCombination = ^TCombination; // Pointer to combination elements array
{ Rotate
Rotate digits forward in alphabet.
If last item in alphabet is reached, then rotate element before current in combination. }
procedure Rotate( const Combination:PCombination; Element:integer );
begin
{ Check if rotation is completed }
if Combination^[Element] = High(ALPHABET) then
begin
{ If rotation is completed:
* rewind element to first in ALPHABET Low()
* Check if the the element before current exists, then rotate it. }
Combination^[Element] := Low(ALPHABET);
if Element > Low(Combination^) then
Rotate( Combination, Element-1 )
else
Writeln('The end. ');
end else
{ Rotation is not complete and just rotate forward the current element. }
begin
inc(Combination^[Element]);
{:: Write out combination HERE!!! ::}
{ If it is not the last element in combination,
we must rotate the others after it. So go back to High(). }
if Element < High(Combination^) then
Rotate( Combination, High(Combination^) )
else
Rotate( Combination, Element );
end;
end;
var
Comb : TCombination; // Holds the current combination
i : integer; // Iterator for various stuff
begin
{ Set the first combination, length is K }
SetLength(Comb,K);
{ Fill with initial values }
for i:=Low(Comb) to High(Comb) do
begin
Comb[i]:=Low(ALPHABET); // Probably [0,0,0]
end;
{ Calculate permutations }
rotate(#Comb, High(Comb));
readln;
end.
It can do about 694 000 calls of "rotation" function, and then it crashes.
It used to do about 59 000, but i made the Combination array pass by reference and later i
made it pass by pointer.( Last edition made no improvement, or can you tell me any ?)
If I decrease the N and K values until the max permutations value becomes smaller
than this 694 000, then it runs perfect. No errors.
For example let's say we have 14 elemnts in alphabet and k = 5.
The formula is 14^5 = 537 824 . And it is generated flawlessly.
Also full alphabet(26) and 4 chosen works fine - 26^4=456 976
Some output from call stack(Copying text crashes Lazarus):
So.. can you spot any errors... memory leaks, waste.. ?
Laz ver. 1.0.8
Fpc ver. 2.6.2
Thanks!
I'm stuck with computing the integral at each point of an array. The idea is first to create a function ("Integrand"). Then, create a second function ("MyConvolve") that computes the necessary integral.
Here's what I did up to now:
Integrand = function(s,x)
{ 1/4*(abs(x-s)<=1)*(abs(s)<=1) }
MyConvolve = function(func,data)
{ return( integrate(func, lower=-Inf, upper=Inf, data) ) }
Now, running the code with some array, I get an error message:
SomeMatrix = replicate(10, rnorm(10))
MyConvolve(Integrand, SomeMatrix)
Which ends up with the following error message:
Error in integrate(func, lower = -Inf, upper = Inf, data) :
evaluation of function gave a result of wrong length
I already tried vectorizing the function, but still ended up with error messages.
Thank you very much for your help!
I am not sure I understand what you are trying to compute,
but if you want to evaluate MyConvolve(Integrand,s),
where s takes all the values in SomeMatrix,
then apply is sufficient.
sapply( SomeMatrix, function(s) MyConvolve( Integrand, s )$value )
However, the dimensions of the matrix are lost.
You can recover them as follows:
result <- SomeMatrix
result[] <- sapply( SomeMatrix, function(s) MyConvolve( Integrand, s )$value )