Zwrot tablicy wyników z funkcji Runge-Kutty4

0

Witam,
Jestem poczatkującym "programistą", któremu uprzykrzyły się już analityczne metody obliczeń i chciałbym nieco przyśpieszyć ten proces. Ponadto jestem 100% samoukiem, dlatego ocena kodu będzie dla mnie bardzo cenna.

Program jest implementacją numerycznej metody całkowania funcji różniczkowych metodą RK4. W programie tkwi błąd. Wypisywanie wrtości w wewnątrz funkcji odbywa się gładko, ale przekazanie adresu do tablicy wyników do funkcji głównej skutkuje niezrozumiałym dla mnie wypisywaniem nieprawidłowych wartości.

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

/***przykladowe rownanie rozniczkowe***/
float funk1(float y, float t)
{
float dy_dt=0;
dy_dt=3*exp(-4*t)-2*y;
return dy_dt;
}

/***RK 4***/
float *rk4(float t_init,float y_init,float interval,float krok,float(*deriv)(float,float))
{
int i;
float rozm_tab_f;
float *wyniki=0;

rozm_tab_f=interval/krok; /*program rozniczkuje w rownych krokach nie w rownych proporcjach*/
int rozm_tab=rozm_tab_f; /*rzutowanie float do int*/
float k1[rozm_tab],k2[rozm_tab],k3[rozm_tab],k4[rozm_tab],Y[rozm_tab],YY[rozm_tab],YYY[rozm_tab],YYYY[rozm_tab],t[rozm_tab];

t[0]=t_init;
Y[0]=y_init;

    for (i=0;i<=rozm_tab;i++)
    {
    k1[i]=deriv(Y[i],t[i]);

    t[i]=t[i]+0.5*krok;
    YY[i]=Y[i]+0.5*k1[i]*krok;

    k2[i]=deriv(YY[i],t[i]);
    YYY[i]=Y[i]+0.5*k2[i]*krok;

    k3[i]=deriv(YYY[i],t[i]);
    t[i]=t[i]+0.5*krok;
    YYYY[i]=Y[i]+k3[i]*krok;

    k4[i]=deriv(YYYY[i],t[i]);

    Y[i+1]=Y[i]+(k1[i]+2*k2[i]+2*k3[i]+k4[i])*krok/6;
    printf("\nrozwiazanie rownania rozniczkowego y(%f)=%f",i*krok,Y[i]);
    t[i+1]=t[i];
    }

wyniki=&Y[0];
return wyniki;
}


int main()
{
int i;
float *f;
f=rk4(0,1,0.025,0.001,&funk1);
	for(i=0;i<=10;i++)
	{
	printf("\nrozwiazanie: %f",*(f+i));
	}
return 0;
}

Zasadnicze pytanie, dlaczego w kolejnych elementach wyświetlanych w funkcji głównej, pojawiają się błędne wartości?

usuniecie pogrubienia z całego tekstu posta - Furious Programming

0

Dokladnie tak, wprowadzilem do fukcji w celu sprawdzania poprawnosci: printf("\nrozwiazanie rownania ..., tam wyniki zgadzaja sie z obliczonymi w matlabie, jednak przekazujac adres z funkcji na pierwszy element tablicy z wynikami (&Y[0]) do fukcji glownej i inkrementujac znacznik, wyswietlane sa niepoprawne wartosci, ale pierwsze dwa sa prawidlowe, pozniejsze sa skopane. Podejrzewam ze moze miec to zwiazek z niewlasciwym przydzielaniem pamieci, ale nie jestem zbyt mocny w tej mterii...

Proponuje abys skompilowal kod wtedy wszystko bedzie jasne.

0

Odpaliłem, pierwsze wyniki są z funkcji, kolejne z funkcji głównej. Oto one:

y(0.000000)=1.000000
y(0.001000)=1.000993
y(0.002000)=1.001972
y(0.003000)=1.002937
y(0.004000)=1.003889
y(0.005000)=1.004827
y(0.006000)=1.005751
y(0.007000)=1.006661
y(0.008000)=1.007558

rozwiazanie: 1.000000
rozwiazanie: 1.000993
rozwiazanie: 1.001972
rozwiazanie: 1.002937
rozwiazanie: 1.003889
rozwiazanie: 1.004827
rozwiazanie: 1.005751
rozwiazanie: 1.006661
rozwiazanie: 1.007558
0

??? opadla mi szczeka, stosuje code::blocks, a Ty?

1

Problem tkwi w tym że funkcja zwraca adres ze stosu. Nie możesz tego robić.
Najprostsze rozwiązanie problemu to dodać słowo static: static float k1[rozm_tab],k2 ... wystarczy że ten Y będzie static
Poprawne rozwiązanie przekazać do funkcji adres tablicy którą funkcja wypełni.

1 użytkowników online, w tym zalogowanych: 0, gości: 1