/***************************************************************************
* RK45.cpp *
* ------------------- *
* copyright : (C) 2012 by Francisco Naveros *
* email : fnaveros@atc.ugr.es *
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 3 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include <math.h>
#include "../../include/integration_method/RK45.h"
#include "../../include/neuron_model/TimeDrivenNeuronModel.h"
RK45::RK45(TimeDrivenNeuronModel * NewModel, int N_neuronStateVariables, int N_differentialNeuronState, int N_timeDependentNeuronState):FixedStep(NewModel, "RK45", N_neuronStateVariables, N_differentialNeuronState, N_timeDependentNeuronState, false, false),
a1(25.0f/216.0f), a2(0), a3(1408.0f/2565.0f), a4(2197.0f/4104.0f), a5(-0.2f),
b1(16.0f/135.0f), b2(0), b3(6656.0f/12825.0f), b4(28561.0f/56430.0f), b5(-0.18f), b6(2.0f/55.0f),
c20(0.25f), c21(0.25f),
c30(0.375f), c31(0.09375f), c32(0.28125f),
c40(12.0f/13.0f), c41(1932.0f/2197.0f), c42(-7200.0f/2197.0f), c43(7296.0f/2197.0f),
c51(439.0f/216.0f), c52(-8.0f), c53(439.0f/216.0f), c54(-845.0f/4104.0f),
c60(0.5f), c61(-8.0f/27.0f), c62(2), c63(-3544.0f/2565.0f), c64(1859.0f/4104.0f), c65(-0.275f)
{
}
RK45::~RK45(){
}
void RK45::NextDifferentialEcuationValue(int index, float * NeuronState, float elapsed_time){
float AuxNeuronState[MAX_VARIABLES];
float AuxNeuronState1[MAX_VARIABLES];
float AuxNeuronState2[MAX_VARIABLES];
float AuxNeuronState3[MAX_VARIABLES];
float AuxNeuronState4[MAX_VARIABLES];
float AuxNeuronState5[MAX_VARIABLES];
float AuxNeuronState6[MAX_VARIABLES];
float x4[MAX_VARIABLES];
//1st term
model->EvaluateDifferentialEcuation(NeuronState, AuxNeuronState1);
//2nd term
memcpy(AuxNeuronState, NeuronState,sizeof(float)*N_NeuronStateVariables);
for (int j=0; j<N_DifferentialNeuronState; j++){
AuxNeuronState[j]= NeuronState[j] + c21*AuxNeuronState1[j]*elapsed_time;
}
model->EvaluateTimeDependentEcuation(AuxNeuronState, c20*elapsed_time);
model->EvaluateDifferentialEcuation(AuxNeuronState, AuxNeuronState2);
//3rd term
for (int j=0; j<N_DifferentialNeuronState; j++){
AuxNeuronState[j]=NeuronState[j] + (c31*AuxNeuronState1[j] + c32*AuxNeuronState2[j])*elapsed_time;
}
model->EvaluateTimeDependentEcuation(AuxNeuronState, c30*elapsed_time);
model->EvaluateDifferentialEcuation(AuxNeuronState, AuxNeuronState3);
//4rd term
for (int j=0; j<N_DifferentialNeuronState; j++){
AuxNeuronState[j]=NeuronState[j] + (c41*AuxNeuronState1[j] + c42*AuxNeuronState2[j] + c43*AuxNeuronState3[j])*elapsed_time;
}
model->EvaluateTimeDependentEcuation(AuxNeuronState, c40*elapsed_time);
model->EvaluateDifferentialEcuation(AuxNeuronState, AuxNeuronState4);
//5rd term
for (int j=0; j<N_DifferentialNeuronState; j++){
AuxNeuronState[j]=NeuronState[j] + (c51*AuxNeuronState1[j] + c52*AuxNeuronState2[j] + c53*AuxNeuronState3[j] + c54*AuxNeuronState4[j])*elapsed_time;
}
model->EvaluateTimeDependentEcuation(AuxNeuronState, elapsed_time);
model->EvaluateDifferentialEcuation(AuxNeuronState, AuxNeuronState5);
//6rd term
for (int j=0; j<N_DifferentialNeuronState; j++){
AuxNeuronState[j]=NeuronState[j] + (c61*AuxNeuronState1[j] + c62*AuxNeuronState2[j] + c63*AuxNeuronState3[j] + c64*AuxNeuronState4[j] + c65*AuxNeuronState5[j])*elapsed_time;
}
model->EvaluateTimeDependentEcuation(AuxNeuronState, c60*elapsed_time);
model->EvaluateDifferentialEcuation(AuxNeuronState, AuxNeuronState6);
for (int j=0; j<N_DifferentialNeuronState; j++){
x4[j]=NeuronState[j] + (a1*AuxNeuronState1[j] + a3*AuxNeuronState3[j] + a4*AuxNeuronState4[j] + a5*AuxNeuronState5[j])*elapsed_time;
NeuronState[j]+=(b1*AuxNeuronState1[j] + b3*AuxNeuronState3[j] + b4*AuxNeuronState4[j] + b5*AuxNeuronState5[j] + b6*AuxNeuronState6[j])*elapsed_time;
epsilon[index]+=fabs(NeuronState[j]-x4[j]);
}
model->EvaluateTimeDependentEcuation(NeuronState, elapsed_time);
}
ostream & RK45::PrintInfo(ostream & out){
out << "Integration Method Type: " << this->GetType() << endl;
return out;
}
void RK45::InitializeStates(int N_neurons, float * initialization){
this->epsilon=new float(N_neurons);
}