Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F121754354
mextriang.c
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Sun, Jul 13, 15:45
Size
5 KB
Mime Type
text/x-c
Expires
Tue, Jul 15, 15:45 (2 d)
Engine
blob
Format
Raw Data
Handle
27385206
Attached To
R1252 EMPoWER
mextriang.c
View Options
/**********************************************************************
* y = mextriang(U,b,options)
* Given nxn upper-triangular matrix U,
* options = 1 (default), solves U *y = b,
* = 2 , solves U'*y = b.
*
* Important: U is assumed to be dense.
*********************************************************************/
#include <mex.h>
#include <math.h>
#if !defined(SQR)
#define SQR(x) ((x)*(x))
#endif
/**************************************************************
TIME-CRITICAL PROCEDURE -- r=realdot(x,y,n)
Computes r=sum(x_i * y_i) using LEVEL 8 loop-unrolling.
**************************************************************/
double
realdot
(
const
double
*
x
,
const
double
*
y
,
const
int
n
)
{
int
i
;
double
r
;
r
=
0.0
;
for
(
r
=
0.0
,
i
=
0
;
i
<
n
-
7
;
i
++
){
/* LEVEL 8 */
r
+=
x
[
i
]
*
y
[
i
];
i
++
;
r
+=
x
[
i
]
*
y
[
i
];
i
++
;
r
+=
x
[
i
]
*
y
[
i
];
i
++
;
r
+=
x
[
i
]
*
y
[
i
];
i
++
;
r
+=
x
[
i
]
*
y
[
i
];
i
++
;
r
+=
x
[
i
]
*
y
[
i
];
i
++
;
r
+=
x
[
i
]
*
y
[
i
];
i
++
;
r
+=
x
[
i
]
*
y
[
i
];
}
if
(
i
<
n
-
3
){
/* LEVEL 4 */
r
+=
x
[
i
]
*
y
[
i
];
i
++
;
r
+=
x
[
i
]
*
y
[
i
];
i
++
;
r
+=
x
[
i
]
*
y
[
i
];
i
++
;
r
+=
x
[
i
]
*
y
[
i
];
i
++
;
}
if
(
i
<
n
-
1
){
/* LEVEL 2 */
r
+=
x
[
i
]
*
y
[
i
];
i
++
;
r
+=
x
[
i
]
*
y
[
i
];
i
++
;
}
if
(
i
<
n
)
/* LEVEL 1 */
r
+=
x
[
i
]
*
y
[
i
];
return
r
;
}
/*************************************************************
TIME-CRITICAL PROCEDURE -- subscalarmul(x,alpha,y,n)
Computes x -= alpha * y using LEVEL 8 loop-unrolling.
**************************************************************/
void
subscalarmul
(
double
*
x
,
const
double
alpha
,
const
double
*
y
,
const
int
n
)
{
int
i
;
for
(
i
=
0
;
i
<
n
-
7
;
i
++
){
/* LEVEL 8 */
x
[
i
]
-=
alpha
*
y
[
i
];
i
++
;
x
[
i
]
-=
alpha
*
y
[
i
];
i
++
;
x
[
i
]
-=
alpha
*
y
[
i
];
i
++
;
x
[
i
]
-=
alpha
*
y
[
i
];
i
++
;
x
[
i
]
-=
alpha
*
y
[
i
];
i
++
;
x
[
i
]
-=
alpha
*
y
[
i
];
i
++
;
x
[
i
]
-=
alpha
*
y
[
i
];
i
++
;
x
[
i
]
-=
alpha
*
y
[
i
];
}
if
(
i
<
n
-
3
){
/* LEVEL 4 */
x
[
i
]
-=
alpha
*
y
[
i
];
i
++
;
x
[
i
]
-=
alpha
*
y
[
i
];
i
++
;
x
[
i
]
-=
alpha
*
y
[
i
];
i
++
;
x
[
i
]
-=
alpha
*
y
[
i
];
i
++
;
}
if
(
i
<
n
-
1
){
/* LEVEL 2 */
x
[
i
]
-=
alpha
*
y
[
i
];
i
++
;
x
[
i
]
-=
alpha
*
y
[
i
];
i
++
;
}
if
(
i
<
n
)
/* LEVEL 1 */
x
[
i
]
-=
alpha
*
y
[
i
];
}
/*************************************************************
PROCEDURE fwsolve -- Solve y from U'*y = x.
**************************************************************/
void
fwsolve
(
double
*
y
,
const
double
*
u
,
const
double
*
x
,
const
int
n
)
{
int
k
;
/*-----------------------------------------------
u(1:k-1,k)'*y(1:k-1) + u(k,k)*y(k) = x(k).
-----------------------------------------------*/
for
(
k
=
0
;
k
<
n
;
k
++
,
u
+=
n
)
y
[
k
]
=
(
x
[
k
]
-
realdot
(
y
,
u
,
k
))
/
u
[
k
];
}
/*************************************************************
PROCEDURE ubsolve -- Solves xnew from U * xnew = x,
UPDATED
x - length n vector
On input, contains the right-hand-side.
On output, xnew = U\x
**************************************************************/
void
bwsolve
(
double
*
x
,
const
double
*
u
,
const
int
n
)
{
int
j
;
/*---------------------------------------------
xnew[j] = x[j] / u[j,j]
Then, we update the right-hand side:
xnew(0:j-1) = x(0:j-1) - xnew[j] * u(0:j-1)
---------------------------------------------*/
j
=
n
;
u
+=
SQR
(
n
);
while
(
j
>
0
){
--
j
;
u
-=
n
;
x
[
j
]
/=
u
[
j
];
subscalarmul
(
x
,
x
[
j
],
u
,
j
);
}
}
/*************************************************************
* PROCEDURE mexFunction - Entry for Matlab
**************************************************************/
void
mexFunction
(
int
nlhs
,
mxArray
*
plhs
[],
int
nrhs
,
const
mxArray
*
prhs
[])
{
const
double
*
U
;
mwIndex
*
irb
,
*
jcb
;
int
isspb
;
int
n
,
k
,
kend
,
options
;
double
*
y
,
*
b
,
*
btmp
;
if
(
nrhs
<
2
)
{
mexErrMsgTxt
(
"mextriang requires 2 input arguments."
);
}
if
(
nlhs
>
1
)
{
mexErrMsgTxt
(
"mextriang generates 1 output argument."
);
}
U
=
mxGetPr
(
prhs
[
0
]);
if
(
mxIsSparse
(
prhs
[
0
]))
{
mexErrMsgTxt
(
"mextriang: Sparse U not supported."
);
}
n
=
mxGetM
(
prhs
[
0
]);
if
(
mxGetN
(
prhs
[
0
])
!=
n
)
{
mexErrMsgTxt
(
"mextriang: U should be square and upper triangular."
);
}
isspb
=
mxIsSparse
(
prhs
[
1
]);
if
(
mxGetM
(
prhs
[
1
])
*
mxGetN
(
prhs
[
1
])
!=
n
)
{
mexErrMsgTxt
(
"mextriang: size of U,b mismatch."
);
}
if
(
nrhs
>
2
)
{
options
=
(
int
)
*
mxGetPr
(
prhs
[
2
]);
}
else
{
options
=
1
;
}
if
(
isspb
)
{
btmp
=
mxGetPr
(
prhs
[
1
]);
irb
=
mxGetIr
(
prhs
[
1
]);
jcb
=
mxGetJc
(
prhs
[
1
]);
b
=
(
double
*
)
mxCalloc
(
n
,
sizeof
(
double
));
kend
=
jcb
[
1
];
for
(
k
=
0
;
k
<
kend
;
k
++
)
{
b
[
irb
[
k
]]
=
btmp
[
k
];
}
}
else
{
b
=
mxGetPr
(
prhs
[
1
]);
}
/************************************************/
plhs
[
0
]
=
mxCreateDoubleMatrix
(
n
,
1
,
mxREAL
);
y
=
mxGetPr
(
plhs
[
0
]);
/************************************************/
if
(
options
==
1
)
{
for
(
k
=
0
;
k
<
n
;
k
++
)
{
y
[
k
]
=
b
[
k
];
}
bwsolve
(
y
,
U
,
n
);
}
else
if
(
options
==
2
)
{
fwsolve
(
y
,
U
,
b
,
n
);
}
return
;
}
/*************************************************************/
Event Timeline
Log In to Comment