3

I'm writing a Runge-Kutta ODE solver which takes in initial conditions, and 'events' and solves the equation. It starts and stops at these events to form 'patches'. These 'patches' are then put into an array which is saved.

The programme worked fine when it was evaluated for a large number of steps, however, when it was evaluated for a small number of steps it gave strange results, which would change in value between evaluations of the programme, sometimes being extremely large (~e200) or extremely small (~e-200).

I tried to probe the issue with printf statements, and it seems that the value of the variables changes on calling the print statement.

printf("after solution K1_M[0] = %e,K1_M[1] = %e,K1_M[2] = %e\n",k1_M[0],k1_M[1],k1_M[2]);//This is fine

printf("Going into K2 Mx: %e, My: %e, Mz: %e\n",M_f[0],M_f[1],M_f[2]);// This is fine
printf("What is happening to this division? k1_M[0] = %e, 1/6.0 = %e, k1_M[0]/6.0 = %e\n",k1_M[0],1/6.0,k1_M[0]/6.0);

int hh = 1,hhh=3;
hhh = hh + hhh;
printf("Print statement to make sure other statements exicute in order %d\n",hhh);

M_f[0] = M_inf[1] + k1_M[0]/(double)(6.0);//This is not fine
printf("What is happening to this division? k1_M[0] = %e, 1/6.0 = %e, k1_M[0]/6.0 = %e\n",k1_M[0],1/6.0,k1_M[0]/6.0); 

Example of the execution of the code and issue present

k1_M[0] has memory allocated to it just before this quotation.

I've used malloc a lot when parsing arrays into the functions, and I think that this is probably where the error occurs. I was initially trying to minimise the calls to malloc, as I understand that it is quite slow, so I was parsing the pointers to the function, however, I have now swapped to declaring as much as possible in the function (which is why some things are declared twice, but only one should be in scope) for debugging.

I thought that it could be something to do with the typecasting of 6.0, and that it might be dividing by zero, but that can't be it as the output is sometimes very small too. The fact that it is inconstant seems to go with my idea of it being some kind of memory leakage issue. I tried to debug it with gdb but I couldn't get it to run on my computer.

I was compiling with gcc 8.2, on a mac running OS 10.13.6

If anyone has any ideas what might be wrong I'd be extremely grateful. I don't know if other people have had similar problems, I couldn't find any other questions with the same issue, but then I didn't know exactly what to look for. Thanks very much.

All of the code is quoted here:

#include <stdio.h>
#include <math.h>
#include <stdlib.h>
//#include "plcdemos.h"
//#include <unistd.h>
//#include <string.h>

double vec_max(double *vec, int length){//find maximum value in a double vector of length length
    double max_so_far = vec[0];
    for(int i = 1;i<length;i++){
        if(vec[i] > max_so_far){
            max_so_far = vec[i];
        }
    }
    return max_so_far;
}

double *bloch_patch(double t, double M[3], double Amplitude_RF, double gyro, double T_1, double T_2, double M_0, double B_z,int pulse_on){
//(M_inf[0],M_f,Amplitude_RF,gyro,T_1,T_2,M_0,B_z,pulse_on)
    double B_x = 0.0;

    double w_l = B_z*gyro;
    double w = w_l;
    double w_1 = 0.0;
    double dM[3] = {0.0,0.0,0.0};
    double (*dM_pointer);// malloc(3*sizeof(double));
    dM_pointer = (double*) malloc(3*sizeof(double));

    if(pulse_on == 1)
        B_x = Amplitude_RF;

    //printf("Value of B_x in function is %e\n",B_x);
    w_1 = gyro*B_x;
    //w_l = B_z*gyro;
    //ODE
    //printf("Mx: %e, My: %e, Mz: %e\n",M[0],M[1],M[2]);

    //printf("dM[1] First term is: %e\n",(w_l - w)*M[1]);
    //printf("dM[1] Second term is: %e\n",- M[0]/T_2);

    //printf("dM[2] First term is: %e\n",-(w_l - w)*M[0]);
    //printf("dM[2] Second term is: %e\n",w_1*M[2]);
    //printf("dM[2] Third term is: %e\n",- M[1]/T_2);

    //actual ODE
    dM[0] = (w_l - w)*M[1] - M[0]/T_2; 
    dM[1] = -(w_l - w)*M[0] + w_1*M[2] - M[1]/T_2;
    dM[2] = -w_1*M[1] - (M[2] - M_0)/T_1;

    //printf("dM values are: %e, %e, %e\n",dM[0],dM[1],dM[2]); 

    //end of ODE

        //http://www.mmrrcc.upenn.edu/mediawiki/images/d/d1/Bloch.pdf
    //printf("words %lf\n",dM[0]);
    dM_pointer = dM;
    return dM_pointer;
    //return dM[0];
}


double *JVerner_step(double actual_dt,double *a,double *b,double *c,double *d,double *e,double *f,double *g, double M_inf[4],double Amplitude_RF,double gyro,double T_1,double T_2,double M_0,double B_z,int pulse_on){
//double *JVerner_step(double actual_dt,double *k1_M,double *k2_M,double *k3_M,double *k4_M,double *k5_M,double *k7_M,double *k8_M, double M_inf[4],double Amplitude_RF,double gyro,double T_1,double T_2,double M_0,double B_z,int pulse_on){
    //printf("Jstep6\n");
    double *M_out;
    M_out = (double*)malloc(3*sizeof(double));
    double M_f[3] = {0.0,0.0,0.0};


    //was previously parsing kn_Ms into function. Where a-g are passed in. a-g do nothing.
    double *k1_M,*k2_M,*k3_M,*k4_M,*k5_M,*k7_M,*k8_M;


    k1_M = (double*)malloc(3 * sizeof(double));         //Try: does allocating the memory in the function make it work?
    k2_M = (double*)malloc(3 * sizeof(double));         //It doens't fix it, but it doesn't make it less clear either
    k3_M = (double*)malloc(3* sizeof(double));
    k4_M = (double*)malloc(3 * sizeof(double));
    k5_M = (double*)malloc(3* sizeof(double));
    //k6_M not needed
    k7_M = (double*)malloc(3 * sizeof(double));
    k8_M = (double*)malloc(3 * sizeof(double));


    for(int j = 0;j<3;j++){
        k1_M[j] = 0.0;//force set to be zero
        k2_M[j] = 0.0;// not using these 
        k3_M[j] = 0.0;
        k4_M[j] = 0.0;
        k5_M[j] = 0.0;

        k7_M[j] = 0.0;
        k8_M[j] = 0.0;

    }


    printf("Actual_dt: %e\n",actual_dt);
    printf("Mx %e, My %e, Mz %e\n",M_inf[1],M_inf[2],M_inf[3]);
    //M_inf[0] = M_t[2*i + 1];//time
    //M_inf[1] = M_t[2*i + 2];//space
    printf("before solution K1_y = %e\n",k1_M[1]);
    M_f[0] = M_inf[1];
    M_f[1] = M_inf[2];
    M_f[2] = M_inf[3];
    k1_M = bloch_patch(M_inf[0],M_f,Amplitude_RF,gyro,T_1,T_2,M_0,B_z,pulse_on); 
    k1_M[0] = k1_M[0]*actual_dt;//done
    k1_M[1] = k1_M[1]*actual_dt;
    k1_M[2] = k1_M[2]*actual_dt;


    printf("after solution K1_M[0] = %e,K1_M[1] = %e,K1_M[2] = %e\n",k1_M[0],k1_M[1],k1_M[2]);//This is fine

    printf("Going into K2 Mx: %e, My: %e, Mz: %e\n",M_f[0],M_f[1],M_f[2]);// This is fine
    printf("What is happening to this division? k1_M[0] = %e, 1/6.0 = %e, k1_M[0]/6.0 = %e\n",k1_M[0],1/6.0,k1_M[0]/6.0);

    int hh = 1,hhh=3;
    hhh = hh + hhh;
    printf("Print statement to make sure other statements exicute in order %d\n",hhh);

    M_f[0] = M_inf[1] + k1_M[0]/(double)(6.0);//This is not fine
    printf("What is happening to this division? k1_M[0] = %e, 1/6.0 = %e, k1_M[0]/6.0 = %e\n",k1_M[0],1/6.0,k1_M[0]/6.0);

    M_f[1] = M_inf[2] + k1_M[1]/(double)(6.0);
    M_f[2] = M_inf[3] + k1_M[2]/(double)(6.0);
    printf("Going into K2 Mx: %e, My: %e, Mz: %e\n",M_f[0],M_f[1],M_f[2]);
    k2_M = bloch_patch(M_inf[0]+(actual_dt/6.0),M_f,Amplitude_RF,gyro,T_1,T_2,M_0,B_z,pulse_on);
    k2_M[0] = k2_M[0]*actual_dt;//done
    k2_M[1] = k2_M[1]*actual_dt;
    k2_M[2] = k2_M[2]*actual_dt;

    printf("K2_y = %e\n",k2_M[1]);

    M_f[0] = M_inf[1] + (4.0*k1_M[0] + 16.0*k2_M[0])/75.0;
    M_f[1] = M_inf[2] + (4.0*k1_M[1] + 16.0*k2_M[1])/75.0;
    M_f[2] = M_inf[3] + (4.0*k1_M[2] + 16.0*k2_M[2])/75.0;
    k3_M = bloch_patch(M_inf[0]+(actual_dt*4.0/15.0),M_f,Amplitude_RF,gyro,T_1,T_2,M_0,B_z,pulse_on);
    k3_M[0] = k3_M[0]*actual_dt;//done
    k3_M[1] = k3_M[1]*actual_dt;// coeffs equal to 0.266666666666667
    k3_M[2] = k3_M[2]*actual_dt;

    printf("K3_y = %e\n",k3_M[1]);

    M_f[0] = M_inf[1] + (5.0*k1_M[0]/6.0 - 8.0*k2_M[0]/3.0 + 5.0*k3_M[0]/2.0);
    M_f[1] = M_inf[2] + (5.0*k1_M[1]/6.0 - 8.0*k2_M[1]/3.0 + 5.0*k3_M[1]/2.0);
    M_f[2] = M_inf[3] + (5.0*k1_M[2]/6.0 - 8.0*k2_M[2]/3.0 + 5.0*k3_M[2]/2.0);
    k4_M = bloch_patch(M_inf[0]+(actual_dt*2.0/3.0),M_f,Amplitude_RF,gyro,T_1,T_2,M_0,B_z,pulse_on);
    k4_M[0] = k4_M[0]*actual_dt;//done
    k4_M[1] = k4_M[1]*actual_dt;//coeffs equal to 0.666666666666667
    k4_M[2] = k4_M[2]*actual_dt;

    printf("K4_y = %e\n",k4_M[1]);

    M_f[0] = M_inf[1] + (-165.0*k1_M[0]/64.0 + 55.0*k2_M[0]/6.0 - 425.0*k3_M[0]/64.0 + 85.0*k4_M[0]/96.0);
    M_f[1] = M_inf[2] + (-165.0*k1_M[1]/64.0 + 55.0*k2_M[1]/6.0 - 425.0*k3_M[1]/64.0 + 85.0*k4_M[1]/96.0);
    M_f[2] = M_inf[3] + (-165.0*k1_M[2]/64.0 + 55.0*k2_M[2]/6.0 - 425.0*k3_M[2]/64.0 + 85.0*k4_M[2]/96.0);
    k5_M = bloch_patch(M_inf[0]+actual_dt*5.0/6.0,M_f,Amplitude_RF,gyro,T_1,T_2,M_0,B_z,pulse_on);
    k5_M[0] = k5_M[0]*actual_dt;//done
    k5_M[1] = k5_M[1]*actual_dt;//coeffs equal to 0.833333333333333
    k5_M[2] = k5_M[2]*actual_dt;
    printf("K5_y = %e\n",k5_M[1]);
    //no need for k6
    M_f[0] = M_inf[1] + (-8263.0*k1_M[0]/15000.0 + 124.0*k2_M[0]/75.0 - 643.0*k3_M[0]/680.0 - 81.0*k4_M[0]/250.0 + 2484.0*k5_M[0]/10625.0);
    M_f[1] = M_inf[2] + (-8263.0*k1_M[1]/15000.0 + 124.0*k2_M[1]/75.0 - 643.0*k3_M[1]/680.0 - 81.0*k4_M[1]/250.0 + 2484.0*k5_M[1]/10625.0);
    M_f[2] = M_inf[3] + (-8263.0*k1_M[2]/15000.0 + 124.0*k2_M[2]/75.0 - 643.0*k3_M[2]/680.0 - 81.0*k4_M[2]/250.0 + 2484.0*k5_M[2]/10625.0);
    k7_M = bloch_patch(M_inf[0]+(actual_dt/15.0),M_f,Amplitude_RF,gyro,T_1,T_2,M_0,B_z,pulse_on);
    k7_M[0] = k7_M[0]*actual_dt; //coeffs equal to 0.066666666666667
    k7_M[1] = k7_M[1]*actual_dt;
    k7_M[2] = k7_M[2]*actual_dt;
    printf("K7_y = %e\n",k7_M[1]);

    M_f[0] = M_inf[1] + (3501.0*k1_M[0]/1720.0 - 300.0*k2_M[0]/43.0 + 297275.0*k3_M[0]/52632.0 - 319.0*k4_M[0]/2322.0 + 24068.0*k5_M[0]/84065.0 + 3850.0*k7_M[0]/26703.0);
    M_f[1] = M_inf[2] + (3501.0*k1_M[1]/1720.0 - 300.0*k2_M[1]/43.0 + 297275.0*k3_M[1]/52632.0 - 319.0*k4_M[1]/2322.0 + 24068.0*k5_M[1]/84065.0 + 3850.0*k7_M[1]/26703.0);
    M_f[2] = M_inf[3] + (3501.0*k1_M[2]/1720.0 - 300.0*k2_M[2]/43.0 + 297275.0*k3_M[2]/52632.0 - 319.0*k4_M[2]/2322.0 + 24068.0*k5_M[2]/84065.0 + 3850.0*k7_M[2]/26703.0);
    //M_f[0] = M_inf[1] + (3501.0*k1_M[0]/1720.0 - 300.0*k2_M[0]/43.0 + 297275.0*k3_M[0]/52632.0 - 319.0*k4_M[0]/2322.0 + 24068.0*k5_M[0]/84065.0 + k7_M[0]*0.144178556716475);
    //M_f[1] = M_inf[2] + (3501.0*k1_M[1]/1720.0 - 300.0*k2_M[1]/43.0 + 297275.0*k3_M[1]/52632.0 - 319.0*k4_M[1]/2322.0 + 24068.0*k5_M[1]/84065.0 + k7_M[1]*0.144178556716475);
    //M_f[2] = M_inf[3] + (3501.0*k1_M[2]/1720.0 - 300.0*k2_M[2]/43.0 + 297275.0*k3_M[2]/52632.0 - 319.0*k4_M[2]/2322.0 + 24068.0*k5_M[2]/84065.0 + k7_M[2]*0.144178556716475);
    k8_M = bloch_patch(M_inf[0]+(actual_dt),M_f,Amplitude_RF,gyro,T_1,T_2,M_0,B_z,pulse_on);
    k8_M[0] = k8_M[0]*actual_dt;// coeffs equal to 1.000 000 000 000 001 = 1 + 1e-15 
    k8_M[1] = k8_M[1]*actual_dt;
    k8_M[2] = k8_M[2]*actual_dt;//0.144178556716475
    printf("K8_y = %e\n",k8_M[1]);
    // sixth order inc
    M_out[0] = (3.0*k1_M[0]/40.0 + 875.0*k3_M[0]/2244.0 + 23.0*k4_M[0]/72.0 + 264.0*k5_M[0]/1955.0 + 125.0*k7_M[0]/11592.0 + 43.0*k8_M[0]/616.0);
    M_out[1] = (3.0*k1_M[1]/40.0 + 875.0*k3_M[1]/2244.0 + 23.0*k4_M[1]/72.0 + 264.0*k5_M[1]/1955.0 + 125.0*k7_M[1]/11592.0 + 43.0*k8_M[1]/616.0);
    M_out[2] = (3.0*k1_M[2]/40.0 + 875.0*k3_M[2]/2244.0 + 23.0*k4_M[2]/72.0 + 264.0*k5_M[2]/1955.0 + 125.0*k7_M[2]/11592.0 + 43.0*k8_M[2]/616.0);
    printf("M_y = %e\n",M_out[1]);
    // coeffs equal to 1.0 to machine precision
    return M_out;
}



double *JsolveVernerPatch(double t,double t_start,double t_end, int n, double M_in[3],double Amplitude_RF, double gyro, double T_1, double T_2, double M_0, double B_z,int pulse_on){
    //takes parameters of the function to be solved as well as the start point, the end point, and the regular stepsize
    double actual_dt = (t_end-t_start)/(double)n;
    printf("Actual_dt: %e\n",actual_dt);
    double M_inf[4];//first for time, then three for mx my mz
    double *k1_M,*k2_M,*k3_M,*k4_M,*k5_M,*k7_M,*k8_M; //k values in solver
    double *F_out; //solution out
    double *M_t;

    M_t = (double*)malloc((4*(n+1)) * sizeof(double)); //vector will store points, t and M

    //These are not currently used, how allocating inside of '_step' function
    k1_M = (double*)malloc(3 * sizeof(double));         // allocation of memeory for k solver values I don't know 
    k2_M = (double*)malloc(3 * sizeof(double));         // if this is faster, but it seems like a sort of sensible thing
    k3_M = (double*)malloc(3 * sizeof(double));
    k4_M = (double*)malloc(3 * sizeof(double));
    k5_M = (double*)malloc(3 * sizeof(double));
    //k6_M not needed
    k7_M = (double*)malloc(3 * sizeof(double));
    k8_M = (double*)malloc(3 * sizeof(double));
    F_out = (double*)malloc(3 * sizeof(double));



    M_t[0] = t_start;
    M_t[1] = M_in[0];
    M_t[2] = M_in[1];
    M_t[3] = M_in[2];


    for(int i = 0;i<n;i++){

        M_inf[0] = M_t[4*i + 0]; //time
        M_inf[1] = M_t[4*i + 1]; //space
        M_inf[2] = M_t[4*i + 2]; //space
        M_inf[3] = M_t[4*i + 3]; //space
        printf("Going into function: t: %e,Mx: %e,My: %e,Mz: %e\n",M_inf[0],M_inf[1],M_inf[2],M_inf[3]);

        for(int j = 0;j<3;j++){
            k1_M[j] = 0.0;//force set to be zero
            k2_M[j] = 0.0;// not using these 
            k3_M[j] = 0.0;
            k4_M[j] = 0.0;
            k5_M[j] = 0.0;

            k7_M[j] = 0.0;
            k8_M[j] = 0.0;

        } 
        F_out = JVerner_step(actual_dt,k1_M,k2_M,k3_M,k4_M,k5_M,k7_M,k8_M,M_inf,Amplitude_RF,gyro,T_1,T_2,M_0,B_z,pulse_on);

        M_t[4*(i + 1) + 0] = M_inf[0] + actual_dt;  //time
        M_t[4*(i + 1) + 1] = M_inf[1] + F_out[0];   //space
        M_t[4*(i + 1) + 2] = M_inf[2] + F_out[1];   //space
        M_t[4*(i + 1) + 3] = M_inf[3] + F_out[2];   //space 

    }
    return M_t;
}


double *JsolveVernerWhole(double t_start,double t_end, int n, double M_in[3],double Amplitude_RF, double gyro, double T_1, double T_2, double M_0, double B_z,int *pulse_v_pt,double *pulse_t_pt,int length_pulse){
    //takes parameters of the function to be solved as well as the start point, the end point, and the regular stepsize
    //double actual_dt = (t_end-t_star)/n;



    //double *k1_M,*k2_M,*k3_M,*k4_M,*k5_M,*k7_M; //k values in solver

    double *M_t,*M_patch;
    double t;


    int pulse_on = 0;
    //typical_dt = dt;//pow(dt_min * dt_max,0.5);

    int (*pulse_v);
    double (*pulse_t);


    pulse_v = (int*)malloc((length_pulse+1) * sizeof(int)); //how to get array of unknown length into function
    pulse_t = (double*)malloc((length_pulse+1) * sizeof(double));

    //pulse sequence
    printf("Pulse length is %d\n",length_pulse);
    for(int i=0;i<length_pulse+1;i++){
        pulse_v[i] = pulse_v_pt[i]; //might be able to use use the pointers directly and skip this out
        pulse_t[i] = pulse_t_pt[i];
        printf("Pulse t is %e\n",pulse_t[i]);
        //printf("pulse_v[%d] = %e\n",i,pulse_v[i]);
    }



    M_t = (double*)malloc((4*(n*(length_pulse)) + 4 ) * sizeof(double)); //vector will store points, t and M
    printf("Function Whole M_t allocated size: %d\n",(4*(n*(length_pulse)) + 4 ));
    M_patch = (double*)malloc(4*n* sizeof(double));
    M_t[0] = t_start;
    M_t[1] = M_in[0];
    M_t[2] = M_in[1];
    M_t[3] = M_in[2];
    int start_at = 4;
    printf("Time is: %e, Mx is: %e, My is: %e, Mz is: %e\n",M_t[0],M_t[1],M_t[2],M_t[3]);
    for(int i = 0;i<(length_pulse);i++){
        t = M_t[i*n*4 + 0];
        //printf("Starting patch at t = %e\n",t);
        M_in[0] = M_t[i*n*4 + 1];
        M_in[1] = M_t[i*n*4 + 2];
        M_in[2] = M_t[i*n*4 + 3];

        if(length_pulse > 1){
            for(int i = 0;i<length_pulse;i++){
                if(t<=pulse_t[i]){
                    if(pulse_v[i] == 1){
                        pulse_on = 1;
                    }
                break;
                }   
            }
        }//end of pulse sequence
        printf("Tstart at %e, Tend at %e for current patch\n",pulse_t[i],pulse_t[i+1]);
        printf("Index value is: %d\n",i);
        M_patch = JsolveVernerPatch(t,pulse_t[i],pulse_t[i+1],n, M_in,Amplitude_RF, gyro, T_1, T_2, M_0, B_z, pulse_on);
        printf("Time is: %e, Mx is: %e, My is: %e\n",M_patch[4*0 + 0],M_patch[4*0+ 1],M_patch[4*0 + 2]);
        for(int j=1;j<n+1;j++){
            printf("Time is: %e, Mx is: %e, My is: %e\n",M_patch[4*j + 0],M_patch[4*j + 1],M_patch[4*j + 2]);
            /*
            M_t[i*(n-1)*4  +4+ 0 + 4*j] = M_patch[4*j + 0];// time
            M_t[i*(n-1)*4  +4+ 1 + 4*j] = M_patch[4*j + 1];
            M_t[i*(n-1)*4  +4+ 2 + 4*j] = M_patch[4*j + 2];
            M_t[i*(n-1)*4  +4+ 3 + 4*j] = M_patch[4*j + 3];// copy patch into matrix    
            */
            M_t[start_at + 0] = M_patch[4*j + 0];// time
            M_t[start_at + 1] = M_patch[4*j + 1];
            M_t[start_at + 2] = M_patch[4*j + 2];
            M_t[start_at + 3] = M_patch[4*j + 3];// copy patch into matrix
            printf("start_at: %d\n",start_at);
            start_at = start_at + 4;
        }

        //for(int j=1;j<n+1;j++){
            //printf("Time is: %e, Mz is: %e\n",M_patch[4*j + 0],M_patch[4*j + 3]);
            /*
            M_t[i*(n-1)*4  +4+ 0 + 4*j] = M_patch[4*j + 0];// time
            M_t[i*(n-1)*4  +4+ 1 + 4*j] = M_patch[4*j + 1];
            M_t[i*(n-1)*4  +4+ 2 + 4*j] = M_patch[4*j + 2];
            M_t[i*(n-1)*4  +4+ 3 + 4*j] = M_patch[4*j + 3];// copy patch into matrix    
            */

        //}


    }
    /*
    printf("Check loop\n");
    for(int j=0;j<n+1;j++){
        printf("Time is: %e, My is: %e\n",M_t[4*j + 0],M_t[4*j + 2]);

        M_t[i*(n-1)*4  +4+ 0 + 4*j] = M_patch[4*j + 0];// time
        M_t[i*(n-1)*4  +4+ 1 + 4*j] = M_patch[4*j + 1];
        M_t[i*(n-1)*4  +4+ 2 + 4*j] = M_patch[4*j + 2];
        M_t[i*(n-1)*4  +4+ 3 + 4*j] = M_patch[4*j + 3];// copy patch into matrix    


    }
    */


    printf("start_at: %d\n",start_at);
    return M_t;
}






int main(){

    double Amplitude_RF,B_x,gyro,T_1,T_2,M_0,B_z,pulse_t[3];
    int length_pulse;
    int pulse_v[3];
    double (*M_out);
    Amplitude_RF = 1.0e-4;B_x = 0.0;gyro = 267.513e6;T_1 = 900e-3;T_2 = 90e-3;M_0 = 1.0;B_z = 3.5;

    double M_in[3] = {0.0,1.0,0.0}; //xyz

    double t_start = 0.0;
    double t_end = 0.3;
    int n = 3;
    length_pulse = 1;
    pulse_v[0] = 0; pulse_v[1] = 0; pulse_v[2] = 0;// pulse_v[1] = 0.0;
    pulse_t[0] = t_start; pulse_t[1] = t_end; pulse_t[2] = t_end;

    int *pulse_v_pt ;//= pulse_v;
    double *pulse_t_pt;// = pulse_t;

    pulse_v_pt = (int*)malloc((length_pulse + 1)*sizeof(int));
    pulse_t_pt = (double*)malloc((length_pulse + 1)*sizeof(double));


    //pulse sequence
    printf("Pulse length is %d\n",length_pulse);
    for(int i=0;i<length_pulse+1;i++){
        pulse_v_pt[i] = pulse_v[i]; //might be able to use use the pointers directly and skip this out
        pulse_t_pt[i] = pulse_t[i];
        printf("Pulse t is %e\n",pulse_t[i]);
        //printf("pulse_v[%d] = %e\n",i,pulse_v[i]);
    }

    //double tol = 4.6416e-7;

    //double tol = 2.1544e-7;

    //solver_out = Jsolve_RK6(t_start,t_end, dt_guess, M_in,Amplitude_RF, B_x, gyro, T_1, T_2, M_0, B_z,pulse_v,pulse_t, length_pulse);
    //solver_out = Jsolve46(tol,rel_tol,t_start,t_end, dt_guess,dt_min,dt_max,M_in,Amplitude_RF, B_x, gyro, T_1, T_2, M_0, B_z,pulse_v,pulse_t,length_pulse);

    //solver_out = Jsolve_RK4(t_start,t_end, dt_guess,M_in,a);
    //M_out = JsolveFehlberg45(tol,1.0,t_start,t_end, dt_in,dt_min,dt_max,M_in,Amplitude_RF, B_x, gyro, T_1, T_2, M_0, B_z,pulse_v,pulse_t,length_pulse);
    printf("Going into function t_start is: %e, coming out of function %e \n",t_start,t_end);
    printf("Pulse_t[0] s: %e, pulse_t[1] %e \n",pulse_t[0],pulse_t[1]);
    M_out = JsolveVernerWhole(t_start,t_end, n, M_in,Amplitude_RF, gyro, T_1, T_2, M_0, B_z,pulse_v_pt,pulse_t_pt,length_pulse);

    //int skip = (int)fmax(ceil(1000/M_out[0]),1);

    //double *mx,*my,*mz,*t,*modmy,*modmz,*diff,max_diff;
    //mx = malloc(((length_pulse-1)*n + 1)  * sizeof(double));
    //my = malloc(((length_pulse-1)*n + 1)  * sizeof(double));
    //mz = malloc(((length_pulse-1)*n + 1)  * sizeof(double));
    //t = malloc(((length_pulse-1)*n + 1) * sizeof(double));
    //modmy = malloc(((length_pulse-1)*n + 1) * sizeof(double));
    //modmz = malloc(((length_pulse-1)*n + 1) * sizeof(double));
    //diff = malloc(((length_pulse-1)*n + 1) * sizeof(double));


    //max_diff = 0.0;


    printf("end point = %d\n",((length_pulse)*n+1));



    //printf("does this bit work\n");
    //for(int i=0;i<((length_pulse)*n +1);i++){
        //printf("index %d\n",i);
        //printf("%lf %lf %lf %lf\n", solver_out[4*i+1],solver_out[4*i +2],solver_out[4*i +3],solver_out[4*i +4]);
        //fprintf(fp,"%lf %lf %lf %lf \n", M_out[4*i+1],M_out[4*i +2],M_out[4*i+3],M_out[4*i +4]);
        //printf("points = %d\n",points);
        //printf("My[%d] = %e\n",points,M_out[4*i+2]);
    //      t[points] = M_out[4*i+0];
    //      printf("Time points %3.16e\n",t[points]);
    //      mx[points] = M_out[4*i+1];  
    //      my[points] = M_out[4*i+2];
        //  printf("My[%d] = %e\n",points,my[points]);
    //      mz[points] = M_out[4*i+3];
            //printf("t = %e,My data: %e\n",t[points],my[points]);
            //printf("Index number is: %d\n",i);
            //modmy[points] = exp(-t[points]/T_2);
            //modmz[points] = 1-exp(-t[points]/T_1);
            //diff[points] = fmax(fabs(my[points]-modmy[points]),fabs(mz[points]-modmz[points]));
            //max_diff = fmax(max_diff,diff[points]);
    //      points++;
            //printf("Time is: %e My is: %e\n",t[points],my[points]);


        //fprintf(fp,"%3.16e %3.16e %3.16e %3.16e \n", M_out[4*i+1],M_out[4*i +2],M_out[4*i+3],M_out[4*i +4]);
        //fprintf(fp,"the word data\n");
    //}



    printf("Solver_finished\n");
    printf("Plotting\n");
    printf("total points: %d\n",(int)(4*((length_pulse)*n+1)));


    //FILE *fp = fopen(strcat(getcwd(cwd,sizeof(cwd)),"data.csv"),"W");
    printf("opening file to write to\n");
    FILE *fp = fopen("Bloch_RKR.csv","w");
    if (fp == NULL)
    {
        printf("Error opening file!\n");
        exit(1);
    }

    //printf("fp %f\n",fp);
    //fp ;
    printf("writing data to file\n");
    //for(int i=0;i<(points);i++){
        //printf("index %d\n",i);
        //printf("%lf %lf %lf %lf\n", solver_out[4*i+1],solver_out[4*i +2],solver_out[4*i +3],solver_out[4*i +4]);
        //fprintf(fp,"%lf %lf %lf %lf \n", M_out[4*i+1],M_out[4*i +2],M_out[4*i+3],M_out[4*i +4]);
    //  printf("%3.16e %3.16e %3.16e %3.16e\n", t[i],mx[i],my[i],mz[i]);
    //  fprintf(fp,"%3.16e %3.16e %3.16e %3.16e\n", t[i],mx[i],my[i],mz[i]);
        //fprintf(fp,"the word data\n");
    //}


    for(int i=0;i<((length_pulse)*n +1);i++){
        //printf("index %d\n",i);
        //printf("%lf %lf %lf %lf\n", solver_out[4*i+1],solver_out[4*i +2],solver_out[4*i +3],solver_out[4*i +4]);
        //fprintf(fp,"%lf %lf %lf %lf \n", M_out[4*i+1],M_out[4*i +2],M_out[4*i+3],M_out[4*i +4]);
        //printf("points = %d\n",points);
        //printf("My[%d] = %e\n",points,M_out[4*i+2]);
        printf("%3.16e %3.16e %3.16e %3.16e\n", M_out[4*i+0],M_out[4*i+1],M_out[4*i+2],M_out[4*i+3]);
        fprintf(fp,"%3.16e %3.16e %3.16e %3.16e\n", M_out[4*i+0],M_out[4*i+1],M_out[4*i+2],M_out[4*i+3]);
            //t[points] = M_out[4*i+0];
            //printf("Time points %3.16e\n",t[points]);
            //mx[points] = M_out[4*i+1];    
            //my[points] = M_out[4*i+1];
        //  printf("My[%d] = %e\n",points,my[points]);
            //mz[points] = M_out[4*i+3];
            //printf("t = %e,My data: %e\n",t[points],my[points]);
            //printf("Index number is: %d\n",i);
            //modmy[points] = exp(-t[points]/T_2);
            //modmz[points] = 1-exp(-t[points]/T_1);
            //diff[points] = fmax(fabs(my[points]-modmy[points]),fabs(mz[points]-modmz[points]));
            //max_diff = fmax(max_diff,diff[points]);
            //points++;
            //printf("Time is: %e My is: %e\n",t[points],my[points]);


        //fprintf(fp,"%3.16e %3.16e %3.16e %3.16e \n", M_out[4*i+1],M_out[4*i +2],M_out[4*i+3],M_out[4*i +4]);
        //fprintf(fp,"the word data\n");
    }



    fclose(fp);
    printf("data written\n");


    return 0;
}
anothermh
  • 9,815
  • 3
  • 33
  • 52
  • You're returning the address of a local array from `bloch_patch()`. The underlying array ceases to exist as soon as the function returns. – pmg Sep 11 '18 at 12:28

1 Answers1

0

Your bloch_patch function returns a pointer to a local array. That is bad. Once the function ends, that pointer no longer points to valid memory, and should no longer be used. You do however, which leads to undefined behavior. And in your case, that undefined behavior manifests itself as a strange value being printed, and further calculations being meaningless (most likely because the memory that was originally allocated for the array has been re-used, and filled with other data).

Also, you then assign that returned pointer to k1_M, overwriting the pointer to allocated memory it contained. This creates a memory leak.

Sander De Dycker
  • 16,053
  • 1
  • 35
  • 40