সি #, জাভা এবং অনুরূপ গণিত-ভিত্তিক কোডের পাঠযোগ্যতার উন্নতি করতে কেউ কী করতে পারে? [বন্ধ]


16

একজন সি প্রোগ্রামার এবং একটি সি # প্রোগ্রামার উভয় হিসাবে, সি # সম্পর্কে আমি পছন্দ করি না এমন একটিগুলির মধ্যে হ'ল ভার্বোস গণিতের ক্রিয়াগুলি কীভাবে হয়। প্রতিবার আপনাকে উদাহরণস্বরূপ কোনও সিন, কোসাইন বা পাওয়ার ফাংশন ব্যবহার করতে হবে, আপনাকে ম্যাথ স্ট্যাটিক ক্লাসটি প্রিপেন্ড করতে হবে। সমীকরণ নিজেই বেশ সহজ যখন এটি খুব দীর্ঘ কোড বাড়ে। আপনার যদি টাইপকাস্ট ডেটা টাইপ করতে হয় তবে সমস্যাটি আরও খারাপ হয়। ফলস্বরূপ, আমার মতে, পাঠযোগ্যতার ক্ষতি হয়। উদাহরণ স্বরূপ:

double x =  -Math.Cos(X) * Math.Sin(Z) + Math.Sin(X) * Math.Sin(Y) * Math.Cos(Z);

সহজভাবে বিরোধিতা হিসাবে

double x = -cos(X) * sin(Z) + sin(X) * sin(Y) * cos(Z);

জাভার মতো অন্যান্য ল্যাংগুলিতেও এটি ঘটে।

আমি নিশ্চিত নই যে এই প্রশ্নের আসলে সমাধান আছে কিনা, তবে আমি জানতে চাই যে ম্যাথ কোডের পাঠযোগ্যতার উন্নতি করতে সি # বা জাভা প্রোগ্রামাররা কোনও কৌশল ব্যবহার করেন কিনা। আমি বুঝতে পারছি যে সি # / জাভা / ইত্যাদি। ম্যাটল্যাব বা অনুরূপ মতো গণিত-ভিত্তিক ভাষা নয়, তাই এটি উপলব্ধি করে। তবে মাঝেমধ্যে কোনওটির জন্যও গণিতের কোড লিখতে হবে এবং যদি এটি আরও পাঠযোগ্য হয় তবে এটি দুর্দান্ত।


আমি কোনও বিশেষভাবে জানি না, তবে আপনি সম্ভবত একটি বীজগণিত গ্রন্থাগার সন্ধান করতে পারেন যা আপনাকে স্ট্রিং সহ গণিত ফাংশনগুলি সংজ্ঞায়িত করার অনুমতি দেয়, যদিও কিছু পারফরম্যান্স পেনাল্টি থাকবে।
raptortech97


7
আপনি কিছুটা অতিরিক্ত ভার্বোসটি নিয়ে উদ্বেগ প্রকাশ করেছেন তবুও আনন্দের সাথে আনারি অপারেটরগুলির সাথে '*' এর মধ্যে একটি '+' লুকিয়ে রাখুন - সমস্ত ব্রেস ছাড়াই - আমার সন্দেহ হয় যে আপনার অগ্রাধিকারগুলি ভুল আছে।
mattnz

1
এটি কেবল একটি উদাহরণ ছিল, তবে ভাল বিষয়
9a3eedi

6
সি # 6.0, আপনি লিখতে সক্ষম হবে: using System.Math; … double x = -Cos(X) * Sin(Z) + Sin(X) * Sin(Y) * Cos(Z);
এসভিউ

উত্তর:


14

আপনি স্থানীয় ফাংশনগুলি সংজ্ঞায়িত করতে পারেন যা গ্লোবাল স্ট্যাটিক ফাংশনগুলিকে কল করে। আশা করি সংকলকটি মোড়কগুলিকে ইনলাইন করবে এবং তারপরে জেআইটি সংকলক প্রকৃত ক্রিয়াকলাপের জন্য কঠোর সমাবেশ কোড তৈরি করবে। উদাহরণ স্বরূপ:

class MathHeavy
{
    private double sin(double x) { return Math.sin(x); }
    private double cos(double x) { return Math.cos(x); }

    public double foo(double x, double y)
    {
        return sin(x) * cos(y) - cos(x) * sin(y);
    }
}

আপনি এমন ফাংশনও তৈরি করতে পারেন যা সাধারণ গণিত ক্রিয়াকে একক ক্রিয়াকলাপে বান্ডিল করে bu এটি আপনার কোডগুলিতে ফাংশন পছন্দ করে sinএবং cosউপস্থিত হয় এমন উদাহরণগুলির সংখ্যা হ্রাস করবে , যার ফলে বিশ্বব্যাপী স্থিতিশীল ফাংশনগুলিকে অনুরোধ করার খাঁটিতা কম লক্ষণীয় হয়ে উঠবে। উদাহরণ স্বরূপ:

public Point2D rotate2D(double angle, Point2D p)
{
    double x = p.x * Math.cos(angle) - p.y * Math.sin(angle);
    double y = p.x * Math.sin(angle) + p.y * Math.cos(angle);

    return new Point2D(x, y)
}

আপনি পয়েন্ট এবং আবর্তনের স্তরে কাজ করছেন এবং অন্তর্নিহিত ট্রিগ ফাংশন সমাহিত করা হয়।


... আমি কেন এটি ভেবে
দেখিনি

আমি এটিকে সঠিক উত্তর হিসাবে চিহ্নিত করেছি কারণ এটি একটি ক্রস প্ল্যাটফর্ম সমাধান যা যথেষ্ট সহজ। অন্যান্য সমাধানগুলিও সঠিক। আমি সত্যই বিশ্বাস করতে পারছি না যদিও আমি এটি ভেবে দেখিনি :) এটি কেবল খুব সুস্পষ্ট
9a3eedi

31

জাভাতে, কিছু জিনিসকে কম ভার্বোস বানানোর জন্য অনেকগুলি সরঞ্জাম উপলব্ধ রয়েছে, আপনাকে কেবল তাদের সম্পর্কে সচেতন হতে হবে। এই ক্ষেত্রে দরকারী যেটি হ'ল staticআমদানি ( টিউটোরিয়াল পৃষ্ঠা , উইকিপিডিয়া )।

এক্ষেত্রে,

import static java.lang.Math.*;

class Demo {
    public static void main (String[] args) {
        double X = 42.0;
        double Y = 4.0;
        double Z = PI;

        double x =  -cos(X) * sin(Z) + sin(X) * sin(Y) * cos(Z);
        System.out.println(x);
    }
}

বেশ সুন্দরভাবে চালায় ( আদর্শ )। ম্যাথ ক্লাসের সকলের একটি স্থিতিশীল আমদানি করা কিছুটা ভারী , তবে আপনি যদি খুব বেশি গণিত করছেন, তবে এটির জন্য বলা যেতে পারে।

স্ট্যাটিক আমদানি আপনাকে এই শ্রেণীর নামস্থানে স্থিতিশীল ক্ষেত্র বা পদ্ধতি আমদানি করতে এবং প্যাকেজের নাম প্রয়োজন ছাড়াই এটি প্রার্থনা করতে দেয়। আপনি প্রায়ই যেখানে Junit পরীক্ষা ক্ষেত্রে এই এটি import static org.junit.Assert.*;সব পেতে পাওয়া যায় দাবি করে পাওয়া যায়।


দুর্দান্ত উত্তর। আমি এই বৈশিষ্ট্য সম্পর্কে সচেতন ছিলাম না। জাভা এর কোন সংস্করণের অধীনে এটি সম্ভব?
9a3eedi

@ 9a3eedi এটি প্রথম জাভা 1.5 তে উপলব্ধ করা হয়েছিল।

চমৎকার কৌশল। আমি এটা পছন্দ করি. +1 টি।
র্যান্ডল কুক

1
@RandallCook জাভা 1.4 দিন, মানুষ কিছু চাই public interface Constants { final static public double PI = 3.14; }এবং তারপর public class Foo implements Constantsসব ক্লাসের ইন্টারফেসে ধ্রুবক অ্যাক্সেস পেতে। এটি একটি বিরাট গন্ডগোল করেছে। সুতরাং, 1.5 এর সাথে, কোনও ইন্টারফেস বাস্তবায়ন না করে নির্দিষ্ট ধ্রুবক এবং স্থির ফাংশনগুলিতে টানা অনুমতি দেওয়ার জন্য স্থিতিশীল আমদানি যুক্ত করা হয়েছিল।

3
আপনি নির্বাচিতভাবে কিছু ফাংশন আমদানি করতে পারেনimport static java.lang.Math.cos;
রাচেট ফ্রিক

5

সি # 6.0 এর সাহায্যে আপনি স্ট্যাটিক আমদানির বৈশিষ্ট্যটি ব্যবহার করতে পারেন।

আপনার কোড হতে পারে:

using static System.Math;
using static System.Console;
namespace SomeTestApp
{
    class Program
    {
        static void Main(string[] args)
        {
            double X = 123;
            double Y = 5;
            double Z = 10;
            double x = -Cos(X) * Sin(Z) + Sin(X) * Sin(Y) * Cos(Z);
            WriteLine(x); //Without System, since it is imported 
        }
    }
}

দেখুন: স্ট্যাটিক ব্যবহারের বিবৃতি (এসি # 6.0 ভাষা পূর্বরূপ)

অন্য সি # 6.0 "সিনট্যাকটিক চিনি" বৈশিষ্ট্যটি হ'ল স্ট্যাটিক ব্যবহারের প্রবর্তন। এই বৈশিষ্ট্যটির সাথে, কোনও স্ট্যাটিক পদ্ধতিতে অনুরোধ করার সময় ধরণের একটি স্পষ্ট উল্লেখ উল্লেখ দূর করা সম্ভব । তদ্ব্যতীত, স্ট্যাটিক ব্যবহার আপনাকে একটি নির্দিষ্ট জায়গার উপরে কেবলমাত্র নামকরণের মধ্যে সমস্ত এক্সটেনশন পদ্ধতির পরিবর্তে এক্সটেনশন পদ্ধতিগুলি প্রবর্তন করতে দেয়।

সম্পাদনা: ভিজ্যুয়াল স্টুডিও ২০১৫ সাল থেকে, সিটিপি জানুয়ারীতে প্রকাশিত হয়েছে, স্ট্যাটিক আমদানির জন্য স্পষ্ট কীওয়ার্ড প্রয়োজন static। মত:

using static System.Console;

4

এখানে অন্যান্য ভাল উত্তরের পাশাপাশি, আমি উল্লেখযোগ্য গাণিতিক জটিলতাগুলির জন্য ( ডিএসএল- গড় ব্যবহারের ক্ষেত্রে নয়, তবে সম্ভবত কিছু আর্থিক বা একাডেমিক প্রকল্প) জন্য ডিএসএলকে সুপারিশ করতে পারি ।

এক্সটেক্সটের মতো ডিএসএল প্রজন্মের সরঞ্জামের সাহায্যে আপনি আপনার নিজের সরলিকৃত গাণিতিক ব্যাকরণটি সংজ্ঞায়িত করতে পারেন যা জাভা (বা অন্য কোনও ভাষা) আপনার সূত্রগুলির প্রতিনিধিত্ব সহ একটি শ্রেণি তৈরি করতে পারে।

ডিএসএল এক্সপ্রেশন:

domain GameMath {
    formula CalcLinearDistance(double): sqrt((x2 - x1)^2 + (y2 - y1)^2)
}

উত্পাদিত আউটপুট:

public class GameMath {
    public static double CalcLinearDistance(int x1, int x2, int y1, int y2) {
        return Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
    }
}

এইরকম একটি সাধারণ উদাহরণে, ব্যাকরণ এবং একলাইপস প্লাগইন তৈরির সুবিধাগুলি কার্যকর হবে না তবে আরও জটিল প্রকল্পগুলির জন্য এটি দুর্দান্ত উপকার পেতে পারে, বিশেষত ডিএসএল যদি ব্যবসায় লোকেরা বা একাডেমিক গবেষকদের একটি আরামদায়ক মধ্যে আনুষ্ঠানিক নথিগুলি বজায় রাখতে সক্ষম করে থাকে ভাষা এবং নিশ্চিত করুন যে তাদের কাজটি প্রকল্পের বাস্তবায়নের ভাষায় নির্ভুলভাবে অনুবাদ হয়েছিল was


8
হ্যাঁ, সাধারণভাবে এবং সংজ্ঞা অনুসারে আপনি যখন কোনও নির্দিষ্ট ডোমেনে কাজ করেন তখন কোনও ডিএসএল কার্যকর হতে পারে। তবে, যদি এই ডিএসএলটি বিদ্যমান না থাকে, বা এটি প্রয়োজনীয়তার সাথে খাপ খায় না, আপনাকে এটি বজায় রাখতে হবে, যা সমস্যাযুক্ত হতে পারে। এছাড়াও, নির্দিষ্ট প্রশ্নের জন্য ("আমি প্রতিবার ম্যাথ ক্লাস না লিখে পাপ, কোস, ... পদ্ধতি / ফাংশন কীভাবে ব্যবহার করতে পারি"), ডিএসএল সম্ভবত একটি বড় আকারের সমাধান is
mgoeminne

4

সি # তে আপনি এক্সটেনশন পদ্ধতিগুলি ব্যবহার করতে পারেন।

একবার আপনি "পোস্টফিক্স" স্বরলিপি ব্যবহার করতে লাগলে নীচে খুব সুন্দরভাবে পড়ে:

public static class DoubleMathExtensions
{
    public static double Cos(this double n)
    {
        return Math.Cos(n);
    }

    public static double Sin(this double n)
    {
        return Math.Sin(n);
    }

    ...
}

var x =  -X.Cos() * Z.Sin() + X.Sin() * Y.Sin() * Z.Cos();

দুর্ভাগ্যক্রমে অপারেটর প্রাধান্য এখানে নেতিবাচক সংখ্যার সাথে কাজ করার সময় জিনিসগুলিকে কিছুটা খারাপ করে তোলে g আপনি যদি Math.Cos(-X)পরিবর্তে গণনা করতে চান -Math.Cos(X)তবে সংখ্যাটি প্রথম বন্ধনে আবদ্ধ করতে হবে:

var x = (-X).Cos() ...

1
ঘটনাচক্রে, এটি এক্সটেনশন সম্পত্তিগুলির জন্য একটি দুর্দান্ত ব্যবহারের কেস তৈরি করবে এবং এমনকি সম্পত্তি হিসাবে পদ্ধতি হিসাবে আপত্তিজনক ব্যবহারের জন্য একটি বৈধ ব্যবহারের কেস!
Jörg ডব্লু মিটাগ

এটাই আমি ভেবেছিলাম। x.Sin()কিছু সামঞ্জস্য নিতে পারে, কিন্তু আমি এক্সটেনশন পদ্ধতিগুলি অপব্যবহার করি এবং এটি ব্যক্তিগতভাবে আমার প্রথম ঝোঁক।
ওয়ার্নারসিডি

2

সি #: র‌্যান্ডাল কুকের উত্তরের একটি প্রকরণ , যা আমি পছন্দ করি কারণ এটি কোডের গাণিতিক "চেহারা" বর্ধিত পদ্ধতির চেয়ে বেশি বজায় রাখে তা হল একটি মোড়ক ব্যবহার করা তবে কলগুলি আবৃত করার পরিবর্তে ফাংশন রেফারেন্স ব্যবহার করা। আমি ব্যক্তিগতভাবে মনে করি এটি কোডটিকে আরও পরিষ্কার দেখায়, তবে এটি মূলত একই জিনিসটি করছে।

আমি র‌্যান্ডাল এর মোড়ানো ফাংশন, আমার ফাংশন উল্লেখগুলি এবং সরাসরি কলগুলি সহ সামান্য লিনকিপ্যাড পরীক্ষা প্রোগ্রামটি নক করলাম।

ফাংশন রেফারেন্সড কলগুলি মূলত সরাসরি কলগুলির একই সময় নেয়। মোড়ানো ফাংশনগুলি ধারাবাহিকভাবে ধীরে ধীরে - যদিও বিশাল পরিমাণে নয়।

কোডটি এখানে:

void Main()
{
    MyMathyClass mmc = new MyMathyClass();

    System.Diagnostics.Stopwatch sw = System.Diagnostics.Stopwatch.StartNew();

    for(int i = 0; i < 50000000; i++)
        mmc.DoStuff(1, 2, 3);

    "Function reference:".Dump();
    sw.Elapsed.Dump();      
    sw.Restart();

    for(int i = 0; i < 50000000; i++)
        mmc.DoStuffWrapped(1, 2, 3);

    "Wrapped function:".Dump();
    sw.Elapsed.Dump();      
    sw.Restart();

    "Direct call:".Dump();
    for(int i = 0; i < 50000000; i++)
        mmc.DoStuffControl(1, 2, 3);

    sw.Elapsed.Dump();
}

public class MyMathyClass
{
    // References
    public Func<double, double> sin;
    public Func<double, double> cos;
    public Func<double, double> tan;
    // ...

    public MyMathyClass()
    {
        sin = System.Math.Sin;
        cos = System.Math.Cos;
        tan = System.Math.Tan;
        // ...
    }

    // Wrapped functions
    public double wsin(double x) { return Math.Sin(x); }
    public double wcos(double x) { return Math.Cos(x); }
    public double wtan(double x) { return Math.Tan(x); }

    // Calculation functions
    public double DoStuff(double x, double y, double z)
    {
        return sin(x) + cos(y) + tan(z);
    }

    public double DoStuffWrapped(double x, double y, double z)
    {
        return wsin(x) + wcos(y) + wtan(z);
    }

    public double DoStuffControl(double x, double y, double z)
    {
        return Math.Sin(x) + Math.Cos(y) + Math.Tan(z);
    }
}

ফলাফল:

Function reference:
00:00:06.5952113

Wrapped function:
00:00:07.2570828

Direct call:
00:00:06.6396096

1

স্কেল ব্যবহার করুন! আপনি প্রতীকী অপারেটরগুলি সংজ্ঞায়িত করতে পারেন, এবং আপনার পদ্ধতির জন্য আপনার প্যারেন্স দরকার নেই। এটি গণিতের উপায় ব্যাখ্যা করতে সহজ করে তোলে ।

উদাহরণস্বরূপ, স্কেলা এবং জাভাতে একই গণনা এমন কিছু হতে পারে:

// Scala
def angle(u: Vec, v: Vec) = (u*v) / sqrt((u*u)*(v*v))

// Java
public double angle(u: Vec, v: Vec) {
  return u.dot(v) / sqrt(u.dot(u)*v.dot(v));
}

এটি বেশ দ্রুত যুক্ত হয় up


2
স্কেলা সিএলআর উপলভ্য নয়, কেবল জেভিএম। সুতরাং এটি সত্যিই সি # এর একটি কার্যকর বিকল্প নয়।
বেন rudgers

@ বেনডুজার্স - সি # জেভিএম-তে চলবে না, সুতরাং এটি জাভা-র সত্যিই কার্যকর বিকল্প নয়, যা প্রশ্নটিও জিজ্ঞাসা করেছিল। প্রশ্নটি উল্লেখ করে না যে এটি সিএলআর হতে হবে!
রেক্স কের

সম্ভবত আমি লুডাইটাইট, তবে কোডটি পরিষ্কার হওয়ার সুবিধার সাথে "*" এর পরিবর্তে "ডট" এর জন্য দুটি অতিরিক্ত অক্ষর, অর্থ প্রদানের জন্য খুব কম দাম বলে মনে হচ্ছে। তবুও, একটি ভাল উত্তর।
user949300
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.