@@ -92,12 +92,12 @@ end function factorial
9292
9393 ! > Create colormap from Lagrange interpolation of control colors
9494 pure function lagrange (colors , levels ) result(map)
95- integer , dimension (:,:), intent (in ) :: colors
95+ integer , intent (in ) :: colors(:,:)
9696 integer , intent (in ), optional :: levels
97- integer , dimension (:,:), allocatable :: map
98- real (wp), dimension (:,:), allocatable :: map_r
99- integer :: order, i, j, levels_
100- real (wp) :: t
97+ integer , allocatable :: map(:,:)
98+ integer :: order, i, j, n, levels_
99+ real (wp) :: t, r, g, b
100+ real (wp), allocatable :: L(:)
101101
102102 ! Set default value for levels
103103 if (present (levels)) then
@@ -110,51 +110,50 @@ pure function lagrange(colors, levels) result(map)
110110 order = size (colors, 1 ) - 1
111111 if (order < 1 ) error stop " Error: At least two control colors are required for Lagrange interpolation."
112112
113- allocate (map_r(levels_,3 ), map(levels_,3 )) ! 3 for RGB
113+ allocate (map(levels_, 3 ))
114+ n = order + 1
114115 do i = 1 , levels_
115116 t = real (i-1 , wp) / real (levels_-1 , wp)
116- map_r(i,:) = 0.0_wp
117- do j = 0 , order
118- map_r(i,1 ) = dot_product (lagrange_poly(t,order+1 ), real (colors(:,1 ), wp))
119- map_r(i,2 ) = dot_product (lagrange_poly(t,order+1 ), real (colors(:,2 ), wp))
120- map_r(i,3 ) = dot_product (lagrange_poly(t,order+1 ), real (colors(:,3 ), wp))
117+ L = lagrange_poly(t, n)
118+ r = 0.0_wp
119+ g = 0.0_wp
120+ b = 0.0_wp
121+ do j = 1 , n
122+ r = r + L(j) * real (colors(j,1 ), wp)
123+ g = g + L(j) * real (colors(j,2 ), wp)
124+ b = b + L(j) * real (colors(j,3 ), wp)
121125 end do
122- map(i,1 ) = min (255 , max (0 , nint (map_r(i, 1 ) )))
123- map(i,2 ) = min (255 , max (0 , nint (map_r(i, 2 ) )))
124- map(i,3 ) = min (255 , max (0 , nint (map_r(i, 3 ) )))
126+ map(i,1 ) = min (255 , max (0 , nint (r )))
127+ map(i,2 ) = min (255 , max (0 , nint (g )))
128+ map(i,3 ) = min (255 , max (0 , nint (b )))
125129 end do
126130 end function lagrange
127131
128132 ! > Interpolates a Lagrange polynomial defined by n equidistant points between 0 and 1
129133 pure function lagrange_poly (t , n ) result(B)
130134 real (wp), intent (in ) :: t
131- integer , intent (in ) :: n ! ! order + 1
132- real (wp), allocatable :: B(: )
135+ integer , intent (in ) :: n
136+ real (wp) :: B(n )
133137 integer :: i, l
134- real (wp), dimension (:), allocatable :: Xth
138+ real (wp) :: inv, xi, xl
135139
136- ! Create an array of n equidistant points between 0 and 1
137- allocate (Xth(n), source = 0.0_wp )
138- do i = 1 , n - 1
139- Xth(i) = 0.0_wp + real (i - 1 , wp) * (1.0_wp - (0.0_wp )) / real (n - 1 , wp)
140- end do
141- Xth(n) = 1.0_wp
142-
143- allocate (B(n), source = 1.0_wp )
144- l = 0
145- i = 0
140+ if (n <= 1 ) error stop " Error: Number of points n must be greater than 1 in lagrange_poly."
141+ if (t < 0.0_wp .or. t > 1.0_wp ) error stop " Error: t must be in [0,1] in lagrange_poly."
142+ B = 1.0_wp
143+ inv = 1.0_wp / real (n-1 , wp)
146144 do i = 1 , n
145+ xi = real (i-1 , wp) * inv
147146 do l = 1 , n
148147 if (l /= i) then
149- if (abs (Xth(i) - Xth(l)) >= tiny (0.0_wp )) then
150- B(i) = B(i)* (t - Xth(l))/ (Xth(i) - Xth(l))
148+ xl = real (l-1 , wp) * inv
149+ if (abs (xi- xl) >= tiny (0.0_wp )) then
150+ B(i) = B(i)* (t- xl)/ (xi- xl)
151151 end if
152152 end if
153153 end do
154154 end do
155155 end function lagrange_poly
156156
157-
158157 ! > Normalize the input real array to the range [0, 1]
159158 pure function scale_real_real (real_array ,a ,b ) result(real_scaled_array)
160159 real (wp), dimension (:), intent (in ) :: real_array
0 commit comments