Shapeworks Studio  2.1
Shape analysis software suite
itkPSMTwoCostFunction.hxx
1 /*=========================================================================
2  *
3  * Copyright Insight Software Consortium
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0.txt
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *=========================================================================*/
18 #ifndef __itkPSMTwoCostFunction_hxx
19 #define __itkPSMTwoCostFunction_hxx
20 #include "itkPSMTwoCostFunction.h"
21 
22 namespace itk
23 {
24 
25 template <unsigned int VDimension>
28 ::Evaluate(unsigned int idx, unsigned int d,
29  const ParticleSystemType *system,
30  double &maxmove) const
31 {
32  double maxA, maxB;
33  maxA = 0;
34  maxB = 0;
35  VectorType ansA;
36  ansA.fill(0.0);
37  VectorType ansB;
38  ansB.fill(0.0);
39 
40  const_cast<PSMTwoCostFunction *>(this)->m_Counter = m_Counter + 1.0;
41 
42  // Evaluate A if it is turned on
43  if (m_AOn)
44  {
45  ansA = m_FunctionA->Evaluate(idx, d, system, maxA);
46  const_cast<PSMTwoCostFunction *>(this)->m_AverageGradMagA = m_AverageGradMagA + ansA.magnitude();
47  }
48 
49  // Evaluate B if it is turned on
50  if (m_BOn)
51  {
52  ansB = m_FunctionB->Evaluate(idx, d, system, maxB);
53  const_cast<PSMTwoCostFunction *>(this)->m_AverageGradMagB = m_AverageGradMagB + ansB.magnitude();
54  }
55 
56  // Compute maximum move and return the predicted move for current configuration
57  if (m_BOn)
58  {
59  if (m_AOn) // both A and B are active
60  {
61  if (maxA > maxB) maxmove = maxB;
62  else maxmove = maxA;
63  return (ansA + m_RelativeGradientScaling * ansB);
64  }
65  else // B is active, A is not active
66  {
67  maxmove = maxB;
68  return ansB;
69  }
70  }
71  else // only A is active
72  {
73  maxmove = maxA;
74  return ansA;
75  }
76 
77  // If nothing is turned on, then return a max time
78  // step of 0 and a bogus vector.
79  maxmove = 0.0;
80  return ansA;
81 }
82 
83 template <unsigned int VDimension>
86 ::Evaluate(unsigned int idx, unsigned int d,
87  const ParticleSystemType *system,
88  double &maxmove, double &energy) const
89 {
90  double maxA = 0.0;
91  double maxB = 0.0;
92  double energyA = 0.0;
93  double energyB = 0.0;
94  VectorType ansA; ansA.fill(0.0);
95  VectorType ansB; ansB.fill(0.0);
96 
97  const_cast<PSMTwoCostFunction *>(this)->m_Counter = m_Counter + 1.0;
98 
99  // evaluate individual functions: A = surface energy, B = correspondence, C = normal entropy
100  if (m_AOn)
101  {
102  ansA = m_FunctionA->Evaluate(idx, d, system, maxA, energyA);
103 
104  const_cast<PSMTwoCostFunction *>(this)->m_AverageGradMagA = m_AverageGradMagA + ansA.magnitude();
105  const_cast<PSMTwoCostFunction *>(this)->m_AverageEnergyA = m_AverageEnergyA + energyA;
106  }
107 
108  if (m_BOn)
109  {
110  ansB = m_FunctionB->Evaluate(idx, d, system, maxB, energyB);
111 
112  const_cast<PSMTwoCostFunction *>(this)->m_AverageGradMagB = m_AverageGradMagB + ansB.magnitude();
113  const_cast<PSMTwoCostFunction *>(this)->m_AverageEnergyB = m_AverageEnergyB + energyB;
114  }
115 
116  // Compute the final energy, maxmove and predicted move based on
117  // current configuration of A and B
118  if (m_BOn)
119  {
120  if (m_AOn) // both A and B are active
121  {
122  if (maxA > maxB) maxmove = maxB;
123  else maxmove = maxA;
124  energy = energyA + m_RelativeEnergyScaling * energyB;
125  return (ansA + m_RelativeGradientScaling * ansB);
126  }
127  else // only B is active, A is not active
128  {
129  maxmove = maxB;
130  energy = energyB;
131  return ansB;
132  }
133  }
134  else // only A is active
135  {
136  maxmove = maxA;
137  energy = energyA;
138  return ansA;
139  }
140 
141  // If nothing is turned on, then return a max time
142  // step of 0 and a bogus vector.
143  maxmove = 0.0;
144  return ansA;
145 }
146 
147 template <unsigned int VDimension>
148 double
150 ::Energy(unsigned int idx, unsigned int d,
151  const ParticleSystemType *system) const
152 {
153  double ansA = 0.0;
154  double ansB = 0.0;
155 
156  if (m_AOn ) ansA = m_FunctionA->Energy(idx, d, system);
157  if (m_BOn ) ansB = m_FunctionB->Energy(idx, d, system);
158 
159  // Compute the final energy for the current configuration of A and
160  // B
161  if (m_BOn )
162  {
163  if (m_AOn ) // both A and B are active
164  { return ansA + m_RelativeEnergyScaling * ansB; }
165  else // B is active, A is not active
166  { return ansB;}
167  }
168 
169  else // only A is active
170  { return ansA; }
171 
172  return 0.0;
173 }
174 
175 } // end namespace itk
176 
177 #endif
virtual VectorType Evaluate(unsigned int idx, unsigned int d, const ParticleSystemType *system, double &maxmove) const
A facade class that manages interactions with a particle system.
vnl_vector_fixed< double, VDimension > VectorType
Superclass::VectorType VectorType