#define NULL ((void *)0)
typedef unsigned long size_t; // Customize by platform.
typedef long intptr_t;
typedef unsigned long uintptr_t;
typedef long scalar_t__; // Either arithmetic or pointer type.
/* By default, we understand bool (as a convenience). */
typedef int bool;
#define false 0
#define true 1

/* Forward declarations */

/* Type definitions */

/* Variables and functions */
int /*<<< orphan*/ COPY(double *, double *, double *, double *, int);
int /*<<< orphan*/ COPYI(double *, double *, double *, double *, int);
int /*<<< orphan*/ IC(double *, double *, int, double, double);
int /*<<< orphan*/ PT(double *, double *, double *, int, double, double,
                      double);
double *malloc(int);
double pow(double, int);
int /*<<< orphan*/ printf(char *, double, double, double);
int main() {
  double *x;
  double *u_init;
  double *u_past;
  double *u_present;
  double *u_future;
  int n_points = 1000;
  double T = 40;
  double pho = 0.01;
  double c;
  double L = 100;
  double dt = 0.0005;
  int i;
  int j;
  int t = 10000;
  x = malloc(sizeof(double) * n_points);
  u_init = malloc(sizeof(double) * n_points);
  u_past = malloc(sizeof(double) * n_points);
  u_present = malloc(sizeof(double) * n_points);
  u_future = malloc(sizeof(double) * n_points);
  c = pow(T / pho, 0.5);
  IC(u_init, x, n_points, c, L);
  PT(u_init, x, u_future, n_points, c, L, dt);
  COPYI(u_init, u_past, u_present, u_future, n_points);
  double dx = x[1] - x[0];
  double r = c * dt / dx;
  for (j = 0; j < t; j++) {
    for (i = 0; i < n_points - 1; i++) {
      u_future[i] = 2 * (1 - pow(r, 2)) * u_present[i] - u_past[i] +
                    pow(r, 2) * (u_present[i + 1] + u_present[i - 1]);
      COPY(u_init, u_past, u_present, u_future, n_points);
    }
  }
  for (i = 0; i < n_points; i++) {
    printf("%f \t %f \t %f\n", x[i], u_init[i], u_present[i]);
  }
  return 0;
}


x86 assembly (clang, -O0):
<main>:
push   %rbp
mov    %rsp,%rbp
sub    $0x90,%rsp
movl   $0x0,-0x4(%rbp)
movl   $0x3e8,-0x34(%rbp)
movsd  0xe87(%rip),%xmm0
movsd  %xmm0,-0x40(%rbp)
movsd  0xe72(%rip),%xmm0
movsd  %xmm0,-0x48(%rbp)
movsd  0xe5d(%rip),%xmm0
movsd  %xmm0,-0x58(%rbp)
movsd  0xe48(%rip),%xmm0
movsd  %xmm0,-0x60(%rbp)
movl   $0x2710,-0x6c(%rbp)
movslq -0x34(%rbp),%rax
shl    $0x3,%rax
mov    %eax,%edi
call   1070 <malloc@plt>
mov    %rax,-0x10(%rbp)
movslq -0x34(%rbp),%rax
shl    $0x3,%rax
mov    %eax,%edi
call   1070 <malloc@plt>
mov    %rax,-0x18(%rbp)
movslq -0x34(%rbp),%rax
shl    $0x3,%rax
mov    %eax,%edi
call   1070 <malloc@plt>
mov    %rax,-0x20(%rbp)
movslq -0x34(%rbp),%rax
shl    $0x3,%rax
mov    %eax,%edi
call   1070 <malloc@plt>
mov    %rax,-0x28(%rbp)
movslq -0x34(%rbp),%rax
shl    $0x3,%rax
mov    %eax,%edi
call   1070 <malloc@plt>
mov    %rax,-0x30(%rbp)
movsd  -0x40(%rbp),%xmm0
divsd  -0x48(%rbp),%xmm0
xor    %edi,%edi
call   1080 <pow@plt>
movsd  %xmm0,-0x50(%rbp)
mov    -0x18(%rbp),%rdi
mov    -0x10(%rbp),%rsi
mov    -0x34(%rbp),%edx
movsd  -0x50(%rbp),%xmm0
movsd  -0x58(%rbp),%xmm1
call   1050 <IC@plt>
mov    -0x18(%rbp),%rdi
mov    -0x10(%rbp),%rsi
mov    -0x30(%rbp),%rdx
mov    -0x34(%rbp),%ecx
movsd  -0x50(%rbp),%xmm0
movsd  -0x58(%rbp),%xmm1
movsd  -0x60(%rbp),%xmm2
call   1060 <PT@plt>
mov    -0x18(%rbp),%rdi
mov    -0x20(%rbp),%rsi
mov    -0x28(%rbp),%rdx
mov    -0x30(%rbp),%rcx
mov    -0x34(%rbp),%r8d
call   1090 <COPYI@plt>
mov    -0x10(%rbp),%rax
movsd  0x8(%rax),%xmm0
mov    -0x10(%rbp),%rax
subsd  (%rax),%xmm0
movsd  %xmm0,-0x78(%rbp)
movsd  -0x50(%rbp),%xmm0
mulsd  -0x60(%rbp),%xmm0
divsd  -0x78(%rbp),%xmm0
movsd  %xmm0,-0x80(%rbp)
movl   $0x0,-0x68(%rbp)
mov    -0x68(%rbp),%eax
cmp    -0x6c(%rbp),%eax
jge    13d6 <main+0x266>
movl   $0x0,-0x64(%rbp)
mov    -0x64(%rbp),%eax
mov    -0x34(%rbp),%ecx
sub    $0x1,%ecx
cmp    %ecx,%eax
jge    13c3 <main+0x253>
movsd  -0x80(%rbp),%xmm0
mov    $0x2,%edi
call   1080 <pow@plt>
movsd  0xd2d(%rip),%xmm1
subsd  %xmm0,%xmm1
movsd  0xd19(%rip),%xmm0
mulsd  %xmm1,%xmm0
mov    -0x28(%rbp),%rax
movslq -0x64(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm2
mov    -0x20(%rbp),%rax
movslq -0x64(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm1
movq   %xmm1,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x88(%rbp)
ff
movsd  -0x80(%rbp),%xmm0
mov    $0x2,%edi
call   1080 <pow@plt>
movsd  -0x88(%rbp),%xmm1
ff
mov    -0x28(%rbp),%rax
mov    -0x64(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm2
mov    -0x28(%rbp),%rax
mov    -0x64(%rbp),%ecx
sub    $0x1,%ecx
movslq %ecx,%rcx
addsd  (%rax,%rcx,8),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
mov    -0x30(%rbp),%rax
movslq -0x64(%rbp),%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x18(%rbp),%rdi
mov    -0x20(%rbp),%rsi
mov    -0x28(%rbp),%rdx
mov    -0x30(%rbp),%rcx
mov    -0x34(%rbp),%r8d
call   1030 <COPY@plt>
mov    -0x64(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x64(%rbp)
jmp    12d3 <main+0x163>
jmp    13c8 <main+0x258>
mov    -0x68(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x68(%rbp)
jmp    12c0 <main+0x150>
movl   $0x0,-0x64(%rbp)
mov    -0x64(%rbp),%eax
cmp    -0x34(%rbp),%eax
jge    142a <main+0x2ba>
mov    -0x10(%rbp),%rax
movslq -0x64(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x18(%rbp),%rax
movslq -0x64(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm1
mov    -0x28(%rbp),%rax
movslq -0x64(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm2
lea    0xc19(%rip),%rdi
call   1040 <printf@plt>
mov    -0x64(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x64(%rbp)
jmp    13dd <main+0x26d>
xor    %eax,%eax
add    $0x90,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<main>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x28,%rsp
mov    $0x1f40,%edi
call   1070 <malloc@plt>
mov    %rax,%r14
mov    $0x1f40,%edi
call   1070 <malloc@plt>
mov    %rax,%r15
mov    $0x1f40,%edi
call   1070 <malloc@plt>
mov    %rax,%r12
mov    $0x1f40,%edi
call   1070 <malloc@plt>
mov    %rax,%rbx
mov    $0x1f40,%edi
call   1070 <malloc@plt>
mov    %rax,%r13
movsd  0xe39(%rip),%xmm0
xor    %ebp,%ebp
xor    %edi,%edi
call   1080 <pow@plt>
movsd  %xmm0,0x8(%rsp)
movsd  0xe2a(%rip),%xmm1
mov    %r15,%rdi
mov    %r14,%rsi
mov    $0x3e8,%edx
call   1050 <IC@plt>
movsd  0xe1a(%rip),%xmm2
mov    %r15,%rdi
mov    %r14,%rsi
mov    %r13,%rdx
mov    $0x3e8,%ecx
movsd  0x8(%rsp),%xmm0
movsd  0xdf6(%rip),%xmm1
call   1060 <PT@plt>
mov    %r15,%rdi
mov    %r12,%rsi
mov    %rbx,%rdx
mov    %r13,%rcx
mov    $0x3e8,%r8d
call   1090 <COPYI@plt>
movsd  0x8(%r14),%xmm0
mov    %r14,0x10(%rsp)
subsd  (%r14),%xmm0
movsd  0x8(%rsp),%xmm1
mulsd  0xdc4(%rip),%xmm1
divsd  %xmm0,%xmm1
movapd %xmm1,%xmm0
movsd  %xmm1,0x8(%rsp)
nopw   0x0(%rax,%rax,1)
mov    %rbp,0x18(%rsp)
xor    %r14d,%r14d
nopl   0x0(%rax,%rax,1)
movsd  0x8(%rsp),%xmm0
mov    $0x2,%edi
call   1080 <pow@plt>
movsd  0xd90(%rip),%xmm1
subsd  %xmm0,%xmm1
addsd  %xmm1,%xmm1
mulsd  (%rbx,%r14,8),%xmm1
subsd  (%r12,%r14,8),%xmm1
movsd  %xmm1,0x20(%rsp)
movsd  0x8(%rsp),%xmm0
mov    $0x2,%edi
call   1080 <pow@plt>
movsd  0x8(%rbx,%r14,8),%xmm1
addsd  -0x8(%rbx,%r14,8),%xmm1
lea    0x1(%r14),%rbp
mulsd  %xmm0,%xmm1
addsd  0x20(%rsp),%xmm1
movsd  %xmm1,0x0(%r13,%r14,8)
mov    %r15,%rdi
mov    %r12,%rsi
mov    %rbx,%rdx
mov    %r13,%rcx
mov    $0x3e8,%r8d
call   1030 <COPY@plt>
mov    %rbp,%r14
cmp    $0x3e7,%rbp
jne    1270 <main+0x100>
mov    0x18(%rsp),%rbp
add    $0x1,%ebp
cmp    $0x2710,%ebp
jne    1260 <main+0xf0>
xor    %ebp,%ebp
lea    0xd07(%rip),%r12
mov    0x10(%rsp),%r14
xchg   %ax,%ax
movsd  (%r14,%rbp,8),%xmm0
movsd  (%r15,%rbp,8),%xmm1
movsd  (%rbx,%rbp,8),%xmm2
mov    %r12,%rdi
call   1040 <printf@plt>
add    $0x1,%rbp
cmp    $0x3e8,%rbp
jne    1320 <main+0x1b0>
xor    %eax,%eax
add    $0x28,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
@.str = [14 x i8] c"%f \09 %f \09 %f\0A\00"
define i32 @main() {
%1 = alloca i32
%2 = alloca double*
%3 = alloca double*
%4 = alloca double*
%5 = alloca double*
%6 = alloca double*
%7 = alloca i32
%8 = alloca double
%9 = alloca double
%10 = alloca double
%11 = alloca double
%12 = alloca double
%13 = alloca i32
%14 = alloca i32
%15 = alloca i32
%16 = alloca double
%17 = alloca double
store i32 0, i32* %1
store i32 1000, i32* %7
store double 4.000000e+01, double* %8
store double 1.000000e-02, double* %9
store double 1.000000e+02, double* %11
store double 5.000000e-04, double* %12
store i32 10000, i32* %15
%18 = load i32, i32* %7
%19 = sext i32 %18 to i64
%20 = mul i64 8, %19
%21 = trunc i64 %20 to i32
%22 = call double* @malloc(i32 %21)
store double* %22, double** %2
%23 = load i32, i32* %7
%24 = sext i32 %23 to i64
%25 = mul i64 8, %24
%26 = trunc i64 %25 to i32
%27 = call double* @malloc(i32 %26)
store double* %27, double** %3
%28 = load i32, i32* %7
%29 = sext i32 %28 to i64
%30 = mul i64 8, %29
%31 = trunc i64 %30 to i32
%32 = call double* @malloc(i32 %31)
store double* %32, double** %4
%33 = load i32, i32* %7
%34 = sext i32 %33 to i64
%35 = mul i64 8, %34
%36 = trunc i64 %35 to i32
%37 = call double* @malloc(i32 %36)
store double* %37, double** %5
%38 = load i32, i32* %7
%39 = sext i32 %38 to i64
%40 = mul i64 8, %39
%41 = trunc i64 %40 to i32
%42 = call double* @malloc(i32 %41)
store double* %42, double** %6
%43 = load double, double* %8
%44 = load double, double* %9
%45 = fdiv double %43, %44
%46 = call double @pow(double %45, i32 0)
store double %46, double* %10
%47 = load double*, double** %3
%48 = load double*, double** %2
%49 = load i32, i32* %7
%50 = load double, double* %10
%51 = load double, double* %11
%52 = call i32 @IC(double* %47, double* %48, i32 %49, double %50, double %51)
%53 = load double*, double** %3
%54 = load double*, double** %2
%55 = load double*, double** %6
%56 = load i32, i32* %7
%57 = load double, double* %10
%58 = load double, double* %11
%59 = load double, double* %12
%60 = call i32 @PT(double* %53, double* %54, double* %55, i32 %56, double %57, double %58, double %59)
%61 = load double*, double** %3
%62 = load double*, double** %4
%63 = load double*, double** %5
%64 = load double*, double** %6
%65 = load i32, i32* %7
%66 = call i32 @COPYI(double* %61, double* %62, double* %63, double* %64, i32 %65)
%67 = load double*, double** %2
%68 = getelementptr inbounds double, double* %67, i64 1
%69 = load double, double* %68
%70 = load double*, double** %2
%71 = getelementptr inbounds double, double* %70, i64 0
%72 = load double, double* %71
%73 = fsub double %69, %72
store double %73, double* %16
%74 = load double, double* %10
%75 = load double, double* %12
%76 = fmul double %74, %75
%77 = load double, double* %16
%78 = fdiv double %76, %77
store double %78, double* %17
store i32 0, i32* %14
br label %79
79: ; preds = %136, %0
%80 = load i32, i32* %14
%81 = load i32, i32* %15
%82 = icmp slt i32 %80, %81
br i1 %82, label %83, label %139
83: ; preds = %79
store i32 0, i32* %13
br label %84
84: ; preds = %132, %83
%85 = load i32, i32* %13
%86 = load i32, i32* %7
%87 = sub nsw i32 %86, 1
%88 = icmp slt i32 %85, %87
br i1 %88, label %89, label %135
89: ; preds = %84
%90 = load double, double* %17
%91 = call double @pow(double %90, i32 2)
%92 = fsub double 1.000000e+00, %91
%93 = fmul double 2.000000e+00, %92
%94 = load double*, double** %5
%95 = load i32, i32* %13
%96 = sext i32 %95 to i64
%97 = getelementptr inbounds double, double* %94, i64 %96
%98 = load double, double* %97
%99 = load double*, double** %4
%100 = load i32, i32* %13
%101 = sext i32 %100 to i64
%102 = getelementptr inbounds double, double* %99, i64 %101
%103 = load double, double* %102
%104 = fneg double %103
%105 = call double @llvm.fmuladd.f64(double %93, double %98, double %104)
%106 = load double, double* %17
%107 = call double @pow(double %106, i32 2)
%108 = load double*, double** %5
%109 = load i32, i32* %13
%110 = add nsw i32 %109, 1
%111 = sext i32 %110 to i64
%112 = getelementptr inbounds double, double* %108, i64 %111
%113 = load double, double* %112
%114 = load double*, double** %5
%115 = load i32, i32* %13
%116 = sub nsw i32 %115, 1
%117 = sext i32 %116 to i64
%118 = getelementptr inbounds double, double* %114, i64 %117
%119 = load double, double* %118
%120 = fadd double %113, %119
%121 = call double @llvm.fmuladd.f64(double %107, double %120, double %105)
%122 = load double*, double** %6
%123 = load i32, i32* %13
%124 = sext i32 %123 to i64
%125 = getelementptr inbounds double, double* %122, i64 %124
store double %121, double* %125
%126 = load double*, double** %3
%127 = load double*, double** %4
%128 = load double*, double** %5
%129 = load double*, double** %6
%130 = load i32, i32* %7
%131 = call i32 @COPY(double* %126, double* %127, double* %128, double* %129, i32 %130)
br label %132
132: ; preds = %89
%133 = load i32, i32* %13
%134 = add nsw i32 %133, 1
store i32 %134, i32* %13
br label %84
135: ; preds = %84
br label %136
136: ; preds = %135
%137 = load i32, i32* %14
%138 = add nsw i32 %137, 1
store i32 %138, i32* %14
br label %79
139: ; preds = %79
store i32 0, i32* %13
br label %140
140: ; preds = %161, %139
%141 = load i32, i32* %13
%142 = load i32, i32* %7
%143 = icmp slt i32 %141, %142
br i1 %143, label %144, label %164
144: ; preds = %140
%145 = load double*, double** %2
%146 = load i32, i32* %13
%147 = sext i32 %146 to i64
%148 = getelementptr inbounds double, double* %145, i64 %147
%149 = load double, double* %148
%150 = load double*, double** %3
%151 = load i32, i32* %13
%152 = sext i32 %151 to i64
%153 = getelementptr inbounds double, double* %150, i64 %152
%154 = load double, double* %153
%155 = load double*, double** %5
%156 = load i32, i32* %13
%157 = sext i32 %156 to i64
%158 = getelementptr inbounds double, double* %155, i64 %157
%159 = load double, double* %158
%160 = call i32 @printf(i8* getelementptr inbounds ([14 x i8], [14 x i8]* @.str, i64 0, i64 0), double %149, double %154, double %159)
br label %161
161: ; preds = %144
%162 = load i32, i32* %13
%163 = add nsw i32 %162, 1
store i32 %163, i32* %13
br label %140
164: ; preds = %140
ret i32 0
}

LLVM IR (-O2):
@.str = [14 x i8] c"%f \09 %f \09 %f\0A\00"
define i32 @main() {
%1 = tail call double* @malloc(i32 8000)
%2 = tail call double* @malloc(i32 8000)
%3 = tail call double* @malloc(i32 8000)
%4 = tail call double* @malloc(i32 8000)
%5 = tail call double* @malloc(i32 8000)
%6 = tail call double @pow(double 4.000000e+03, i32 0)
%7 = tail call i32 @IC(double* %2, double* %1, i32 1000, double %6, double 1.000000e+02)
%8 = tail call i32 @PT(double* %2, double* %1, double* %5, i32 1000, double %6, double 1.000000e+02, double 5.000000e-04)
%9 = tail call i32 @COPYI(double* %2, double* %3, double* %4, double* %5, i32 1000)
%10 = getelementptr inbounds double, double* %1, i64 1
%11 = load double, double* %10
%12 = load double, double* %1
%13 = fsub double %11, %12
%14 = fmul double %6, 5.000000e-04
%15 = fdiv double %14, %13
br label %16
16: ; preds = %0, %41
%17 = phi i32 [ 0, %0 ], [ %42, %41 ]
br label %18
18: ; preds = %16, %18
%19 = phi i64 [ 0, %16 ], [ %30, %18 ]
%20 = tail call double @pow(double %15, i32 2)
%21 = fsub double 1.000000e+00, %20
%22 = fmul double %21, 2.000000e+00
%23 = getelementptr inbounds double, double* %4, i64 %19
%24 = load double, double* %23
%25 = getelementptr inbounds double, double* %3, i64 %19
%26 = load double, double* %25
%27 = fneg double %26
%28 = tail call double @llvm.fmuladd.f64(double %22, double %24, double %27)
%29 = tail call double @pow(double %15, i32 2)
%30 = add nuw nsw i64 %19, 1
%31 = getelementptr inbounds double, double* %4, i64 %30
%32 = load double, double* %31
%33 = add nsw i64 %19, -1
%34 = getelementptr inbounds double, double* %4, i64 %33
%35 = load double, double* %34
%36 = fadd double %32, %35
%37 = tail call double @llvm.fmuladd.f64(double %29, double %36, double %28)
%38 = getelementptr inbounds double, double* %5, i64 %19
store double %37, double* %38
%39 = tail call i32 @COPY(double* %2, double* %3, double* %4, double* %5, i32 1000)
%40 = icmp eq i64 %30, 999
br i1 %40, label %41, label %18
41: ; preds = %18
%42 = add nuw nsw i32 %17, 1
%43 = icmp eq i32 %42, 10000
br i1 %43, label %44, label %16
44: ; preds = %41, %44
%45 = phi i64 [ %53, %44 ], [ 0, %41 ]
%46 = getelementptr inbounds double, double* %1, i64 %45
%47 = load double, double* %46
%48 = getelementptr inbounds double, double* %2, i64 %45
%49 = load double, double* %48
%50 = getelementptr inbounds double, double* %4, i64 %45
%51 = load double, double* %50
%52 = tail call i32 @printf(i8* getelementptr inbounds ([14 x i8], [14 x i8]* @.str, i64 0, i64 0), double %47, double %49, double %51)
%53 = add nuw nsw i64 %45, 1
%54 = icmp eq i64 %53, 1000
br i1 %54, label %55, label %44
55: ; preds = %44
ret i32 0
}