corr() with sparse matrix - MATLAB - matlab

I wonder whether MATLAB has a toolbox to do common matrixial operation with sparse matrices.
Using a dense matrix, I can compute the correlogram matrix doing:
R = rand(10,100)
[r,p] = corr(R)
With sparse matrix I would love to do:
S = sprand(10,100,.2)
[r,p] = corr(S)
However, the following error is elicited:
Error using betainc
Inputs must be real, full, and double or single.
Error in tcdf (line 70)
p(t) = betainc(xsq(t) ./ (v(t) + xsq(t)), 0.5, v(t)/2, 'upper') / 2;
Error in corr>pvalPearson (line 720)
p = 2*tcdf(-abs(t),n-2);
Error in corr>corrPearson (line 321)
pval(ltri) = pvalPearson(tail, coef(ltri), n);
Error in corr (line 204)
[coef,pval] = corrFun(rows,tail,x);
Can anyone help me?

Cmon ppl, let's do some math! Let x be a random vector. An entry in the correlation matrix CORR(x_i, x_j) is given by:
CORR(x_i, x_j) = COV(x_i, x_j) / (SQRT(VAR(x_i)) *SQRT(VAR(x_j));
That is, to build our correlation matrix, we need the covariance matrix, which also gives us the individual variances. Formula for covariance: COV(x) = E[x*x'] - E[x]E[x]'. We can then approximate the the population moments E[x*x'] with the sample moments (i.e. X'*X/n and mean(X))
Hence the following Matlab code:
[n, k] = size(X);
Exxprim = full(X'*X)/n; %I'm shocked if this isn't full so let's drop sparse now
Ex = full(mean(X))'; %same deal
COVX = (Exxprim - Ex*Ex');
STDEVX = sqrt(diag(COVX));
CORRX = COVX ./ (STDEVX * STDEVX');
This may help if X'*X and mean(X) can be done more efficiently because X is sparse.

Related

WORHP - Matlab interface, ERROR IN LEQSOL: symbolic step

I try to transform Hessian in matlab handle into Worhp structure. The idea is using random input to find nonzero-element in Hessian, something like:
% Hessian
H = #(x)[x(1) x(2); x(2) 0];
% evaluate for some random points
nr = 3;
S = zeros(2,2);
for i=1:nr
S = S + full(H(rand(2,1)) ~=0);
end
% get sparsity
S = S ~=0;
% convert everything to vectors for WORHP
[ HMrow, HMcol ] = find(S);
posCombined = find(S);
hess2vec(rand(2,1),posCombined,H)
function hVec = hess2vec(x, mu, scale,posCombined,Hess)
H = Hess(x,mu, scale);
hVec = H(posCombined);
end
And the hess2Vec is assigned to wCallback.hm in matlab-interface.
It works well with the given example, i.e. the example from Maltab-interface, whose hessian is a 2x2 matrix
However it failed with an error by our own project:
Error using worhp
WorhpIPLeqInit: ERROR IN LEQSOL: symbolic step! flag =
-1
Error in worhp_interface (line 82)
[xFinal,lambdaFinal,muFinal,solverstatus] =
worhp(wData, wCallback);
Perhaps someone knows what that means? What might be the cause?

Error using vertcat-Dimensions of matrices being concatenated are not consistent

I'm new to Matlab and am trying to implement this scheme.
Scheme: Un+1 = Minv*((1+2theta)*Un + *Un-1 +bn+1 + fn+1
Given the following equation:
ut(x; t) = cuxx(x; t) + f(x; t)
where x belongs to ]0; 1[: t belongs to ]0; T[, T > 0 and c>0
with Dirichlet boundaries
conditions:
u(0; t) = alpha(t)
u(1; t) = beta(t)
t belongs to [0; T]
The goal of the function in the code is to determine the error(defined in the code).
I keep getting:
Error using vertcat
Dimensions of matrices being concatenated are not consistent.
Error in wave1d_func11910448 (line 60)
uh=[UL;U;UR];
The code:
function [ h,err ] = wave1d_func11910448( nx )
a=0.0; b=1.0;
nx=20;
c=1.0;
tfinal=1;
h=(b-a)/(nx-1);
dt=0.5*h*h/c;
lambda=c*dt/h/h;
theta=1;
x=linspace(a,b,nx);
%defining the function f(x,t)
f = #(x,t) (pi^2-1)*exp(-t)*cos(pi*x)+4*x-2;
Fh=zeros(nx-2,1);%filling the vector f(n+1)
%defining the function g(x,t):initial condition-filling the vector U0
u = #(x) x.^2+cos(pi*x);
U0=u(x(2:end-1));
%defining the exact solution exact(x,t)
exact=#(x,t) x.^2+4*x*t+cos(pi*x)*exp(-t);
%filling the vector u1
U1=exact(x(2:end-1),1);
%defining the functions alpha(t) and beta(t)
alpha = #(t) exp(-t);
beta = #(t) -exp(-t)+4*t+1;
%filling the matrix Mh
Ah=diag(0.0*ones(1,nx-2),0)+diag(1.0*ones(1,nx-3),1)+diag(1.0*ones(1,nx-
3),-1);
Mh=eye(nx-2,nx-2)*(1+theta+2*lambda)-lambda*Ah;
Minv=inv(Mh);
Bh = zeros(nx-2,1);%filling the vector b
time=0.0;
i=0.0;
U2=Minv.*((1+2*theta )*U1-theta*U0+Bh+ dt*Fh);
while(time<tfinal)
time=time+dt;
i=i+1;
Bh(1)=lambda*alpha(time);Bh(nx-2)=lambda*beta(time);
Fh=f(x(2:end-1),time);
U=Minv.*((1+2*theta )*U1-theta*U0+Bh+ dt*Fh);
U0=U1;
U1=U2;
UL=alpha(time);
UR=beta(time);
uh=[UL;U;UR];
error(i) = norm(uh - exact(x,time),inf);
end
err=max(error);
expected results: err= a positive number <1
error message:
Error using vertcat
Dimensions of matrices being concatenated are not consistent.
Error in wave1d_func11910448 (line 60)
uh=[UL;U;UR];

Use Matlab/Maple to find roots of a nonlinear equation

I am having difficulty in finding roots of a nonlinear equation. I have tried Matlab and Maple both, and both give me the same error which is
Error, (in RootFinding:-NextZero) can only handle isolated zeros
The equation goes like
-100 + 0.1335600000e-5*H + (1/20)*H*arcsinh(2003.40/H)
The variable is H in the equation.
How do I find the roots (or the approximate roots) of this equation?
Matlab Code:
The function file:
function hor_force = horizontal(XY, XZ, Lo, EAo, qc, VA)
syms H
equation = (-1*ZZ) + (H/qc)*(cosh((qc/H)*(XZ- XB))) - H/qc + ZB;
hor_force = `solve(equation);`
The main file:
EAo = 7.5*10^7;
Lo = 100.17;
VA = 2002;
XY = 0;
ZY = 0;
XB = 50;
ZB = -2;
XZ = 100;
ZZ = 0;
ql = 40;
Error which Matlab shows:
Error using sym/solve (line 22)
Error using maplemex
Error, (in RootFinding:-NextZero) can only handle isolated zeros
Error in horizontal (line 8)
hor_force = solve(equation);
Error in main (line 34)
h = horizontal(XY, XZ, Lo, EAo, ql, VA)
http://postimg.org/image/gm93z3b7z/
You don't need the symbolic toolbox for this:
First, create an anonymous function that can take vectors at input (use .* and ./:
equation = #(H) ((-1*ZZ) + (H./qc).*(cosh((qc./H).*(XZ- XB))) - H./qc + ZB);
Second, create a vector that you afterwards insert into the equation to find approximately when the sign of the function changes. In the end, use fzero with x0 as the second input parameter.
H = linspace(1,1e6,1e4);
x0 = H(find(diff(sign(equation(H))))); %// Approximation of when the line crosses zero
x = fzero(equation, x0) %// Use fzero to find the crossing point, using the initial guess x0
x =
2.5013e+04
equation(x)
ans =
0
To verify:
You might want to check out this question for more information about how to find roots of non-polynomials.
In Maple, using the expression from your question,
restart:
ee := -100 + 0.1335600000e-5*H + (1/20)*H*arcsinh(2003.40/H):
Student:-Calculus1:-Roots(ee, -1e6..1e6);
[ 5 ]
[-1.240222868 10 , -21763.54830, 18502.23816]
#plot(ee, H=-1e6..1e6, view=-1..1);

Create flexible function handle

I am using numerical integration in MATLAB, with one varibale to integrate over but the function also contains a variable number of terms depending on the dimension of my data. Right now this looks like the following for the 2-dimensional case:
for t = 1:T
fxt = #(u) exp(-0.5*(x(t,1)-theta*norminv(u,0,1)).^2) .* ...
exp(-0.5*(x(t,2) -theta*norminv(u,0,1)).^2);
f(t) = integral(fxt,1e-4,1-1e-4,'AbsTol',1e-3);
end
I would like to have this function flexible in the sense that there could be any number of data points in, each in the following term:
exp(-0.5*(x(t,i) -theta*norminv(u,0,1)).^2);
I hope this is understandable.
If x and u have a valid dimension match (vector-vector or array-scalar) for the subtraction, you can put the whole matrix x into the handle and pass it to the integral function using the name-parameter pair ('ArrayValued',true):
fxt = #(u) exp(-0.5*(x - theta*norminv(u,0,1)).^2) .* ...
exp(-0.5*(x - theta*norminv(u,0,1)).^2);
f = integral(fxt,1e-4,1-1e-4,'AbsTol',1e-3,'ArrayValued',true);
[Documentation]
You may need a loop if integral ever passes a vector u into the handle.
But in looking at how the integral function is written, the integration nodes are entered as scalars for array-valued functions, so the loop shouldn't be necessary unless some weird dimension-mismatch error is thrown.
Array-Valued Output
In response to the comments below, you could try this function handle:
fx = #(u,t,k) prod(exp(-0.5*(x(t,1:k)-theta*norminv(u,0,1)).^2),2);
Then your current loop would look like
fx = #(u,t,k) prod(exp(-0.5*(x(t,1:k)-theta*norminv(u,0,1)).^2),2);
k = 2;
for t = 1:T
f(t) = integral(#(u)fx(u,t,k),1e-4,1-1e-4,'AbsTol',1e-3,'ArrayValued',true);
end
The ArrayValued flag is needed since x and u will have a dimension mismatch.
In this form, another loop would be needed to sweep through the k indexes.
However, we can improve this function by skipping the loop altogether since each iterate of the loop is independent by using the ArrayValued mode:
fx = #(u,k) prod(exp(-0.5*(x(:,1:k)-theta*norminv(u,0,1)).^2),2);
k = 2;
f = integral(#(u)fx(u,k),1e-4,1-1e-4,'AbsTol',1e-3,'ArrayValued',true);
Vector-Valued Output
If ArrayValued is not desired, which may be the case if the integration requires a lot of subdivisions and a vector-valued u is preferable, you can also try a recursive version of the handle using cell arrays:
% x has size [T,K]
fx = cell(K,1);
fx{1} = #(u,t) exp(-0.5*(x(t,1) - theta*norminv(u,0,1)).^2);
for k = 2:K
fx{k} = #(u,t) fx{k-1}(u,t).*exp(-0.5*(x(t,k) - theta*norminv(u,0,1)).^2);
end
f(T) = 0;
k = 2;
for t = 1:T
f(t) = integral(#(u)fx{k}(u,t),1e-4,1-1e-4,'AbsTol',1e-3);
end
ThanksTroy but now I run into the follwing:
x = [0.3,0.8;1.5,-0.7];
T = size(x,1);
k = size(x,2);
theta= 1;
fx = #(u,t,k) prod(exp(-0.5*(x(t,1:k) - theta*norminv(u,0,1))^2));
for t = 1,T
f(t) = integral(#(u)fx(u,t,k),1e-4,1-1e-4,'AbsTol',1e-3);
end
Error using -
Matrix dimensions must agree.
Error in #(u,t,k)prod(exp(-0.5*(x(t,1:k)-theta*norminv(u,0,1))^2))
Error in #(u)fx(u,t,k)
Error in integralCalc/iterateScalarValued (line 314)
fx = FUN(t);
Error in integralCalc/vadapt (line 133)
[q,errbnd] = iterateScalarValued(u,tinterval,pathlen);
Error in integralCalc (line 76)
[q,errbnd] = vadapt(#AtoBInvTransform,interval);
Error in integral (line 89)
Q = integralCalc(fun,a,b,opstruct);

Cubic spline interpolation of function

I am trying to interpolate the following function using the MATLAB function spline,
at equidistant points xi = i./n, i = 0,1,...,n, and for n = 2^j, j = 4,5,...,14.
For each calculation, I record the maximum error at the points x = 0:0.001:1 and plot these errors against n using a loglog plot.
Below is the code,
index=1
for j = 4:1:14;
n = 2^j;
i = 0:1:n;
xi = i./n;
yi = ((exp(3*xi))*sin(200.*(xi.^2))) ./(1+20.*(xi.^2));
x = 0:.001:1;
ye = ((exp(3*x))*sin(200*x.^2)) ./(1+20*x.^2);
yp = spline(x,xi,yi);
err = ye - yp;
merr(index) = max(err);
index = index+1;
end
n1 = 10:10:170;
loglog(n1, merr,'.')
xlabel('n');
ylabel('errors');
title('Cubic Splines');
but when I run the code, I got the following error:
Error using * Inner matrix dimensions must agree.
Error in (line 9) yi = ((exp(3*xi))sin(200.(xi.^2)))
./(1+20.*(xi.^2));
I'm just starting learning MatLab, can anyone help?
You want element-wise multiplication (.*) for the following part of code:
yi = ((exp(3*xi))*sin(200.*(xi.^2))) ./(1+20.*(xi.^2));
should be
yi = ((exp(3*xi)).*sin(200.*(xi.^2))) ./(1+20.*(xi.^2));
The same issue is present for the computation of ye.
When you use mtimes (*), MATLAB tries to do matrix multiplication, which in your case (1-by-n times 1-by-n) is invalid.
Then you will run into a problem with your spline command. Change it to yp = spline(xi,yi,x); so that the values at which you want to interploate (x) are the last argument.