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
3cedfc7a
Commit
3cedfc7a
authored
Mar 17, 2025
by
Andrey Filippov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Found multithreaded Cholesky almost 10 times faster than single-threaded
for n=2300, 16 threads
parent
663a964a
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
1064 additions
and
169 deletions
+1064
-169
CholeskyBlock.java
src/main/java/com/elphel/imagej/common/CholeskyBlock.java
+445
-0
CholeskyLDLTMulti.java
...main/java/com/elphel/imagej/common/CholeskyLDLTMulti.java
+189
-164
CholeskyLLTMulti.java
src/main/java/com/elphel/imagej/common/CholeskyLLTMulti.java
+386
-0
Eyesis_Correction.java
.../java/com/elphel/imagej/correction/Eyesis_Correction.java
+18
-2
VegetationLMA.java
...main/java/com/elphel/imagej/vegetation/VegetationLMA.java
+26
-3
No files found.
src/main/java/com/elphel/imagej/common/CholeskyBlock.java
0 → 100644
View file @
3cedfc7a
package
com
.
elphel
.
imagej
.
common
;
import
java.util.Arrays
;
import
java.util.concurrent.atomic.AtomicInteger
;
import
com.elphel.imagej.tileprocessor.ImageDtt
;
import
Jama.Matrix
;
public
class
CholeskyBlock
{
public
final
int
m
;
// tile size
public
final
int
np
;
// number of elements in row/col
public
final
int
n
;
// number of tiles in row/col
public
final
int
nf
;
// number of full rows/cols
public
final
double
[]
A
;
public
final
double
[]
L
;
public
CholeskyBlock
(
double
[][]
A_in
,
int
size
)
{
m
=
size
;
np
=
A_in
.
length
;
nf
=
np
/
m
;
n
=
((
nf
*
m
)
<
np
)?
(
nf
+
1
)
:
nf
;
A
=
new
double
[
n
*
n
*
m
*
m
];
L
=
new
double
[
A
.
length
];
setup_ATriangle
(
A_in
);
}
private
void
setup_ATriangle
(
double
[][]
A_in
)
{
for
(
int
tile_row
=
0
;
tile_row
<
nf
;
tile_row
++)
{
for
(
int
tile_col
=
0
;
tile_col
<
tile_row
;
tile_col
++)
{
int
indx
=
indx_IJ
(
tile_row
,
tile_col
);
for
(
int
k
=
0
;
k
<
m
;
k
++)
{
System
.
arraycopy
(
A_in
[
tile_row
*
m
+
k
],
tile_col
*
m
,
A
,
indx
+
m
*
k
,
m
);
}
}
// copy diagonal
int
indx
=
indx_IJ
(
tile_row
,
tile_row
);
for
(
int
k
=
0
;
k
<
m
;
k
++)
{
System
.
arraycopy
(
A_in
[
tile_row
*
m
+
k
],
tile_row
*
m
,
A
,
indx
+
m
*
k
,
k
+
1
);
}
}
if
(
n
>
nf
)
{
// if there are small tiles below and to the right
int
tile_row
=
nf
;
int
m1
=
np
-
m
*
nf
;
for
(
int
tile_col
=
0
;
tile_col
<
nf
;
tile_col
++)
{
int
indx
=
indx_IJ
(
tile_row
,
tile_col
);
for
(
int
k
=
0
;
k
<
m1
;
k
++)
{
System
.
arraycopy
(
A_in
[
tile_row
*
m
+
k
],
tile_col
*
m
,
A
,
indx
+
m
*
k
,
m
);
}
}
// copy diagonal
int
indx
=
indx_IJ
(
tile_row
,
tile_row
);
for
(
int
k
=
0
;
k
<
m1
;
k
++)
{
System
.
arraycopy
(
A_in
[
tile_row
*
m
+
k
],
tile_row
*
m
,
A
,
indx
+
m1
*
k
,
k
+
1
);
}
}
}
public
Matrix
getL
()
{
return
new
Matrix
(
get_LTriangle
(),
np
,
np
);
}
public
double
[][]
get_LTriangle
()
{
double
[][]
L_out
=
new
double
[
np
][
np
];
for
(
int
tile_row
=
0
;
tile_row
<
nf
;
tile_row
++)
{
for
(
int
tile_col
=
0
;
tile_col
<
tile_row
;
tile_col
++)
{
int
indx
=
indx_IJ
(
tile_row
,
tile_col
);
for
(
int
k
=
0
;
k
<
m
;
k
++)
{
System
.
arraycopy
(
L
,
indx
+
m
*
k
,
L_out
[
tile_row
*
m
+
k
],
tile_col
*
m
,
m
);
}
}
// copy diagonal
int
indx
=
indx_IJ
(
tile_row
,
tile_row
);
for
(
int
k
=
0
;
k
<
m
;
k
++)
{
System
.
arraycopy
(
L
,
indx
+
m
*
k
,
L_out
[
tile_row
*
m
+
k
],
tile_row
*
m
,
k
+
1
);
}
}
if
(
n
>
nf
)
{
// if there are small tiles below and to the right
int
tile_row
=
nf
;
int
m1
=
np
-
m
*
nf
;
for
(
int
tile_col
=
0
;
tile_col
<
nf
;
tile_col
++)
{
int
indx
=
indx_IJ
(
tile_row
,
tile_col
);
for
(
int
k
=
0
;
k
<
m1
;
k
++)
{
System
.
arraycopy
(
L
,
indx
+
m
*
k
,
L_out
[
tile_row
*
m
+
k
],
tile_col
*
m
,
m
);
}
}
// copy diagonal
int
indx
=
indx_IJ
(
tile_row
,
tile_row
);
for
(
int
k
=
0
;
k
<
m1
;
k
++)
{
System
.
arraycopy
(
L
,
indx
+
m1
*
k
,
L_out
[
tile_row
*
m
+
k
],
tile_row
*
m
,
k
+
1
);
}
}
return
L_out
;
}
/**
* Get index of the top-left tile corner
* @param i tile row
* @param j tile column
* @return index in A and L arrays
*/
public
int
indx_IJ
(
int
i
,
int
j
)
{
return
j
*
(
m
*
np
)
+
((
j
>=
nf
)
?
(
np
-
nf
*
m
):
m
)
*
m
*
i
;
}
/**
* Get a new diagonal square submatrix
* @param arr A or L packed array (line-scan order for each tile column)
* @param i tile index on the diagonal
* @return new array with tile data (m x m, or smaller for the bottom right)
*/
public
double
[][]
getDiagSquare
(
double
[]
arr
,
int
i
){
int
l
=
(
i
>=
nf
)
?
(
np
-
nf
*
m
):
m
;
double
[][]
a_diag
=
new
double
[
l
][
l
];
return
getDiagSquare
(
arr
,
a_diag
,
i
);
}
/**
* Get a new diagonal square submatrix
* @param arr A or L packed array (line-scan order for each tile column)
* @param a_diag - preallocated array (should be smaller if needed)
* @param i tile index on the diagonal
* @return new array with tile data (m x m, or smaller for the bottom right)
*/
public
double
[][]
getDiagSquare
(
double
[]
arr
,
double
[][]
a_diag
,
int
i
){
int
indx
=
indx_IJ
(
i
,
i
);
int
l
=
a_diag
.
length
;
for
(
int
k
=
0
;
k
<
l
;
k
++)
{
int
kl
=
k
*
l
;
System
.
arraycopy
(
arr
,
indx
+
kl
,
a_diag
[
k
],
0
,
l
);
}
return
a_diag
;
}
/**
* Get a new diagonal square submatrix, copy only lower triangle including diagonal
* @param arr A or L packed array (line-scan order for each tile column)
* @param i tile index on the diagonal
* @return new array with tile data (m x m, or smaller for the bottom right)
*/
public
double
[][]
getDiagTriangle
(
double
[]
arr
,
int
i
){
int
l
=
(
i
>=
nf
)
?
(
np
-
nf
*
m
):
m
;
double
[][]
a_diag
=
new
double
[
l
][
l
];
return
getDiagLTriangle
(
arr
,
a_diag
,
i
);
}
/**
* Get a new diagonal square submatrix, copy only lower triangle including diagonal
* @param arr A or L packed array (line-scan order for each tile column)
* @param a_diag - preallocated array (should be smaller if needed)
* @param i tile index on the diagonal
* @return new array with tile data (m x m, or smaller for the bottom right)
*/
public
double
[][]
getDiagLTriangle
(
double
[]
arr
,
double
[][]
a_diag
,
int
i
){
int
indx
=
indx_IJ
(
i
,
i
);
int
l
=
a_diag
.
length
;
for
(
int
k
=
0
;
k
<
l
;
k
++)
{
int
kl
=
k
*
l
;
System
.
arraycopy
(
arr
,
indx
+
kl
,
a_diag
[
k
],
0
,
k
+
1
);
}
return
a_diag
;
}
/**
* Save calculated tile L lower diagonal matrix to a packed array
* @param arr A or L packed array (line-scan order for each tile column)
* @param l_diag lower triangular array with Cholesky decomposition
* @param i tile index on a diagonal
*/
public
void
putDiagLTriangle
(
double
[]
arr
,
double
[][]
l_diag
,
int
i
)
{
int
indx
=
indx_IJ
(
i
,
i
);
int
l
=
l_diag
.
length
;
for
(
int
k
=
0
;
k
<
l
;
k
++)
{
int
kl
=
k
*
l
;
System
.
arraycopy
(
l_diag
[
k
],
0
,
arr
,
indx
+
kl
,
k
+
1
);
}
}
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
++)
{
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
;
}
public
void
setA22
(
int
diag
,
// < col, < row
int
row
,
// >= col
int
col
)
{
int
h
=
(
row
<
nf
)
?
m
:
(
np
-
nf
*
m
);
int
indx_a
=
indx_IJ
(
row
,
col
);
int
indx_lrow
=
indx_IJ
(
row
,
diag
);
if
(
row
==
col
)
{
for
(
int
i
=
0
;
i
<
h
;
i
++)
{
for
(
int
j
=
0
;
j
<=
i
;
j
++)
{
for
(
int
k
=
0
;
k
<
h
;
k
++)
{
A
[
indx_a
+
i
*
m
+
j
]
-=
L
[
indx_lrow
+
i
*
h
+
k
]
*
L
[
indx_lrow
+
j
*
h
+
k
];
}
}
}
}
else
{
int
indx_lcol
=
indx_IJ
(
col
,
diag
);
for
(
int
i
=
0
;
i
<
h
;
i
++)
{
for
(
int
j
=
0
;
j
<
m
;
j
++)
{
for
(
int
k
=
0
;
k
<
m
;
k
++)
{
A
[
indx_a
+
i
*
m
+
j
]
-=
L
[
indx_lrow
+
i
*
m
+
k
]
*
L
[
indx_lcol
+
j
*
m
+
k
];
}
}
}
}
return
;
}
public
void
choleskyBlockMulti
()
{
final
Thread
[]
threads
=
ImageDtt
.
newThreadArray
();
final
AtomicInteger
ai
=
new
AtomicInteger
(
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
ai
.
set
(
1
);
// start from the second tile row
for
(
int
ithread
=
0
;
ithread
<
threads
.
length
;
ithread
++)
{
// first sum for pairs
threads
[
ithread
]
=
new
Thread
()
{
public
void
run
()
{
for
(
int
tile_row
=
ai
.
getAndIncrement
();
tile_row
<
n
;
tile_row
=
ai
.
getAndIncrement
())
{
setL21
(
tile_row
,
0
);
}
}
};
}
ImageDtt
.
startAndJoin
(
threads
);
for
(
int
tile_diag
=
1
;
tile_diag
<
n
;
tile_diag
++)
{
final
int
ftile_diag
=
tile_diag
;
// Calculate A in one tile column of the remaining A2'
// start with diagonal (top) tile, and calculate its Cholesky
// In parallel, calculate A for all tiles in that column below diagonal
ai
.
set
(
ftile_diag
);
for
(
int
ithread
=
0
;
ithread
<
threads
.
length
;
ithread
++)
{
// first sum for pairs
threads
[
ithread
]
=
new
Thread
()
{
public
void
run
()
{
for
(
int
nRow
=
ai
.
getAndIncrement
();
nRow
<
n
;
nRow
=
ai
.
getAndIncrement
())
{
setA22
(
ftile_diag
-
1
,
// int diag,// < col, < row
nRow
,
// int row, // >= col
ftile_diag
);
// int col)
if
(
nRow
==
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)
/*
// Calculate first column under diagonal (L21) - maybe use m
for (int tr = ftile_diag; tr < n; tr++) {
setL21(tr, ftile_diag);
}
*/
}
}
}
};
}
ImageDtt
.
startAndJoin
(
threads
);
if
(
ftile_diag
<
(
n
-
1
))
{
// Now in parallel calculate L in column ftile_diag under diagonal and
// finish A2' to the right of ftile_diag column
final
int
left_rows
=
n
-
ftile_diag
-
1
;
final
int
num_tiles
=
left_rows
*
(
left_rows
+
1
)
/
2
+
1
;
ai
.
set
(
0
);
for
(
int
ithread
=
0
;
ithread
<
threads
.
length
;
ithread
++)
{
// first sum for pairs
threads
[
ithread
]
=
new
Thread
()
{
public
void
run
()
{
for
(
int
ntile
=
ai
.
getAndIncrement
();
ntile
<
num_tiles
;
ntile
=
ai
.
getAndIncrement
())
{
if
(
ntile
==
0
)
{
// Calculate first column of L under diagonal (L21) - maybe use m
for
(
int
tr
=
ftile_diag
+
1
;
tr
<
n
;
tr
++)
{
setL21
(
tr
,
// row > column
ftile_diag
);
// column
}
}
else
{
int
nrow
=
(
int
)
Math
.
floor
(-
0.5
+
0.5
*
Math
.
sqrt
(
1
+
8
*
(
ntile
-
1
)));
int
ncol
=
(
ntile
-
1
)
-
(
nrow
*
(
nrow
+
1
)
/
2
);
int
row
=
ftile_diag
+
nrow
+
1
;
int
col
=
ftile_diag
+
ncol
+
1
;
setA22
(
ftile_diag
-
1
,
// int diag,// < col, < row
row
,
// int row, // >= col
col
);
// int col)
}
}
}
};
}
ImageDtt
.
startAndJoin
(
threads
);
}
}
}
// Cholesky-Banachiewicz Algorithm ?
// Single-threaded
public
static
double
[][]
cholesky_single
(
double
[][]
a
,
double
[][]
l
)
{
int
n
=
a
.
length
;
// double [][] l = new double[n][n];
for
(
int
j
=
0
;
j
<
n
;
j
++)
{
Arrays
.
fill
(
l
[
j
],
0.0
);
}
// Main loop.
for
(
int
j
=
0
;
j
<
n
;
j
++)
{
double
[]
Lrowj
=
l
[
j
];
double
d
=
0.0
;
for
(
int
k
=
0
;
k
<
j
;
k
++)
{
double
[]
Lrowk
=
l
[
k
];
double
s
=
0.0
;
for
(
int
i
=
0
;
i
<
k
;
i
++)
{
s
+=
Lrowk
[
i
]*
Lrowj
[
i
];
}
Lrowj
[
k
]
=
s
=
(
a
[
j
][
k
]
-
s
)/
l
[
k
][
k
];
d
=
d
+
s
*
s
;
}
d
=
a
[
j
][
j
]
-
d
;
l
[
j
][
j
]
=
Math
.
sqrt
(
Math
.
max
(
d
,
0.0
));
}
return
l
;
}
}
src/main/java/com/elphel/imagej/common/CholeskyLDLTMulti.java
View file @
3cedfc7a
...
@@ -7,6 +7,7 @@ import com.elphel.imagej.tileprocessor.ImageDtt;
...
@@ -7,6 +7,7 @@ import com.elphel.imagej.tileprocessor.ImageDtt;
import
Jama.CholeskyDecomposition
;
import
Jama.CholeskyDecomposition
;
import
Jama.Matrix
;
import
Jama.Matrix
;
import
ij.ImagePlus
;
public
class
CholeskyLDLTMulti
{
public
class
CholeskyLDLTMulti
{
public
final
int
n
;
public
final
int
n
;
...
@@ -14,178 +15,149 @@ public class CholeskyLDLTMulti {
...
@@ -14,178 +15,149 @@ public class CholeskyLDLTMulti {
public
int
solve_step
=
10
;
public
int
solve_step
=
10
;
public
double
thread_scale
=
2.5
;
// split jobs in thread_scale * num_treads chunks
public
double
thread_scale
=
2.5
;
// split jobs in thread_scale * num_treads chunks
// public double [][] L;
public
CholeskyLDLTMulti
(
Matrix
matA
,
boolean
b
)
{
boolean
debug
=
true
;
public
CholeskyLDLTMulti
(
Matrix
matA
)
{
int
dbg_j
=
100
;
// 1520;
n
=
matA
.
getRowDimension
();
n
=
matA
.
getRowDimension
();
L
=
matA
.
getArray
();
// will be modified, copy externally if needed
L
=
CholeskyLDLTMulti_multi
(
matA
);
final
Thread
[]
threads
=
ImageDtt
.
newThreadArray
();
final
AtomicInteger
ai
=
new
AtomicInteger
(
0
);
for
(
int
j
=
0
;
j
<
n
;
j
++)
{
if
(
j
==
dbg_j
)
{
System
.
out
.
println
(
"CholeskyLDLTMulti(): j=dbg_j="
+
j
);
}
final
int
fj
=
j
;
for
(
int
k
=
0
;
k
<
j
;
k
++)
{
final
int
fk
=
k
;
L
[
j
][
j
]
-=
L
[
j
][
k
]*
L
[
j
][
k
];
// diagonal
final
double
Ljk
=
L
[
j
][
k
];
// for (int i = j+1; i < n; i++) {
// l[i][j] -= l[i][k]*l[j][k]; // not including diagonal
// }
// parallel
ai
.
set
(
j
+
1
);
for
(
int
ithread
=
0
;
ithread
<
threads
.
length
;
ithread
++)
{
threads
[
ithread
]
=
new
Thread
()
{
public
void
run
()
{
for
(
int
i
=
ai
.
getAndIncrement
();
i
<
n
;
i
=
ai
.
getAndIncrement
())
{
L
[
i
][
fj
]
-=
L
[
i
][
fk
]*
Ljk
;
}
}
};
}
ImageDtt
.
startAndJoin
(
threads
);
}
// parallel
// for (int i = j+1; i < n; i++) {
// l[i][j] /= l[j][j];
// }
final
double
Ljj
=
L
[
j
][
j
];
ai
.
set
(
j
+
1
);
for
(
int
ithread
=
0
;
ithread
<
threads
.
length
;
ithread
++)
{
threads
[
ithread
]
=
new
Thread
()
{
public
void
run
()
{
for
(
int
i
=
ai
.
getAndIncrement
();
i
<
n
;
i
=
ai
.
getAndIncrement
())
{
L
[
i
][
fj
]
/=
Ljj
;
}
}
};
}
ImageDtt
.
startAndJoin
(
threads
);
if
(
debug
)
{
System
.
out
.
println
(
"CholeskyLDLTMulti(): j="
+
j
);
}
}
return
;
}
}
// L overwites strict lower A, d overwrites diagonal A
public
CholeskyLDLTMulti
(
Matrix
matA
,
int
mode
)
{
public
CholeskyLDLTMulti
(
Matrix
matA
,
int
[]
ii
)
{
// boolean debug = true;
int
dbg_j
=
100
;
// 1520;
n
=
matA
.
getRowDimension
();
n
=
matA
.
getRowDimension
();
// not needed
switch
(
mode
)
{
L
=
matA
.
getArray
();
// will be modified, copy externally if needed
case
0
:
L
=
CholeskyLDLTMulti_single
(
matA
);
break
;
final
double
[][]
a
=
matA
.
getArray
();
case
1
:
L
=
CholeskyLDLTMulti_multi
(
matA
);
break
;
final
Thread
[]
threads
=
ImageDtt
.
newThreadArray
();
case
2
:
L
=
CholeskyLDLTMulti_fast
(
matA
);
break
;
final
AtomicInteger
ai
=
new
AtomicInteger
(
0
);
default
:
L
=
CholeskyLDLTMulti_single
(
matA
);
}
}
public
double
[][]
CholeskyLDLTMulti_multi
(
Matrix
matA
)
{
final
double
[][]
a
=
matA
.
getArray
();
final
Thread
[]
threads
=
ImageDtt
.
newThreadArray
();
final
AtomicInteger
ai
=
new
AtomicInteger
(
0
);
final
AtomicInteger
ati
=
new
AtomicInteger
(
0
);
final
double
[]
ajj_threaded
=
new
double
[
threads
.
length
];
final
int
threads_chunk
=
(
int
)
(
n
/
(
thread_scale
*
threads
.
length
));
for
(
int
j
=
0
;
j
<
n
;
j
++)
{
for
(
int
j
=
0
;
j
<
n
;
j
++)
{
final
int
fj
=
j
;
final
int
fj
=
j
;
if
(
j
==
dbg_j
)
{
final
double
[]
aj
=
a
[
j
];
System
.
out
.
println
(
"CholeskyLDLTMulti(): j=dbg_j="
+
j
);
double
ajj
=
aj
[
j
];
}
if
(
j
>
threads_chunk
)
{
// use multithreaded
/*
Arrays
.
fill
(
ajj_threaded
,
0.0
);
if (j > 0) {
ai
.
set
(
0
);
ai
.
set
(
0
);
for (int ithread = 0; ithread < threads.length; ithread++) {
ati
.
set
(
0
);
for
(
int
ithread
=
0
;
ithread
<
threads
.
length
;
ithread
++)
{
// first sum for pairs
threads
[
ithread
]
=
new
Thread
()
{
threads
[
ithread
]
=
new
Thread
()
{
public
void
run
()
{
public
void
run
()
{
for (int i = ai.getAndIncrement(); i < fj; i = ai.getAndIncrement()) {
int
nthread
=
ati
.
getAndIncrement
();
a[fj][fj] -= a[i][i]*a[fj][i]*a[fj][i]; // squared
for
(
int
i0
=
ai
.
getAndAdd
(
threads_chunk
);
i0
<
fj
;
i0
=
ai
.
getAndAdd
(
threads_chunk
))
{
int
i1
=
Math
.
min
(
fj
,
i0
+
threads_chunk
);
for
(
int
i
=
i0
;
i
<
i1
;
i
++)
{
double
aji
=
aj
[
i
];
ajj_threaded
[
nthread
]
+=
a
[
i
][
i
]*
aji
*
aji
;
// squared
}
}
}
}
}
};
};
}
}
ImageDtt
.
startAndJoin
(
threads
);
ImageDtt
.
startAndJoin
(
threads
);
for
(
int
nthread
=
0
;
nthread
<
ajj_threaded
.
length
;
nthread
++)
{
ajj
-=
ajj_threaded
[
nthread
];
}
}
else
{
for
(
int
i
=
0
;
i
<
j
;
i
++)
{
// use aj, a, i
double
aji
=
aj
[
i
];
ajj
-=
a
[
i
][
i
]*
aji
*
aji
;
// squared
}
}
}
*/
aj
[
j
]
=
ajj
;
for
(
int
i
=
0
;
i
<
j
;
i
++)
{
// TODO: above run single-threaded for small, then multithreaded with post-accumulation of ajj
a
[
j
][
j
]
-=
a
[
i
][
i
]*
a
[
j
][
i
]*
a
[
j
][
i
];
// squared
if
((
n
-
j
+
1
)
>
threads_chunk
)
{
// use multithreaded
ai
.
set
(
j
+
1
);
for
(
int
ithread
=
0
;
ithread
<
threads
.
length
;
ithread
++)
{
threads
[
ithread
]
=
new
Thread
()
{
public
void
run
()
{
for
(
int
k0
=
ai
.
getAndAdd
(
threads_chunk
);
k0
<
n
;
k0
=
ai
.
getAndAdd
(
threads_chunk
))
{
int
k1
=
Math
.
min
(
n
,
k0
+
threads_chunk
);
for
(
int
k
=
k0
;
k
<
k1
;
k
++)
{
double
[]
ak
=
a
[
k
];
for
(
int
i
=
0
;
i
<
fj
;
i
++)
{
// ak, aj, i,
ak
[
fj
]
-=
a
[
i
][
i
]
*
ak
[
i
]
*
aj
[
i
];
}
ak
[
fj
]
/=
aj
[
fj
];
}
}
}
};
}
ImageDtt
.
startAndJoin
(
threads
);
}
else
{
// use single-threaded
for
(
int
k
=
j
+
1
;
k
<
n
;
k
++)
{
final
double
[]
ak
=
a
[
k
];
for
(
int
i
=
0
;
i
<
j
;
i
++)
{
// ak, aj, i,
ak
[
j
]
-=
a
[
i
][
i
]*
ak
[
i
]
*
aj
[
i
];
}
ak
[
j
]
/=
ajj
;
}
}
}
/* for (int i = 0; i < j; i++) {
a[j][j] -= a[i][i]*a[j][i]*a[j][i]; // squared
} */
for
(
int
k
=
j
+
1
;
k
<
n
;
k
++)
{
final
int
fk
=
k
;
/*
if (j > 0) {
ai.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int i = ai.getAndIncrement(); i < fj; i = ai.getAndIncrement()) {
a[fk][fj] -= a[i][i]* a[fk][i] * a[fj][i];
}
}
};
}
ImageDtt.startAndJoin(threads);
}
*/
for
(
int
i
=
0
;
i
<
j
;
i
++)
{
a
[
k
][
j
]
-=
a
[
i
][
i
]*
a
[
k
][
i
]
*
a
[
j
][
i
];
}
a
[
k
][
j
]
/=
a
[
j
][
j
];
}
/* for (int k = j+1; k < n; k++) {
for (int i = 0; i < j; i++) {
a[k][j] -= a[i][i]* a[k][i] * a[j][i];
}
a[k][j] /= a[j][j];
} */
}
}
return
;
// L = a;
return
a
;
}
}
public
CholeskyLDLTMulti
(
Matrix
matA
,
int
ii
)
{
// single-threaded
public
double
[][]
CholeskyLDLTMulti_fast
(
Matrix
matA
)
{
n
=
matA
.
getRowDimension
();
// not needed
// L = matA.getArray(); // will be modified, copy externally if needed
final
double
[][]
a
=
matA
.
getArray
();
for
(
int
j
=
0
;
j
<
n
;
j
++)
{
for
(
int
i
=
0
;
i
<
j
;
i
++)
{
a
[
j
][
j
]
-=
a
[
i
][
i
]*
a
[
j
][
i
]*
a
[
j
][
i
];
// squared
}
for
(
int
k
=
j
+
1
;
k
<
n
;
k
++)
{
for
(
int
i
=
0
;
i
<
j
;
i
++)
{
a
[
k
][
j
]
-=
a
[
i
][
i
]*
a
[
k
][
i
]
*
a
[
j
][
i
];
}
a
[
k
][
j
]
/=
a
[
j
][
j
];
}
}
L
=
a
;
return
;
}
public
CholeskyLDLTMulti
(
Matrix
matA
)
{
n
=
matA
.
getRowDimension
();
final
double
[][]
a
=
matA
.
getArray
();
final
double
[][]
a
=
matA
.
getArray
();
final
Thread
[]
threads
=
ImageDtt
.
newThreadArray
();
final
Thread
[]
threads
=
ImageDtt
.
newThreadArray
();
final
AtomicInteger
ai
=
new
AtomicInteger
(
0
);
final
AtomicInteger
ai
=
new
AtomicInteger
(
0
);
final
AtomicInteger
ati
=
new
AtomicInteger
(
0
);
final
AtomicInteger
ati
=
new
AtomicInteger
(
0
);
final
double
[]
ajj_threaded
=
new
double
[
threads
.
length
];
final
double
[]
ajj_threaded
=
new
double
[
threads
.
length
];
final
int
threads_chunk
=
(
int
)
(
n
/
(
thread_scale
*
threads
.
length
));
final
int
threads_chunk
=
(
int
)
(
n
/
(
thread_scale
*
threads
.
length
));
final
Integer
[]
slots_order
=
new
Integer
[
threads
.
length
];
// per-thread slot index
final
int
[]
slot_j
=
new
int
[
threads
.
length
];
// slot synchronized to this j (including)
final
double
[][][]
slots_a
=
new
double
[
threads
.
length
][
n
][
n
];
// copies of L in progress
Arrays
.
fill
(
slot_j
,
-
1
);
// Arrays.setAll(slots_order, i->i);
// for (int i = 0; i < slots_order.length; i++) {
// slots_order[i] = i;
// }
for
(
int
j
=
0
;
j
<
n
;
j
++)
{
for
(
int
j
=
0
;
j
<
n
;
j
++)
{
final
int
fj
=
j
;
final
int
fj
=
j
;
Arrays
.
setAll
(
slots_order
,
i
->
i
);
//https://stackoverflow.com/questions/68331291/how-do-i-reorder-another-array-based-on-a-sorted-array-java
Arrays
.
sort
(
slots_order
,
(
la
,
lb
)
->
slot_j
[
lb
]
-
slot_j
[
la
]);
// decreasing order
final
double
[]
aj
=
a
[
j
];
final
double
[]
aj
=
a
[
j
];
double
ajj
=
aj
[
j
];
double
ajj
=
aj
[
j
];
if
(
j
>
threads_chunk
)
{
// use multithreaded
if
(
j
>
threads_chunk
)
{
// use multithreaded
TEMPORARY MAKE IT ALWAYS SINGLE
Arrays
.
fill
(
ajj_threaded
,
0.0
);
Arrays
.
fill
(
ajj_threaded
,
0.0
);
ai
.
set
(
0
);
ai
.
set
(
0
);
ati
.
set
(
0
);
ati
.
set
(
0
);
for
(
int
ithread
=
0
;
ithread
<
threads
.
length
;
ithread
++)
{
// first sum for pairs
for
(
int
ithread
=
0
;
ithread
<
threads
.
length
;
ithread
++)
{
// first sum for pairs
threads
[
ithread
]
=
new
Thread
()
{
threads
[
ithread
]
=
new
Thread
()
{
public
void
run
()
{
public
void
run
()
{
int
nthread
=
ati
.
getAndIncrement
();
int
ithread
=
ati
.
getAndIncrement
();
double
[][]
local_a
;
for
(
int
i0
=
ai
.
getAndAdd
(
threads_chunk
);
i0
<
fj
;
i0
=
ai
.
getAndAdd
(
threads_chunk
))
{
for
(
int
i0
=
ai
.
getAndAdd
(
threads_chunk
);
i0
<
fj
;
i0
=
ai
.
getAndAdd
(
threads_chunk
))
{
int
slot
=
slots_order
[
ithread
];
local_a
=
slots_a
[
slot
];
int
local_j
=
slot_j
[
slot
];
if
(
local_j
<
fj
-
1
)
{
// catch up if needed
for
(
int
col
=
local_j
+
1
;
col
<
fj
;
col
++){
for
(
int
row
=
local_j
;
row
<
n
;
row
++)
{
local_a
[
row
][
col
]
=
a
[
row
][
col
];
// copying from global to local memory
}
}
slot_j
[
slot
]
=
fj
-
1
;
}
int
i1
=
Math
.
min
(
fj
,
i0
+
threads_chunk
);
int
i1
=
Math
.
min
(
fj
,
i0
+
threads_chunk
);
double
[]
local_aj
=
local_a
[
fj
];
for
(
int
i
=
i0
;
i
<
i1
;
i
++)
{
for
(
int
i
=
i0
;
i
<
i1
;
i
++)
{
double
aji
=
aj
[
i
];
double
aji
=
local_
aj
[
i
];
ajj_threaded
[
nthread
]
+=
a
[
i
][
i
]*
aji
*
aji
;
// squared
ajj_threaded
[
slot
]
+=
local_
a
[
i
][
i
]*
aji
*
aji
;
// squared
}
}
}
}
}
}
...
@@ -202,20 +174,45 @@ public class CholeskyLDLTMulti {
...
@@ -202,20 +174,45 @@ public class CholeskyLDLTMulti {
}
}
}
}
aj
[
j
]
=
ajj
;
aj
[
j
]
=
ajj
;
final
double
fajj
=
ajj
;
// use in all threads, a[j][j] is also valid
// TODO: above run single-threaded for small, then multithreaded with post-accumulation of ajj
// TODO: above run single-threaded for small, then multithreaded with post-accumulation of ajj
if
((
n
-
j
+
1
)
>
threads_chunk
)
{
// use multithreaded
if
((
n
-
j
+
1
)
>
threads_chunk
)
{
// use multithreaded
// re-evaluate slots, they could change after diagonal calculations
Arrays
.
setAll
(
slots_order
,
i
->
i
);
//https://stackoverflow.com/questions/68331291/how-do-i-reorder-another-array-based-on-a-sorted-array-java
Arrays
.
sort
(
slots_order
,
(
la
,
lb
)
->
slot_j
[
lb
]
-
slot_j
[
la
]);
// decreasing order
ai
.
set
(
j
+
1
);
ai
.
set
(
j
+
1
);
ati
.
set
(
0
);
for
(
int
ithread
=
0
;
ithread
<
threads
.
length
;
ithread
++)
{
for
(
int
ithread
=
0
;
ithread
<
threads
.
length
;
ithread
++)
{
threads
[
ithread
]
=
new
Thread
()
{
threads
[
ithread
]
=
new
Thread
()
{
public
void
run
()
{
public
void
run
()
{
int
ithread
=
ati
.
getAndIncrement
();
double
[][]
local_a
;
for
(
int
k0
=
ai
.
getAndAdd
(
threads_chunk
);
k0
<
n
;
k0
=
ai
.
getAndAdd
(
threads_chunk
))
{
for
(
int
k0
=
ai
.
getAndAdd
(
threads_chunk
);
k0
<
n
;
k0
=
ai
.
getAndAdd
(
threads_chunk
))
{
int
slot
=
slots_order
[
ithread
];
local_a
=
slots_a
[
slot
];
int
local_j
=
slot_j
[
slot
];
if
(
local_j
<
fj
-
1
)
{
// catch up if needed
for
(
int
col
=
local_j
+
1
;
col
<
fj
;
col
++){
for
(
int
row
=
col
;
row
<
n
;
row
++)
{
local_a
[
row
][
col
]
=
a
[
row
][
col
];
// copying from global to local memory
}
}
slot_j
[
slot
]
=
fj
-
1
;
}
double
[]
local_aj
=
local_a
[
fj
];
int
k1
=
Math
.
min
(
n
,
k0
+
threads_chunk
);
int
k1
=
Math
.
min
(
n
,
k0
+
threads_chunk
);
for
(
int
k
=
k0
;
k
<
k1
;
k
++)
{
for
(
int
k
=
k0
;
k
<
k1
;
k
++)
{
double
[]
ak
=
a
[
k
];
double
[]
local_ak
=
local_a
[
k
];
double
akj
=
local_ak
[
fj
];
for
(
int
i
=
0
;
i
<
fj
;
i
++)
{
// ak, aj, i,
for
(
int
i
=
0
;
i
<
fj
;
i
++)
{
// ak, aj, i,
ak
[
fj
]
-=
a
[
i
][
i
]
*
ak
[
i
]
*
aj
[
i
];
// ak[fj] -= a[i][i] * ak[i] * aj[i];
// local_ak[fj] -= local_a[i][i] * local_ak[i] * local_aj[i];
akj
-=
local_a
[
i
][
i
]
*
local_ak
[
i
]
*
local_aj
[
i
];
}
}
ak
[
fj
]
/=
aj
[
fj
];
// ak[fj] /= aj[fj];
a
[
k
][
fj
]
=
local_ak
[
fj
]
/
fajj
;
// write to global memory
a
[
k
][
fj
]
=
akj
/
fajj
;
// write to global memory
}
}
}
}
}
}
...
@@ -232,44 +229,34 @@ public class CholeskyLDLTMulti {
...
@@ -232,44 +229,34 @@ public class CholeskyLDLTMulti {
}
}
}
}
}
}
L
=
a
;
//
L = a;
return
;
return
a
;
}
}
public
double
[][]
CholeskyLDLTMulti_single
(
Matrix
matA
)
{
// single-threaded
public
CholeskyLDLTMulti
(
Matrix
matA
,
long
ll
)
{
// single-threaded
// n = matA.getRowDimension();
n
=
matA
.
getRowDimension
();
// not needed
// not needed
// L = matA.getArray(); // will be modified, copy externally if needed
final
double
[][]
a
=
matA
.
getArray
();
final
double
[][]
a
=
matA
.
getArray
();
for
(
int
j
=
0
;
j
<
n
;
j
++)
{
for
(
int
j
=
0
;
j
<
n
;
j
++)
{
final
double
[]
aj
=
a
[
j
];
for
(
int
i
=
0
;
i
<
j
;
i
++)
{
double
ajj
=
aj
[
j
];
a
[
j
][
j
]
-=
a
[
i
][
i
]*
a
[
j
][
i
]*
a
[
j
][
i
];
// squared
for
(
int
i
=
0
;
i
<
j
;
i
++)
{
// use aj, a, i
double
aji
=
aj
[
i
];
// a[j][j] -= a[i][i]*a[j][i]*a[j][i]; // squared
ajj
-=
a
[
i
][
i
]*
aji
*
aji
;
// squared
aj
[
j
]
-=
a
[
i
][
i
]*
aji
*
aji
;
// squared
}
}
aj
[
j
]
=
ajj
;
for
(
int
k
=
j
+
1
;
k
<
n
;
k
++)
{
for
(
int
k
=
j
+
1
;
k
<
n
;
k
++)
{
final
double
[]
ak
=
a
[
k
];
for
(
int
i
=
0
;
i
<
j
;
i
++)
{
for
(
int
i
=
0
;
i
<
j
;
i
++)
{
// ak, aj, i,
a
[
k
][
j
]
-=
a
[
i
][
i
]*
a
[
k
][
i
]
*
a
[
j
][
i
];
// a[k][j] -= a[i][i]* a[k][i] * a[j][i]; // use digonal
ak
[
j
]
-=
a
[
i
][
i
]*
ak
[
i
]
*
aj
[
i
];
}
}
// a[k][j] /= a[j][j];
a
[
k
][
j
]
/=
a
[
j
][
j
];
// ak[j] /= aj[j];
ak
[
j
]
/=
ajj
;
}
}
}
}
L
=
a
;
//
L = a;
return
;
return
a
;
}
}
public
Matrix
solve0
(
Matrix
B
)
{
// multithreaded
public
Matrix
solve0
(
Matrix
B
)
{
// multithreased
if
(
B
.
getRowDimension
()
!=
n
)
{
if
(
B
.
getRowDimension
()
!=
n
)
{
throw
new
IllegalArgumentException
(
"Matrix row dimensions must agree."
);
throw
new
IllegalArgumentException
(
"Matrix row dimensions must agree."
);
}
}
...
@@ -407,18 +394,56 @@ public class CholeskyLDLTMulti {
...
@@ -407,18 +394,56 @@ public class CholeskyLDLTMulti {
return
new
Matrix
(
x
,
n
);
return
new
Matrix
(
x
,
n
);
}
}
public
static
void
testCholesky
(
ImagePlus
imp_src
)
{
float
[]
fpixels
=
(
float
[])
imp_src
.
getProcessor
().
getPixels
();
int
width
=
imp_src
.
getWidth
();
int
height
=
imp_src
.
getHeight
();
int
n
=
height
;
double
[][]
a
=
new
double
[
n
][
n
];
double
[][]
b
=
new
double
[
n
][
1
];
for
(
int
i
=
0
;
i
<
n
;
i
++)
{
for
(
int
j
=
0
;
j
<
n
;
j
++)
{
a
[
i
][
j
]
=
fpixels
[
i
*
width
+
j
];
}
b
[
i
][
0
]
=
fpixels
[
i
*
width
+
n
];
}
testCholesky
(
new
Matrix
(
a
),
// Matrix wjtjlambda,
new
Matrix
(
b
));
// Matrix jty)
}
public
static
Matrix
[]
testCholesky
(
public
static
Matrix
[]
testCholesky
(
Matrix
wjtjlambda
,
Matrix
wjtjlambda
,
Matrix
jty
)
{
Matrix
jty
)
{
Matrix
wjtjlambda_copy0
=
new
Matrix
(
wjtjlambda
.
getArrayCopy
());
Matrix
wjtjlambda_copy0
=
new
Matrix
(
wjtjlambda
.
getArrayCopy
());
CholeskyDecomposition
choleskyDecomposition
=
new
CholeskyDecomposition
(
wjtjlambda_copy0
);
Matrix
wjtjlambda_copy1
=
new
Matrix
(
wjtjlambda
.
getArrayCopy
()
);
Matrix
wjtjlambda_copy2
=
new
Matrix
(
wjtjlambda
.
getArrayCopy
());
Matrix
wjtjlambda_copy
=
new
Matrix
(
wjtjlambda
.
getArrayCopy
());
Matrix
wjtjlambda_copy
=
new
Matrix
(
wjtjlambda
.
getArrayCopy
());
CholeskyLDLTMulti
choleskyLDLTMulti
=
new
CholeskyLDLTMulti
(
wjtjlambda_copy
);
double
[]
starts
=
new
double
[
7
];
double
start_time
=
(((
double
)
System
.
nanoTime
())
*
1
E
-
9
);
CholeskyDecomposition
choleskyDecomposition
=
new
CholeskyDecomposition
(
wjtjlambda_copy
);
starts
[
0
]
=
(((
double
)
System
.
nanoTime
())
*
1
E
-
9
)
-
start_time
;
CholeskyLDLTMulti
choleskyLDLTMulti_single
=
new
CholeskyLDLTMulti
(
wjtjlambda_copy0
,
0
);
starts
[
1
]
=
(((
double
)
System
.
nanoTime
())
*
1
E
-
9
)
-
start_time
;
CholeskyLDLTMulti
choleskyLDLTMulti_multi
=
new
CholeskyLDLTMulti
(
wjtjlambda_copy1
,
1
);
starts
[
2
]
=
(((
double
)
System
.
nanoTime
())
*
1
E
-
9
)
-
start_time
;
CholeskyLDLTMulti
choleskyLDLTMulti_fast
=
new
CholeskyLDLTMulti
(
wjtjlambda_copy2
,
2
);
starts
[
3
]
=
(((
double
)
System
.
nanoTime
())
*
1
E
-
9
)
-
start_time
;
CholeskyLDLTMulti
choleskyLDLTMulti
=
choleskyLDLTMulti_fast
;
Matrix
mdelta_cholesky
=
choleskyDecomposition
.
solve
(
jty
);
Matrix
mdelta_cholesky
=
choleskyDecomposition
.
solve
(
jty
);
starts
[
4
]
=
(((
double
)
System
.
nanoTime
())
*
1
E
-
9
)
-
start_time
;
Matrix
mdelta_cholesky_multi0
=
choleskyLDLTMulti
.
solve0
(
jty
);
Matrix
mdelta_cholesky_multi0
=
choleskyLDLTMulti
.
solve0
(
jty
);
starts
[
5
]
=
(((
double
)
System
.
nanoTime
())
*
1
E
-
9
)
-
start_time
;
Matrix
mdelta_cholesky_multi
=
choleskyLDLTMulti
.
solve
(
jty
);
Matrix
mdelta_cholesky_multi
=
choleskyLDLTMulti
.
solve
(
jty
);
starts
[
6
]
=
(((
double
)
System
.
nanoTime
())
*
1
E
-
9
)
-
start_time
;
System
.
out
.
println
(
"testCholesky(): choleskyDecomposition: "
+(
starts
[
0
])+
" sec"
);
System
.
out
.
println
(
"testCholesky(): choleskyLDLTMulti_single: "
+(
starts
[
1
]-
starts
[
0
])+
" sec"
);
System
.
out
.
println
(
"testCholesky(): choleskyLDLTMulti_multi: "
+(
starts
[
2
]-
starts
[
1
])+
" sec"
);
System
.
out
.
println
(
"testCholesky(): choleskyLDLTMulti_fast: "
+(
starts
[
3
]-
starts
[
2
])+
" sec"
);
System
.
out
.
println
(
"testCholesky(): mdelta_cholesky: "
+(
starts
[
4
]-
starts
[
3
])+
" sec"
);
System
.
out
.
println
(
"testCholesky(): mdelta_cholesky_multi0: "
+(
starts
[
5
]-
starts
[
4
])+
" sec"
);
System
.
out
.
println
(
"testCholesky(): mdelta_cholesky_multi: "
+(
starts
[
6
]-
starts
[
5
])+
" sec"
);
return
new
Matrix
[]
{
mdelta_cholesky
,
mdelta_cholesky_multi0
,
mdelta_cholesky_multi
};
return
new
Matrix
[]
{
mdelta_cholesky
,
mdelta_cholesky_multi0
,
mdelta_cholesky_multi
};
}
}
...
...
src/main/java/com/elphel/imagej/common/CholeskyLLTMulti.java
0 → 100644
View file @
3cedfc7a
package
com
.
elphel
.
imagej
.
common
;
import
java.util.Arrays
;
import
java.util.concurrent.atomic.AtomicInteger
;
import
com.elphel.imagej.tileprocessor.ImageDtt
;
import
Jama.CholeskyDecomposition
;
import
Jama.Matrix
;
import
ij.ImagePlus
;
public
class
CholeskyLLTMulti
{
public
final
int
n
;
public
final
double
[][]
L
;
public
int
solve_step
=
1
;
//0;
public
double
thread_scale
=
10
;
// 2.5; // split jobs in thread_scale * num_treads chunks
public
Matrix
getL
()
{
return
new
Matrix
(
L
,
n
,
n
);
}
public
CholeskyLLTMulti
(
Matrix
matA
,
int
mode
)
{
n
=
matA
.
getRowDimension
();
L
=
new
double
[
n
][
n
];
switch
(
mode
)
{
case
0
:
CholeskyLLTMulti_single
(
matA
);
break
;
case
1
:
CholeskyLLTMulti_multi
(
matA
);
break
;
case
2
:
CholeskyLLTMulti_fast
(
matA
);
break
;
default
:
CholeskyLLTMulti_single
(
matA
);
}
}
// Cholesky-Banachiewicz Algorithm ?
public
double
[][]
CholeskyLLTMulti_single
(
Matrix
mA
)
{
double
[][]
a
=
mA
.
getArray
();
// Main loop.
for
(
int
j
=
0
;
j
<
n
;
j
++)
{
double
[]
Lrowj
=
L
[
j
];
double
d
=
0.0
;
for
(
int
k
=
0
;
k
<
j
;
k
++)
{
double
[]
Lrowk
=
L
[
k
];
double
s
=
0.0
;
for
(
int
i
=
0
;
i
<
k
;
i
++)
{
s
+=
Lrowk
[
i
]*
Lrowj
[
i
];
}
Lrowj
[
k
]
=
s
=
(
a
[
j
][
k
]
-
s
)/
L
[
k
][
k
];
d
=
d
+
s
*
s
;
}
d
=
a
[
j
][
j
]
-
d
;
L
[
j
][
j
]
=
Math
.
sqrt
(
Math
.
max
(
d
,
0.0
));
// for (int k = j+1; k < n; k++) {
// L[j][k] = 0.0;
// }
}
return
L
;
}
public
double
[][]
CholeskyLLTMulti_multi
(
Matrix
mA
)
{
double
[][]
a
=
mA
.
getArray
();
final
Thread
[]
threads
=
ImageDtt
.
newThreadArray
();
final
AtomicInteger
ai
=
new
AtomicInteger
(
0
);
final
AtomicInteger
ati
=
new
AtomicInteger
(
0
);
final
int
threads_chunk
=
(
int
)
(
n
/
(
thread_scale
*
threads
.
length
));
final
double
[]
threads_d
=
new
double
[
threads
.
length
];
// Main loop.
for
(
int
j
=
0
;
j
<
n
;
j
++)
{
final
int
fj
=
j
;
final
double
[]
Lrowj
=
L
[
j
];
double
d
=
0.0
;
if
(
j
>
threads_chunk
)
{
ai
.
set
(
0
);
ati
.
set
(
0
);
Arrays
.
fill
(
threads_d
,
0.0
);
for
(
int
ithread
=
0
;
ithread
<
threads
.
length
;
ithread
++)
{
// first sum for pairs
threads
[
ithread
]
=
new
Thread
()
{
public
void
run
()
{
int
nthread
=
ati
.
getAndIncrement
();
for
(
int
k0
=
ai
.
getAndAdd
(
threads_chunk
);
k0
<
fj
;
k0
=
ai
.
getAndAdd
(
threads_chunk
))
{
int
k1
=
Math
.
min
(
fj
,
k0
+
threads_chunk
);
for
(
int
k
=
k0
;
k
<
k1
;
k
++)
{
double
[]
Lrowk
=
L
[
k
];
double
s
=
0.0
;
for
(
int
i
=
0
;
i
<
k
;
i
++)
{
s
+=
Lrowk
[
i
]*
Lrowj
[
i
];
}
s
=
(
a
[
fj
][
k
]
-
s
)/
L
[
k
][
k
];
Lrowj
[
k
]
=
s
;
threads_d
[
nthread
]
+=
s
*
s
;
}
}
}
};
}
ImageDtt
.
startAndJoin
(
threads
);
for
(
double
dt:
threads_d
)
d
+=
dt
;
}
else
{
for
(
int
k
=
0
;
k
<
j
;
k
++)
{
double
[]
Lrowk
=
L
[
k
];
double
s
=
0.0
;
for
(
int
i
=
0
;
i
<
k
;
i
++)
{
s
+=
Lrowk
[
i
]*
Lrowj
[
i
];
}
Lrowj
[
k
]
=
s
=
(
a
[
j
][
k
]
-
s
)/
L
[
k
][
k
];
d
=
d
+
s
*
s
;
}
}
d
=
a
[
j
][
j
]
-
d
;
L
[
j
][
j
]
=
Math
.
sqrt
(
Math
.
max
(
d
,
0.0
));
// for (int k = j+1; k < n; k++) {
// L[j][k] = 0.0;
// }
}
return
a
;
}
public
double
[][]
CholeskyLLTMulti_fast
(
Matrix
mA
)
{
double
[][]
a
=
mA
.
getArray
();
final
Thread
[]
threads
=
ImageDtt
.
newThreadArray
();
final
AtomicInteger
ai
=
new
AtomicInteger
(
0
);
final
AtomicInteger
ati
=
new
AtomicInteger
(
0
);
final
int
threads_chunk
=
(
int
)
(
n
/
(
thread_scale
*
threads
.
length
));
final
double
[]
threads_d
=
new
double
[
threads
.
length
];
// Main loop.
for
(
int
j
=
0
;
j
<
n
;
j
++)
{
final
int
fj
=
j
;
final
double
[]
Lrowj
=
L
[
j
];
double
d
=
0.0
;
// WRONG! parallel only for the inner-most (i), because k should progress consequently
if
(
j
>
threads_chunk
)
{
ai
.
set
(
0
);
ati
.
set
(
0
);
Arrays
.
fill
(
threads_d
,
0.0
);
for
(
int
ithread
=
0
;
ithread
<
threads
.
length
;
ithread
++)
{
// first sum for pairs
threads
[
ithread
]
=
new
Thread
()
{
public
void
run
()
{
int
nthread
=
ati
.
getAndIncrement
();
// double[] localLrowj = Lrowj.clone();
for
(
int
k0
=
ai
.
getAndAdd
(
threads_chunk
);
k0
<
fj
;
k0
=
ai
.
getAndAdd
(
threads_chunk
))
{
int
k1
=
Math
.
min
(
fj
,
k0
+
threads_chunk
);
for
(
int
k
=
k0
;
k
<
k1
;
k
++)
{
double
[]
Lrowk
=
L
[
k
];
double
s
=
0.0
;
for
(
int
i
=
0
;
i
<
k
;
i
++)
{
s
+=
Lrowk
[
i
]*
Lrowj
[
i
];
}
s
=
(
a
[
fj
][
k
]
-
s
)/
L
[
k
][
k
];
Lrowj
[
k
]
=
s
;
// write ***
threads_d
[
nthread
]
+=
s
*
s
;
}
}
}
};
}
ImageDtt
.
startAndJoin
(
threads
);
for
(
double
dt:
threads_d
)
d
+=
dt
;
}
else
{
for
(
int
k
=
0
;
k
<
j
;
k
++)
{
double
[]
Lrowk
=
L
[
k
];
double
s
=
0.0
;
for
(
int
i
=
0
;
i
<
k
;
i
++)
{
s
+=
Lrowk
[
i
]*
Lrowj
[
i
];
}
Lrowj
[
k
]
=
s
=
(
a
[
j
][
k
]
-
s
)/
L
[
k
][
k
];
d
=
d
+
s
*
s
;
}
}
d
=
a
[
j
][
j
]
-
d
;
L
[
j
][
j
]
=
Math
.
sqrt
(
Math
.
max
(
d
,
0.0
));
// write ***
// for (int k = j+1; k < n; k++) {
// L[j][k] = 0.0;
// }
}
return
a
;
}
public
Matrix
solve
(
Matrix
B
,
int
mode
)
{
switch
(
mode
)
{
case
0
:
return
solve_single
(
B
);
// case 1: return solve_multi (B);
// case 2: return solve_fast (B);
default
:
return
solve_single
(
B
);
}
}
/** Solve A*X = B
@param B A Matrix with as many rows as A and any number of columns.
@return X so that L*L'*X = B
@exception IllegalArgumentException Matrix row dimensions must agree.
@exception RuntimeException Matrix is not symmetric positive definite.
*/
public
Matrix
solve_single
(
Matrix
B
)
{
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
static
Matrix
solve_single
(
Matrix
B
,
Matrix
L_mat
)
{
double
[][]
L
=
L_mat
.
getArray
();
return
solve_single
(
B
,
L
);
}
public
static
Matrix
solve_single
(
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
static
void
testCholesky
(
ImagePlus
imp_src
)
{
float
[]
fpixels
=
(
float
[])
imp_src
.
getProcessor
().
getPixels
();
int
width
=
imp_src
.
getWidth
();
int
height
=
imp_src
.
getHeight
();
int
n
=
height
;
double
[][]
a
=
new
double
[
n
][
n
];
double
[][]
b
=
new
double
[
n
][
1
];
for
(
int
i
=
0
;
i
<
n
;
i
++)
{
for
(
int
j
=
0
;
j
<
n
;
j
++)
{
a
[
i
][
j
]
=
fpixels
[
i
*
width
+
j
];
}
b
[
i
][
0
]
=
fpixels
[
i
*
width
+
n
];
}
testCholesky
(
new
Matrix
(
a
),
// Matrix wjtjlambda,
new
Matrix
(
b
),
// Matrix jty)
imp_src
.
getTitle
());
// String title);
}
public
static
Matrix
[]
testCholesky
(
Matrix
wjtjlambda
,
Matrix
jty
,
String
title
)
{
int
block_size
=
70
;
// 64; // 60; // 70; // 80; // 120; // 150; // 200; // 100; // 4; // 10; // 100; // 28;
String
dbg_title
=
title
+
"ch_diff_choleskyBlock-choleskyDecomposition-"
+
block_size
;
Matrix
wjtjlambda_copy0
=
new
Matrix
(
wjtjlambda
.
getArrayCopy
());
Matrix
wjtjlambda_copy1
=
new
Matrix
(
wjtjlambda
.
getArrayCopy
());
Matrix
wjtjlambda_copy2
=
new
Matrix
(
wjtjlambda
.
getArrayCopy
());
Matrix
wjtjlambda_copy
=
new
Matrix
(
wjtjlambda
.
getArrayCopy
());
double
[]
starts
=
new
double
[
7
];
double
start_time
=
(((
double
)
System
.
nanoTime
())
*
1
E
-
9
);
CholeskyDecomposition
choleskyDecomposition
=
new
CholeskyDecomposition
(
wjtjlambda_copy
);
starts
[
0
]
=
(((
double
)
System
.
nanoTime
())
*
1
E
-
9
)
-
start_time
;
CholeskyLLTMulti
choleskyLLTMulti_single
=
new
CholeskyLLTMulti
(
wjtjlambda_copy0
,
0
);
starts
[
1
]
=
(((
double
)
System
.
nanoTime
())
*
1
E
-
9
)
-
start_time
;
CholeskyBlock
choleskyBlock
=
new
CholeskyBlock
(
wjtjlambda_copy1
.
getArray
(),
block_size
);
starts
[
2
]
=
(((
double
)
System
.
nanoTime
())
*
1
E
-
9
)
-
start_time
;
choleskyBlock
.
choleskyBlockMulti
();
starts
[
3
]
=
(((
double
)
System
.
nanoTime
())
*
1
E
-
9
)
-
start_time
;
double
[][]
LTriangle
=
choleskyBlock
.
get_LTriangle
();
Matrix
mdelta_cholesky
=
choleskyDecomposition
.
solve
(
jty
);
starts
[
4
]
=
(((
double
)
System
.
nanoTime
())
*
1
E
-
9
)
-
start_time
;
Matrix
mdelta_cholesky_single
=
CholeskyLLTMulti
.
solve_single
(
jty
,
choleskyLLTMulti_single
.
getL
());
starts
[
5
]
=
(((
double
)
System
.
nanoTime
())
*
1
E
-
9
)
-
start_time
;
Matrix
mdelta_cholesky_multi
=
CholeskyLLTMulti
.
solve_single
(
jty
,
LTriangle
);
starts
[
6
]
=
(((
double
)
System
.
nanoTime
())
*
1
E
-
9
)
-
start_time
;
System
.
out
.
println
(
"testCholesky(): block_size= "
+
block_size
);
System
.
out
.
println
(
"testCholesky(): choleskyDecomposition: "
+(
starts
[
0
])+
" sec"
);
System
.
out
.
println
(
"testCholesky(): choleskyLLTMulti_single:"
+(
starts
[
1
]-
starts
[
0
])+
" sec"
);
System
.
out
.
println
(
"testCholesky(): CholeskyBlock(): "
+
(
starts
[
2
]-
starts
[
1
])+
" sec"
);
System
.
out
.
println
(
"testCholesky(): choleskyBlockMulti(): "
+(
starts
[
3
]-
starts
[
2
])+
" sec"
);
System
.
out
.
println
(
"testCholesky(): get_LTriangle(): "
+(
starts
[
4
]-
starts
[
3
])+
" sec"
);
System
.
out
.
println
(
"testCholesky(): solve_single(,single): "
+(
starts
[
5
]-
starts
[
4
])+
" sec"
);
System
.
out
.
println
(
"testCholesky(): solve_single(,block): "
+(
starts
[
6
]-
starts
[
5
])+
" sec"
);
System
.
out
.
println
(
"testCholesky(): title= "
+
block_size
);
System
.
out
.
println
(
"testCholesky(): dbg_title= "
+
block_size
);
Matrix
ch_diff
=
choleskyLLTMulti_single
.
getL
().
minus
(
choleskyDecomposition
.
getL
());
Matrix
ch_diff_fast
=
choleskyBlock
.
getL
().
minus
(
choleskyDecomposition
.
getL
());
double
[][]
dbg_img
=
{
choleskyLLTMulti_single
.
getL
().
getRowPackedCopy
(),
choleskyBlock
.
getL
().
getRowPackedCopy
(),
choleskyDecomposition
.
getL
().
getRowPackedCopy
(),
ch_diff
.
getRowPackedCopy
(),
ch_diff_fast
.
getRowPackedCopy
()};
String
[]
dbg_titles
=
{
"choleskyLLTMulti_single"
,
"choleskyBlock"
,
"choleskyDecomposition"
,
"choleskyLLTMulti_single-choleskyDecomposition"
,
"choleskyBlock-choleskyDecomposition"
};
ShowDoubleFloatArrays
.
showArrays
(
dbg_img
,
// double[] pixels,
ch_diff
.
getRowDimension
(),
// int width,
ch_diff
.
getRowDimension
(),
// int height,
true
,
dbg_title
,
// String title)
dbg_titles
);
return
new
Matrix
[]
{
mdelta_cholesky
,
mdelta_cholesky_single
,
mdelta_cholesky_multi
};
}
public
static
Matrix
[]
testCholesky0
(
Matrix
wjtjlambda
,
Matrix
jty
)
{
int
block_size
=
128
;
Matrix
wjtjlambda_copy0
=
new
Matrix
(
wjtjlambda
.
getArrayCopy
());
Matrix
wjtjlambda_copy1
=
new
Matrix
(
wjtjlambda
.
getArrayCopy
());
Matrix
wjtjlambda_copy2
=
new
Matrix
(
wjtjlambda
.
getArrayCopy
());
Matrix
wjtjlambda_copy
=
new
Matrix
(
wjtjlambda
.
getArrayCopy
());
double
[]
starts
=
new
double
[
8
];
double
start_time
=
(((
double
)
System
.
nanoTime
())
*
1
E
-
9
);
CholeskyDecomposition
choleskyDecomposition
=
new
CholeskyDecomposition
(
wjtjlambda_copy
);
starts
[
0
]
=
(((
double
)
System
.
nanoTime
())
*
1
E
-
9
)
-
start_time
;
CholeskyLLTMulti
choleskyLLTMulti_single
=
new
CholeskyLLTMulti
(
wjtjlambda_copy0
,
0
);
starts
[
1
]
=
(((
double
)
System
.
nanoTime
())
*
1
E
-
9
)
-
start_time
;
CholeskyLLTMulti
choleskyLLTMulti_multi
=
new
CholeskyLLTMulti
(
wjtjlambda_copy1
,
1
);
starts
[
2
]
=
(((
double
)
System
.
nanoTime
())
*
1
E
-
9
)
-
start_time
;
CholeskyLLTMulti
choleskyLLTMulti_fast
=
new
CholeskyLLTMulti
(
wjtjlambda_copy2
,
2
);
starts
[
3
]
=
(((
double
)
System
.
nanoTime
())
*
1
E
-
9
)
-
start_time
;
CholeskyLLTMulti
choleskyLLTMulti
=
choleskyLLTMulti_multi
;
// fast;
Matrix
mdelta_cholesky
=
choleskyDecomposition
.
solve
(
jty
);
starts
[
4
]
=
(((
double
)
System
.
nanoTime
())
*
1
E
-
9
)
-
start_time
;
Matrix
mdelta_cholesky_single
=
choleskyLLTMulti
.
solve
(
jty
,
0
);
starts
[
5
]
=
(((
double
)
System
.
nanoTime
())
*
1
E
-
9
)
-
start_time
;
Matrix
mdelta_cholesky_multi
=
choleskyLLTMulti
.
solve
(
jty
,
1
);
starts
[
6
]
=
(((
double
)
System
.
nanoTime
())
*
1
E
-
9
)
-
start_time
;
Matrix
mdelta_cholesky_fast
=
choleskyLLTMulti
.
solve
(
jty
,
2
);
starts
[
7
]
=
(((
double
)
System
.
nanoTime
())
*
1
E
-
9
)
-
start_time
;
System
.
out
.
println
(
"testCholesky(): choleskyDecomposition: "
+(
starts
[
0
])+
" sec"
);
System
.
out
.
println
(
"testCholesky(): choleskyLLTMulti_single:"
+(
starts
[
1
]-
starts
[
0
])+
" sec"
);
System
.
out
.
println
(
"testCholesky(): choleskyLLTMulti_multi: "
+(
starts
[
2
]-
starts
[
1
])+
" sec"
);
System
.
out
.
println
(
"testCholesky(): choleskyLLTMulti_fast: "
+(
starts
[
3
]-
starts
[
2
])+
" sec"
);
System
.
out
.
println
(
"testCholesky(): mdelta_cholesky: "
+(
starts
[
4
]-
starts
[
3
])+
" sec"
);
System
.
out
.
println
(
"testCholesky(): mdelta_cholesky_single: "
+(
starts
[
5
]-
starts
[
4
])+
" sec"
);
System
.
out
.
println
(
"testCholesky(): mdelta_cholesky_multi: "
+(
starts
[
6
]-
starts
[
5
])+
" sec"
);
System
.
out
.
println
(
"testCholesky(): mdelta_cholesky_fast: "
+(
starts
[
7
]-
starts
[
6
])+
" sec"
);
Matrix
ch_diff
=
choleskyLLTMulti
.
getL
().
minus
(
choleskyDecomposition
.
getL
());
Matrix
ch_diff_fast
=
choleskyLLTMulti_fast
.
getL
().
minus
(
choleskyDecomposition
.
getL
());
double
[][]
dbg_img
=
{
choleskyLLTMulti
.
getL
().
getRowPackedCopy
(),
choleskyLLTMulti_fast
.
getL
().
getRowPackedCopy
(),
choleskyDecomposition
.
getL
().
getRowPackedCopy
(),
ch_diff
.
getRowPackedCopy
(),
ch_diff_fast
.
getRowPackedCopy
()};
String
[]
dbg_titles
=
{
"choleskyLLTMulti"
,
"choleskyLLTMulti_fast"
,
"choleskyDecomposition"
,
"choleskyLLTMulti-choleskyDecomposition"
,
"choleskyLLTMulti_fast-choleskyDecomposition"
};
ShowDoubleFloatArrays
.
showArrays
(
dbg_img
,
// double[] pixels,
ch_diff
.
getRowDimension
(),
// int width,
ch_diff
.
getRowDimension
(),
// int height,
true
,
"ch_diff_choleskyLLTMulti-choleskyDecomposition"
,
// String title)
dbg_titles
);
return
new
Matrix
[]
{
mdelta_cholesky
,
mdelta_cholesky_single
,
mdelta_cholesky_multi
,
mdelta_cholesky_fast
};
}
}
src/main/java/com/elphel/imagej/correction/Eyesis_Correction.java
View file @
3cedfc7a
...
@@ -96,6 +96,8 @@ import com.elphel.imagej.cameras.CLTParameters;
...
@@ -96,6 +96,8 @@ import com.elphel.imagej.cameras.CLTParameters;
import
com.elphel.imagej.cameras.ColorProcParameters
;
import
com.elphel.imagej.cameras.ColorProcParameters
;
import
com.elphel.imagej.cameras.EyesisCorrectionParameters
;
import
com.elphel.imagej.cameras.EyesisCorrectionParameters
;
import
com.elphel.imagej.cameras.ThermalColor
;
import
com.elphel.imagej.cameras.ThermalColor
;
import
com.elphel.imagej.common.CholeskyLDLTMulti
;
import
com.elphel.imagej.common.CholeskyLLTMulti
;
import
com.elphel.imagej.common.DoubleFHT
;
import
com.elphel.imagej.common.DoubleFHT
;
import
com.elphel.imagej.common.DoubleGaussianBlur
;
import
com.elphel.imagej.common.DoubleGaussianBlur
;
import
com.elphel.imagej.common.GenericJTabbedDialog
;
import
com.elphel.imagej.common.GenericJTabbedDialog
;
...
@@ -865,6 +867,8 @@ public class Eyesis_Correction implements PlugIn, ActionListener {
...
@@ -865,6 +867,8 @@ public class Eyesis_Correction implements PlugIn, ActionListener {
addButton
(
"Vegetation LMA"
,
panelOrange
,
color_process
);
addButton
(
"Vegetation LMA"
,
panelOrange
,
color_process
);
addButton
(
"Combine LMA Segments"
,
panelOrange
,
color_process
);
addButton
(
"Combine LMA Segments"
,
panelOrange
,
color_process
);
addButton
(
"Generate LWIR target"
,
panelOrange
,
color_process
);
addButton
(
"Generate LWIR target"
,
panelOrange
,
color_process
);
addButton
(
"Test LDLT Cholesky"
,
panelOrange
,
color_process
);
addButton
(
"Test LLT Cholesky"
,
panelOrange
,
color_process
);
plugInFrame
.
add
(
panelOrange
);
plugInFrame
.
add
(
panelOrange
);
}
}
plugInFrame
.
pack
();
plugInFrame
.
pack
();
...
@@ -5807,8 +5811,20 @@ public class Eyesis_Correction implements PlugIn, ActionListener {
...
@@ -5807,8 +5811,20 @@ public class Eyesis_Correction implements PlugIn, ActionListener {
SYNC_COMMAND
,
// // SyncCommand SYNC_COMMAND,
SYNC_COMMAND
,
// // SyncCommand SYNC_COMMAND,
CLT_PARAMETERS
,
//CLTParameters clt_parameters,
CLT_PARAMETERS
,
//CLTParameters clt_parameters,
true
);
//boolean combine_segments);
true
);
//boolean combine_segments);
}
else
if
(
label
.
equals
(
"Generate LWIR target"
))
{
}
else
if
(
label
.
equals
(
"Test LDLT Cholesky"
))
{
VegetationSegment
.
generateSineTarget
();
ImagePlus
imp_sel
=
WindowManager
.
getCurrentImage
();
if
(
imp_sel
==
null
)
{
IJ
.
showMessage
(
"Error"
,
"No images selected"
);
return
;
}
CholeskyLDLTMulti
.
testCholesky
(
imp_sel
);
// ImagePlus imp.);
}
else
if
(
label
.
equals
(
"Test LLT Cholesky"
))
{
ImagePlus
imp_sel
=
WindowManager
.
getCurrentImage
();
if
(
imp_sel
==
null
)
{
IJ
.
showMessage
(
"Error"
,
"No images selected"
);
return
;
}
CholeskyLLTMulti
.
testCholesky
(
imp_sel
);
// ImagePlus imp.);
}
}
//
//
}
}
...
...
src/main/java/com/elphel/imagej/vegetation/VegetationLMA.java
View file @
3cedfc7a
...
@@ -1907,9 +1907,32 @@ public class VegetationLMA {
...
@@ -1907,9 +1907,32 @@ public class VegetationLMA {
Matrix mdelta_cholesky = choleskyDecomposition.solve(jty);
Matrix mdelta_cholesky = choleskyDecomposition.solve(jty);
Matrix mdelta_cholesky_multi = choleskyLDLTMulti.solve(jty);
Matrix mdelta_cholesky_multi = choleskyLDLTMulti.solve(jty);
*/
*/
CholeskyLDLTMulti
.
testCholesky
(
boolean
save_cholesky
=
true
;
wjtjlambda
,
// Matrix wjtjlambda,
boolean
debug_cholesky
=
true
;
jty
);
if
(
save_cholesky
)
{
int
dbg_n
=
wjtjlambda
.
getRowDimension
();
double
[]
dbg_a0
=
wjtjlambda
.
getRowPackedCopy
();
double
[]
dbg_a
=
new
double
[
dbg_n
*(
dbg_n
+
1
)];
for
(
int
i
=
0
;
i
<
dbg_n
;
i
++)
{
System
.
arraycopy
(
dbg_a0
,
i
*
dbg_n
,
dbg_a
,
i
*(
dbg_n
+
1
),
dbg_n
);
dbg_a
[(
i
+
1
)*(
dbg_n
+
1
)-
1
]
=
jty
.
get
(
i
,
0
);
}
ShowDoubleFloatArrays
.
showArrays
(
dbg_a
,
// double[] pixels,
dbg_n
+
1
,
// int width,
dbg_n
,
// int height,
"spd_a_"
+
debug_iter
);
// String title)
}
if
(
debug_cholesky
)
{
CholeskyLDLTMulti
.
testCholesky
(
wjtjlambda
,
// Matrix wjtjlambda,
jty
);
}
if
(
debug_level
>
2
)
{
if
(
debug_level
>
2
)
{
System
.
out
.
println
(
"mdelta"
);
System
.
out
.
println
(
"mdelta"
);
mdelta
.
print
(
18
,
6
);
mdelta
.
print
(
18
,
6
);
...
...
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