Kaynağa Gözat

управление через параметр

master
gvitbsord 10 ay önce
ebeveyn
işleme
75c7d79384
11 değiştirilmiş dosya ile 82 ekleme ve 210 silme
  1. 1
    1
      draghilevinout.cpp
  2. 12
    1
      main.cpp
  3. 14
    2
      octaveplg.cpp
  4. 1
    1
      octaveplg.h
  5. 13
    6
      solver.cpp
  6. 0
    180
      src/ginac/parser/lexer.cpp
  7. 30
    10
      sysdiffeqn.cpp
  8. 2
    2
      sysdiffeqn.h
  9. 2
    2
      sysosndan.cpp
  10. 5
    3
      sysosndan.h
  11. 2
    2
      virteqn.h

+ 1
- 1
draghilevinout.cpp Dosyayı Görüntüle

@@ -12,7 +12,7 @@ draghilevinout::draghilevinout(int argc, char *argv[]) :
#endif
nodel("n", "nodel", "Не удалять сду", cmd, false),
nocomp("c", "nocomp", "Не компилировать сду, если она существует", cmd, false),
nocpp("p", "nocpp", "Не удалять сду-файл, если он существует", cmd, false),
nocpp("p", "nocpp", "Не удалять/перезаписывать сду-файл, если он существует", cmd, false),
benchmark("b", "benchmark", "Формирование m-файла для тестирования производительности", cmd, false),
inp_file("inp_file", "Чтение из входного файла", false, "example.txt", "входной файл", cmd),
out_file("o", "outfile","Запись в выходной файл", false, "", "выходной файл", cmd),

+ 12
- 1
main.cpp Dosyayı Görüntüle

@@ -47,6 +47,7 @@ DEFUN_DLD (draghilev_oct, args, , "Draghilev method")
double N=DATA.get_par_diff().N;
int N_var=DATA.get_par_diff().nv;
double dt=DATA.get_par_diff().dt;
int N_upr=DATA.get_par_diff().up.size();//число управляющих параметро

if ( args.length() == 2)
{
@@ -66,10 +67,20 @@ DEFUN_DLD (draghilev_oct, args, , "Draghilev method")
for (int i=0;i<nrow;i++)
for (int j=0;j<N_var;j++)
res_matrix(i,j)=DATA.get_resOUT()[t++];
retval(0)=res_matrix;
retval(1)=dt;

if (N_upr != 0 )
{
int t=0;
Matrix upr_matrix(nrow, N_upr);
for (int i=0;i<nrow;i++)
for (int j=0;j<N_upr;j++)
upr_matrix(i,j)=DATA.get_uprOUT()[t++];
retval(2)=upr_matrix;
}

return retval;
}
#endif

+ 14
- 2
octaveplg.cpp Dosyayı Görüntüle

@@ -6,6 +6,7 @@ octaveplg::octaveplg(sys_osn_dan &sod_, sys_diff_equation &sde_, std::string &na
n_svob=sod->get_par_diff().nsv;
equations=sod->get_par_diff().eqn;
dim_line=sod->get_par_diff().dln;
est_upr=sod->get_par_diff().up.size();
vp_num=sde->get_ginacdata().vpnum;
circ_num=sde->get_ginacdata().cnum;
circ_coord=sde->get_ginacdata().ccord;
@@ -21,18 +22,27 @@ void octaveplg::octave_m()
for (auto i: x)
out << (i) << " ";
out << "\n#}\n\n" << "clear all;\n\n";

if (bench_m)
out << "#b_var=logspace(,);\n" << "for iter=1:columns(b_var)\n" <<"clear sol error_eqn;\n";
out << "tic();\n";

if (est_upr != 0)
out << "[sol dt upr]=";
else
out << "[sol dt]=";

if (bench_m)
out<< "[sol dt]=draghilev_oct(-1,b_var(iter));\n";
out << "draghilev_oct(-1,b_var(iter));\n";
else
out<< "[sol dt]=draghilev_oct;\n";
out << "draghilev_oct;\n";
out<< "draghilev_time=toc();\n" << "num=rows(sol);\n" << "N_col=columns(sol);\n";

if (n_svob != 1)
{
out << "if (mod(num, " << n_svob <<") != 0)\n num=num-mod(num," << n_svob << ");\n" << "endif\n\n";
out << "sol=sol(1:num,:);\n";

for (int i=0;i<dim_line;i++)
out << coord_nam[i] << " = (sol(1:" << n_svob << ":end, " << i+1 << ":" << dim_line << ":N_col) + sol(2:" << n_svob << ":end, " << i+1 << ":" << dim_line << ":N_col))/" << n_svob << ";\n";
}
@@ -42,10 +52,12 @@ void octaveplg::octave_m()
out << "\n"<< eqn_stream.rdbuf();
out << "\n"<< error_stream.rdbuf();

if (bench_m)
out << "err_bench(iter,:)=max_error;\n" << "time_bench(iter,:)=draghilev_time;\n" <<"endfor\n\n" << "loglog(time_bench, err_bench, \"marker\", \"o\", \"linestyle\", \"none\");\n"<<"xlabel(\"Время, с\");\n"<<"ylabel(\"Максимальная абсолютная погрешность по модулю\");\n"<<"set (gca, \"ygrid\", \"on\");";
else
write_graphic_tom();

octout<<out.str();
octout.close();
}

+ 1
- 1
octaveplg.h Dosyayı Görüntüle

@@ -16,7 +16,7 @@ class octaveplg
state_type x;
int n_svob;
int dim_line;
bool bench_m;
bool bench_m, est_upr;
std::vector<std::string> equations;
std::vector<int> vp_num;
std::vector<int> circ_num;

+ 13
- 6
solver.cpp Dosyayı Görüntüle

@@ -1,4 +1,5 @@
#include "solver.h"
//#include <iostream>

solver_diff_eqn::solver_diff_eqn(sys_osn_dan &sod_, double exit_tol):sod(&sod_)
{
@@ -26,12 +27,13 @@ solver_diff_eqn::solver_diff_eqn(sys_osn_dan &sod_, double exit_tol):sod(&sod_)
// std::vector<double> temvec{-.6,.2,-2};
double l_dt=0, r_dt=dt;
coordinate.insert(coordinate.end(), x.begin(), x.end());
const state_type x0=x;
const state_type x0=x;//начальная точка
state_type _upr_par={0};

if ( exit_tol>0 )
{
c1_=x;
for (unsigned int i = 0; i < x.size(); i++)
for (size_t i = 0; i < x.size(); i++)
if (x[i] <= 0)
max_x.push_back(-x[i]);
else
@@ -44,10 +46,13 @@ solver_diff_eqn::solver_diff_eqn(sys_osn_dan &sod_, double exit_tol):sod(&sod_)
{
i++;
rk.do_step( func[k] , x , l_dt , r_dt );
//std::copy(_upr_par.begin(), _upr_par.end(), std::back_inserter(func_sys->get_upr_par()));
for (size_t i = 0; i < sod->get_par_diff().up.size(); i++)
_upr_par.push_back(func_sys->get_upr_par()[i]);
coordinate.insert(coordinate.end(), x.begin(), x.end());
if ( exit_tol>0 )
{
for (unsigned int i = 0; i < x.size(); i++)
for (size_t i = 0; i < x.size(); i++)
{
c_diff[i]=fabs(x[i]-x0[i]);
if (x[i] <= 0 && max_x[i] < -x[i] )
@@ -55,8 +60,8 @@ solver_diff_eqn::solver_diff_eqn(sys_osn_dan &sod_, double exit_tol):sod(&sod_)
if (x[i] >= 0 && max_x[i] < x[i] )
max_x[i]=x[i];
}
m_diff=std::max_element(c_diff.begin(), c_diff.end());
m_pos=std::distance(c_diff.begin(), m_diff);
m_diff=std::max_element(c_diff.begin(), c_diff.end());//максимальная разность
m_pos=std::distance(c_diff.begin(), m_diff);//номер координаты

if ( *m_diff < exit_tol*max_x[m_pos] )
{
@@ -66,12 +71,14 @@ solver_diff_eqn::solver_diff_eqn(sys_osn_dan &sod_, double exit_tol):sod(&sod_)
}
}
sod->set_resIN(coordinate);
sod->set_uprIN(_upr_par);
unload_sys(func_sys);

closeso=true; //исправить sysosndan
// if (closeso)
// dlclose(shared_object);

// for (size_t i=0; i<_upr_par.size();i++)
// std::cout<<_upr_par[i]<<std::endl;
}

solver_diff_eqn::~solver_diff_eqn(){ dlclose(shared_object); }//вызывает segmentation fault

+ 0
- 180
src/ginac/parser/lexer.cpp Dosyayı Görüntüle

@@ -1,180 +0,0 @@
/** @file lexer.cpp
*
* Implementation of GiNaC's lexer. */

/*
* GiNaC Copyright (C) 1999-2014 Johannes Gutenberg University Mainz, Germany
*
* 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 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/

#include "lexer.h"
#include "compiler.h"

#include <iostream>
#include <sstream>
#include <string>
#include <cstdio>

namespace GiNaC {

/// Skip to the end of line
static int skipline(std::istream* s);
/// Skip to the next non-whitespace character
static int skipspace(std::istream* s, int c, std::size_t& line);
/// Check if the identifier is predefined literal
static bool literal_p(const std::string& name);

/// gettok - Return the next token from standard input.
int lexer::gettok()
{
// Skip any whitespace.
c = skipspace(input, c, line_num);

// identifier: [a-zA-Z][a-zA-Z0-9_]*
if (isalpha(c)) {
str = c;
do {
c = input->get();
if ( isalnum(c) || c=='_' || c=='[' || c==']')
str += c;
else
break;
} while (true);
if (unlikely(literal_p(str)))
return token_type::literal;
else
return token_type::identifier;
}

// Number: [0-9]+([.][0-9]*(eE[+-][0-9]+)*)*
if (isdigit(c) || c == '.') {
str = "";
do {
str += c;
c = input->get();
} while (isdigit(c) || c == '.');
if (c == 'E' || c == 'e') {
str += 'E';
c = input->get();
if (isdigit(c))
str += '+';
do {
str += c;
c = input->get();
} while (isdigit(c));
}
return token_type::number;
}

// Comment until end of line.
if (c == '#') {
c = skipline(input);
++line_num;
if (c != EOF)
return gettok();
}

// Check for end of file. Don't eat the EOF.
if (c == EOF)
return token_type::eof;

// Otherwise, just return the character as its ascii value.
int current = c;
c = input->get();
return current;
}

static int skipline(std::istream* s)
{
int c;
do {
c = s->get();
} while (c != EOF && c != '\n' && c != '\r');
return c;
}

static int skipspace(std::istream* s, int c, std::size_t& line)
{
while (isspace(c)) {
if (c == '\n')
++line;
c = s->get();
}
return c;
}

static bool literal_p(const std::string& name)
{
if (name == "I")
return true;
else if (name == "Pi")
return true;
else if (name == "Euler")
return true;
else if (name == "Catalan")
return true;
else
return false;
}

lexer::lexer(std::istream* in, std::ostream* out, std::ostream* err)
{
if (in)
input = in;
else
in = &std::cin;

if (out)
output = out;
else
output = &std::cout;

if (err)
error = err;
else
error = &std::cerr;

c = ' ';
str = "";
line_num = 0;
column = 0;
}

lexer::~lexer() { }

void lexer::switch_input(std::istream* in)
{
input = in;
line_num = 0;
column = 0;
c = ' ';
}

/// Symbolic name of current token (for error reporting)
std::string lexer::tok2str(const int tok) const
{
switch (tok) {
case lexer::token_type::identifier:
case lexer::token_type::number:
return std::string("\"") + str + "\"";
case lexer::token_type::eof:
return std::string("EOF");
default:
return std::string("\"") + char(tok) + "\"";
}
}

} // namespace GiNaC

+ 30
- 10
sysdiffeqn.cpp Dosyayı Görüntüle

@@ -4,7 +4,7 @@
//объявление статичных переменных
std::vector<int> sys_diff_equation::vp_num ={};
std::vector<int> sys_diff_equation::circ_num ={};
std::vector<double> sys_diff_equation::circ_coord ={};
state_type sys_diff_equation::circ_coord ={};
unsigned sys_diff_equation::dim_line=2;
std::vector<GiNaC::symbol> sys_diff_equation::var_name ={};

@@ -25,7 +25,7 @@ sys_diff_equation::sys_diff_equation(sys_osn_dan &sod_): sod(&sod_)
// std::getline(mystreamin, str);
// std::getline(mystreamin, str);
x=sod->get_par_diff().x0;
uprav_par=sod->get_par_diff().up;
uprav_par_naz=sod->get_par_diff().up;
// _isstemp.str(str);
// for (double temp; _isstemp>>temp;)
// x.push_back(temp);
@@ -50,10 +50,10 @@ sys_diff_equation::sys_diff_equation(sys_osn_dan &sod_): sod(&sod_)
table["zx"]=GiNaC::symbol("zx");
table["zy"]=GiNaC::symbol("zy");

for (unsigned i=0;i<uprav_par.size();i++)
for (unsigned i=0;i<uprav_par_naz.size();i++)
{
uprav_par_ex.push_back(GiNaC::symbol(uprav_par[i]));
table[uprav_par[i]]=uprav_par_ex[i];
uprav_par_ex.push_back(GiNaC::symbol(uprav_par_naz[i]));
table[uprav_par_naz[i]]=uprav_par_ex[i];
}
// GiNaC::ex cc=GiNaC::symbol("a");
@@ -92,6 +92,12 @@ sys_diff_equation::sys_diff_equation(sys_osn_dan &sod_): sod(&sod_)
N_ex=expr_in.size(); //число уравнений
if (!sod->get_par_diff().npp)
det_comp();
else
{
std::ifstream _cppsdu("test.cpp");
if (_cppsdu.fail())
throw std::invalid_argument("Файл сду cpp отсутствует");
}
}

void sys_diff_equation::det_comp()
@@ -102,12 +108,19 @@ void sys_diff_equation::det_comp()
ofst << "#include \"virteqn.h\"" << '\n' << std::endl;
ofst << "class funcinst : public diffeqninterface {" << std::endl << "public:" <<std::endl;
ofst << "virtual std::vector<syseqn> funcv();" << std::endl;
ofst << "virtual state_type get_upr_par()";

if (!est_uprav)
ofst << " {return {};}" << std::endl;
else
ofst << ";" << std::endl;

ofst << "private:" << std::endl;

for (std::vector<std::string>::iterator it = uprav_par.begin(); it != uprav_par.end(); it++)
for (auto it = uprav_par_naz.begin(); it != uprav_par_naz.end(); it++)
ofst << "static double "<< *it <<";" << std::endl;
//ofst << "virtual void set_par_a(double &_a) {a=_a;}" <<std::endl;
ofst << "private:" << std::endl;

GiNaC::ex temp_1=expr_in.back();
//bool check_t=false;

@@ -123,9 +136,16 @@ void sys_diff_equation::det_comp()
ofst << "extern \"C\" diffeqninterface* create() {" << "return new funcinst;" << "}"<<std::endl;

ofst << "extern \"C\" void destroy(diffeqninterface *p) {" << "delete p;" << "}"<<std::endl <<std::endl;
for (std::vector<std::string>::iterator it = uprav_par.begin(); it != uprav_par.end() && est_uprav; it++)
for (auto it = uprav_par_naz.begin(); it != uprav_par_naz.end() && est_uprav; it++)
ofst << "double funcinst::"<< *it << "=0;" << std::endl;

if (est_uprav)
{
ofst << "state_type funcinst::get_upr_par() {" << std::endl << "state_type _upr_par;" << std::endl;
for (auto it = uprav_par_naz.begin(); it != uprav_par_naz.end() && est_uprav; it++)
ofst << "_upr_par.push_back("<< *it << ");" << std::endl;
ofst << "return _upr_par;" << std::endl << "}" << std::endl << std::endl;
}
ofst << "std::vector<syseqn> funcinst::funcv() {" << std::endl;
ofst << "std::vector<syseqn> temp_;" << std::endl;
for (int k=0; k < n_svob;k++)
@@ -211,7 +231,7 @@ void sys_diff_equation::info_eqn_octave(std::stringstream &error_stream, std::st
eqn_stream << "eqn(:," << i+1 << ")=" << str << ";" << std::endl;
error_stream << "error_eqn(:," << i+1 << ")=" << str << " - (" <<regex_replace(str, regSn, "1") << ");" <<std::endl;
}
if (uprav_par.size() == 0)
if (uprav_par_naz.size() == 0)
{
eqn_stream << "#}\n";
error_stream << "max_error=max(abs(error_eqn));\n\n";

+ 2
- 2
sysdiffeqn.h Dosyayı Görüntüle

@@ -52,9 +52,9 @@ class sys_diff_equation
GiNaC::matrix b_temp; // временной столбец, служит для возвращении A_mat исходного значения
std::string dimension; //dimension 2-ух, 3-х мерное
std::stringstream &vnut_pred(std::stringstream &);//x_ to x[]
std::vector<std::string> uprav_par;//управляющие параметры
std::vector<std::string> uprav_par_naz;//управляющие параметры
static std::vector<int> circ_num;
static std::vector<double> circ_coord;
static state_type circ_coord;
int n_svob; //число свободных переменных
int N_var;
int N_ex; //число уравнений

+ 2
- 2
sysosndan.cpp Dosyayı Görüntüle

@@ -23,7 +23,7 @@ void sys_osn_dan::isxod_dan(std::stringstream &mystreamin_)
std::getline(mystreamin, str);
std::stringstream _iss(str);
for (std::string sub; _iss>>sub;)
uprav_par.push_back(sub);
uprav_par_naz.push_back(sub);

std::getline(mystreamin, str);
_isstemp.str(str);
@@ -62,7 +62,7 @@ soldif &sys_osn_dan::get_par_diff()
A.str_sm=str_sm;
A.npp=nocpp;
A.noc=nocomp;
A.up=uprav_par;
A.up=uprav_par_naz;
return A;
}


+ 5
- 3
sysosndan.h Dosyayı Görüntüle

@@ -19,7 +19,7 @@ struct soldif
int nsv; //число свободных переменных
int nv; //размерность вектора начального положения
std::vector<std::string> eqn; //уравнения
std::vector<std::string> eqn_svob; //уравнения свободных недоопределенной системы nsv=2,3..
std::vector<std::string> eqn_svob; //уравнения свободных недоопределенной системы число степеней свободы больше единицы; nsv=2,3..
std::vector<std::string> up; //управляющие параметры
bool npp; //не перезаписывать cpp-файл
bool noc; //не компилировать cpp-файл
@@ -33,7 +33,9 @@ class sys_osn_dan
void set_par_diff(double &_N, double &_dt){N=_N; dt=_dt;};
void set_coord(state_type &_x) {x=_x;};
void set_resIN(state_type &_coord) {res=_coord;};
void set_uprIN(state_type &_upr_) {upr_par=_upr_;};
state_type &get_resOUT() {return res;};
state_type &get_uprOUT() {return upr_par;};
soldif &get_par_diff();
private:
void isxod_dan(std::stringstream &); // исходные данные
@@ -43,10 +45,10 @@ class sys_osn_dan
int N_var;
std::string dimension, str_sm;
static unsigned dim_line;
state_type x, res;//res - полученное решение
state_type x, res, upr_par;//res - полученное решение
double dt, N;
bool nocomp, nocpp;
std::vector<std::string> equations, equations_svob, uprav_par;
std::vector<std::string> equations, equations_svob, uprav_par_naz;
};

#endif

+ 2
- 2
virteqn.h Dosyayı Görüntüle

@@ -8,9 +8,9 @@ typedef void (*syseqn)(const state_type &, state_type &, const double );

class diffeqninterface {
public:
virtual void set_par_a(double &) {}
// virtual void set_upr_par(double &) {}
virtual ~diffeqninterface() {}
virtual state_type get_upr_par() = 0;
virtual std::vector<syseqn> funcv() = 0;
};


Loading…
İptal
Kaydet