235 lines
3.0 KiB
C++
235 lines
3.0 KiB
C++
//-----------------------------------------------------------------------------
|
|
//
|
|
// Author : philippe.billet@noos.fr
|
|
//
|
|
// convolution product
|
|
//
|
|
// Input: tos-2 x (can be a symbol or expr)
|
|
//
|
|
// tos-1 y (can be a symbol or expr)
|
|
//
|
|
//
|
|
// Output: Result on stack
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#include "stdafx.h"
|
|
#include "defs.h"
|
|
int h1, h2, h3, h4;
|
|
|
|
static void yconvolution(void);
|
|
|
|
void
|
|
eval_convolution(void)
|
|
{
|
|
push(cadr(p1));
|
|
eval();
|
|
push(caddr(p1));
|
|
eval();
|
|
convolution();
|
|
}
|
|
|
|
void
|
|
convolution(void)
|
|
{
|
|
save();
|
|
yconvolution();
|
|
restore();
|
|
}
|
|
|
|
#define X p1
|
|
#define Y p2
|
|
|
|
static void
|
|
yconvolution(void)
|
|
{
|
|
Y = pop();
|
|
X = pop();
|
|
push(Y);
|
|
guess();
|
|
p4=pop();
|
|
pop();
|
|
push(X);
|
|
guess();
|
|
p3=pop();
|
|
pop();
|
|
|
|
|
|
if (iszero(X) || iszero(Y)) {
|
|
push_integer(0);
|
|
return;
|
|
}
|
|
|
|
if (car(X) == symbol(DIRAC)) {
|
|
push(Y);
|
|
return;
|
|
}
|
|
|
|
if (car(Y) == symbol(DIRAC)) {
|
|
push(X);
|
|
return;
|
|
}
|
|
|
|
if (car(X) == symbol(DERIVATIVE)) {
|
|
push_symbol(CONVOLUTION);
|
|
push(cadr(X));
|
|
push(Y);
|
|
push(caddr(X));
|
|
derivative();
|
|
list(3);
|
|
return;
|
|
}
|
|
|
|
if (car(Y) == symbol(DERIVATIVE)) {
|
|
push_symbol(CONVOLUTION);
|
|
push(cadr(Y));
|
|
push(X);
|
|
push(caddr(Y));
|
|
derivative();
|
|
list(3);
|
|
return;
|
|
}
|
|
|
|
if (car(X) == symbol(ADD)) {
|
|
X = cdr(X);
|
|
push(car(X));
|
|
push(Y);
|
|
convolution();
|
|
X = cdr(X);
|
|
while (iscons(X)) {
|
|
push(car(X));
|
|
push(Y);
|
|
convolution();
|
|
add();
|
|
X = cdr(X);
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (car(Y) == symbol(ADD)) {
|
|
Y = cdr(Y);
|
|
push(X);
|
|
push(car(Y));
|
|
convolution();
|
|
Y = cdr(Y);
|
|
while (iscons(Y)) {
|
|
push(X);
|
|
push(car(Y));
|
|
convolution();
|
|
add();
|
|
Y = cdr(Y);
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (car(X) == symbol(MULTIPLY) && p3 == p4) {
|
|
|
|
h1 = tos;
|
|
|
|
p5 = cdr(X);
|
|
while (iscons(p5)) {
|
|
if (!find(car(p5), p3))
|
|
push(car(p5));
|
|
p5 = cdr(p5);
|
|
}
|
|
|
|
h2 = tos;
|
|
|
|
p5 = cdr(X);
|
|
while (iscons(p5)) {
|
|
if (find(car(p5), p3))
|
|
push(car(p5));
|
|
p5 = cdr(p5);
|
|
}
|
|
|
|
if (tos - h2 == 0) {
|
|
push(one);
|
|
push(Y);
|
|
convolution();}
|
|
else {
|
|
multiply_all(tos - h2);
|
|
X = pop();
|
|
push(X);
|
|
push(Y);
|
|
convolution();
|
|
}
|
|
|
|
multiply_all(tos - h1);
|
|
return;
|
|
}
|
|
|
|
|
|
if (car(Y) == symbol(MULTIPLY) && p3 == p4) {
|
|
|
|
h3 = tos;
|
|
|
|
p5 = cdr(Y);
|
|
while (iscons(p5)) {
|
|
if (!find(car(p5), p3))
|
|
push(car(p5));
|
|
p5 = cdr(p5);
|
|
}
|
|
|
|
h4 = tos;
|
|
|
|
p5 = cdr(Y);
|
|
while (iscons(p5)) {
|
|
if (find(car(p5), p3))
|
|
push(car(p5));
|
|
p5 = cdr(p5);
|
|
}
|
|
|
|
if (tos - h4 == 0) {
|
|
push(X);
|
|
push(one);
|
|
convolution();}
|
|
else {
|
|
multiply_all(tos - h4);
|
|
Y = pop();
|
|
push(X);
|
|
push(Y);
|
|
convolution();
|
|
}
|
|
|
|
multiply_all(tos - h3);
|
|
return;
|
|
}
|
|
|
|
// if (exp_flag) {
|
|
// push(X);
|
|
// fourier();
|
|
// push(Y);
|
|
// fourier();
|
|
// multiply();
|
|
// invfourier();
|
|
// return;
|
|
// }
|
|
|
|
push_symbol(CONVOLUTION);
|
|
push(X);
|
|
push(Y);
|
|
list(3);
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
#if SELFTEST
|
|
|
|
static char *s[] = {
|
|
"convolution(dirac(x),f(x))",
|
|
"f(x)",
|
|
|
|
"eval(convolution(d(dirac(x),x),f(x)))",
|
|
"d(f(x),x)",
|
|
|
|
};
|
|
|
|
void
|
|
test_convolution(void)
|
|
{
|
|
test(__FILE__, s, sizeof s / sizeof (char *));
|
|
}
|
|
|
|
#endif
|