def apply_nonlinear(self, inputs, outputs, residuals): """ Calculate the residual for each balance. Parameters ---------- inputs : Vector Unscaled, dimensional input variables read via inputs[key]. outputs : Vector Unscaled, dimensional output variables read via outputs[key]. residuals : Vector Unscaled, dimensional residuals written to via residuals[key]. """ for name, options in self._state_vars.items(): lhs = inputs[options['lhs_name']] rhs = inputs[options['rhs_name']] _scale_factor = np.ones((rhs.shape)) if options['normalize']: # Indices where the rhs is near zero or not near zero idxs_nz = np.where(cs_safe.abs(rhs) < 2) idxs_nnz = np.where(cs_safe.abs(rhs) >= 2) # Compute scaling factors # scale factor that normalizes by the rhs, except near 0 _scale_factor[idxs_nnz] = 1.0 / cs_safe.abs(rhs[idxs_nnz]) _scale_factor[idxs_nz] = 1.0 / (.25 * rhs[idxs_nz]**2 + 1) if options['use_mult']: residuals[name] = (inputs[options['mult_name']] * lhs - rhs) * _scale_factor else: residuals[name] = (lhs - rhs) * _scale_factor
def compute(self, inputs, outputs): """ Calculate the output for each equality constraint. Parameters ---------- inputs : Vector Unscaled, dimensional input variables read via inputs[key]. outputs : Vector Unscaled, dimensional output variables read via outputs[key]. """ for name, options in self._output_vars.items(): lhs = inputs[options['lhs_name']] rhs = inputs[options['rhs_name']] _scale_factor = np.ones((rhs.shape)) # Compute scaling factors # scale factor that normalizes by the rhs, except near 0 if options['normalize']: # Indices where the rhs is near zero or not near zero idxs_nz = np.where(cs_safe.abs(rhs) < 2) idxs_nnz = np.where(cs_safe.abs(rhs) >= 2) _scale_factor[idxs_nnz] = 1.0 / cs_safe.abs(rhs[idxs_nnz]) _scale_factor[idxs_nz] = 1.0 / (.25 * rhs[idxs_nz]**2 + 1) if options['use_mult']: outputs[name] = (inputs[options['mult_name']] * lhs - rhs) * _scale_factor else: outputs[name] = (lhs - rhs) * _scale_factor
def linearize(self, inputs, outputs, jacobian): """ Calculate the partials of the residual for each balance. Parameters ---------- inputs : Vector unscaled, dimensional input variables read via inputs[key] outputs : Vector unscaled, dimensional output variables read via outputs[key] jacobian : Jacobian sub-jac components written to jacobian[output_name, input_name] """ if inputs._under_complex_step: self._dscale_drhs = self._dscale_drhs.astype(np.complex) else: self._dscale_drhs = self._dscale_drhs.real for name, options in self._state_vars.items(): lhs_name = options['lhs_name'] rhs_name = options['rhs_name'] lhs = inputs[lhs_name] rhs = inputs[rhs_name] if options['normalize']: # Indices where the rhs is near zero or not near zero idxs_nz = np.where(cs_safe.abs(rhs) < 2)[0] idxs_nnz = np.where(cs_safe.abs(rhs) >= 2)[0] # scale factor that normalizes by the rhs, except near 0 self._scale_factor[idxs_nnz] = 1.0 / cs_safe.abs(rhs[idxs_nnz]) self._scale_factor[idxs_nz] = 1.0 / (.25 * rhs[idxs_nz]**2 + 1) self._dscale_drhs[idxs_nnz] = -np.sign( rhs[idxs_nnz]) / rhs[idxs_nnz]**2 self._dscale_drhs[idxs_nz] = -.5 * rhs[idxs_nz] / ( .25 * rhs[idxs_nz]**2 + 1)**2 else: self._scale_factor[:] = 1.0 self._dscale_drhs[:] = 0.0 if options['use_mult']: mult_name = options['mult_name'] mult = inputs[mult_name] # Partials of residual wrt mult deriv = lhs * self._scale_factor jacobian[name, mult_name] = deriv.flatten() else: mult = 1.0 # Partials of residual wrt rhs deriv = (mult * lhs - rhs) * self._dscale_drhs - self._scale_factor jacobian[name, rhs_name] = deriv.flatten() # Partials of residual wrt lhs deriv = mult * self._scale_factor jacobian[name, lhs_name] = deriv.flatten()
def linearize(self, inputs, outputs, jacobian): """ Calculate the partials of the residual for each balance. Parameters ---------- inputs : Vector Unscaled, dimensional input variables read via inputs[key]. outputs : Vector Unscaled, dimensional output variables read via outputs[key]. jacobian : Jacobian Sub-jac components written to jacobian[output_name, input_name]. """ for name, options in self._state_vars.items(): lhs_name = options['lhs_name'] rhs_name = options['rhs_name'] lhs = inputs[lhs_name] rhs = inputs[rhs_name] _scale_factor = np.ones((rhs.shape)) _dscale_drhs = np.zeros((rhs.shape)) if options['normalize']: # Indices where the rhs is near zero or not near zero idxs_nz = np.where(cs_safe.abs(rhs) < 2)[0] idxs_nnz = np.where(cs_safe.abs(rhs) >= 2)[0] # scale factor that normalizes by the rhs, except near 0 _scale_factor[idxs_nnz] = 1.0 / cs_safe.abs(rhs[idxs_nnz]) _scale_factor[idxs_nz] = 1.0 / (.25 * rhs[idxs_nz]**2 + 1) _dscale_drhs[idxs_nnz] = -np.sign( rhs[idxs_nnz]) / rhs[idxs_nnz]**2 _dscale_drhs[idxs_nz] = -.5 * rhs[idxs_nz] / ( .25 * rhs[idxs_nz]**2 + 1)**2 if options['use_mult']: mult_name = options['mult_name'] mult = inputs[mult_name] # Partials of residual wrt mult deriv = lhs * _scale_factor jacobian[name, mult_name] = deriv.flatten() else: mult = 1.0 # Partials of residual wrt rhs deriv = (mult * lhs - rhs) * _dscale_drhs - _scale_factor jacobian[name, rhs_name] = deriv.flatten() # Partials of residual wrt lhs deriv = mult * _scale_factor jacobian[name, lhs_name] = deriv.flatten()
def test_abs(self): test_data = np.array([1, -1, -2, 2, 5.675, -5.676], dtype='complex') assert_near_equal(cs_safe.abs(test_data), np.abs(test_data)) test_data += complex(0, 1e-50) cs_derivs = cs_safe.abs(test_data).imag / 1e-50 expected = [1, -1, -1, 1, 1, -1] assert_near_equal(cs_derivs, expected)
def compute_partials(self, inputs, partials): """ Compute sub-jacobian parts. The model is assumed to be in an unscaled state. Parameters ---------- inputs : Vector Unscaled, dimensional input variables read via inputs[key]. partials : Jacobian Sub-jac components written to partials[output_name, input_name]. """ for name, options in self._output_vars.items(): lhs_name = options['lhs_name'] rhs_name = options['rhs_name'] lhs = inputs[lhs_name] rhs = inputs[rhs_name] _scale_factor = np.ones((rhs.shape)) _dscale_drhs = np.zeros((rhs.shape)) if options['normalize']: # Indices where the rhs is near zero or not near zero idxs_nz = np.where(cs_safe.abs(rhs) < 2) idxs_nnz = np.where(cs_safe.abs(rhs) >= 2) # scale factor that normalizes by the rhs, except near 0 _scale_factor[idxs_nnz] = 1.0 / cs_safe.abs(rhs[idxs_nnz]) _scale_factor[idxs_nz] = 1.0 / (.25 * rhs[idxs_nz]**2 + 1) _dscale_drhs[idxs_nnz] = -np.sign( rhs[idxs_nnz]) / rhs[idxs_nnz]**2 _dscale_drhs[idxs_nz] = -.5 * rhs[idxs_nz] / ( .25 * rhs[idxs_nz]**2 + 1)**2 if options['use_mult']: mult_name = options['mult_name'] mult = inputs[mult_name] # Partials of output wrt mult deriv = lhs * _scale_factor partials[name, mult_name] = deriv.flatten() else: mult = 1.0 # Partials of output wrt rhs deriv = (mult * lhs - rhs) * _dscale_drhs - _scale_factor partials[name, rhs_name] = deriv.flatten() # Partials of output wrt lhs deriv = mult * _scale_factor partials[name, lhs_name] = deriv.flatten()
def apply_nonlinear(self, inputs, outputs, residuals): """ Calculate the residual for each balance. Parameters ---------- inputs : Vector unscaled, dimensional input variables read via inputs[key] outputs : Vector unscaled, dimensional output variables read via outputs[key] residuals : Vector unscaled, dimensional residuals written to via residuals[key] """ if inputs._under_complex_step: self._scale_factor = self._scale_factor.astype(np.complex) else: self._scale_factor = self._scale_factor.real for name, options in self._state_vars.items(): lhs = inputs[options['lhs_name']] rhs = inputs[options['rhs_name']] if options['normalize']: # Indices where the rhs is near zero or not near zero idxs_nz = np.where(cs_safe.abs(rhs) < 2)[0] idxs_nnz = np.where(cs_safe.abs(rhs) >= 2)[0] # Compute scaling factors # scale factor that normalizes by the rhs, except near 0 self._scale_factor[idxs_nnz] = 1.0 / cs_safe.abs(rhs[idxs_nnz]) self._scale_factor[idxs_nz] = 1.0 / (.25 * rhs[idxs_nz]**2 + 1) else: self._scale_factor[:] = 1.0 if options['use_mult']: residuals[name] = (inputs[options['mult_name']] * lhs - rhs) * self._scale_factor else: residuals[name] = (lhs - rhs) * self._scale_factor
def func(x=np.ones(3)*-2.0): y=2.0*abs(x) return y
def func(x=-2.0): y=2.0*abs(x) return y