|
|
| Author |
Message |
vsgdp science forum addict
Joined: 01 May 2005
Posts: 78
|
Posted: Sat Jun 11, 2005 2:50 pm Post subject:
solving large system of equations
|
|
|
Hi,
This is a follow up to my "help with finite difference scheme" post.
Instead of doing my hack to create an explicit scheme, I just left it in
implicit form and solve a system of equations at every step (which is
working now!). Right now I am taking the inverse to solve the system.
However, it is taking some time. I know there are better methods for
solving. My system is tridiagonal except for the first and last row of the
matrix. The system looks like this.
[1 c 0 ... 0 -c ]
..
..
..
[0 ... 0 -c 1 c 0 ... 0]
..
..
..
[c 0 0 ... -c 1]
In particular, I am looking for a MATLAB function that will solve this
efficiently. I don't really want to code up my own right now since the
course topic is on numeric differential equations and not matrix
computations. |
|
| Back to top |
|
 |
Ron Shepard science forum beginner
Joined: 11 Jun 2005
Posts: 31
|
Posted: Sun Jun 12, 2005 3:18 pm Post subject:
Re: solving large system of equations
|
|
|
In article <wDEqe.6804$6s.4099@fed1read02>, "vsgdp" <spam@null.com>
wrote:
| Quote: | The system looks like this.
[1 c 0 ... 0 -c ]
.
.
.
[0 ... 0 -c 1 c 0 ... 0]
.
.
.
[c 0 0 ... -c 1]
In particular, I am looking for a MATLAB function that will solve this
efficiently. I don't really want to code up my own right now since the
course topic is on numeric differential equations and not matrix
computations.
|
This is called a "circulant" matrix. You can use FFT techniques to
solve linear equations and eigenvalues of circulant matrices that
scale as n*log(n) rather than n^3. The particular form you have
might even have a closed form solution. I do not know if MATLAB
supports these methods directly.
$.02 -Ron Shepard |
|
| Back to top |
|
 |
spasmous science forum addict
Joined: 03 May 2005
Posts: 66
|
Posted: Sun Jun 12, 2005 4:28 pm Post subject:
Re: solving large system of equations
|
|
|
MATLAB has lsqr() implemented, if you don't need anything particularly
specialized - ie. not optimal for your matrix. |
|
| Back to top |
|
 |
Carl Barron science forum beginner
Joined: 12 Jun 2005
Posts: 27
|
Posted: Sun Jun 12, 2005 11:10 pm Post subject:
Re: solving large system of equations
|
|
|
Ron Shepard <ron-shepard@NOSPAM.comcast.net> wrote:
| Quote: | In article <wDEqe.6804$6s.4099@fed1read02>, "vsgdp" <spam@null.com
wrote:
The system looks like this.
[1 c 0 ... 0 -c ]
.
.
.
[0 ... 0 -c 1 c 0 ... 0]
.
.
.
[c 0 0 ... -c 1]
In particular, I am looking for a MATLAB function that will solve this
efficiently. I don't really want to code up my own right now since the
course topic is on numeric differential equations and not matrix
computations.
This is called a "circulant" matrix. You can use FFT techniques to
solve linear equations and eigenvalues of circulant matrices that
scale as n*log(n) rather than n^3. The particular form you have
might even have a closed form solution. I do not know if MATLAB
supports these methods directly.
$.02 -Ron Shepard
I must be missing something since guass elimination is only O(N) for |
this with arbitrary numbers for each c.
A_0 .X = B_0
rows 2 and n only rows 2 and n need elimination and these change
4 elements of A_0 and two of B_0
A_0 = 1 | c_0 X_0 = b0
0 | A_1 X_1 B_1
divide A_1(1,i) and B_1(1) by A_1(1,1) now A_1 is of the same form
as A_0 etc so ew end up with
1 a 0 .... A B1
0 1 b 0 ... B B2
....
0 ..........1 Bn
back substitition requires at most 2n mults or it too is O(N)
therefore it can be solved in O(N) operations
can be done with 4N stores if need be, N + a const stores and a rowwise
read and update and write of the matrix if 4N is too much.
Implimentation left to reader:) |
|
| Back to top |
|
 |
spasmous science forum addict
Joined: 03 May 2005
Posts: 66
|
|
| Back to top |
|
 |
Peter Spellucci science forum Guru
Joined: 29 Apr 2005
Posts: 702
|
Posted: Mon Jun 13, 2005 1:38 pm Post subject:
Re: solving large system of equations
|
|
|
In article <wDEqe.6804$6s.4099@fed1read02>,
"vsgdp" <spam@null.com> writes:
| Quote: | Hi,
This is a follow up to my "help with finite difference scheme" post.
Instead of doing my hack to create an explicit scheme, I just left it in
implicit form and solve a system of equations at every step (which is
working now!). Right now I am taking the inverse to solve the system.
However, it is taking some time. I know there are better methods for
solving. My system is tridiagonal except for the first and last row of the
matrix. The system looks like this.
[1 c 0 ... 0 -c ]
.
.
.
[0 ... 0 -c 1 c 0 ... 0]
.
.
.
[c 0 0 ... -c 1]
In particular, I am looking for a MATLAB function that will solve this
efficiently. I don't really want to code up my own right now since the
course topic is on numeric differential equations and not matrix
computations.
|
no matalb has it not. but you can do this easily yourself. in the situation
given your matrix is irreducibly diagonally dominant, hence Gauss LU
needs no pivoting and in eliminating the tridiagonal structure you simply must
also eleminate in every of the n-1 steps one entry in the last row.
this produces the U-part with diagonal, one superdiagonal which is not touched
and a full last column. total effort is O(n).
hth
peter |
|
| Back to top |
|
 |
Jean-Claude Arbaut science forum Guru
Joined: 13 Jun 2005
Posts: 573
|
Posted: Mon Jun 13, 2005 2:31 pm Post subject:
Re : solving large system of equations
|
|
|
Some C code I needed for the same job (finite difference). Comes with
no guarantee :-)
/*
tridiag(n,a,b,c,d)
b[i] * x[i-1] + a[i] * x[i] + c[i] * x[i+1] = d[i], 0 <= i < n
b[0] = c[n-1] = 0
Solution in a[0] ... a[n-1]
*/
void tridiag(int n,double *a,double *b,double *c,double *d) {
int i;
double t;
for(i=1;i<n;i++) {
t=b[i]/a[i-1];
a[i]-=c[i-1]*t;
d[i]-=d[i-1]*t;
}
a[n-1]=d[n-1]/a[n-1];
for(i=n-2;i>=0;i--) a[i]=(d[i]-c[i]*a[i+1])/a[i];
}
/*
tricyc(n,a,b,c,d,u,v)
b[i] * x[i-1] + a[i] * x[i] + c[i] * x[i+1] + u[i] * x[n-1] = d[i], 0 <=
i < n
add to the first row: b[0] * x[n-1]
add to the last row: c[n-1] * x[0] + v[0] * x[0] + ... + v[n-1] * x[n-1]
Solution in a[0] ... a[n-1]
*/
void tricyc(int n,double *a,double *b,double *c,double *d,double *u,double
*v) {
int i;
double t,z;
u[0]+=b[0];
v[0]+=c[n-1];
for(i=1;i<n;i++) {
t=b[i]/a[i-1];
a[i]-=c[i-1]*t;
u[i]-=u[i-1]*t;
d[i]-=d[i-1]*t;
z=v[i-1]/a[i-1];
v[i]-=c[i-1]*z;
v[n-1]-=u[i-1]*z;
d[n-1]-=d[i-1]*z;
}
a[n-1]=d[n-1]/(a[n-1]+u[n-1]+v[n-1]);
for(i=n-2;i>=0;i--) a[i]=(d[i]-c[i]*a[i+1]-u[i]*a[n-1])/a[i];
}
/*
penta(n,a,b,c,d,e,z)
a c e .
b \ \ \
d \ \ \
. \ \ \
Solution in a
*/
void penta(int n,double *a,double *b,double *c,double *d,double *e,double
*z) {
int i;
double t,u;
for(i=2;i<n;i++) {
t=b[i-1]/a[i-2];
a[i-1]-=c[i-2]*t;
c[i-1]-=e[i-2]*t;
z[i-1]-=z[i-2]*t;
u=d[i]/a[i-2];
b[i]-=c[i-2]*u;
a[i]-=e[i-2]*u;
z[i]-=z[i-2]*u;
}
t=b[n-1]/a[n-2];
a[n-1]-=c[n-2]*t;
z[n-1]-=z[n-2]*t;
a[n-1]=z[n-1]/a[n-1];
a[n-2]=(z[n-2]-c[n-2]*a[n-1])/a[n-2];
for(i=n-3;i>=0;i--) a[i]=(z[i]-c[i]*a[i+1]-e[i]*a[i+2])/a[i];
}
Le 13/06/2005 15:38, dans d8k285$lng$1@fb04373.mathematik.tu-darmstadt.de,
« Peter Spellucci » <spellucci@fb04373.mathematik.tu-darmstadt.de> a écrit :
| Quote: |
In article <wDEqe.6804$6s.4099@fed1read02>,
"vsgdp" <spam@null.com> writes:
Hi,
This is a follow up to my "help with finite difference scheme" post.
Instead of doing my hack to create an explicit scheme, I just left it in
implicit form and solve a system of equations at every step (which is
working now!). Right now I am taking the inverse to solve the system.
However, it is taking some time. I know there are better methods for
solving. My system is tridiagonal except for the first and last row of the
matrix. The system looks like this.
[1 c 0 ... 0 -c ]
.
.
.
[0 ... 0 -c 1 c 0 ... 0]
.
.
.
[c 0 0 ... -c 1]
In particular, I am looking for a MATLAB function that will solve this
efficiently. I don't really want to code up my own right now since the
course topic is on numeric differential equations and not matrix
computations.
no matalb has it not. but you can do this easily yourself. in the situation
given your matrix is irreducibly diagonally dominant, hence Gauss LU
needs no pivoting and in eliminating the tridiagonal structure you simply must
also eleminate in every of the n-1 steps one entry in the last row.
this produces the U-part with diagonal, one superdiagonal which is not touched
and a full last column. total effort is O(n).
hth
peter
|
|
|
| Back to top |
|
 |
Jean-Claude Arbaut science forum Guru
Joined: 13 Jun 2005
Posts: 573
|
Posted: Mon Jun 13, 2005 4:18 pm Post subject:
Re : solving large system of equations
|
|
|
Ok, the answer was still truncated... Sorry I hope this time it's OK.
/*
penta(n,a,b,c,d,e,z)
a c e *
b \ \ \
d \ \ \
* \ \ \
Solution in a
*/
void penta(int n,double *a,double *b,double *c,double *d,double *e,double
*z) {
int i;
double t,u;
for(i=2;i<n;i++) {
t=b[i-1]/a[i-2];
a[i-1]-=c[i-2]*t;
c[i-1]-=e[i-2]*t;
z[i-1]-=z[i-2]*t;
u=d[i]/a[i-2];
b[i]-=c[i-2]*u;
a[i]-=e[i-2]*u;
z[i]-=z[i-2]*u;
}
t=b[n-1]/a[n-2];
a[n-1]-=c[n-2]*t;
z[n-1]-=z[n-2]*t;
a[n-1]=z[n-1]/a[n-1];
a[n-2]=(z[n-2]-c[n-2]*a[n-1])/a[n-2];
for(i=n-3;i>=0;i--) a[i]=(z[i]-c[i]*a[i+1]-e[i]*a[i+2])/a[i];
} |
|
| Back to top |
|
 |
Google
|
|
| Back to top |
|
 |
|
|
The time now is Fri Jul 30, 2010 5:34 am | All times are GMT
|
|
Copyright © 2004-2005 DeniX Solutions SRL
|
|
Other DeniX Solutions sites:
Electronics forum |
Medicine forum |
Unix/Linux blog |
Unix/Linux documentation |
Unix/Linux forums
|
Powered by phpBB © 2001, 2005 phpBB Group
|
|