3次方程式ソルバ

by uwi
♥0 | Line 105 | Modified 2009-09-21 22:49:28 | MIT License
play

ActionScript3 source code

/**
 * Copyright uwi ( http://wonderfl.net/user/uwi )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/6fZA
 */

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
    <mx:Script>
    <![CDATA[
    
        // @see http://www.gifu-nct.ac.jp/sizen/okada/3eq/3eq.html
        private function onClick() : void
        {
            var a : Number = Number(cora.text);
            var b : Number = Number(corb.text);
            var c : Number = Number(corc.text);
            var d : Number = Number(cord.text);
            
            ans.text = "";
            if(a == 0){
                ans.text += "x = " + format(solveQEC(b, c, d)) + "\n";
                return;
            }
            
            var p : Number = -b * b / (3 * a) + c;
            var q : Number = 2 * b * b * b / (27 * a * a) - b * c / (3 * a) + d;
            ans.text += "p = " + p + "\n";
            ans.text += "q = " + q + "\n";
            
            var B : Array = solveQEC(a, q, -p * p * p / (27 * a * a));
            ans.text += "B = " + format(B) + "\n";
            
            var i : int;
            if(B.length > 0){
                var norm : Number;
                var theta : Number;
                if(B[0][1] == 0){
                    norm = B[0][0] * B[0][0];
                    theta = 0;
                }else{
                    norm = B[0][0] * B[0][0] + B[0][1] * B[0][1];
                    theta = Math.acos(B[0][0] / Math.sqrt(norm));
                    if(B[0][1] < 0)theta = -theta;
                    theta /= 3;
                }
                
                var A : Array = [];
                var n3 : Number = Math.pow(norm, 1.0 / 6);
                for(i = 0;i < 1 + (B[0][1] != 0 ? 1 : 0) + (n3 > 0 ? 1 : 0);i++){
                    A.push([
                        n3 * Math.cos(theta + i * 120 * Math.PI / 180),
                        n3 * Math.sin(theta + i * 120 * Math.PI / 180)
                        ]);
                }
                ans.text += "A = " + format(A) + "\n";
            
                var X : Array = [];
                for each(var aa : Array in A)X.push(2 * aa[0]);
                ans.text += "X = " + X + "\n";
            
                var x : Array = [];
                for each(var xx : Number in X)x.push(xx - b / (3 * a));
                ans.text += "x = " + x + "\n";
            }
        }
        
        private function format(a : Array) : String
        {
            var ret : Array = [];
            for each(var c : Array in a){
                if(c[1] == 0){
                    ret.push(c[0]);
                }else{
                    if(c[0] == 0){
                        ret.push(c[1] + "i");
                    }else{
                        if(c[1] > 0){
                            ret.push(c[0] + "+" + c[1] + "i");
                        }else{
                            ret.push(c[0] + "" + c[1] + "i");
                        }
                    }
                }
            }
            return ret.join(",");
        }
        
        private function solveQEC(a : Number, b : Number, c : Number) : Array
        {
            if(a == 0){
                if(b == 0){
                    return [];
                }else{
                    return [[-c / b, 0]];
                }
            }else{
                var D : Number = b * b - 4 * a * c;
                if(D > 0){
                    return [[(-b + Math.sqrt(D)) / (2 * a), 0], [(-b - Math.sqrt(D)) / (2 * a), 0]];
                }else if(D == 0){
                    return [[-b / (2 * a), 0]];
                }else{
                    return [[-b / (2 * a), Math.sqrt(-D) / (2 * a)], [-b / (2 * a), -Math.sqrt(-D) / (2 * a)]];
                }
            }
        }
        /*
        private function solveQE(a : Number, b : Number, c : Number) : Array
        {
            if(a == 0){
                if(b == 0){
                    return [];
                }else{
                    return [-c / b];
                }
            }else{
                var D : Number = b * b - 4 * a * c;
                if(D > 0){
                    return [(-b + Math.sqrt(D)) / (2 * a), (-b - Math.sqrt(D)) / (2 * a)];
                }else if(D == 0){
                    return [-b / (2 * a)];
                }else{
                    return [];
                }
            }
        }
        */
    ]]>
    </mx:Script>
    
    <mx:HBox horizontalGap="2">
        <mx:TextInput id="cora" width="50" text="1" textAlign="right" />
        <mx:Label text="x^3+" />
        <mx:TextInput id="corb" width="50" text="2" textAlign="right" />
        <mx:Label text="x^2+" />
        <mx:TextInput id="corc" width="50" text="3" textAlign="right" />
        <mx:Label text="x+" />
        <mx:TextInput id="cord" width="50" text="4" textAlign="right" />
        <mx:Label text="=0" />
    </mx:HBox>
    <mx:Button id="submit" label="Solve it!" click="onClick()"/>
    <mx:TextArea id="ans" width="400" height="200" wordWrap="true" />
</mx:Application>