コード例 #1
0
void calculateJacobian(const arma::Mat<std::complex<double> >& myOffsets,
		       arma::Mat<double>& myJacobian, 
		       arma::Col<std::complex<double> >& myTargetsCalculated, 
		       arma::Col<std::complex<double> >& myCurrentGuess, 
		       void myCalculateDependentVariables(const arma::Mat<std::complex<double> >&, const arma::Col<std::complex<double> >&, arma::Col<std::complex<double> >&))
{
	//Calculate a temporary, unperturbed target evaluation, such as is needed for solving for the updated guess 
	//formula
	arma::Col<std::complex<double> > unperturbedTargetsCalculated(NUMDIMENSIONS);
	unperturbedTargetsCalculated.fill(0.0);
	myCalculateDependentVariables(myOffsets, myCurrentGuess, unperturbedTargetsCalculated);
	std::complex<double> oldGuessValue(0.0, 0.0);

	//Each iteration fills a column in the Jacobian
	//The Jacobian takes this form:
	//
	//	dF0/dx0 dF0/dx1 
	//	dF1/dx0 dF1/dx1
	//
	for(int j = 0; j< NUMDIMENSIONS; j++)
	{
		//Store old element value, perturb the current value
		oldGuessValue = myCurrentGuess[j];
		myCurrentGuess[j] += std::complex<double>(0.0, PROBEDISTANCE);

		//Evaluate functions for perturbed guess
		myCalculateDependentVariables(myOffsets, myCurrentGuess, myTargetsCalculated);

		//The column of the Jacobian that goes with the independent variable we perturbed
		//can be determined using the finite-difference formula
		//The arma::Col allows this to be expressed as a single vector operation
		//note slice works as: std::slice(start_index, number_of_elements_to_access, index_interval_between_selections)
		//std::cout << "Jacobian column " << j << " with:" << std::endl;
		//std::cout << "myTargetsCalculated" << std::endl;
		//std::cout << myTargetsCalculated << std::endl;
		//std::cout << "unperturbedTargetsCalculated" << std::endl;
		//std::cout << unperturbedTargetsCalculated << std::endl;
		myJacobian.col(j) = arma::imag(myTargetsCalculated);
	       	myJacobian.col(j) *= pow(PROBEDISTANCE, -1.0);
		//std::cout << "The jacobian: " << std::endl;
		//std::cout << myJacobian << std::endl;

		myCurrentGuess[j] = oldGuessValue;
	}

	//Reset to unperturbed, so we dont waste a function evaluation
	myTargetsCalculated = unperturbedTargetsCalculated;
}
コード例 #2
0
void calculateJacobian(const Teuchos::SerialDenseMatrix<int, std::complex<double> >& myOffsets,
		       Teuchos::SerialDenseMatrix<int, std::complex<double> >& myJacobian, 
		       Teuchos::SerialDenseVector<int, std::complex<double> >& myTargetsCalculated, 
		       Teuchos::SerialDenseVector<int, std::complex<double> >& myUnperturbedTargetsCalculated,
		       Teuchos::SerialDenseVector<int, std::complex<double> >& myCurrentGuess, 
		       void myCalculateDependentVariables(const Teuchos::SerialDenseMatrix<int, std::complex<double> >&, const Teuchos::SerialDenseVector<int, std::complex<double> >&, Teuchos::SerialDenseVector<int, std::complex<double> >&)
		)
{

	//Calculate a temporary, unperturbed target evaluation, such as is needed for the finite-difference
	//formula
	myCalculateDependentVariables(myOffsets, myCurrentGuess, myUnperturbedTargetsCalculated);
	std::complex<double> oldGuessValue;

	//Each iteration fills a column in the Jacobian
	//The Jacobian takes this form:
	//
	//	dF0/dx0 dF0/dx1 
	//	dF1/dx0 dF1/dx1
	//
	//
	for(int column = 0; column< NUMDIMENSIONS; column++)
	{
		//Store old element value, perturb the current value
		oldGuessValue = myCurrentGuess[column];
		myCurrentGuess[column] += std::complex<double>(0.0, PROBEDISTANCE);

		//Evaluate functions for perturbed guess
		myCalculateDependentVariables(myOffsets, myCurrentGuess, myTargetsCalculated);

		myTargetsCalculated *= pow(PROBEDISTANCE, -1.0);

		for(int row = 0; row < NUMDIMENSIONS; row ++)
		{
			myJacobian(row, column) = std::imag(myTargetsCalculated[row]);
		}

		myCurrentGuess[column] = oldGuessValue;
	}

	//Reset to unperturbed, so we dont waste a function evaluation
	
	myTargetsCalculated = myUnperturbedTargetsCalculated;
}