package edu.stanford.rsl.conrad.reconstruction.iterative;
import edu.stanford.rsl.conrad.data.numeric.Grid3D;
import edu.stanford.rsl.conrad.data.numeric.NumericPointwiseOperators;
public class huberPenalty {
public float beta = 0.1f;
public float delta = 0.01f;
public huberPenalty( float beta, float delta ){
this.beta = beta;
this.delta = delta;
}
public float huber( Grid3D u ){
float R = 0.0f;
float deltaSh = delta * delta / 2;
final int maxI = u.getSize()[0];
final int maxJ = u.getSize()[1];
final int maxK = u.getSize()[2];
for (int i = 0; i < maxI-1; i++) {
for (int j = 0; j < maxJ-1; j++) {
for (int k = 0; k < maxK; k++) {
float d1 = Math.abs( u.getAtIndex(i, j, k) - u.getAtIndex(i+1, j, k) );
float d2 = Math.abs( u.getAtIndex(i, j, k) - u.getAtIndex(i, j+1, k) );
if ( d1 < delta ){
R = R + d1 * d1 / 2;
}else{
R = R + delta * d1 - deltaSh;
}
if ( d2 < delta ){
R = R + d2 * d2 / 2;
}else{
R = R + delta * d2 - deltaSh;
}
}
}
}
R = R * beta;
return R;
}
public void huberDerivative( Grid3D u, Grid3D s ){
final int maxI = u.getSize()[0];
final int maxJ = u.getSize()[1];
final int maxK = u.getSize()[2];
NumericPointwiseOperators.fill(s , 0.0f );
if (maxI != s.getSize()[0] || maxJ != s.getSize()[1]
|| maxK != s.getSize()[2])
System.out.print("Wrong Size! \n");
for (int i = 0; i < maxI-1; i++) {
for (int j = 0; j < maxJ-1; j++) {
for (int k = 0; k < maxK; k++) {
float d1 = u.getAtIndex(i, j, k) - u.getAtIndex(i+1, j, k) ;
float d2 = u.getAtIndex(i, j, k) - u.getAtIndex(i, j+1, k) ;
if ( d1 < delta ){
d1 = - delta;
}
if ( d1 > delta ){
d1 = delta;
}
if ( d2 < delta ){
d2 = - delta;
}
if ( d1 > delta ){
d2 = delta;
}
s.setAtIndex(i, j, k, ( s.getAtIndex(i, j, k) + d1 + d2 ) );
s.setAtIndex(i+1, j, k, ( s.getAtIndex(i+1, j, k) - d2 ) );
s.setAtIndex(i, j+1, k, ( s.getAtIndex(i, j+1, k) - d2 ) );
}
}
}
NumericPointwiseOperators.multiplyBy(s, beta );
return;
}
public void huberCurvature( Grid3D u, Grid3D s ){
final int maxI = u.getSize()[0];
final int maxJ = u.getSize()[1];
final int maxK = u.getSize()[2];
NumericPointwiseOperators.fill(s , 0.0f );
if (maxI != s.getSize()[0] || maxJ != s.getSize()[1]
|| maxK != s.getSize()[2])
System.out.print("Wrong Size! \n");
for (int i = 0; i < maxI-1; i++) {
for (int j = 0; j < maxJ-1; j++) {
for (int k = 0; k < maxK; k++) {
float d1 = Math.abs( u.getAtIndex(i, j, k) - u.getAtIndex(i+1, j, k) );
float d2 = Math.abs( u.getAtIndex(i, j, k) - u.getAtIndex(i, j+1, k) );
if ( d1 > delta ){
s.setAtIndex(i, j, k, ( s.getAtIndex(i, j, k) + 1 ) );
s.setAtIndex(i+1, j, k, ( s.getAtIndex(i+1, j, k) - 1 ) );
}
if ( d2 > delta ){
s.setAtIndex(i, j, k, ( s.getAtIndex(i, j, k) + 1 ) );
s.setAtIndex(i, j+1, k, ( s.getAtIndex(i, j+1, k) - 1 ) );
}
}
}
}
NumericPointwiseOperators.multiplyBy(s, beta );
return;
}
}
/*
* Copyright (C) 2010-2014 Meng Wu
* CONRAD is developed as an Open Source project under the GNU General Public License (GPL).
*/