Problem with spec block in literate haskell file - haskell

I have this block of code on my literate haskell file
\end{code}
\paragraph{Valorização}
Codigo em C
\begin{spec}
double co(double x, int n){
double a = 1;
double b = -1 * x * x / 2;
double c = 12;
double d = 18;
for(; n > 0; n--){
a = a + b;
b = b * (-1 * x * x) / c;
c = c + d;
d = 8 + d;
}
return a;
}
\end{spec}
\subsection*{Problema 4}
What's happening is, when using lhs2tex and the pdflatex, what's inside the spec block is being completely ignored, and everything after it is forward, like it has a tab before it... Maybe this is something common? I'm not used to this... First time using it
By the way, if I remove the spec block everything else is formatted correctly

The following answer is based on speculation. If you would provide an MCVE—a short .lhs file that clearly demonstrates the issue—perhaps a better answer could emerge.
I think the issue is that lhs2TeX is not meant for C code. It gets confused by the spec block, thinks that it is Haskell code, and outputs problematic TeX commands. In fact, I can't even get your posted code past pdflatex—the .tex is that broken. You can use a different mechanism to output C code. The minted package should do.
\documentclass{article}
%include lhs2TeX.fmt
\usepackage{minted}
\setlength{\parindent}{0pt}
\begin{document}
Some C code:
\begin{minted}{c}
double co(double x, int n){
double a = 1;
double b = -1 * x * x / 2;
double c = 12;
double d = 18;
for(; n > 0; n--){
a = a + b;
b = b * (-1 * x * x) / c;
c = c + d;
d = 8 + d;
}
return a;
}
\end{minted}
It can be directly translated into Haskell:
\begin{code}
co :: Double -> Int -> Double
co x = worker 1 (-1 * x * x / 2) 12 18
where worker a _ _ _ 0 = a
worker a b c d n = worker (a + b) (b * (-1 * x * x) / c) (c + d) (8 + d) (n - 1)
\end{code}
As you can see, \textit{Haskell} code passes through just fine.
\end{document}
PS: The weird for-loop can be written while(n-- > 0) { ... }, no?

Related

Why does x = x * y / z give a different result from x *= y / z for integers?

I have the following function:
pub fn s_v1(n: &u64) -> u64 {
let mut x: u64 = 1;
for i in 1..=*n {
x = x * (*n + i) / i;
}
x
}
This code gives the correct answer for s_v1(&20) == 137846528820
However, if I change the line in the for loop to x *= (*n + i) / i;
The answer changes to s_v1(&20) == 16094453760
Why are the results different? Isn't x = x * y the same as x *= y ?
Because * and / have the same precedence with left associativity, the expression is not
x * ((*n + i) / i)
(which is the same as x *= (*n + i) / i) but
(x * (*n + i)) / i
As others have indicated, there are two problems:
a*=b/c is equivalent to a=a*(b/c) and not to a=a*b/c (which is implicitly a=(a*b)/c).
/ denotes division according to the types of the operands. In this case the operands are both integers, and therefore / denotes integer division discarding any remainder, and therefore (a*b)/c is not the same as a*(b/c) (unless b is an exact multiple of c).
If you want to replace the line in the loop, you'd need to split the two operations:
for i in 1..=*n {
x *= *n + i;
x /= i;
}
One disadvantage of this algorithm is that it will not produce correct results when the answer should be between MAXINT/2n and MAXINT. For that, you actually need to take advantage of what you were attempting to do:
for i in 1..=*n {
if (*n % i == 0) {
x *= *n / i + 1;
} else if (x % i == 0) {
x /= i;
x *= *n + i;
} else {
x *= *n + i;
x /= i;
}
}

maximum volume of a box with perimeter and area given

Here's the link to the question..
http://www.codechef.com/problems/J7
I figured out that 2 edges have to be equal in order to give the maximum volume, and then used x, x, a*x as the lengths of the three edges to write the equations -
4*x + 4*x + 4*a*x = P (perimeter) and,
2*x^2 + 4*(a*x *x) = S (total area of the box)
so from the first equation I got x in terms of P and a, and then substituted it in the second equation and then got a quadratic equation with the unknown being a. and then I used the greater root of a and got x.
But this method seems to be giving the wrong answer! :|
I know that there isn't any logical error in this. Maybe some formatting error?
Here's the main code that I've written :
{
public static void main(String[] args)
{
TheBestBox box = new TheBestBox();
reader = box.new InputReader(System.in);
writer = box.new OutputWriter(System.out);
getAttributes();
writer.flush();
reader.close();
writer.close();
}
public static void getAttributes()
{
t = reader.nextInt(); // t is the number of test cases in the question
for (int i = 0; i < t; i++)
{
p = reader.nextInt(); // p is the perimeter given as input
area = reader.nextInt(); // area of the whole sheet, given as input
a = findRoot(); // the fraction by which the third side differs by the first two
side = (double) p / (4 * (2 + a)); // length of the first and the second sides (equal)
height = a * side; // assuming that the base is a square, the height has to be the side which differs from the other two
// writer.println(side * side * height);
// System.out.printf("%.2f\n", (side * side * height));
writer.println(String.format("%.2f", (side * side * height))); // just printing out the final answer
}
}
public static double findRoot() // the method to find the 2 possible fractions by which the height can differ from the other two sides and return the bigger one of them
{
double a32, b, discriminant, root1, root2;
a32 = 32 * area - p * p;
b = 32 * area - 2 * p * p;
discriminant = Math.sqrt(b * b - 4 * 8 * area * a32);
double temp;
temp = 2 * 8 * area;
root1 = (- b + discriminant) / temp;
root2 = (- b - discriminant) / temp;
return Math.max(root1, root2);
}
}
could someone please help me out with this? Thank You. :)
I also got stuck in this question and realized that can be done by making equation of V(volume) in terms of one side say 'l' and using differentiation to find maximum volume in terms of any one side 'l'.
So, equations are like this :-
P = 4(l+b+h);
S = 2(l*b+b*h+l*h);
V = l*b*h;
so equation in l for V = (l^3) - (l^2)P/4 + lS/2 -------equ(1)
After differentiation we get:-
d(V)/d(l) = 3*(l^2) - l*P/2 + S/2;
to get max V we need to equate above equation to zero(0) and get the value of l.
So, solutions to a quadratic equation will be:-
l = ( P + sqrt((P^2)-24S) ) / 24;
so substitute this l in equation(1) to get max volume.

Initial Conditions in OpenModelica

Will somebody please explain why the initial conditions are properly taken care of in the following openmodelica model compiled and simulated in OMEdit v1.9.1 beta2 in Windows, but if line 5 is commentd and 6 uncommented (x,y) is initialized to (0.5,0)?
Thank you.
class Pendulum "Planar Pendulum"
constant Real PI = 3.141592653589793;
parameter Real m = 1,g = 9.81,L = 0.5;
Real F "Force of the Rod";
output Real x(start=L*sin(PI/4)) ,y(start=-0.35355);
//output Real x(start = L * sin(PI / 4)), y(start=-L*sin(PI/4));
output Real vx,vy;
equation
m * der(vx) = -x / L * F;
m * der(vy) = (-y / L * F) - m * g;
der(x) = vx;
der(y) = vy;
x ^ 2 + y ^ 2 = L ^ 2;
end Pendulum;
The short answer is that initial values are treated merely as hints, you have to add the fixed=true attribute to force them as in:
output Real x(start=L*cos(PI/4),fixed=true);
If initialized variables are constrained, the fixed attribute should not be used on all initialized variables but on a 'proper' subset, in this case on just one.
The long answer can be found here

Why is this integer not incrementing twice? [duplicate]

This question already has answers here:
C# Increment operator (++) question:Why am i getting wrong output?
(5 answers)
Closed 8 years ago.
I am confused by the results of the code below. Why does 'b' retain a seemingly incorrect value when doing these operations?
int a = 0;
int b = 5;
a = b++;
b = b++;
Console.WriteLine("For b = b++; b=" + b.ToString()); // b should be 7 but it's 6
a = 0;
b = 5;
a = b--;
b = b--;
Console.WriteLine("For b = b--; b=" + b.ToString()); // b should be 3 but it's 4
a = 0;
b = 5;
a = b + 1;
b = b + 1;
Console.WriteLine("For b = b++; b=" + b.ToString());
Output
b=6
b=4
b=6
Can anyone explain this behavior in C# and how it's working?
That's indeed the behavior of postfix operators, as detailed here.
For instance, when you write:
b = b++;
The following happens:
The current value of b is saved,
b is incremented,
The saved value of b is produced by the postfix ++ operator,
The value produced by the operator is assigned to b.
Therefore, b will indeed be assigned its original value, and the incremented value is lost.
Because the ++ and -- operators when placed after the value will evaluate to the value itself, and then increment/decrement the value after the evaluation.
So:
int a = 0;
int b = a++;
After running this code, b will equal 0 and a will equal 1.
This is as opposed to using the operators as prefixes:
int a = 0;
int b = ++a;
After running this code, b will equal 1 and a will equal 1.
This is documented behavior and has been around for a long time.
The instruction a=b++ is stored on the stack but not evaluated because it was not used after that.
To get the correct result, make that instruction have a sense fro example change that line:
Console.WriteLine("For b = b++; b=" + b.ToString());
by that one:
Console.WriteLine("For a = b++; a=" + a.ToString());
Console.WriteLine("For b = b++; b=" + b.ToString()); //should give 7
When you use
int a = 0;
int b = 5;
a = b++;
b = b++;
You set a to be 6, and after that you set b to be 6.
When you write b to commandline, it presents 6 because a was never used when incrementing b.
If you want to use a as well, you'd have to make
int a = 1;
int b = 5;
b = b++;
b += a;
Console.WriteLine("For b = a + b++; b=" + b.ToString());
But overall I don't see any use in this kind of incrementation.

Please explain this color blending mode formula so I can replicate it in PHP/ImageMagick

I've been trying to use ImageMagick to replicate Photoshops Colour Blend Mode. I found the following formulas in an online guide but I don't know what they mean. Do I just need to swap certain channels?
A while ago I reversed engineered Photoshop blending modes.
Have a look here:
http://www.kineticsystem.org/?q=node/13
And here below the code I use to convert between HSY (Hue, Saturation, Luminosity) to and from RGB (Red, Green, Blue). Photoshop use something called Hexacones to calculate the saturation.
Giovanni
/**
* This is the formula used by Photoshop to convert a color from
* RGB (Red, Green, Blue) to HSY (Hue, Saturation, Luminosity).
* The hue is calculated using the exacone approximation of the saturation
* cone.
* #param rgb The input color RGB normalized components.
* #param hsy The output color HSY normalized components.
*/
public static void rgbToHsy(double rgb[], double hsy[]) {
double r = Math.min(Math.max(rgb[0], 0d), 1d);
double g = Math.min(Math.max(rgb[1], 0d), 1d);
double b = Math.min(Math.max(rgb[2], 0d), 1d);
double h;
double s;
double y;
// For saturation equals to 0 any value of hue are valid.
// In this case we choose 0 as a default value.
if (r == g && g == b) { // Limit case.
s = 0d;
h = 0d;
} else if ((r >= g) && (g >= b)) { // Sector 0: 0° - 60°
s = r - b;
h = 60d * (g - b) / s;
} else if ((g > r) && (r >= b)) { // Sector 1: 60° - 120°
s = g - b;
h = 60d * (g - r) / s + 60d;
} else if ((g >= b) && (b > r)) { // Sector 2: 120° - 180°
s = g - r;
h = 60d * (b - r) / s + 120d;
} else if ((b > g) && (g > r)) { // Sector 3: 180° - 240°
s = b - r;
h = 60d * (b - g) / s + 180d;
} else if ((b > r) && (r >= g)) { // Sector 4: 240° - 300°
s = b - g;
h = 60d * (r - g) / s + 240d;
} else { // Sector 5: 300° - 360°
s = r - g;
h = 60d * (r - b) / s + 300d;
}
y = R * r + G * g + B * b;
// Approximations erros can cause values to exceed bounds.
hsy[0] = h % 360;
hsy[1] = Math.min(Math.max(s, 0d), 1d);
hsy[2] = Math.min(Math.max(y, 0d), 1d);
}
/**
* This is the formula used by Photoshop to convert a color from
* HSY (Hue, Saturation, Luminosity) to RGB (Red, Green, Blue).
* The hue is calculated using the exacone approximation of the saturation
* cone.
* #param hsy The input color HSY normalized components.
* #param rgb The output color RGB normalized components.
*/
public static void hsyToRgb(double hsy[], double rgb[]) {
double h = hsy[0] % 360;
double s = Math.min(Math.max(hsy[1], 0d), 1d);
double y = Math.min(Math.max(hsy[2], 0d), 1d);
double r;
double g;
double b;
double k; // Intermediate variable.
if (h >= 0d && h < 60d) { // Sector 0: 0° - 60°
k = s * h / 60d;
b = y - R * s - G * k;
r = b + s;
g = b + k;
} else if (h >= 60d && h < 120d) { // Sector 1: 60° - 120°
k = s * (h - 60d) / 60d;
g = y + B * s + R * k;
b = g - s;
r = g - k;
} else if (h >= 120d && h < 180d) { // Sector 2: 120° - 180°
k = s * (h - 120d) / 60d;
r = y - G * s - B * k;
g = r + s;
b = r + k;
} else if (h >= 180d && h < 240d) { // Sector 3: 180° - 240°
k = s * (h - 180d) / 60d;
b = y + R * s + G * k;
r = b - s;
g = b - k;
} else if (h >= 240d && h < 300d) { // Sector 4: 240° - 300°
k = s * (h - 240d) / 60d;
g = y - B * s - R * k;
b = g + s;
r = g + k;
} else { // Sector 5: 300° - 360°
k = s * (h - 300d) / 60d;
r = y + G * s + B * k;
g = r - s;
b = r - k;
}
// Approximations erros can cause values to exceed bounds.
rgb[0] = Math.min(Math.max(r, 0d), 1d);
rgb[1] = Math.min(Math.max(g, 0d), 1d);
rgb[2] = Math.min(Math.max(b, 0d), 1d);
}
Wikipedia has a good article on blend modes
http://en.wikipedia.org/wiki/Blend_modes
They give formulas for Multiply, Screen and Overlay modes.
Multiply
Formula: Result Color = (Top Color) * (Bottom Color) /255
Screen
Formula: Result Color = 255 - [((255 - Top Color)*(255 - Bottom Color))/255]
Overlay
Formula: Result Color = if (Bottom Color < 128)
then (2 * Top Color * Bottom Color / 255)
else (255 - 2 * (255 - Top Color) * (255 - Bottom Color) / 255)
A is the Foreground pixel, B is the Background pixel, C is the new pixel. H is the Hue value for each pixel, S is the Saturation value, L is the Luminance value, and Y is the Brightness value. (Not sure what the difference is between luminance and brightness though.
Anyway, in the first example the Hue(H) and Saturation(S) values of the new pixel(C) are copied from the Foreground pixel(A) while the Brightness(Y) value of the new pixel is taken from the Luminance(L) value of the Background(B) pixel.
These color blending formulas are quite tricky if you need to incorporate also the alpha channel. I was not able to reproduce the blending of Photoshop, but Gimp works like this:
Color mix_hsv(
ColorMixMode::Enum mode, // blending mode
Color cd, // destination color (bottom pixel)
Color cs) // source color (top pixel)
{
// Modify the source color
float dh, ds, dv; // destination hsv
float sh, ss, sv; // source hsv
cd.GetHsv(dh, ds, dv);
cs.GetHsv(sh, ss, sv);
switch (mode) {
case HUE: cs.InitFromHsv(sh, ds, dv); break;
case SATURATION: cs.InitFromHsv(dh, ss, dv); break;
case COLOR: cs.InitFromHsv(sh, ss, dv); break;
case LUMINOSITY: cs.InitFromHsv(dh, ds, sv); break;
}
cs.A = std::min(cd.A, cs.A);
// Blend the modified source color onto the destination color
unsigned char cd_A_orig = cd.A;
cd = mix(NORMAL, cd, cs); // normal blending
cd.A = cd_A_orig;
return cd;
}
If you use premultiplied alpha, don't forget to correctly handle it in the above code. I was not able to find the code for blending in Gimp's source code, but the resulting images are very similar.
Photoshop's color blending is clearly different, so if anyone finds a way to implement it, please let us all know :o)
Miso

Resources