Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
I
imagej-elphel
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
3
Issues
3
List
Board
Labels
Milestones
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Elphel
imagej-elphel
Commits
4a7ba41b
Commit
4a7ba41b
authored
Mar 19, 2025
by
Andrey Filippov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Started solution
parent
99291b6d
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
222 additions
and
40 deletions
+222
-40
CholeskyBlock.java
src/main/java/com/elphel/imagej/common/CholeskyBlock.java
+222
-40
No files found.
src/main/java/com/elphel/imagej/common/CholeskyBlock.java
View file @
4a7ba41b
...
@@ -35,6 +35,7 @@ public class CholeskyBlock {
...
@@ -35,6 +35,7 @@ public class CholeskyBlock {
public
final
int
nf
;
// number of full rows/cols
public
final
int
nf
;
// number of full rows/cols
public
final
double
[]
A
;
public
final
double
[]
A
;
public
final
double
[]
L
;
public
final
double
[]
L
;
public
final
double
[]
B
;
public
CholeskyBlock
(
public
CholeskyBlock
(
double
[][]
A_in
,
double
[][]
A_in
,
...
@@ -45,7 +46,10 @@ public class CholeskyBlock {
...
@@ -45,7 +46,10 @@ public class CholeskyBlock {
n
=
((
nf
*
m
)
<
np
)?
(
nf
+
1
)
:
nf
;
n
=
((
nf
*
m
)
<
np
)?
(
nf
+
1
)
:
nf
;
A
=
new
double
[
np
*
np
];
// [n*n*m*m];
A
=
new
double
[
np
*
np
];
// [n*n*m*m];
L
=
new
double
[
A
.
length
];
L
=
new
double
[
A
.
length
];
B
=
new
double
[
np
];
setup_ATriangle
(
A_in
);
setup_ATriangle
(
A_in
);
// Add convertion here later after done with time measurements
// choleskyBlockMulti()
}
}
private
void
setup_ATriangle
(
double
[][]
A_in
)
{
private
void
setup_ATriangle
(
double
[][]
A_in
)
{
...
@@ -104,6 +108,16 @@ public class CholeskyBlock {
...
@@ -104,6 +108,16 @@ public class CholeskyBlock {
return
new
Matrix
(
get_LTriangle
(),
np
,
np
);
return
new
Matrix
(
get_LTriangle
(),
np
,
np
);
}
}
public
void
setB
(
Matrix
mb
)
{
double
[][]
a
=
mb
.
getArray
();
for
(
int
i
=
0
;
i
<
np
;
i
++)
{
B
[
i
]
=
a
[
i
][
0
];
}
}
public
Matrix
getX
()
{
return
new
Matrix
(
B
,
np
);
}
public
double
[][]
get_LTriangle
()
{
public
double
[][]
get_LTriangle
()
{
double
[][]
L_out
=
new
double
[
np
][
np
];
double
[][]
L_out
=
new
double
[
np
][
np
];
...
@@ -170,6 +184,19 @@ public class CholeskyBlock {
...
@@ -170,6 +184,19 @@ public class CholeskyBlock {
return
j
*
(
m
*
np
)
+
((
j
>=
nf
)
?
(
np
-
nf
*
m
):
m
)
*
m
*
i
;
return
j
*
(
m
*
np
)
+
((
j
>=
nf
)
?
(
np
-
nf
*
m
):
m
)
*
m
*
i
;
}
}
/**
* Tile bottom-right corner, counting i - up, j - to the left.
* Full tile are on the bottom and right (partial - on the top
* and left
* @param i tile row from bottom
* @param j tile column from right
* @return index of the bottom-right corner of the tile (the largest!)
*/
public
int
rindx_IJ
(
int
i
,
int
j
)
{
// upside down
// return (j * (m * np)) + (np-1 -i) * ((j >= nf) ?(np-nf*m): m);
// return (np*np-1) - indx_IJ(i, j);
return
np
*
np
-
1
-
(
j
*
(
m
*
np
)
+
((
j
>=
nf
)
?
(
np
-
nf
*
m
):
m
)
*
m
*
i
);
}
...
@@ -226,28 +253,6 @@ public class CholeskyBlock {
...
@@ -226,28 +253,6 @@ public class CholeskyBlock {
final
Thread
[]
threads
=
ImageDtt
.
newThreadArray
();
final
Thread
[]
threads
=
ImageDtt
.
newThreadArray
();
final
AtomicInteger
ai
=
new
AtomicInteger
(
0
);
final
AtomicInteger
ai
=
new
AtomicInteger
(
0
);
cholesky_single
(
0
);
cholesky_single
(
0
);
/*
final double [][] Am = new double[m][m];
final double [][] Ah = (n > nf) ? new double[(np-nf*m)][(np-nf*m)] : null;
final double [][] A1 = (np < m) ? Ah : Am; // smaller than a tile
final double [][] Lm = new double[m][m];
final double [][] Lh = (n > nf) ? new double[(np-nf*m)][(np-nf*m)] : null;
final double [][] L1 = (np < m) ? Lh : Lm; // smaller than a tile
// Extract top-left tile (only lower triangle)
getDiagLTriangle(
A, // double [] arr,
A1, // double [][] a_diag,
0); // int i)
// Decompose, get L (lower triangle)
cholesky_single (
A1, // double [][] a,
L1); // double [][] l)
// Save it to L-array:
putDiagLTriangle(
L, // double [] arr,
L1, // double [][] l_diag,
0); // int i)
*/
// Calculate first column under diagonal (L21) - maybe use m
// Calculate first column under diagonal (L21) - maybe use m
ai
.
set
(
1
);
// start from the second tile row
ai
.
set
(
1
);
// start from the second tile row
for
(
int
ithread
=
0
;
ithread
<
threads
.
length
;
ithread
++)
{
// first sum for pairs
for
(
int
ithread
=
0
;
ithread
<
threads
.
length
;
ithread
++)
{
// first sum for pairs
...
@@ -280,24 +285,6 @@ public class CholeskyBlock {
...
@@ -280,24 +285,6 @@ public class CholeskyBlock {
ftile_diag
);
// int col)
ftile_diag
);
// int col)
if
(
nRow
==
ftile_diag
)
{
if
(
nRow
==
ftile_diag
)
{
cholesky_single
(
ftile_diag
);
cholesky_single
(
ftile_diag
);
/*
double [][] At = (ftile_diag < nf) ? Am: Ah; // full or reduced array
double [][] Lt = (ftile_diag < nf) ? Lm: Lh; // full or reduced array
// Extract top-left tile (only lower triangle)
getDiagLTriangle(
A, // double [] arr,
At, // double [][] a_diag,
ftile_diag); // int i)
// Decompose, get L (lower triangle)
cholesky_single (
At, // double [][] a,
Lt); // double [][] l)
// Save it to L-array:
putDiagLTriangle(
L, // double [] arr,
Lt, // double [][] l_diag,
ftile_diag); // int i)
*/
}
}
}
}
}
}
...
@@ -340,6 +327,7 @@ public class CholeskyBlock {
...
@@ -340,6 +327,7 @@ public class CholeskyBlock {
ImageDtt
.
startAndJoin
(
threads
);
ImageDtt
.
startAndJoin
(
threads
);
}
}
}
}
return
;
}
}
...
@@ -369,6 +357,200 @@ public class CholeskyBlock {
...
@@ -369,6 +357,200 @@ public class CholeskyBlock {
}
}
}
}
/**
* B has data, will be modified
* @param diag number of the diagonal tile (last may be smaller)
*/
public
void
solveY
(
int
diag
)
{
int
h
=
(
diag
<
nf
)
?
m
:
(
np
-
nf
*
m
);
int
lindx
=
indx_IJ
(
diag
,
diag
);
int
xindx
=
diag
*
m
;
// start of B/x
// Solve L*Y = B;
for
(
int
k
=
0
;
k
<
h
;
k
++)
{
double
x
=
B
[
xindx
+
k
];
for
(
int
i
=
0
;
i
<
k
;
i
++)
{
x
-=
B
[
xindx
+
i
]
*
L
[
lindx
+
h
*
k
+
i
];
// x[k] -= x[i]*L[k][i];
}
B
[
xindx
+
k
]
=
x
/
L
[
lindx
+
(
h
+
1
)*
k
];
// x[k] /= L[k][k];
}
}
/**
* Solve single-tile Lt*X=Y, tiles are counted from the right-bottom
* B has data, will be modified
* @param diag number of the diagonal tile from the bottom-right,
* last may be smaller.
*/
public
void
solveX
(
int
diag
)
{
int
h
=
(
diag
<
nf
)
?
m
:
(
np
-
nf
*
m
);
int
lindx
=
indx_IJ
(
diag
,
diag
);
int
xindx
=
(
np
-
1
)
-
diag
*
m
;
// start of B/x
// Solve L'*X = Y;
for
(
int
k
=
0
;
k
<
h
;
k
++)
{
double
x
=
B
[
xindx
-
k
];
for
(
int
i
=
0
;
i
<
k
;
i
++)
{
x
-=
B
[
xindx
-
i
]
*
L
[
lindx
-
k
-
h
*
i
];
}
B
[
xindx
-
k
]
=
x
/
L
[
lindx
-
(
h
+
1
)*
k
];
}
}
/**
* Subtract Y-column from running B using Y-data in tile j
* from the tile i > j
* @param i tile row corresponding to diagonal L tiles
* @param j tile row to subtract from in B
*/
public
void
subYCol
(
int
i
,
// i > j,
int
j
)
{
// j < i
int
lindx
=
indx_IJ
(
i
,
j
);
int
xindx
=
j
*
m
;
// start of B/x
int
h
=
(
i
<
nf
)
?
m
:
(
np
-
nf
*
m
);
for
(
int
k
=
0
;
k
<
h
;
k
++)
{
double
x
=
B
[
xindx
+
k
];
for
(
int
l
=
0
;
l
<
m
;
l
++)
{
x
-=
L
[
lindx
+
k
*
m
+
l
]
*
B
[
xindx
+
l
];
}
B
[
xindx
+
k
]
=
x
;
}
}
/**
* Subtract X-column from running B using X-data in tile j
* from the tile i > j, counting from the right-bottom
* @param i tile row corresponding to diagonal L tiles, from the bottom
* @param j tile row (from the bottom) to subtract from in B
*/
public
void
subXCol
(
int
i
,
// i > j,
int
j
)
{
// j < i
int
lindx
=
rindx_IJ
(
i
,
j
);
int
xindx
=
np
-
1
-
j
*
m
;
// start of B/x
int
h
=
(
i
<
nf
)
?
m
:
(
np
-
nf
*
m
);
for
(
int
k
=
0
;
k
<
h
;
k
++)
{
double
x
=
B
[
xindx
-
k
];
for
(
int
l
=
0
;
l
<
m
;
l
++)
{
x
-=
L
[
lindx
-
l
*
m
-
k
]
*
B
[
xindx
-
l
];
}
B
[
xindx
-
k
]
=
x
;
}
}
public
Matrix
solve
(
Matrix
b
)
{
setB
(
b
);
solve
();
return
getX
();
}
public
void
solve
()
{
final
Thread
[]
threads
=
ImageDtt
.
newThreadArray
();
final
AtomicInteger
ai
=
new
AtomicInteger
(
0
);
// L, B are set up
// convert top fragment of B->Y using top-left tile of L
solveY
(
0
);
// int diag)
for
(
int
tile_diag
=
1
;
tile_diag
<
n
;
tile_diag
++)
{
final
int
ftile_diag
=
tile_diag
;
// subtract vertical column of tiles for top (previous) segment of B->Y from the remaining
// segments. After subtracting from the top segment, immediately calculate Y for it, all
// other segments subtract in parallel
ai
.
set
(
tile_diag
);
// start from the second tile segment
for
(
int
ithread
=
0
;
ithread
<
threads
.
length
;
ithread
++)
{
// first sum for pairs
threads
[
ithread
]
=
new
Thread
()
{
public
void
run
()
{
for
(
int
tile_seg
=
ai
.
getAndIncrement
();
tile_seg
<
n
;
tile_seg
=
ai
.
getAndIncrement
())
{
subYCol
(
tile_seg
,
// int i, // i > j,
ftile_diag
);
// int j)
if
(
tile_seg
==
ftile_diag
)
{
solveY
(
ftile_diag
);
// int diag)
}
}
}
};
}
ImageDtt
.
startAndJoin
(
threads
);
}
// Solve L'X = Y
solveX
(
0
);
// int diag)
for
(
int
tile_diag
=
1
;
tile_diag
<
n
;
tile_diag
++)
{
final
int
ftile_diag
=
tile_diag
;
// subtract vertical column of tiles for top (previous) segment of X->Y from the remaining
// segments. After subtracting from the top segment, immediately calculate Y for it, all
// other segments subtract in parallel
ai
.
set
(
tile_diag
);
// start from the second tile segment
for
(
int
ithread
=
0
;
ithread
<
threads
.
length
;
ithread
++)
{
// first sum for pairs
threads
[
ithread
]
=
new
Thread
()
{
public
void
run
()
{
for
(
int
tile_seg
=
ai
.
getAndIncrement
();
tile_seg
<
n
;
tile_seg
=
ai
.
getAndIncrement
())
{
subXCol
(
tile_seg
,
// int i, // i > j,
ftile_diag
);
// int j)
if
(
tile_seg
==
ftile_diag
)
{
solveX
(
ftile_diag
);
// int diag)
}
}
}
};
}
ImageDtt
.
startAndJoin
(
threads
);
}
return
;
}
public
static
Matrix
solve
(
Matrix
B
,
double
[][]
L
)
{
int
n
=
L
.
length
;
if
(
B
.
getRowDimension
()
!=
n
)
{
throw
new
IllegalArgumentException
(
"Matrix row dimensions must agree."
);
}
// Copy right hand side.
double
[]
x
=
B
.
getColumnPackedCopy
();
// (for single-column)
// Solve L*Y = B;
for
(
int
k
=
0
;
k
<
n
;
k
++)
{
for
(
int
i
=
0
;
i
<
k
;
i
++)
{
x
[
k
]
-=
x
[
i
]*
L
[
k
][
i
];
}
x
[
k
]
/=
L
[
k
][
k
];
}
// Solve L'*X = Y;
for
(
int
k
=
n
-
1
;
k
>=
0
;
k
--)
{
for
(
int
i
=
k
+
1
;
i
<
n
;
i
++)
{
x
[
k
]
-=
x
[
i
]*
L
[
i
][
k
];
}
x
[
k
]
/=
L
[
k
][
k
];
}
return
new
Matrix
(
x
,
n
);
}
/*
public void setL21(
int i, // i > j,
int j) { // j <nf
int indx_diag = indx_IJ(j,j);
int indx_ij = indx_IJ(i,j);
int h = (i < nf) ? m : (np-nf*m);
// prepare solving Lx = b, copy tile A -> L
System.arraycopy(A, indx_ij, L, indx_ij, m * h);
for (int l_row = 0; l_row < m; l_row++) { // was <m <h!
for (int x_col= 0; x_col < h; x_col++) { // b-vector
int lindx = indx_ij + m * x_col + l_row;
double ls = L[lindx];
for (int l_col = 0; l_col < l_row; l_col++) {
ls -= L[indx_ij + m * x_col + l_col] * L[indx_diag + m* l_row+l_col];
}
L[lindx] = ls/L[indx_diag + (m + 1)* l_row];
}
}
return;
}
*/
// ======================== unused =====================
// ======================== unused =====================
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment