Aufrufen und Ausführen einer C-Funktion in Python

Python in C/C++ embedden, C-Module, ctypes, Cython, SWIG, SIP etc sind hier richtig.
Antworten
moon97
User
Beiträge: 10
Registriert: Samstag 20. November 2021, 17:28

Hallo Zusammen,

im Rahmen meiner Projektarbeit soll ich einen Vergleich zwischen der Scipy Funktion lfilter() und einer C-Funktion die wie lfilter() funktioniert durchführen. Der Vergleich soll auf einem Raspberry Pi in Python stattfinden. Was bedeutet, dass man die C-Funktion in Python Aufrufen und Ausführen können muss.

Die C-Funktion die wie lfilter() funktioniert habe ich folgender Seite entnommen:https://github.com/frankxiongzz/lfilter ... r/lfiler.c

Mein Python-Code ist wie folgt aufgebaut:
Zuerst filtere ich ein Signal aus zufälligen Zahlen bestehend mit den angegebenen Filterkoeffizienten (diese habe ich aus einem Beispiel meines Professors übernommen) und lasse mir die Werte des gefilterten Signals ausgeben.
Im zweiten Teil lade ich die erstellte Library des C-Files, definiere die Koeffizienten ähnlich wie in der C main-Funktion und lasse mir die Ausgangswerte des gefilterten Signals ausgeben. Allerdings stimmen die Ausgangswerte nach Aufruf der C-Funktion nicht. Ich weiß nicht genau ob es sich um einen Fehler bei den Datentypen oder einen Definitionsfehler handelt. Ich würde mich auch als Python Anfängerin bezeichnen, deswegen bitte ich um Nachsicht und nur ernst gemeinte Korrekturvorschläge. Bei weiteren Fragen zum Code können Sie sich gerne melden.

Code: Alles auswählen

#### Filterfunktion in Python

# Defintion
import scipy.signal as scs
import matplotlib.pyplot as plt
import numpy as np
import ctypes
from numpy.ctypeslib import ndpointer

# lfilter()-Funktion in Python
b = np.array([0.0637,0,-0.1061,0,0.3183,0.5,0.3183,0,-0.1061,0,0.0637], dtype=np.float32)

plt.plot(b)
plt.xlabel('n')
plt.ylabel('h(n)')
plt.title('Impulsantwort des FIR-Filters')

# Zufallssignal
x = np.array([2,5,6,7,8,2,3,5,1,2,4,3,9,1], dtype=np.float32)

# lfilter()
y = scs.lfilter(b,1,x)
print('Python: y = ',y)

#### mit C Filter-Funktion
lib = ctypes.cdll.LoadLibrary("/home/pi/Dokumente/CodeLite/filter/filter.so")
cfilter = lib.bb_digital_float_filter

#cfilter(b, a, x, y, Z, len_b, len_x, stride_X, stride_Y)
a = np.array(1, dtype=np.float32)
y1 = np.array(np.zeros(1), dtype=np.float32)
delay = np.array(np.zeros(10), dtype=np.float32)
cfilter.restypes = ctypes.c_float
cfilter.argtypes = [ndpointer(shape=b.shape, dtype=ctypes.c_float),
                    ndpointer(shape=a.shape, dtype=ctypes.c_float),
                    ndpointer(dtype=ctypes.c_float),
                    ndpointer(shape=y1.shape, dtype=ctypes.c_float),
                    ndpointer(shape=delay.shape, dtype=ctypes.c_float),
                    ctypes.c_int, ctypes.c_uint, ctypes.c_int, ctypes.c_int]

for i in range(0,14):
    cfilter(b,a,np.array(x[i]),y1,delay,11,1,1,1)
    print('C: y =', y)
    
#fig, axs = plt.subplots(2)
#axs[0].plot(x)
#axs[0].set_title('Signal')
#axs[1].plot(y1)
#axs[1].set_title('Signal gefiltert mit Python')
#axs[2].plot(y2)
#axs[2].set_title('Signal gefiltert mit C')

#plt.show()
Das Ergebnis sieht wie folgt aus:

Code: Alles auswählen

>>> 
================= RESTART: /home/pi/Dokumente/fir_filter.py =================
Python: y =  [ 0.1274      0.31849999  0.16999999 -0.08460002  0.5096      1.97620004
  4.38870006  6.92590009  7.48940012  5.93110007  4.14080008  3.28280004
  3.4555      2.70720004]
C: y = [ 0.1274]
C: y = [ -4.36068723e+29]
C: y = [ inf]
C: y = [-inf]
C: y = [ nan]
C: y = [ nan]
C: y = [ nan]
C: y = [ nan]
C: y = [ nan]
C: y = [ nan]
C: y = [ nan]
C: y = [ nan]
C: y = [ nan]
C: y = [ nan]
>>> 
Benutzeravatar
__blackjack__
User
Beiträge: 10280
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@moon97: Gibt das C-Programm denn die gleichen Ausgaben für die Eingaben im Python-Programm?
“Ich bin für die Todesstrafe. Wer schreckliche Dinge getan hat, muss eine angemessene Strafe bekommen. So lernt er seine Lektion für das nächste Mal.”
— Britney Spears, Interview in der französischen Zeitung Libération, 2. April 2002
moon97
User
Beiträge: 10
Registriert: Samstag 20. November 2021, 17:28

Wenn ich die Frage richtig verstehe, dann ja. Also wenn ich in die C main Funktion die gleichen Werte für die Koeffezienten und den Rest wie in Python beschrieben eingebe komm ich zu den gleichen Ausgabewerten wie oben beim ersten Ergebnis. Also das C-Programm macht schon das was es soll.
narpfel
User
Beiträge: 507
Registriert: Freitag 20. Oktober 2017, 16:10

@moon97: In `main` im C-Code ist zumindest ein Unterschied zu deinem Aufruf im Python-Code, der mir beim Überfliegen aufgefallen ist: `b` und `a` haben da die gleiche Länge. Und das scheint auch wichtig zu sein, denn in der Funktion werden `b` und `a` zusammen durchlaufen. Bei den anderen Arrays musst du auch nochmal gucken, ob die die richtige Länge haben. Ein Array der Länge 1 scheint für `y` zu kurz zu sein.
moon97
User
Beiträge: 10
Registriert: Samstag 20. November 2021, 17:28

Also wenn ich das in C wie folgt angebe komm ich zum selben Ergebnis.

int main()
{

float b[11] = {0.0637,0,-0.1061,0,0.3183,0.5,0.3183,0,-0.1061,0,0.0637 };
float a[1] = { 1. };
float x[14] = {2,5,6,7,8,2,3,5,1,2,4,3,9,1 };
float delay[10] = { 0,0,0,0,0,0,0,0,0,0 };
float y[1] = {};
for (int i = 0; i < 14; i++)
{
bb_digital_float_filter(b, a, &x, y, delay, 11, 1, 1, 1);
printf("%f\n", y[0]);
}
}
__deets__
User
Beiträge: 11962
Registriert: Mittwoch 14. Oktober 2015, 14:29

In der von dir gezeigten Funktion werden a und b 11 mal gelesen. Sagte narpfel ja auch. So wie du dir hier aufrufst, funktioniert das also nur, weil der Lesezugriff auf a einfach in x überläuft. Korrekt ist das nicht.
narpfel
User
Beiträge: 507
Registriert: Freitag 20. Oktober 2017, 16:10

Also wenn ich deinen C-Code ausführe, bekomme ich einen Buffer Overflow:

Code: Alles auswählen

$ gcc -std=c99 -Wall -Wextra -pedantic -fsanitize=address -g -o t t.c
$ ./t
=================================================================
==9610==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffca3213e64 at pc 0x55e8b752434a bp 0x7ffca3213d70 sp 0x7ffca3213d60
READ of size 4 at 0x7ffca3213e64 thread T0
    #0 0x55e8b7524349 in bb_digital_float_filter /tmp/t/t.c:21
    #1 0x55e8b7525212 in main /tmp/t/t.c:66
    #2 0x7faee807fb24 in __libc_start_main (/usr/lib/libc.so.6+0x27b24)
    #3 0x55e8b75240fd in _start (/tmp/t/t+0x10fd)

Address 0x7ffca3213e64 is located in stack of thread T0 at offset 36 in frame
    #0 0x55e8b7524905 in main /tmp/t/t.c:57

  This frame has 5 object(s):
    [32, 36) 'a' (line 60) <== Memory access at offset 36 overflows this variable
    [48, 52) 'y' (line 63)
    [64, 104) 'delay' (line 62)
    [144, 188) 'b' (line 59)
    [224, 280) 'x' (line 61)
HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork
      (longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-overflow /tmp/t/t.c:21 in bb_digital_float_filter
Shadow bytes around the buggy address:
  0x10001463a770: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10001463a780: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10001463a790: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10001463a7a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10001463a7b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x10001463a7c0: 00 00 00 00 00 00 00 00 f1 f1 f1 f1[04]f2 04 f2
  0x10001463a7d0: 00 00 00 00 00 f2 f2 f2 f2 f2 00 00 00 00 00 04
  0x10001463a7e0: f2 f2 f2 f2 00 00 00 00 00 00 00 f3 f3 f3 f3 f3
  0x10001463a7f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10001463a800: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10001463a810: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==9610==ABORTING
Hier:

Code: Alles auswählen

    #0 0x55e8b7524349 in bb_digital_float_filter /tmp/t/t.c:21
    [...]
    [32, 36) 'a' (line 60) <== Memory access at offset 36 overflows this variable
Was ja auch logisch ist, weil `a` die Länge 1 hat, in Zeile 21 aber auf `a[1]` zugegriffen wird.

Hier der Code (für die Zeilennummern):

Code: Alles auswählen

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>


static void bb_digital_float_filter(float *b, float *a, float *x, float *y, float *Z, int len_b, uint32_t len_x, int stride_X, int stride_Y)
{

	float *ptr_x = x, *ptr_y = y;
	float *ptr_Z;
	float *ptr_b = (float*)b;
	float *ptr_a = (float*)a;
	float *xn, *yn;
	const float a0 = *((float *)a);
	int n;
	uint32_t k;

	/* normalize the filter coefs only once. */
	for (n = 0; n < len_b; ++n) {
		ptr_b[n] /= a0;
		ptr_a[n] /= a0;
	}

	for (k = 0; k < len_x; k++) {
		ptr_b = (float *)b;   /* Reset a and b pointers */
		ptr_a = (float *)a;
		xn = (float *)ptr_x;
		yn = (float *)ptr_y;
		if (len_b > 1) {
			ptr_Z = ((float *)Z);
			*yn = *ptr_Z + *ptr_b  * *xn;   /* Calculate first delay (output) */
			ptr_b++;
			ptr_a++;
			/* Fill in middle delays */
			for (n = 0; n < len_b - 2; n++) {
				*ptr_Z =
					ptr_Z[1] + *xn * (*ptr_b) - *yn * (*ptr_a);
				ptr_b++;
				ptr_a++;
				ptr_Z++;
			}
			/* Calculate last delay */
			*ptr_Z = *xn * (*ptr_b) - *yn * (*ptr_a);
		}
		else {
			*yn = *xn * (*ptr_b);
		}

		ptr_y += stride_Y;      /* Move to next input/output point */
		ptr_x += stride_X;
	}

}


int main()
{

	float b[11] = {0.0637,0,-0.1061,0,0.3183,0.5,0.3183,0,-0.1061,0,0.0637 };
	float a[1] = { 1. };
	float x[14] = {2,5,6,7,8,2,3,5,1,2,4,3,9,1 };
	float delay[10] = { 0,0,0,0,0,0,0,0,0,0 };
	float y[1] = { 0. };
	for (int i = 0; i < 14; i++)
	{
		bb_digital_float_filter(b, a, &x[i], y, delay, 11, 1, 1, 1);
		printf("%f\n", y[0]);
	}
}
Benutzeravatar
__blackjack__
User
Beiträge: 10280
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Also bei mir kommt da beim C-Programm dann folgendes heraus:

Code: Alles auswählen

0.127400
0.318500
0.807000
0.552400
2.251400
3.718000
6.130500
226175540768964345856.000000
inf
-nan
-nan
-nan
-nan
-nan
Das fängt gleich an wie Dein Python-Ergebnis, geht aber offensichtlich nicht bis zum Ende gut. Und ich vermute mal ganz stark, dass hängt unter anderem mit der Anmerkung von narpfel zusammen, dass `a` und `b` gleich lang sein müssen, denn das Programm verändert hier fröhlich Daten die *nach* dem definierten Array `a` im Speicher liegen. Da von C nicht garantiert ist was danach liegt oder ob und wie viel „padding“ zwischen lokalen Variablen liegt, ist das undefiniertes Verhalten. Wahrscheinlich werden dann irgendwann die Daten von `x` verändert beziehungsweise Teile davon, sicher ist das aber auch nicht.

Es gibt auch Compiler/Optionen, die die Reihenfolge und „padding“ zufällig bestimmen. Um das ausnutzen von Pufferüberläufen zu erschweren. Da kann dann nach jedem Kompilieren was anderes passieren.
“Ich bin für die Todesstrafe. Wer schreckliche Dinge getan hat, muss eine angemessene Strafe bekommen. So lernt er seine Lektion für das nächste Mal.”
— Britney Spears, Interview in der französischen Zeitung Libération, 2. April 2002
moon97
User
Beiträge: 10
Registriert: Samstag 20. November 2021, 17:28

Alles klar, danke schon mal für eure Antworten. Dann weiß ich zumindest schon mal wo die Problematik liegt. Ich weiß nicht inwiefern ihr euch mit der Scipy lfilter() Funktion auskennt, aber wisst ihr wie diese mit den Koeffizienten umgeht? Weil diese benötigt ja auch nur b und x um das gefilterte Signal auszugeben. Ich habe nämlich keine Werte für a, ich weiß nur es darf nicht 0 sein.
moon97
User
Beiträge: 10
Registriert: Samstag 20. November 2021, 17:28

Ich nutze CodeLite auf dem Raspberry Pi für das C-Programm und bei mir kommen keinerlei Fehler und das Ergebnis ist richtig. Komisch :D

Code: Alles auswählen

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>


void bb_digital_float_filter(float *b, float *a, float *x, float *y, float *Z, int len_b, uint32_t len_x, int stride_X, int stride_Y)
{

	float *ptr_x = x, *ptr_y = y;
	float *ptr_Z;
	float *ptr_b = (float*)b;
	float *ptr_a = (float*)a;
	float *xn, *yn;
	const float a0 = *((float *)a);
	int n;
	uint32_t k;

	/* normalize the filter coefs only once. */
	for (n = 0; n < len_b; ++n) {
		ptr_b[n] /= a0;
		ptr_a[n] /= a0;
	}

	for (k = 0; k < len_x; k++) {
		ptr_b = (float *)b;   /* Reset a and b pointers */
		ptr_a = (float *)a;
		xn = (float *)ptr_x;
		yn = (float *)ptr_y;
		if (len_b > 1) {
			ptr_Z = ((float *)Z);
			*yn = *ptr_Z + *ptr_b  * *xn;   /* Calculate first delay (output) */
			ptr_b++;
			ptr_a++;
			/* Fill in middle delays */
			for (n = 0; n < len_b - 2; n++) {
				*ptr_Z =
					ptr_Z[1] + *xn * (*ptr_b) - *yn * (*ptr_a);
				ptr_b++;
				ptr_a++;
				ptr_Z++;
			}
			/* Calculate last delay */
			*ptr_Z = *xn * (*ptr_b) - *yn * (*ptr_a);
		}
		else {
			*yn = *xn * (*ptr_b);
		}

		ptr_y += stride_Y;      /* Move to next input/output point */
		ptr_x += stride_X;
	}
    
    

}

// Test C-Programm
int main()
{
    float b[11] = { 0.0637, 0., -0.1061, 0., 0.3183, 0.5, 0.3183, 0., -0.1061, 0., 0.0637 };
    float a[11] = { 1.};
    float x[14] = { 2,5,6,7,8,2,3,5,1,2,4,3,9,1 };
    float delay[10] = { 0 ,0, 0, 0, 0, 0, 0, 0, 0, 0 };
    float y[1] = {};
    for (int i = 0; i < 14; i++)
    {
		bb_digital_float_filter(b, a, &x[i], y, delay, 11, 1, 1, 1);
		printf("%f\n", y[0]);
    }
}
Ergebnis:

Code: Alles auswählen

0.127400
0.318500
0.170000
-0.084600
0.509600
1.976200
4.388700
6.925900
7.489400
5.931100
4.140800
3.282800
3.455500
2.707200
__deets__
User
Beiträge: 11962
Registriert: Mittwoch 14. Oktober 2015, 14:29

Laut https://docs.scipy.org/doc/scipy/refere ... ilter.html braucht das doch auch a und b?

Und hast du den Code so kompliziert wie narpfel? Denn der hat extra Optionen angegeben, die dafür sorgen, dass Fehler bemerkt werden.
moon97
User
Beiträge: 10
Registriert: Samstag 20. November 2021, 17:28

Ach ich habe meinen Fehler gefunden. Vielen Dank für eure Hilfe. Es lag wirklich an den unterschiedlichen Längen für a und b. Ich habe meinen Python Code nun wie folgt für a geändert:

Code: Alles auswählen

a = np.array([1,0,0,0,0,0,0,0,0,0,0], dtype=np.float32)
Auch im C-Code ist nämlich a so aufgebaut. Ich habe mir die Werte mal ausgeben lassen.

Der Unterschied zu lfilter ist wahrscheinlich, dass dann für den zugehörigen a Wert direkt eine 0 übergeben wird.

Durch die 1 in lfilter() gibt man ja an, dass der 1. Wert für a = 1 ist.

Code: Alles auswählen

y = scs.lfilter(b,1,x)
moon97
User
Beiträge: 10
Registriert: Samstag 20. November 2021, 17:28

Könntet ihr mal schauen, ob der Code bei euch noch zu Fehlern führt?

Code: Alles auswählen

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>


void bb_digital_float_filter(float *b, float *a, float *x, float *y, float *Z, int len_b, uint32_t len_x, int stride_X, int stride_Y)
{

	float *ptr_x = x, *ptr_y = y;
	float *ptr_Z;
	float *ptr_b = (float*)b;
	float *ptr_a = (float*)a;
	float *xn, *yn;
	const float a0 = *((float *)a);
	int n;
	uint32_t k;

	/* normalize the filter coefs only once. */
	for (n = 0; n < len_b; ++n) {
		ptr_b[n] /= a0;
		ptr_a[n] /= a0;
	}

	for (k = 0; k < len_x; k++) {
		ptr_b = (float *)b;   /* Reset a and b pointers */
		ptr_a = (float *)a;
		xn = (float *)ptr_x;
		yn = (float *)ptr_y;
		if (len_b > 1) {
			ptr_Z = ((float *)Z);
			*yn = *ptr_Z + *ptr_b  * *xn;   /* Calculate first delay (output) */
			ptr_b++;
			ptr_a++;
			/* Fill in middle delays */
			for (n = 0; n < len_b - 2; n++) {
				*ptr_Z =
					ptr_Z[1] + *xn * (*ptr_b) - *yn * (*ptr_a);
				ptr_b++;
				ptr_a++;
				ptr_Z++;
			}
			/* Calculate last delay */
			*ptr_Z = *xn * (*ptr_b) - *yn * (*ptr_a);
		}
		else {
			*yn = *xn * (*ptr_b);
		}

		ptr_y += stride_Y;      /* Move to next input/output point */
		ptr_x += stride_X;
	}
    
    

}

// Test C-Programm
int main()
{
    float b[11] = { 0.0637, 0., -0.1061, 0., 0.3183, 0.5, 0.3183, 0., -0.1061, 0., 0.0637 };
    float a[11] = { 1.,0,0,0,0,0,0,0,0,0,0};
    float x[14] = { 2,5,6,7,8,2,3,5,1,2,4,3,9,1 };
    float delay[10] = { 0 ,0, 0, 0, 0, 0, 0, 0, 0, 0 };
    float y[1] = {};
    for (int i = 0; i < 14; i++)
    {
		bb_digital_float_filter(b, a, &x[i], y, delay, 11, 1, 1, 1);
		printf("%f\n", y[0]);
    }
}
narpfel
User
Beiträge: 507
Registriert: Freitag 20. Oktober 2017, 16:10

@moon97: Bis auf ein

Code: Alles auswählen

$ gcc -std=c99 -Wall -Wextra -pedantic -fsanitize=address,undefined -g -o t2 t2.c
t2.c: In function ‘main’:
t2.c:64:18: warning: ISO C forbids empty initializer braces [-Wpedantic]
   64 |     float y[1] = {};
      |                  ^
sieht das jetzt okay aus.

Sonstige Anmerkungen: Die ganzen Casts sind unnötig (die kommen aber anscheinend davon, dass das automatisch generierter Code ist). Die `for`-Schleife in `main` ist unnötig, wenn du `y` gleich mit Länge 14 anlegst und 14 als `len_x` übergibst.
Alle `int`- und `uint32_t`-Variablen sollten eigentlich `size_t` sein, weil sie für Arraygrößen und -indices benutzt werden. Die Definitionen von `a`, `delay` und `y` kann man auch einfacher als `{1}` bzw. `{0}` schreiben (alle fehlenden Werte werden mit 0 aufgefüllt). Die 11 und 14 könnte man vielleicht als Konstanten definieren, um die Wiederholungen zu vermeiden.
moon97
User
Beiträge: 10
Registriert: Samstag 20. November 2021, 17:28

Super, danke. :)

Ja, habe auch nicht verstanden wieso derjenige die Klammern leer gelassen hat. Ich hatte es damals nur übernommen.

Ich nehme mir jetzt noch deine Anmerkungen vor und mache ein paar Korrekturen und dann mal schauen was der Professor sagt. Es sind natürlich immer die kleinen Fehler die nicht auffallen. :D
Sirius3
User
Beiträge: 16009
Registriert: Sonntag 21. Oktober 2012, 17:20

Ohne dieses ganze Pointer-Geschwurbel kommt sogar richtig lesbarer Code raus:

Code: Alles auswählen

void bb_digital_float_filter(float *b, float *a, float *x, float *y, float *Z, size_t len_b, size_t len_x, int stride_X, int stride_Y)
{
    size_t n, k;
    for (k = 0; k < len_x; k++) {
        float xn = x[stride_X * k], yn;
        if (len_b > 1) {
            /* Calculate first delay (output) */
            yn = Z[0] + xn * b[0];
            /* Fill in middle delays */
            for (n = 1; n < len_b - 1; n++) {
                Z[n-1] = Z[n] + xn * b[n] - yn * a[n];
            }
            /* Calculate last delay */
            Z[len_b - 2] = xn * b[len_b - 1] - yn * a[len_b - 1];
        }
        else {
            yn = xn * b[0];
        }
        y[stride_Y * k] = yn / a[0];
    }
}

Deine cfilter-Funktion hat keinen Rückgabewert, also solltest Du cfilter.restype nicht als float setzen.
ndpointer macht eine shape-Prüfung. Da solltest Du also die Shapes angeben, die cfilter auch erwartet, dann wird auch automatisch eine Fehlermeldung bei falschen Shapes geworfen. Auch die fixen Längenangaben sollten nicht sein.

Code: Alles auswählen

cfilter.argtypes = [
    ndpointer(shape=len(b), dtype=ctypes.c_float),
    ndpointer(shape=len(b), dtype=ctypes.c_float),
    ndpointer(shape=len(y1), dtype=ctypes.c_float),
    ndpointer(shape=len(y1), dtype=ctypes.c_float),
    ndpointer(shape=len(b) - 1, dtype=ctypes.c_float),
    ctypes.c_size_t, ctypes.c_size_t, ctypes.c_int, ctypes.c_int]

for i in range(0,14):
    cfilter(b, a, x[i:i+1], y1, delay, len(b), len(y1), 1, 1)
    print('C: y =', y1)
moon97
User
Beiträge: 10
Registriert: Samstag 20. November 2021, 17:28

Alles klar. Danke fürs Zeit nehmen und vereinfachen. Ich habe sowohl in C und Python nur grundlegende Kenntnisse. Von daher war ich schon froh, dass das Ganze überhaupt erstmal funktioniert hat.

Wisst ihr wie das mit den Quellenangaben ist, wenn ich deinen veränderten C-Code verwenden würde? Kann man den Forum dann als Link angeben? Alles was nicht von mir selber kommt muss ich ja als Quelle angeben.
__deets__
User
Beiträge: 11962
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das musst du an sich eher deinen Betreuer fragen. Der legt ja fest, was er akzeptiert. Der Post an sich wird hier nicht verschwinden.
moon97
User
Beiträge: 10
Registriert: Samstag 20. November 2021, 17:28

Okay, danke.
Antworten