Program: 26225
Project: 26225
Buggy source:
/** 
 * Evaluate the similarity between the source and the target images but also the transformation regularization and and landmarks energy term if necessary. Multi-threading version.
 * @param c Input: Deformation coefficients
 * @param intervals Input: Number of intervals for the deformation
 * @param grad Output: Gradient of the similarity
 * @param only_image Input: if true, only the image term is considered and not the regularization
 * @param bIsReverse Input: flag to determine the transformation direction (target-source=FALSE or source-target=TRUE)
 * @return images similarity value
 */
private double evaluateSimilarityMultiThread(final double[] c,final int intervals,double[] grad,final boolean only_image,boolean bIsReverse){
  final BSplineModel auxTarget=(!bIsReverse) ? target : source;
  final BSplineModel auxSource=(!bIsReverse) ? source : target;
  final Mask auxTargetMsk=(!bIsReverse) ? targetMsk : sourceMsk;
  final Mask auxSourceMsk=(!bIsReverse) ? sourceMsk : targetMsk;
  final PointHandler auxTargetPh=(!bIsReverse) ? targetPh : sourcePh;
  final PointHandler auxSourcePh=(!bIsReverse) ? sourcePh : targetPh;
  final BSplineModel swx=(!bIsReverse) ? swxTargetToSource : swxSourceToTarget;
  final BSplineModel swy=(!bIsReverse) ? swyTargetToSource : swySourceToTarget;
  final double auxFactorWidth=(!bIsReverse) ? this.target.getFactorWidth() : this.sourceFactorWidth;
  final double auxFactorHeight=(!bIsReverse) ? this.target.getFactorHeight() : this.sourceFactorHeight;
  final double P11[][]=(!bIsReverse) ? this.P11_TargetToSource : this.P11_SourceToTarget;
  final double P12[][]=(!bIsReverse) ? this.P12_TargetToSource : this.P12_SourceToTarget;
  final double P22[][]=(!bIsReverse) ? this.P22_TargetToSource : this.P12_SourceToTarget;
  final int auxTargetCurrentWidth=(!bIsReverse) ? this.targetCurrentWidth : this.sourceCurrentWidth;
  final int auxTargetCurrentHeight=(!bIsReverse) ? this.targetCurrentHeight : this.sourceCurrentHeight;
  final int cYdim=intervals + 3;
  final int cXdim=cYdim;
  final int Nk=cYdim * cXdim;
  final int twiceNk=2 * Nk;
  final double[] vgradreg=new double[grad.length];
  final double[] vgradland=new double[grad.length];
  swx.setCoefficients(c,cYdim,cXdim,0);
  swy.setCoefficients(c,cYdim,cXdim,Nk);
  for (int k=0; k < twiceNk; k++)   vgradreg[k]=vgradland[k]=grad[k]=0.0F;
  double imageSimilarity=0.0;
  if (imageWeight != 0) {
    final int nproc=Runtime.getRuntime().availableProcessors();
    int block_height=auxTargetCurrentHeight / nproc;
    if (auxTargetCurrentHeight % 2 != 0)     block_height++;
    final int nThreads=nproc;
    Thread[] threads=new Thread[nThreads];
    Rectangle[] rects=new Rectangle[nThreads];
    final double[][] grad_thread=new double[nThreads][grad.length];
    final double[][] result=new double[nThreads][2];
    int n=0;
    for (int i=0; i < nThreads; i++) {
      int y_start=i * block_height;
      if (nThreads - 1 == i)       block_height=auxTargetCurrentHeight - i * block_height;
      rects[i]=new Rectangle(0,y_start,auxTargetCurrentWidth,block_height);
      threads[i]=new Thread(new EvaluateSimilarityTile(auxTarget,auxSource,auxTargetMsk,auxSourceMsk,swx,swy,auxFactorWidth,auxFactorHeight,intervals,grad_thread[i],result[i],rects[i]));
      threads[i].start();
    }
    for (int i=0; i < nThreads; i++) {
      try {
        threads[i].join();
        threads[i]=null;
      }
 catch (      InterruptedException e) {
        e.printStackTrace();
      }
    }
    for (int i=0; i < nThreads; i++) {
      imageSimilarity+=result[i][0];
      n+=result[i][1];
    }
    imageSimilarity/=n;
    for (int i=0; i < nThreads; i++) {
      for (int j=0; j < grad.length; j++)       grad[j]+=(grad_thread[i][j] / n);
    }
  }
  double regularization=0.0;
  if (!only_image) {
    for (int i=0; i < Nk; i++)     for (int j=0; j < Nk; j++) {
      regularization+=c[i] * P11[i][j] * c[j] + c[Nk + i] * P22[i][j] * c[Nk + j] + c[i] * P12[i][j] * c[Nk + j];
      vgradreg[i]+=2 * P11[i][j] * c[j];
      vgradreg[Nk + i]+=2 * P22[i][j] * c[Nk + j];
      vgradreg[i]+=P12[i][j] * c[Nk + j];
      vgradreg[Nk + i]+=P12[j][i] * c[j];
    }
    regularization*=1.0 / (auxTargetCurrentHeight * auxTargetCurrentWidth);
    for (int k=0; k < twiceNk; k++)     vgradreg[k]*=1.0 / (auxTargetCurrentHeight * auxTargetCurrentWidth);
  }
  double landmarkError=0.0;
  int K=0;
  if (auxTargetPh != null)   K=auxTargetPh.getPoints().size();
  if (landmarkWeight != 0) {
    Vector<Point> sourceVector=null;
    if (auxSourcePh != null)     sourceVector=auxSourcePh.getPoints();
 else     sourceVector=new Vector<Point>();
    Vector<Point> targetVector=null;
    if (auxTargetPh != null)     targetVector=auxTargetPh.getPoints();
 else     targetVector=new Vector<Point>();
    for (int kp=0; kp < K; kp++) {
      final Point sourcePoint=(Point)sourceVector.elementAt(kp);
      final Point targetPoint=(Point)targetVector.elementAt(kp);
      double u=auxFactorWidth * (double)targetPoint.x;
      double v=auxFactorHeight * (double)targetPoint.y;
      double tu=(double)(u * intervals) / (double)(auxTargetCurrentWidth - 1) + 1.0F;
      double tv=(double)(v * intervals) / (double)(auxTargetCurrentHeight - 1) + 1.0F;
      swx.prepareForInterpolation(tu,tv,false);
      double x=swx.interpolateI();
      swy.prepareForInterpolation(tu,tv,false);
      double y=swy.interpolateI();
      double dx=auxFactorWidth * (double)sourcePoint.x - x;
      double dy=auxFactorHeight * (double)sourcePoint.y - y;
      landmarkError+=dx * dx + dy * dy;
      for (int l=0; l < 4; l++)       for (int m=0; m < 4; m++) {
        if (swx.yIndex[l] == -1 || swx.xIndex[m] == -1)         continue;
        int k=swx.yIndex[l] * cYdim + swx.xIndex[m];
        vgradland[k]-=dx * swx.getWeightI(l,m);
        vgradland[k + Nk]-=dy * swy.getWeightI(l,m);
      }
    }
  }
  if (K != 0) {
    landmarkError*=landmarkWeight / K;
    double aux=2.0 * landmarkWeight / K;
    for (int k=0; k < twiceNk; k++)     vgradland[k]*=aux;
  }
  if (only_image)   landmarkError=0;
  for (int k=0; k < twiceNk; k++)   grad[k]+=vgradreg[k] + vgradland[k];
  if (showMarquardtOptim) {
    String s=bIsReverse ? new String("String_Node_Str") : new String("String_Node_Str");
    if (imageWeight != 0) {
      IJ.log("String_Node_Str" + s + "String_Node_Str"+ imageSimilarity);
      if (bIsReverse)       this.partialInverseSimilarityError=imageSimilarity;
 else       this.partialDirectSimilarityError=imageSimilarity;
    }
    if (landmarkWeight != 0) {
      IJ.log("String_Node_Str" + s + "String_Node_Str"+ landmarkError);
      if (bIsReverse)       this.partialInverseLandmarkError=landmarkError;
 else       this.partialDirectLandmarkError=landmarkError;
    }
    if (divWeight != 0 || curlWeight != 0) {
      IJ.log("String_Node_Str" + s + "String_Node_Str"+ regularization);
      if (bIsReverse)       this.partialInverseRegularizationError=regularization;
 else       this.partialDirectRegularizationError=regularization;
    }
  }
  return imageSimilarity + landmarkError + regularization;
}

Fixed version (ground truth):
/** 
 * Evaluate the similarity between the source and the target images but also the transformation regularization and and landmarks energy term if necessary. Multi-threading version.
 * @param c Input: Deformation coefficients
 * @param intervals Input: Number of intervals for the deformation
 * @param grad Output: Gradient of the similarity
 * @param only_image Input: if true, only the image term is considered and not the regularization
 * @param bIsReverse Input: flag to determine the transformation direction (target-source=FALSE or source-target=TRUE)
 * @return images similarity value
 */
private double evaluateSimilarityMultiThread(final double[] c,final int intervals,double[] grad,final boolean only_image,boolean bIsReverse){
  final BSplineModel auxTarget=(!bIsReverse) ? target : source;
  final BSplineModel auxSource=(!bIsReverse) ? source : target;
  final Mask auxTargetMsk=(!bIsReverse) ? targetMsk : sourceMsk;
  final Mask auxSourceMsk=(!bIsReverse) ? sourceMsk : targetMsk;
  final PointHandler auxTargetPh=(!bIsReverse) ? targetPh : sourcePh;
  final PointHandler auxSourcePh=(!bIsReverse) ? sourcePh : targetPh;
  final BSplineModel swx=(!bIsReverse) ? swxTargetToSource : swxSourceToTarget;
  final BSplineModel swy=(!bIsReverse) ? swyTargetToSource : swySourceToTarget;
  final double auxFactorWidth=(!bIsReverse) ? this.target.getFactorWidth() : this.sourceFactorWidth;
  final double auxFactorHeight=(!bIsReverse) ? this.target.getFactorHeight() : this.sourceFactorHeight;
  final double P11[][]=(!bIsReverse) ? this.P11_TargetToSource : this.P11_SourceToTarget;
  final double P12[][]=(!bIsReverse) ? this.P12_TargetToSource : this.P12_SourceToTarget;
  final double P22[][]=(!bIsReverse) ? this.P22_TargetToSource : this.P12_SourceToTarget;
  final int auxTargetCurrentWidth=(!bIsReverse) ? this.targetCurrentWidth : this.sourceCurrentWidth;
  final int auxTargetCurrentHeight=(!bIsReverse) ? this.targetCurrentHeight : this.sourceCurrentHeight;
  final int cYdim=intervals + 3;
  final int cXdim=cYdim;
  final int Nk=cYdim * cXdim;
  final int twiceNk=2 * Nk;
  final double[] vgradreg=new double[grad.length];
  final double[] vgradland=new double[grad.length];
  swx.setCoefficients(c,cYdim,cXdim,0);
  swy.setCoefficients(c,cYdim,cXdim,Nk);
  for (int k=0; k < twiceNk; k++)   vgradreg[k]=vgradland[k]=grad[k]=0.0F;
  double imageSimilarity=0.0;
  if (imageWeight != 0) {
    final int nproc=Runtime.getRuntime().availableProcessors();
    int block_height=auxTargetCurrentHeight / nproc;
    final int nThreads=nproc;
    Thread[] threads=new Thread[nThreads];
    Rectangle[] rects=new Rectangle[nThreads];
    final double[][] grad_thread=new double[nThreads][grad.length];
    final double[][] result=new double[nThreads][2];
    int n=0;
    for (int i=0; i < nThreads; i++) {
      int y_start=i * block_height;
      if (nThreads - 1 == i)       block_height=auxTargetCurrentHeight - i * block_height;
      rects[i]=new Rectangle(0,y_start,auxTargetCurrentWidth,block_height);
      threads[i]=new Thread(new EvaluateSimilarityTile(auxTarget,auxSource,auxTargetMsk,auxSourceMsk,swx,swy,auxFactorWidth,auxFactorHeight,intervals,grad_thread[i],result[i],rects[i]));
      threads[i].start();
    }
    for (int i=0; i < nThreads; i++) {
      try {
        threads[i].join();
        threads[i]=null;
      }
 catch (      InterruptedException e) {
        e.printStackTrace();
      }
    }
    for (int i=0; i < nThreads; i++) {
      imageSimilarity+=result[i][0];
      n+=result[i][1];
    }
    imageSimilarity/=n;
    for (int i=0; i < nThreads; i++) {
      for (int j=0; j < grad.length; j++)       grad[j]+=(grad_thread[i][j] / n);
    }
  }
  double regularization=0.0;
  if (!only_image) {
    for (int i=0; i < Nk; i++)     for (int j=0; j < Nk; j++) {
      regularization+=c[i] * P11[i][j] * c[j] + c[Nk + i] * P22[i][j] * c[Nk + j] + c[i] * P12[i][j] * c[Nk + j];
      vgradreg[i]+=2 * P11[i][j] * c[j];
      vgradreg[Nk + i]+=2 * P22[i][j] * c[Nk + j];
      vgradreg[i]+=P12[i][j] * c[Nk + j];
      vgradreg[Nk + i]+=P12[j][i] * c[j];
    }
    regularization*=1.0 / (auxTargetCurrentHeight * auxTargetCurrentWidth);
    for (int k=0; k < twiceNk; k++)     vgradreg[k]*=1.0 / (auxTargetCurrentHeight * auxTargetCurrentWidth);
  }
  double landmarkError=0.0;
  int K=0;
  if (auxTargetPh != null)   K=auxTargetPh.getPoints().size();
  if (landmarkWeight != 0) {
    Vector<Point> sourceVector=null;
    if (auxSourcePh != null)     sourceVector=auxSourcePh.getPoints();
 else     sourceVector=new Vector<Point>();
    Vector<Point> targetVector=null;
    if (auxTargetPh != null)     targetVector=auxTargetPh.getPoints();
 else     targetVector=new Vector<Point>();
    for (int kp=0; kp < K; kp++) {
      final Point sourcePoint=(Point)sourceVector.elementAt(kp);
      final Point targetPoint=(Point)targetVector.elementAt(kp);
      double u=auxFactorWidth * (double)targetPoint.x;
      double v=auxFactorHeight * (double)targetPoint.y;
      double tu=(double)(u * intervals) / (double)(auxTargetCurrentWidth - 1) + 1.0F;
      double tv=(double)(v * intervals) / (double)(auxTargetCurrentHeight - 1) + 1.0F;
      swx.prepareForInterpolation(tu,tv,false);
      double x=swx.interpolateI();
      swy.prepareForInterpolation(tu,tv,false);
      double y=swy.interpolateI();
      double dx=auxFactorWidth * (double)sourcePoint.x - x;
      double dy=auxFactorHeight * (double)sourcePoint.y - y;
      landmarkError+=dx * dx + dy * dy;
      for (int l=0; l < 4; l++)       for (int m=0; m < 4; m++) {
        if (swx.yIndex[l] == -1 || swx.xIndex[m] == -1)         continue;
        int k=swx.yIndex[l] * cYdim + swx.xIndex[m];
        vgradland[k]-=dx * swx.getWeightI(l,m);
        vgradland[k + Nk]-=dy * swy.getWeightI(l,m);
      }
    }
  }
  if (K != 0) {
    landmarkError*=landmarkWeight / K;
    double aux=2.0 * landmarkWeight / K;
    for (int k=0; k < twiceNk; k++)     vgradland[k]*=aux;
  }
  if (only_image)   landmarkError=0;
  for (int k=0; k < twiceNk; k++)   grad[k]+=vgradreg[k] + vgradland[k];
  if (showMarquardtOptim) {
    String s=bIsReverse ? new String("String_Node_Str") : new String("String_Node_Str");
    if (imageWeight != 0) {
      IJ.log("String_Node_Str" + s + "String_Node_Str"+ imageSimilarity);
      if (bIsReverse)       this.partialInverseSimilarityError=imageSimilarity;
 else       this.partialDirectSimilarityError=imageSimilarity;
    }
    if (landmarkWeight != 0) {
      IJ.log("String_Node_Str" + s + "String_Node_Str"+ landmarkError);
      if (bIsReverse)       this.partialInverseLandmarkError=landmarkError;
 else       this.partialDirectLandmarkError=landmarkError;
    }
    if (divWeight != 0 || curlWeight != 0) {
      IJ.log("String_Node_Str" + s + "String_Node_Str"+ regularization);
      if (bIsReverse)       this.partialInverseRegularizationError=regularization;
 else       this.partialDirectRegularizationError=regularization;
    }
  }
  return imageSimilarity + landmarkError + regularization;
}